URL
https://opencores.org/ocsvn/ao68000/ao68000/trunk
Subversion Repositories ao68000
Compare Revisions
- This comparison shows the changes necessary to convert path
/ao68000
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/bench/sw_emulators/winuae/table68k
0,0 → 1,279
% 0: bit 0 |
% 1: bit 1 |
% c: condition code |
% C: condition codes, except F |
% f: direction |
% i: immediate |
% I: immediate, except 00 and ff |
% j: immediate 1..8 |
% J: immediate 0..15 |
% k: immediate 0..7 |
% K: immediate 0..63 |
% p: immediate 0..3 (CINV and CPUSH: cache field) |
% s: source mode |
% S: source reg |
% d: dest mode |
% D: dest reg |
% r: reg |
% z: size |
% |
% Actually, a sssSSS may appear as a destination, and |
% vice versa. The only difference between sssSSS and |
% dddDDD are the valid addressing modes. There is |
% no match for immediate and pc-rel. addressing modes |
% in case of dddDDD. |
% |
% Arp: --> -(Ar) |
% ArP: --> (Ar)+ |
% Ara: --> (Ar) |
% L: (xxx.L) |
% |
% Fields on a line: |
% 16 chars bitpattern : |
% CPU level / privilege level : |
% CPU level 0: 68000 |
% 1: 68010 |
% 2: 68020 |
% 3: 68030 |
% 4: 68040 |
% 5: 68060 (not used to produce a cputbl) |
% [Everything from 68020 possibly allows for FPU emulation] |
% privilege level 0: not privileged |
% 1: unprivileged only on 68000 (check regs.s) |
% 2: privileged (check regs.s) |
% 3: privileged if size == word (check regs.s) |
% Flags set by instruction: XNZVC : |
% Flags used by instruction: XNZVC : |
% - means flag unaffected / unused |
% 0 means flag reset |
% 1 means flag set |
% ? means programmer was too lazy to check or instruction may trap |
% + means instruction is conditional branch |
% everything else means flag set/used |
% / means instruction is unconditional branch/call |
% x means flag is unknown and well-behaved programs shouldn't check it |
% srcaddr status destaddr status : |
% bitmasks of |
% 1 means fetched |
% 2 means stored |
% 4 means jump offset |
% 8 means jump address |
% instruction |
% |
|
0000 0000 0011 1100:00:XNZVC:XNZVC:10: ORSR.B #1 |
0000 0000 0111 1100:02:?????:?????:10: ORSR.W #1 |
0000 0zz0 11ss sSSS:20:?????:?????:11: CHK2.z #1,s[!Dreg,Areg,Aipi,Apdi,Immd] |
0000 0000 zzdd dDDD:00:-NZ00:-----:13: OR.z #z,d[!Areg] |
0000 0010 0011 1100:00:XNZVC:XNZVC:10: ANDSR.B #1 |
0000 0010 0111 1100:02:?????:?????:10: ANDSR.W #1 |
0000 0010 zzdd dDDD:00:-NZ00:-----:13: AND.z #z,d[!Areg] |
0000 0100 zzdd dDDD:00:XNZVC:-----:13: SUB.z #z,d[!Areg] |
0000 0110 zzdd dDDD:00:XNZVC:-----:13: ADD.z #z,d[!Areg] |
0000 0110 11ss sSSS:20:?????:?????:10: CALLM s[!Dreg,Areg,Aipi,Apdi,Immd] |
0000 0110 11ss sSSS:20:?????:?????:10: RTM s[Dreg,Areg] |
0000 1000 00ss sSSS:00:--Z--:-----:11: BTST #1,s[!Areg,Immd] |
0000 1000 01ss sSSS:00:--Z--:-----:13: BCHG #1,s[!Areg,Immd,PC8r,PC16] |
0000 1000 10ss sSSS:00:--Z--:-----:13: BCLR #1,s[!Areg,Immd,PC8r,PC16] |
0000 1000 11ss sSSS:00:--Z--:-----:13: BSET #1,s[!Areg,Immd,PC8r,PC16] |
0000 1010 0011 1100:00:XNZVC:XNZVC:10: EORSR.B #1 |
0000 1010 0111 1100:02:?????:?????:10: EORSR.W #1 |
0000 1010 zzdd dDDD:00:-NZ00:-----:13: EOR.z #z,d[!Areg] |
0000 1100 zzss sSSS:00:-NZVC:-----:11: CMP.z #z,s[!Areg,Immd] |
|
0000 1010 11ss sSSS:20:?????:?????:13: CAS.B #1,s[!Dreg,Areg,Immd,PC8r,PC16] |
0000 1100 11ss sSSS:20:?????:?????:13: CAS.W #1,s[!Dreg,Areg,Immd,PC8r,PC16] |
0000 1100 1111 1100:20:?????:?????:10: CAS2.W #2 |
0000 1110 zzss sSSS:22:?????:?????:13: MOVES.z #1,s[!Dreg,Areg,Immd,PC8r,PC16] |
0000 1110 11ss sSSS:20:?????:?????:13: CAS.L #1,s[!Dreg,Areg,Immd,PC8r,PC16] |
0000 1110 1111 1100:20:?????:?????:10: CAS2.L #2 |
|
0000 rrr1 00dd dDDD:00:-----:-----:12: MVPMR.W d[Areg-Ad16],Dr |
0000 rrr1 01dd dDDD:00:-----:-----:12: MVPMR.L d[Areg-Ad16],Dr |
0000 rrr1 10dd dDDD:00:-----:-----:12: MVPRM.W Dr,d[Areg-Ad16] |
0000 rrr1 11dd dDDD:00:-----:-----:12: MVPRM.L Dr,d[Areg-Ad16] |
0000 rrr1 00ss sSSS:00:--Z--:-----:11: BTST Dr,s[!Areg] |
0000 rrr1 01ss sSSS:00:--Z--:-----:13: BCHG Dr,s[!Areg,Immd,PC8r,PC16] |
0000 rrr1 10ss sSSS:00:--Z--:-----:13: BCLR Dr,s[!Areg,Immd,PC8r,PC16] |
0000 rrr1 11ss sSSS:00:--Z--:-----:13: BSET Dr,s[!Areg,Immd,PC8r,PC16] |
|
0001 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.B s,d[!Areg] |
0010 DDDd ddss sSSS:00:-----:-----:12: MOVEA.L s,d[Areg] |
0010 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.L s,d[!Areg] |
0011 DDDd ddss sSSS:00:-----:-----:12: MOVEA.W s,d[Areg] |
0011 DDDd ddss sSSS:00:-NZ00:-----:12: MOVE.W s,d[!Areg] |
|
0100 0000 zzdd dDDD:00:XxZxC:X-Z--:30: NEGX.z d[!Areg] |
0100 0000 11dd dDDD:01:?????:?????:10: MVSR2.W d[!Areg] |
0100 0010 zzdd dDDD:00:-0100:-----:20: CLR.z d[!Areg] |
0100 0010 11dd dDDD:10:?????:?????:10: MVSR2.B d[!Areg] |
0100 0100 zzdd dDDD:00:XNZVC:-----:30: NEG.z d[!Areg] |
0100 0100 11ss sSSS:00:XNZVC:-----:10: MV2SR.B s[!Areg] |
0100 0110 zzdd dDDD:00:-NZ00:-----:30: NOT.z d[!Areg] |
0100 0110 11ss sSSS:02:?????:?????:10: MV2SR.W s[!Areg] |
0100 1000 0000 1rrr:20:-----:-----:31: LINK.L Ar,#2 |
0100 1000 00dd dDDD:00:X?Z?C:X-Z--:30: NBCD.B d[!Areg] |
0100 1000 0100 1kkk:20:?????:?????:10: BKPT #k |
0100 1000 01ss sSSS:00:-NZ00:-----:30: SWAP.W s[Dreg] |
0100 1000 01ss sSSS:00:-----:-----:00: PEA.L s[!Dreg,Areg,Aipi,Apdi,Immd] |
0100 1000 10dd dDDD:00:-NZ00:-----:30: EXT.W d[Dreg] |
0100 1000 10dd dDDD:00:-----:-----:02: MVMLE.W #1,d[!Dreg,Areg,Aipi] |
0100 1000 11dd dDDD:00:-NZ00:-----:30: EXT.L d[Dreg] |
0100 1000 11dd dDDD:00:-----:-----:02: MVMLE.L #1,d[!Dreg,Areg,Aipi] |
0100 1001 11dd dDDD:20:-NZ00:-----:30: EXT.B d[Dreg] |
0100 1010 zzss sSSS:00:-NZ00:-----:10: TST.z s |
0100 1010 11dd dDDD:00:?????:?????:30: TAS.B d[!Areg] |
0100 1010 1111 1100:00:?????:?????:00: ILLEGAL |
0100 1100 00ss sSSS:20:-NZVC:-----:13: MULL.L #1,s[!Areg] |
0100 1100 01ss sSSS:20:?????:?????:13: DIVL.L #1,s[!Areg] |
0100 1100 10ss sSSS:00:-----:-----:01: MVMEL.W #1,s[!Dreg,Areg,Apdi,Immd] |
0100 1100 11ss sSSS:00:-----:-----:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd] |
0100 1110 0100 JJJJ:00:-----:XNZVC:10: TRAP #J |
0100 1110 0101 0rrr:00:-----:-----:31: LINK.W Ar,#1 |
0100 1110 0101 1rrr:00:-----:-----:30: UNLK.L Ar |
0100 1110 0110 0rrr:02:-----:-----:10: MVR2USP.L Ar |
0100 1110 0110 1rrr:02:-----:-----:20: MVUSP2R.L Ar |
0100 1110 0111 0000:02:-----:-----:00: RESET |
0100 1110 0111 0001:00:-----:-----:00: NOP |
0100 1110 0111 0010:02:XNZVC:-----:10: STOP #1 |
0100 1110 0111 0011:02:XNZVC:-----:00: RTE |
0100 1110 0111 0100:10:?????:?????:10: RTD #1 |
0100 1110 0111 0101:00:-----:-----:00: RTS |
0100 1110 0111 0110:00:-----:XNZVC:00: TRAPV |
0100 1110 0111 0111:00:XNZVC:-----:00: RTR |
0100 1110 0111 1010:12:?????:?????:10: MOVEC2 #1 |
0100 1110 0111 1011:12:?????:?????:10: MOVE2C #1 |
0100 1110 10ss sSSS:00://///://///:80: JSR.L s[!Dreg,Areg,Aipi,Apdi,Immd] |
0100 rrr1 00ss sSSS:20:?????:?????:11: CHK.L s[!Areg],Dr |
0100 rrr1 10ss sSSS:00:?????:?????:11: CHK.W s[!Areg],Dr |
0100 1110 11ss sSSS:00://///://///:80: JMP.L s[!Dreg,Areg,Aipi,Apdi,Immd] |
0100 rrr1 11ss sSSS:00:-----:-----:02: LEA.L s[!Dreg,Areg,Aipi,Apdi,Immd],Ar |
|
0101 jjj0 01dd dDDD:00:-----:-----:13: ADDA.W #j,d[Areg] |
0101 jjj0 10dd dDDD:00:-----:-----:13: ADDA.L #j,d[Areg] |
0101 jjj0 zzdd dDDD:00:XNZVC:-----:13: ADD.z #j,d[!Areg] |
0101 jjj1 01dd dDDD:00:-----:-----:13: SUBA.W #j,d[Areg] |
0101 jjj1 10dd dDDD:00:-----:-----:13: SUBA.L #j,d[Areg] |
0101 jjj1 zzdd dDDD:00:XNZVC:-----:13: SUB.z #j,d[!Areg] |
0101 cccc 1100 1rrr:00:-----:-++++:31: DBcc.W Dr,#1 |
0101 cccc 11dd dDDD:00:-----:-++++:20: Scc.B d[!Areg] |
0101 cccc 1111 1010:20:?????:?????:10: TRAPcc #1 |
0101 cccc 1111 1011:20:?????:?????:10: TRAPcc #2 |
0101 cccc 1111 1100:20:?????:?????:00: TRAPcc |
|
% Bxx.L is 68020 only, but setting the CPU level to 2 would give illegal |
% instruction exceptions when compiling a 68000 only emulation, which isn't |
% what we want either. |
0110 0001 0000 0000:00://///://///:40: BSR.W #1 |
0110 0001 IIII IIII:00://///://///:40: BSR.B #i |
0110 0001 1111 1111:00://///://///:40: BSR.L #2 |
0110 CCCC 0000 0000:00:-----:-++++:40: Bcc.W #1 |
0110 CCCC IIII IIII:00:-----:-++++:40: Bcc.B #i |
0110 CCCC 1111 1111:00:-----:-++++:40: Bcc.L #2 |
|
0111 rrr0 iiii iiii:00:-NZ00:-----:12: MOVE.L #i,Dr |
|
1000 rrr0 zzss sSSS:00:-NZ00:-----:13: OR.z s[!Areg],Dr |
1000 rrr0 11ss sSSS:00:?????:?????:13: DIVU.W s[!Areg],Dr |
1000 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: SBCD.B d[Dreg],Dr |
1000 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: SBCD.B d[Areg-Apdi],Arp |
1000 rrr1 zzdd dDDD:00:-NZ00:-----:13: OR.z Dr,d[!Areg,Dreg] |
1000 rrr1 01dd dDDD:20:?????:?????:12: PACK d[Dreg],Dr |
1000 rrr1 01dd dDDD:20:?????:?????:12: PACK d[Areg-Apdi],Arp |
1000 rrr1 10dd dDDD:20:?????:?????:12: UNPK d[Dreg],Dr |
1000 rrr1 10dd dDDD:20:?????:?????:12: UNPK d[Areg-Apdi],Arp |
1000 rrr1 11ss sSSS:00:?????:?????:13: DIVS.W s[!Areg],Dr |
|
1001 rrr0 zzss sSSS:00:XNZVC:-----:13: SUB.z s,Dr |
1001 rrr0 11ss sSSS:00:-----:-----:13: SUBA.W s,Ar |
1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: SUBX.z d[Dreg],Dr |
1001 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: SUBX.z d[Areg-Apdi],Arp |
1001 rrr1 zzdd dDDD:00:XNZVC:-----:13: SUB.z Dr,d[!Areg,Dreg] |
1001 rrr1 11ss sSSS:00:-----:-----:13: SUBA.L s,Ar |
|
1011 rrr0 zzss sSSS:00:-NZVC:-----:11: CMP.z s,Dr |
1011 rrr0 11ss sSSS:00:-NZVC:-----:11: CMPA.W s,Ar |
1011 rrr1 11ss sSSS:00:-NZVC:-----:11: CMPA.L s,Ar |
1011 rrr1 zzdd dDDD:00:-NZVC:-----:11: CMPM.z d[Areg-Aipi],ArP |
1011 rrr1 zzdd dDDD:00:-NZ00:-----:13: EOR.z Dr,d[!Areg] |
|
1100 rrr0 zzss sSSS:00:-NZ00:-----:13: AND.z s[!Areg],Dr |
1100 rrr0 11ss sSSS:00:-NZ00:-----:13: MULU.W s[!Areg],Dr |
1100 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: ABCD.B d[Dreg],Dr |
1100 rrr1 00dd dDDD:00:XxZxC:X-Z--:13: ABCD.B d[Areg-Apdi],Arp |
1100 rrr1 zzdd dDDD:00:-NZ00:-----:13: AND.z Dr,d[!Areg,Dreg] |
1100 rrr1 01dd dDDD:00:-----:-----:33: EXG.L Dr,d[Dreg] |
1100 rrr1 01dd dDDD:00:-----:-----:33: EXG.L Ar,d[Areg] |
1100 rrr1 10dd dDDD:00:-----:-----:33: EXG.L Dr,d[Areg] |
1100 rrr1 11ss sSSS:00:-NZ00:-----:13: MULS.W s[!Areg],Dr |
|
1101 rrr0 zzss sSSS:00:XNZVC:-----:13: ADD.z s,Dr |
1101 rrr0 11ss sSSS:00:-----:-----:13: ADDA.W s,Ar |
1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: ADDX.z d[Dreg],Dr |
1101 rrr1 zzdd dDDD:00:XNZVC:X-Z--:13: ADDX.z d[Areg-Apdi],Arp |
1101 rrr1 zzdd dDDD:00:XNZVC:-----:13: ADD.z Dr,d[!Areg,Dreg] |
1101 rrr1 11ss sSSS:00:-----:-----:13: ADDA.L s,Ar |
|
1110 jjjf zz00 0RRR:00:XNZVC:-----:13: ASf.z #j,DR |
1110 jjjf zz00 1RRR:00:XNZ0C:-----:13: LSf.z #j,DR |
1110 jjjf zz01 0RRR:00:XNZ0C:X----:13: ROXf.z #j,DR |
1110 jjjf zz01 1RRR:00:-NZ0C:-----:13: ROf.z #j,DR |
1110 rrrf zz10 0RRR:00:XNZVC:X----:13: ASf.z Dr,DR |
1110 rrrf zz10 1RRR:00:XNZ0C:X----:13: LSf.z Dr,DR |
1110 rrrf zz11 0RRR:00:XNZ0C:X----:13: ROXf.z Dr,DR |
1110 rrrf zz11 1RRR:00:-NZ0C:-----:13: ROf.z Dr,DR |
1110 000f 11dd dDDD:00:XNZVC:-----:13: ASfW.W d[!Dreg,Areg] |
1110 001f 11dd dDDD:00:XNZ0C:-----:13: LSfW.W d[!Dreg,Areg] |
1110 010f 11dd dDDD:00:XNZ0C:X----:13: ROXfW.W d[!Dreg,Areg] |
1110 011f 11dd dDDD:00:-NZ0C:-----:13: ROfW.W d[!Dreg,Areg] |
|
1110 1000 11ss sSSS:20:?????:?????:11: BFTST #1,s[!Areg,Apdi,Aipi,Immd] |
1110 1001 11ss sSSS:20:?????:?????:11: BFEXTU #1,s[!Areg,Apdi,Aipi,Immd] |
1110 1010 11ss sSSS:20:?????:?????:13: BFCHG #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] |
1110 1011 11ss sSSS:20:?????:?????:11: BFEXTS #1,s[!Areg,Apdi,Aipi,Immd] |
1110 1100 11ss sSSS:20:?????:?????:13: BFCLR #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] |
1110 1101 11ss sSSS:20:?????:?????:11: BFFFO #1,s[!Areg,Apdi,Aipi,Immd] |
1110 1110 11ss sSSS:20:?????:?????:13: BFSET #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] |
1110 1111 11ss sSSS:20:?????:?????:13: BFINS #1,s[!Areg,Apdi,Aipi,Immd,PC8r,PC16] |
|
% floating point co processor |
1111 0010 00ss sSSS:20:?????:?????:11: FPP #1,s |
1111 0010 01ss sSSS:20:?????:?????:11: FDBcc #1,s[Areg-Dreg] |
1111 0010 01ss sSSS:20:?????:?????:11: FScc #1,s[!Areg,Immd,PC8r,PC16] |
1111 0010 0111 1010:20:?????:?????:10: FTRAPcc #1 |
1111 0010 0111 1011:20:?????:?????:10: FTRAPcc #2 |
1111 0010 0111 1100:20:?????:?????:00: FTRAPcc |
1111 0010 10KK KKKK:20:?????:?????:11: FBcc #K,#1 |
1111 0010 11KK KKKK:20:?????:?????:11: FBcc #K,#2 |
1111 0011 00ss sSSS:22:?????:?????:20: FSAVE s[!Dreg,Areg,Aipi,Immd,PC8r,PC16] |
1111 0011 01ss sSSS:22:?????:?????:10: FRESTORE s[!Dreg,Areg,Apdi,Immd] |
|
% 68030 MMU (allowed addressing modes not checked!) |
1111 0000 00ss sSSS:32:?????:?????:11: MMUOP030 s[Aind,Ad16,Ad8r,absl,absw],#1 |
|
% 68040/68060 instructions |
1111 0100 pp00 1rrr:42:-----:-----:02: CINVL #p,Ar |
1111 0100 pp01 0rrr:42:-----:-----:02: CINVP #p,Ar |
1111 0100 pp01 1rrr:42:-----:-----:00: CINVA #p |
1111 0100 pp10 1rrr:42:-----:-----:02: CPUSHL #p,Ar |
1111 0100 pp11 0rrr:42:-----:-----:02: CPUSHP #p,Ar |
1111 0100 pp11 1rrr:42:-----:-----:00: CPUSHA #p |
1111 0101 0000 0rrr:42:-----:-----:00: PFLUSHN Ara |
1111 0101 0000 1rrr:42:-----:-----:00: PFLUSH Ara |
1111 0101 0001 0rrr:42:-----:-----:00: PFLUSHAN Ara |
1111 0101 0001 1rrr:42:-----:-----:00: PFLUSHA Ara |
1111 0101 0100 1rrr:42:-----:-----:00: PTESTR Ara |
1111 0101 0110 1rrr:42:-----:-----:00: PTESTW Ara |
|
% destination register number is encoded in the following word |
1111 0110 0010 0rrr:40:-----:-----:12: MOVE16 ArP,AxP |
1111 0110 00ss sSSS:40:-----:-----:12: MOVE16 s[Dreg-Aipi],L |
1111 0110 00dd dDDD:40:-----:-----:12: MOVE16 L,d[Areg-Aipi] |
1111 0110 00ss sSSS:40:-----:-----:12: MOVE16 s[Aind],L |
1111 0110 00dd dDDD:40:-----:-----:12: MOVE16 L,d[Aipi-Aind] |
|
% 68060 |
1111 1000 0000 0000:52:?????:?????:10: LPSTOP #1 |
1111 0101 1000 1rrr:52:-----:-----:00: PLPAR Ara |
1111 0101 1100 1rrr:52:-----:-----:00: PLPAW Ara |
|
/trunk/bench/sw_emulators/winuae/ao.c
0,0 → 1,696
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
#include "ao.h" |
#include "readcpu.h" |
|
/* changes in WinUAE sources: |
* BCHG,BSET,BCLR,BTST: changes in table68k |
* RTD/illegal command: changes in table68k |
*/ |
|
uae_u32 get_wordi(uaecptr addr); |
uae_u8 *get_real_address(uaecptr addr); |
uae_u32 get_long(uaecptr addr); |
uae_u32 get_word(uaecptr addr); |
uae_u32 get_byte(uaecptr addr); |
void put_byte(uaecptr addr, uae_u32 b); |
void put_word(uaecptr addr, uae_u32 w); |
void put_long(uaecptr addr, uae_u32 l); |
|
void exception3 (uae_u32 opcode, uaecptr addr, uaecptr fault); |
void exception3i (uae_u32 opcode, uaecptr addr, uaecptr fault); |
void REGPARAM2 MakeSR (void); |
|
|
struct regstruct regs; |
|
const int areg_byteinc[] = { 1, 1, 1, 1, 1, 1, 1, 2 }; |
const int imm8_table[] = { 8, 1, 2, 3, 4, 5, 6, 7 }; |
|
int movem_index1[256]; |
int movem_index2[256]; |
int movem_next[256]; |
|
struct flag_struct regflags; |
|
|
//newcpu.h start |
uaecptr m68k_getpc (void) |
{ |
return (uaecptr)(regs.pc + ((uae_u8*)regs.pc_p - (uae_u8*)regs.pc_oldp)); |
} |
void m68k_setpc(uaecptr newpc) |
{ |
regs.pc_p = regs.pc_oldp = get_real_address (newpc); |
//AOregs.fault_pc = regs.pc = newpc; |
regs.pc = newpc; |
} |
|
void m68k_do_bsr (uaecptr oldpc, uae_s32 offset, uae_u32 opcode) |
{ |
//AO extra |
uaecptr spa = m68k_areg (regs, 7) - 4; |
if (spa & 1) { |
exception3write(opcode, m68k_getpc () + offset, spa); |
return; |
} |
//AO extra end |
|
m68k_areg (regs, 7) -= 4; |
put_long (m68k_areg (regs, 7), oldpc); |
m68k_incpc (offset); |
} |
void m68k_do_rts (void) |
{ |
//AO extra |
uaecptr pca = m68k_areg (regs, 7); |
if (pca & 1) { |
exception3 (0x4e75, m68k_getpc () + 2, pca); |
return; |
} |
uae_s32 pc = get_long (pca); |
m68k_areg (regs, 7) += 4; |
if (pc & 1) |
exception3i(0x4e75, m68k_getpc () + 2, pc); |
else |
m68k_setpc (pc); |
|
//m68k_setpc (get_long (m68k_areg (regs, 7))); |
//m68k_areg (regs, 7) += 4; |
} |
//newcpu.h end |
|
//cpu_prefetch.c - start |
uae_u32 get_word_prefetch (int o) |
{ |
uae_u32 v = regs.irc; |
regs.irc = get_wordi (m68k_getpc () + o); |
return v; |
} |
uae_u32 get_long_prefetch (int o) |
{ |
uae_u32 v = get_word_prefetch (o) << 16; |
v |= get_word_prefetch (o + 2); |
return v; |
} |
//cpu_prefetch.c - end |
|
void cpureset(void) |
{ |
} |
|
void uae_reset(int hardreset) { |
printf("processor blocked: yes\n"); |
} |
|
void m68k_setstopped(void) |
{ |
regs.stopped = 1; |
/* A traced STOP instruction drops through immediately without |
actually stopping. */ |
} |
|
//------------------------------------------------------------------- newcpu.c start |
|
/* Opcode of faulting instruction */ |
static uae_u16 last_op_for_exception_3; |
/* PC at fault time */ |
static uaecptr last_addr_for_exception_3; |
/* Address that generated the exception */ |
static uaecptr last_fault_for_exception_3; |
/* read (0) or write (1) access */ |
static int last_writeaccess_for_exception_3; |
/* instruction (1) or data (0) access */ |
static int last_instructionaccess_for_exception_3; |
/* instruction (0) or not instruction (1) */ |
static int last_wasgroup0or1_for_exception_3; |
|
cpuop_func *cpufunctbl[65536]; |
|
/* 68000 slow but compatible. */ |
extern const struct cputbl op_smalltbl_11_ff[]; |
|
void Exception (int nr, uaecptr oldpc); |
|
unsigned long REGPARAM2 op_illg (uae_u32 opcode) |
{ |
if ((opcode & 0xF000) == 0xF000) { |
Exception (0xB, 0); |
return 4; |
} |
if ((opcode & 0xF000) == 0xA000) { |
Exception (0xA, 0); |
return 4; |
} |
|
Exception (4, 0); |
return 4; |
} |
|
void fill_prefetch_slow (void) |
{ |
regs.ir = get_word (m68k_getpc ()); |
regs.irc = get_word (m68k_getpc () + 2); |
} |
|
// exception start |
|
//was Exception_normal(int nr, uaecptr oldpc) |
void Exception(int nr, uaecptr oldpc) |
{ |
// illegal, line 1111, line 1010, privilege, trace |
// left: interrupt |
if(nr == 4 || nr == 0xA || nr == 0xB || nr == 8 || nr == 9) { |
last_wasgroup0or1_for_exception_3 = 1; |
} |
|
uae_u32 currpc = m68k_getpc (), newpc; |
int sv = regs.s; |
|
if (nr >= 24 && nr < 24 + 8) |
nr = get_byte(0x00fffff1 | (nr << 1)); |
|
MakeSR(); |
|
if (!regs.s) { |
regs.usp = m68k_areg (regs, 7); |
m68k_areg (regs, 7) = regs.isp; |
regs.s = 1; |
} |
//AO extra |
regs.t1 = 0; |
|
//AO extra |
if (m68k_areg(regs, 7) & 1) { |
if (nr == 2 || nr == 3) |
m68k_setpc(last_addr_for_exception_3); |
uae_reset(1); /* there is nothing else we can do.. */ |
return; |
} |
if (nr == 2 || nr == 3) { |
uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); |
mode |= last_writeaccess_for_exception_3 ? 0 : 16; |
//AO extra |
mode |= last_wasgroup0or1_for_exception_3 ? 8 : 0; |
m68k_areg (regs, 7) -= 14; |
|
put_word (m68k_areg (regs, 7) + 0, mode); |
put_long (m68k_areg (regs, 7) + 2, last_fault_for_exception_3); |
put_word (m68k_areg (regs, 7) + 6, last_op_for_exception_3); |
put_word (m68k_areg (regs, 7) + 8, regs.sr); |
put_long (m68k_areg (regs, 7) + 10, last_addr_for_exception_3); |
|
last_wasgroup0or1_for_exception_3 = 1; |
goto kludge_me_do; |
} |
m68k_areg (regs, 7) -= 4; |
put_long (m68k_areg (regs, 7), currpc); |
m68k_areg (regs, 7) -= 2; |
put_word (m68k_areg (regs, 7), regs.sr); |
|
kludge_me_do: |
newpc = get_long (regs.vbr + 4 * nr); |
if (newpc & 1) { |
if (nr == 2 || nr == 3) { |
//AO extra |
m68k_setpc(last_addr_for_exception_3); |
uae_reset (1); /* there is nothing else we can do.. */ |
} |
else |
exception3i(regs.ir, m68k_getpc (), newpc); |
return; |
} |
m68k_setpc (newpc); |
fill_prefetch_slow (); |
|
last_wasgroup0or1_for_exception_3 = 0; |
//AOexception_trace (nr); |
} |
|
// exception end |
|
|
//exception3 start |
|
static void exception3f(uae_u32 opcode, uaecptr addr, uaecptr fault, int writeaccess, int instructionaccess) |
{ |
last_addr_for_exception_3 = addr; |
last_fault_for_exception_3 = fault; |
last_op_for_exception_3 = opcode; |
last_writeaccess_for_exception_3 = writeaccess; |
last_instructionaccess_for_exception_3 = instructionaccess; |
Exception(3, fault); |
} |
|
void exception3 (uae_u32 opcode, uaecptr addr, uaecptr fault) |
{ |
exception3f(opcode, addr, fault, 0, 0); |
} |
void exception3i (uae_u32 opcode, uaecptr addr, uaecptr fault) |
{ |
exception3f(opcode, addr, fault, 0, 1); |
} |
void exception3write(uae_u32 opcode, uaecptr addr, uaecptr fault) |
{ |
exception3f(opcode, addr, fault, 1, 0); |
} |
//exception3 end |
|
void REGPARAM2 MakeSR (void) |
{ |
regs.sr = ((regs.t1 << 15) | (regs.t0 << 14) |
| (regs.s << 13) | (regs.m << 12) | (regs.intmask << 8) |
| (GET_XFLG () << 4) | (GET_NFLG () << 3) |
| (GET_ZFLG () << 2) | (GET_VFLG () << 1) |
| GET_CFLG ()); |
} |
|
void REGPARAM2 MakeFromSR (void) |
{ |
int oldm = regs.m; |
int olds = regs.s; |
|
SET_XFLG ((regs.sr >> 4) & 1); |
SET_NFLG ((regs.sr >> 3) & 1); |
SET_ZFLG ((regs.sr >> 2) & 1); |
SET_VFLG ((regs.sr >> 1) & 1); |
SET_CFLG (regs.sr & 1); |
if (regs.t1 == ((regs.sr >> 15) & 1) && |
regs.t0 == ((regs.sr >> 14) & 1) && |
regs.s == ((regs.sr >> 13) & 1) && |
regs.m == ((regs.sr >> 12) & 1) && |
regs.intmask == ((regs.sr >> 8) & 7)) |
return; |
regs.t1 = (regs.sr >> 15) & 1; |
regs.t0 = (regs.sr >> 14) & 1; |
regs.s = (regs.sr >> 13) & 1; |
regs.m = (regs.sr >> 12) & 1; |
regs.intmask = (regs.sr >> 8) & 7; |
|
//code fragment for: currprefs.cpu_model < 68020 |
regs.t0 = regs.m = 0; |
if (olds != regs.s) { |
if (olds) { |
regs.isp = m68k_areg (regs, 7); |
m68k_areg (regs, 7) = regs.usp; |
} else { |
regs.usp = m68k_areg (regs, 7); |
m68k_areg (regs, 7) = regs.isp; |
} |
} |
|
// doint() |
|
// if(regs.t1 || regs.t0) |
// set_special (SPCFLAG_TRACE); |
// else |
/* Keep SPCFLAG_DOTRACE, we still want a trace exception for |
SR-modifying instructions (including STOP). */ |
// unset_special (SPCFLAG_TRACE); |
} |
|
uae_u32 REGPARAM3 get_disp_ea_000 (uae_u32 base, uae_u32 dp) REGPARAM |
{ |
int reg = (dp >> 12) & 15; |
uae_s32 regd = regs.regs[reg]; |
|
if ((dp & 0x800) == 0) |
regd = (uae_s32)(uae_s16)regd; |
return base + (uae_s8)dp + regd; |
} |
|
//------------------------------------------------------------------- newcpu.c end |
|
//------------------------------------------------------------------- test start |
|
char **global_argv; |
int global_argc; |
|
unsigned int get_arg(const char *name) { |
int i; |
char buf[64]; |
|
for(i=1; i<global_argc; i++) { |
unsigned int ret = snprintf(buf, sizeof(buf), "+%s=%%08x", name); |
if(ret != (strlen(name) + 6)) { |
printf("Internal error while reading argument: %s\n", name); |
exit(-1); |
} |
|
unsigned int result; |
ret = sscanf(global_argv[i], buf, &result); |
if(ret != 1) continue; |
else return result; |
} |
printf("Error reading argument: %s\n", name); |
exit(-2); |
} |
|
|
void load_state() { |
m68k_dreg(regs, 0) = get_arg("D0"); |
m68k_dreg(regs, 1) = get_arg("D1"); |
m68k_dreg(regs, 2) = get_arg("D2"); |
m68k_dreg(regs, 3) = get_arg("D3"); |
m68k_dreg(regs, 4) = get_arg("D4"); |
m68k_dreg(regs, 5) = get_arg("D5"); |
m68k_dreg(regs, 6) = get_arg("D6"); |
m68k_dreg(regs, 7) = get_arg("D7"); |
|
m68k_setpc(get_arg("PC")); |
|
SET_CFLG(get_arg("C")); |
SET_VFLG(get_arg("V")); |
SET_ZFLG(get_arg("Z")); |
SET_NFLG(get_arg("N")); |
SET_XFLG(get_arg("X")); |
|
regs.intmask = get_arg("IPM"); |
regs.s = get_arg("S"); |
regs.t1 = get_arg("T"); |
regs.m = 0; |
|
m68k_areg(regs, 0) = get_arg("A0"); |
m68k_areg(regs, 1) = get_arg("A1"); |
m68k_areg(regs, 2) = get_arg("A2"); |
m68k_areg(regs, 3) = get_arg("A3"); |
m68k_areg(regs, 4) = get_arg("A4"); |
m68k_areg(regs, 5) = get_arg("A5"); |
m68k_areg(regs, 6) = get_arg("A6"); |
regs.usp = get_arg("USP"); |
regs.isp = get_arg("SSP"); |
if(regs.s == 0) m68k_areg(regs, 7) = regs.usp; |
else m68k_areg(regs, 7) = regs.isp; |
} |
|
void save_state() { |
printf("A0: %08x\n", m68k_areg(regs, 0)); |
printf("A1: %08x\n", m68k_areg(regs, 1)); |
printf("A2: %08x\n", m68k_areg(regs, 2)); |
printf("A3: %08x\n", m68k_areg(regs, 3)); |
printf("A4: %08x\n", m68k_areg(regs, 4)); |
printf("A5: %08x\n", m68k_areg(regs, 5)); |
printf("A6: %08x\n", m68k_areg(regs, 6)); |
printf("SSP: %08x\n", (regs.s == 1)? m68k_areg(regs, 7) : regs.isp); |
printf("USP: %08x\n", (regs.s == 0)? m68k_areg(regs, 7) : regs.usp); |
|
printf("D0: %08x\n", m68k_dreg(regs, 0)); |
printf("D1: %08x\n", m68k_dreg(regs, 1)); |
printf("D2: %08x\n", m68k_dreg(regs, 2)); |
printf("D3: %08x\n", m68k_dreg(regs, 3)); |
printf("D4: %08x\n", m68k_dreg(regs, 4)); |
printf("D5: %08x\n", m68k_dreg(regs, 5)); |
printf("D6: %08x\n", m68k_dreg(regs, 6)); |
printf("D7: %08x\n", m68k_dreg(regs, 7)); |
|
printf("PC: %08x\n", m68k_getpc()); |
|
printf("C: %d\n", GET_CFLG()); |
printf("V: %d\n", GET_VFLG()); |
printf("Z: %d\n", GET_ZFLG()); |
printf("N: %d\n", GET_NFLG()); |
printf("X: %d\n", GET_XFLG()); |
printf("IPM: %d\n", regs.intmask); |
printf("S: %d\n", regs.s); |
printf("T: %d\n", regs.t1); |
} |
|
int get_mem_arg(uae_u32 *vals, int vals_count, uaecptr addr) { |
if((vals_count != 1 && vals_count != 2) || vals == NULL) { |
printf("Illegal get_mem_arg arguments: %p, %d\n", vals, vals_count); |
exit(-1); |
} |
char buf[1+3+8+1 +1]; |
if(snprintf(buf, sizeof(buf), "+MEM%08x=", addr>>2) != sizeof(buf)-1) { |
printf("Internal error while preparing +MEM argument: %08x (%08x)\n", addr>>2, addr); |
exit(-2); |
} |
uae_u32 temp = 0; |
int i; |
for(i=0; i<global_argc; i++) { |
if(strncmp(global_argv[i], buf, sizeof(buf)-1) == 0) { |
if(sscanf(global_argv[i], "+MEM%08x=%x", &temp, &(vals[0])) != 2) { |
printf("Error parsing argument: %s\n", global_argv[i]); |
exit(-3); |
} |
else break; |
} |
} |
if(i==global_argc) { |
printf("Missing argument: MEM%08x\n", addr>>2); |
exit(-4); |
} |
if(vals_count == 1) return 1; |
|
if(snprintf(buf, sizeof(buf), "+MEM%08x=", (addr>>2)+1) != sizeof(buf)-1) { |
printf("Internal error while preparing +MEM argument: %08x (%08x)\n", (addr>>2)+1, addr+4); |
exit(-5); |
} |
|
for(i=0; i<global_argc; i++) { |
if(strncmp(global_argv[i], buf, sizeof(buf)-1) == 0) { |
if(sscanf(global_argv[i], "+MEM%08x=%x", &temp, &(vals[1])) != 2) { |
printf("Error parsing argument: %s\n", global_argv[i]); |
exit(-6); |
} |
else break; |
} |
} |
if(i==global_argc) return 1; |
return 2; |
} |
|
//memory.h start |
|
uae_u8 *get_real_address(uaecptr addr) |
{ |
return (uae_u8 *)addr; |
} |
uae_u32 get_long(uaecptr ptr) |
{ |
printf("memory read: address=%08x, select=%x\n", ptr>>2, 0xf); |
|
uae_u32 vals[2]; |
int res = get_mem_arg(vals, 2, ptr); |
|
if( (ptr % 4) > 0 && (res == 1) ) { |
printf("Missing argument: MEM%08x\n", (ptr>>2)+1); |
exit(-1); |
} |
else if((ptr % 4) == 0) return vals[0]; |
else if((ptr % 4) == 2) return (vals[0] << 16) | (vals[1] >> 16); |
else if((ptr % 2) == 1) { |
printf("memory read on odd address: long, ptr=%p\n", ptr); |
exit(-1); |
//return (vals[0] << 8) | (vals[1] >> 24); |
//return 0; |
} |
} |
uae_u32 get_word(uaecptr ptr) |
{ |
printf("memory read: address=%08x, select=%x\n", ptr>>2, 0xf); |
|
uae_u32 vals[2]; |
int res = get_mem_arg(vals, 2, ptr); |
|
if( (ptr % 4) == 3 && (res == 1) ) { |
printf("Missing argument: MEM%08x\n", (ptr>>2)+1); |
exit(-1); |
} |
else if((ptr % 4) == 0) return (vals[0] >> 16) & 0xFFFF; |
else if((ptr % 4) == 2) return (vals[0]) & 0xFFFF; |
else if((ptr % 2) == 1) { |
printf("memory read on odd address: word, ptr=%p\n", ptr); |
exit(-1); |
//return (vals[0] >> 8) & 0xFFFF; |
//return 0; |
} |
|
} |
uae_u32 get_byte(uaecptr ptr) |
{ |
printf("memory read: address=%08x, select=%x\n", ptr>>2, 0xf); |
uae_u32 vals[1]; |
get_mem_arg(vals, 1, ptr); |
|
if((ptr % 4) == 0) return (vals[0] >> 24) & 0xFF; |
else if((ptr % 4) == 1) return (vals[0] >> 16) & 0xFF; |
else if((ptr % 4) == 2) return (vals[0] >> 8) & 0xFF; |
else if((ptr % 4) == 3) return (vals[0]) & 0xFF; |
} |
|
void put_byte(uaecptr ptr, uae_u32 val) |
{ |
if((ptr % 4) == 0) { |
printf("memory write address=%08x, select=%x: value=%08x\n", ptr>>2, 0x8, val<<24); |
} |
else if((ptr % 4) == 1) { |
printf("memory write address=%08x, select=%x: value=%08x\n", ptr>>2, 0x4, (val<<16) & 0x00FF0000); |
} |
else if((ptr % 4) == 2) { |
printf("memory write address=%08x, select=%x: value=%08x\n", ptr>>2, 0x2, (val<<8) & 0x0000FF00); |
} |
else if((ptr % 4) == 3) { |
printf("memory write address=%08x, select=%x: value=%08x\n", ptr>>2, 0x1, val & 0xFF); |
} |
} |
void put_word(uaecptr ptr, uae_u32 val) |
{ |
if((ptr % 4) == 0) { |
printf("memory write address=%08x, select=%x: value=%08x\n", ptr>>2, 0xc, val<<16); |
} |
else if((ptr % 4) == 2) { |
printf("memory write address=%08x, select=%x: value=%08x\n", ptr>>2, 0x3, val & 0xFFFF); |
} |
else if((ptr % 2) == 1) { |
printf("memory write on odd address: word, ptr=%p, val=%x\n", ptr,val); |
exit(-1); |
//return; |
} |
} |
void put_long(uaecptr ptr, uae_u32 val) |
{ |
if((ptr % 4) == 0) { |
printf("memory write address=%08x, select=%x: value=%08x\n", ptr>>2, 0xf, val); |
} |
else if((ptr % 4) == 2) { |
printf("memory write address=%08x, select=%x: value=%08x\n", ptr>>2, 0x3, val>>16); |
printf("memory write address=%08x, select=%x: value=%08x\n", (ptr>>2)+1, 0xc, val<<16); |
} |
else if((ptr % 2) == 1) { |
printf("memory write on odd address: long, ptr=%p, val=%x\n", ptr,val); |
exit(-1); |
//return; |
} |
} |
uae_u32 get_wordi(uaecptr addr) |
{ |
return get_word(addr); |
} |
//memory.h end |
|
//------------------------------------------------------------------- test end |
|
static void build_cpufunctbl(void) |
{ |
int i, opcnt; |
unsigned long opcode; |
const struct cputbl *tbl = 0; |
int lvl; |
|
lvl = 0; |
tbl = op_smalltbl_11_ff; /* prefetch */ |
|
for (opcode = 0; opcode < 65536; opcode++) |
cpufunctbl[opcode] = op_illg; |
for (i = 0; tbl[i].handler != NULL; i++) { |
opcode = tbl[i].opcode; |
cpufunctbl[opcode] = tbl[i].handler; |
} |
|
opcnt = 0; |
for (opcode = 0; opcode < 65536; opcode++) { |
cpuop_func *f; |
|
if (table68k[opcode].mnemo == i_ILLG) |
continue; |
if (table68k[opcode].clev > lvl) { |
continue; |
} |
|
if (table68k[opcode].handler != -1) { |
int idx = table68k[opcode].handler; |
f = cpufunctbl[idx]; |
if (f == op_illg) |
abort (); |
cpufunctbl[opcode] = f; |
opcnt++; |
} |
} |
} |
|
int main(int argc, char **argv) { |
global_argv = argv; |
global_argc = argc; |
|
//init_m68k() |
int i; |
|
for (i = 0 ; i < 256 ; i++) { |
int j; |
for (j = 0 ; j < 8 ; j++) { |
if (i & (1 << j)) break; |
} |
movem_index1[i] = j; |
movem_index2[i] = 7-j; |
movem_next[i] = i & (~(1 << j)); |
} |
|
regs.address_space_mask = 0xffffffff; |
|
read_table68k(); |
do_merges(); |
|
build_cpufunctbl(); |
|
//m68k_reset() |
regs.spcflags = 0; |
m68k_areg (regs, 7) = get_arg("SSP"); |
m68k_setpc(get_arg("PC")); |
regs.s = 1; |
regs.m = 0; |
regs.stopped = 0; |
regs.t1 = 0; |
regs.t0 = 0; |
SET_ZFLG(0); |
SET_XFLG(0); |
SET_CFLG(0); |
SET_VFLG(0); |
SET_NFLG(0); |
regs.intmask = 7; |
regs.vbr = regs.sfc = regs.dfc = 0; |
regs.irc = 0xffff; |
|
regs.pcr = 0; |
|
printf("START TEST\n"); |
|
load_state(); |
|
MakeSR(); |
fill_prefetch_slow(); |
|
//m68k_go(); |
//m68k_run_1(); |
|
//AO m68k_setpc (regs.pc); |
(*cpufunctbl[regs.ir])(regs.ir); |
|
|
save_state(); |
|
return 0; |
} |
|
/trunk/bench/sw_emulators/winuae/gencpu.c
0,0 → 1,3813
/* |
* UAE - The Un*x Amiga Emulator |
* |
* MC68000 emulation generator |
* |
* This is a fairly stupid program that generates a lot of case labels that |
* can be #included in a switch statement. |
* As an alternative, it can generate functions that handle specific |
* MC68000 instructions, plus a prototype header file and a function pointer |
* array to look up the function for an opcode. |
* Error checking is bad, an illegal table68k file will cause the program to |
* call abort(). |
* The generated code is sometimes sub-optimal, an optimizing compiler should |
* take care of this. |
* |
* The source for the insn timings is Markt & Technik's Amiga Magazin 8/1992. |
* |
* Copyright 1995, 1996, 1997, 1998, 1999, 2000 Bernd Schmidt |
*/ |
|
//AO#include "sysconfig.h" |
//AO#include "sysdeps.h" |
#include "ao.h" |
#include <ctype.h> |
|
#include "readcpu.h" |
|
#define BOOL_TYPE "int" |
/* Define the minimal 680x0 where NV flags are not affected by xBCD instructions. */ |
#define xBCD_KEEPS_NV_FLAGS 4 |
|
static FILE *headerfile; |
static FILE *stblfile; |
|
static int using_prefetch, using_indirect, using_mmu; |
static int using_ce020; |
static int using_exception_3; |
static int using_ce; |
static int cpu_level; |
static int count_read, count_write, count_cycles, count_ncycles; |
static int count_read_ea, count_write_ea, count_cycles_ea; |
|
static int optimized_flags; |
|
#define GF_APDI 1 |
#define GF_AD8R 2 |
#define GF_PC8R 4 |
#define GF_AA 7 |
#define GF_NOREFILL 8 |
#define GF_PREFETCH 16 |
#define GF_FC 32 |
|
/* For the current opcode, the next lower level that will have different code. |
* Initialized to -1 for each opcode. If it remains unchanged, indicates we |
* are done with that opcode. */ |
static int next_cpu_level; |
|
static int *opcode_map; |
static int *opcode_next_clev; |
static int *opcode_last_postfix; |
static unsigned long *counts; |
static int generate_stbl; |
static int fixupcnt; |
|
#define GENA_GETV_NO_FETCH 0 |
#define GENA_GETV_FETCH 1 |
#define GENA_GETV_FETCH_ALIGN 2 |
#define GENA_MOVEM_DO_INC 0 |
#define GENA_MOVEM_NO_INC 1 |
#define GENA_MOVEM_MOVE16 2 |
|
static void read_counts (void) |
{ |
FILE *file; |
unsigned long opcode, count, total; |
char name[20]; |
int nr = 0; |
memset (counts, 0, 65536 * sizeof *counts); |
|
count = 0; |
file = fopen ("frequent.68k", "r"); |
if (file) { |
fscanf (file, "Total: %lu\n", &total); |
while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) { |
opcode_next_clev[nr] = 5; |
opcode_last_postfix[nr] = -1; |
opcode_map[nr++] = opcode; |
counts[opcode] = count; |
} |
fclose (file); |
} |
if (nr == nr_cpuop_funcs) |
return; |
for (opcode = 0; opcode < 0x10000; opcode++) { |
if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG |
&& counts[opcode] == 0) |
{ |
opcode_next_clev[nr] = 5; |
opcode_last_postfix[nr] = -1; |
opcode_map[nr++] = opcode; |
counts[opcode] = count; |
} |
} |
if (nr != nr_cpuop_funcs) |
abort (); |
} |
|
static char endlabelstr[80]; |
static int endlabelno = 0; |
static int need_endlabel; |
|
static int n_braces, limit_braces; |
static int m68k_pc_offset; |
static int insn_n_cycles, insn_n_cycles020; |
|
static void fpulimit (void) |
{ |
if (limit_braces) |
return; |
printf ("\n#ifdef FPUEMU\n"); |
limit_braces = n_braces; |
n_braces = 0; |
} |
static void cpulimit (void) |
{ |
printf ("#ifndef CPUEMU_68000_ONLY\n"); |
} |
|
static void returncycles (char *s, int cycles) |
{ |
if (using_ce) |
return; |
if (using_ce020) |
printf ("%sreturn;\n", s); |
else |
printf ("%sreturn %d * CYCLE_UNIT / 2;\n", s, cycles); |
} |
|
static void addcycles_ce020 (int cycles) |
{ |
if (!using_ce020) |
return; |
if (cycles > 0) |
printf ("\tregs.ce020memcycles += %d * cpucycleunit;\n", cycles); |
count_cycles += cycles; |
} |
static void addcycles000 (int cycles) |
{ |
if (!using_ce) |
return; |
printf ("\tdo_cycles_ce000 (%d);\n", cycles); |
count_cycles += cycles; |
} |
static void addcycles000_2 (char *s, int cycles) |
{ |
if (!using_ce) |
return; |
printf ("%sdo_cycles_ce000 (%d);\n", s, cycles); |
count_cycles += cycles; |
} |
|
static void addcycles000_3 (char *s) |
{ |
if (!using_ce) |
return; |
printf ("%sif (cycles > 0) do_cycles_ce000 (cycles);\n", s); |
count_ncycles++; |
} |
|
static int isreg (amodes mode) |
{ |
if (mode == Dreg || mode == Areg) |
return 1; |
return 0; |
} |
|
static void start_brace (void) |
{ |
n_braces++; |
printf ("{"); |
} |
|
static void close_brace (void) |
{ |
assert (n_braces > 0); |
n_braces--; |
printf ("}"); |
} |
|
static void finish_braces (void) |
{ |
while (n_braces > 0) |
close_brace (); |
} |
|
static void pop_braces (int to) |
{ |
while (n_braces > to) |
close_brace (); |
} |
|
static int bit_size (int size) |
{ |
switch (size) { |
case sz_byte: return 8; |
case sz_word: return 16; |
case sz_long: return 32; |
default: abort (); |
} |
return 0; |
} |
|
static const char *bit_mask (int size) |
{ |
switch (size) { |
case sz_byte: return "0xff"; |
case sz_word: return "0xffff"; |
case sz_long: return "0xffffffff"; |
default: abort (); |
} |
return 0; |
} |
|
static void gen_nextilong (char *type, char *name, int norefill) |
{ |
int r = m68k_pc_offset; |
m68k_pc_offset += 4; |
|
if (using_ce020) { |
printf ("\t%s %s = get_long_ce020_prefetch (%d);\n", type, name, r); |
count_read += 2; |
} else if (using_ce) { |
printf ("\t%s %s;\n", type, name); |
/* we must do this because execution order of (something | something2) is not defined */ |
if (norefill) { |
printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2); |
count_read++; |
printf ("\t%s |= regs.irc;\n", name); |
} else { |
printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2); |
count_read++; |
printf ("\t%s |= get_word_ce_prefetch (%d);\n", name, r + 4); |
count_read++; |
} |
} else { |
if (using_prefetch) { |
if (norefill) { |
printf ("\t%s %s;\n", type, name); |
printf ("\t%s = get_word_prefetch (%d) << 16;\n", name, r + 2); |
count_read++; |
printf ("\t%s |= regs.irc;\n", name); |
insn_n_cycles += 4; |
} else { |
printf ("\t%s %s = get_long_prefetch (%d);\n", type, name, r + 2); |
count_read++; |
count_read++; |
insn_n_cycles += 8; |
} |
} else if (using_indirect) { |
insn_n_cycles += 8; |
printf ("\t%s %s = get_ilongi (%d);\n", type, name, r); |
} else if (using_mmu) { |
insn_n_cycles += 8; |
printf ("\t%s %s = get_ilong_mmu (%d);\n", type, name, r); |
} else { |
insn_n_cycles += 8; |
printf ("\t%s %s = get_ilong (%d);\n", type, name, r); |
} |
} |
} |
|
static const char *gen_nextiword (int norefill) |
{ |
static char buffer[80]; |
int r = m68k_pc_offset; |
m68k_pc_offset += 2; |
|
if (using_ce020) { |
sprintf (buffer, "get_word_ce020_prefetch (%d)", r); |
count_read++; |
} else if (using_ce) { |
if (norefill) { |
strcpy (buffer, "regs.irc"); |
} else { |
sprintf (buffer, "get_word_ce_prefetch (%d)", r + 2); |
count_read++; |
} |
} else { |
if (using_prefetch) { |
if (norefill) { |
sprintf (buffer, "regs.irc", r); |
} else { |
sprintf (buffer, "get_word_prefetch (%d)", r + 2); |
count_read++; |
insn_n_cycles += 4; |
} |
} else if (using_indirect) { |
sprintf (buffer, "get_iwordi(%d)", r); |
insn_n_cycles += 4; |
} else if (using_mmu) { |
sprintf (buffer, "get_iword_mmu (%d)", r); |
insn_n_cycles += 4; |
} else { |
sprintf (buffer, "get_iword (%d)", r); |
insn_n_cycles += 4; |
} |
} |
return buffer; |
} |
|
static const char *gen_nextibyte (int norefill) |
{ |
static char buffer[80]; |
int r = m68k_pc_offset; |
m68k_pc_offset += 2; |
|
if (using_ce020) { |
sprintf (buffer, "(uae_u8)get_word_ce020_prefetch (%d)", r); |
count_read++; |
} else if (using_ce) { |
if (norefill) { |
strcpy (buffer, "(uae_u8)regs.irc"); |
} else { |
sprintf (buffer, "(uae_u8)get_word_ce_prefetch (%d)", r + 2); |
count_read++; |
} |
} else { |
insn_n_cycles += 4; |
if (using_prefetch) { |
if (norefill) { |
sprintf (buffer, "(uae_u8)regs.irc", r); |
} else { |
sprintf (buffer, "(uae_u8)get_word_prefetch (%d)", r + 2); |
insn_n_cycles += 4; |
count_read++; |
} |
} else if (using_indirect) { |
sprintf (buffer, "get_ibytei (%d)", r); |
insn_n_cycles += 4; |
} else if (using_mmu) { |
sprintf (buffer, "get_ibyte_mmu (%d)", r); |
insn_n_cycles += 4; |
} else { |
sprintf (buffer, "get_ibyte (%d)", r); |
insn_n_cycles += 4; |
} |
} |
return buffer; |
} |
|
static void irc2ir (void) |
{ |
if (!using_prefetch) |
return; |
printf ("\tregs.ir = regs.irc;\n"); |
} |
|
static int did_prefetch; |
|
static void fill_prefetch_2 (void) |
{ |
if (!using_prefetch) |
return; |
if (using_ce) |
printf ("\tget_word_ce_prefetch (%d);\n", m68k_pc_offset + 2); |
else |
printf ("\tget_word_prefetch (%d);\n", m68k_pc_offset + 2); |
did_prefetch = 1; |
count_read++; |
insn_n_cycles += 4; |
} |
|
static void fill_prefetch_1 (int o) |
{ |
if (!using_prefetch) |
return; |
if (using_ce) { |
printf ("\tget_word_ce_prefetch (%d);\n", o); |
} else { |
printf ("\tget_word_prefetch (%d);\n", o); |
} |
did_prefetch = 1; |
count_read++; |
insn_n_cycles += 4; |
} |
|
static void fill_prefetch_full (void) |
{ |
fill_prefetch_1 (0); |
irc2ir (); |
fill_prefetch_1 (2); |
} |
|
static void fill_prefetch_0 (void) |
{ |
if (!using_prefetch) |
return; |
if (using_ce) |
printf ("\tget_word_ce_prefetch (0);\n"); |
else |
printf ("\tget_word_prefetch (0);\n"); |
did_prefetch = 1; |
count_read++; |
insn_n_cycles += 4; |
} |
|
static void fill_prefetch_next_1 (void) |
{ |
irc2ir (); |
fill_prefetch_1 (m68k_pc_offset + 2); |
} |
|
static void fill_prefetch_next (void) |
{ |
fill_prefetch_next_1 (); |
} |
|
#if 0 |
static void fill_prefetch_next_delay (int extracycles) |
{ |
if (!using_prefetch) |
return; |
if (using_ce) { |
if (extracycles > 0) { |
printf("\t{\n"); |
fill_prefetch_next (); |
printf("\tif (%d > 0) do_cycles(%d * CYCLE_UNIT / 2);\n", |
extracycles, extracycles); |
printf("\t}\n"); |
} else { |
fill_prefetch_next (); |
} |
} else { |
fill_prefetch_next (); |
} |
} |
#endif |
|
static void fill_prefetch_finish (void) |
{ |
if (did_prefetch || !using_prefetch) |
return; |
fill_prefetch_1 (m68k_pc_offset); |
} |
|
static void setpc (const char *format, ...) |
{ |
va_list parms; |
char buffer[1000]; |
|
va_start (parms, format); |
_vsnprintf (buffer, 1000 - 1, format, parms); |
va_end (parms); |
|
if (using_mmu) |
printf ("\tm68k_setpc_mmu (%s);\n", buffer); |
else |
printf ("\tm68k_setpc (%s);\n", buffer); |
} |
|
static void incpc (const char *format, ...) |
{ |
va_list parms; |
char buffer[1000]; |
|
va_start (parms, format); |
_vsnprintf (buffer, 1000 - 1, format, parms); |
va_end (parms); |
|
if (using_mmu) |
printf ("\tm68k_incpci (%s);\n", buffer); |
else |
printf ("\tm68k_incpc (%s);\n", buffer); |
} |
|
static void sync_m68k_pc (void) |
{ |
if (m68k_pc_offset == 0) |
return; |
incpc ("%d", m68k_pc_offset); |
m68k_pc_offset = 0; |
} |
|
static void gen_set_fault_pc (void) |
{ |
if (!using_mmu) |
return; |
sync_m68k_pc (); |
printf ("\tregs.fault_pc = m68k_getpci ();\n"); |
m68k_pc_offset = 0; |
} |
|
/* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, |
* the calling routine handles Apdi and Aipi modes. |
* gb-- movem == 2 means the same thing but for a MOVE16 instruction */ |
|
/* fixup indicates if we want to fix up adress registers in pre decrement |
* or post increment mode now (0) or later (1). A value of 2 will then be |
* used to do the actual fix up. This allows to do all memory readings |
* before any register is modified, and so to rerun operation without |
* side effect in case a bus fault is generated by any memory access. |
* XJ - 2006/11/13 */ |
|
static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int fixup, int e3fudge) |
{ |
char namea[100]; |
//AO extra |
//int m68k_pc_offset_last = m68k_pc_offset; |
|
sprintf (namea, "%sa", name); |
|
start_brace (); |
switch (mode) { |
case Dreg: |
if (movem) |
abort (); |
if (getv == 1) |
switch (size) { |
case sz_byte: |
#ifdef USE_DUBIOUS_BIGENDIAN_OPTIMIZATION |
/* This causes the target compiler to generate better code on few systems */ |
printf ("\tuae_s8 %s = ((uae_u8*)&m68k_dreg (regs, %s))[3];\n", name, reg); |
#else |
printf ("\tuae_s8 %s = m68k_dreg (regs, %s);\n", name, reg); |
#endif |
break; |
case sz_word: |
#ifdef USE_DUBIOUS_BIGENDIAN_OPTIMIZATION |
printf ("\tuae_s16 %s = ((uae_s16*)&m68k_dreg (regs, %s))[1];\n", name, reg); |
#else |
printf ("\tuae_s16 %s = m68k_dreg (regs, %s);\n", name, reg); |
#endif |
break; |
case sz_long: |
printf ("\tuae_s32 %s = m68k_dreg (regs, %s);\n", name, reg); |
break; |
default: |
abort (); |
} |
return; |
case Areg: |
if (movem) |
abort (); |
if (getv == 1) |
switch (size) { |
case sz_word: |
printf ("\tuae_s16 %s = m68k_areg (regs, %s);\n", name, reg); |
break; |
case sz_long: |
printf ("\tuae_s32 %s = m68k_areg (regs, %s);\n", name, reg); |
break; |
default: |
abort (); |
} |
return; |
case Aind: // (An) |
printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg); |
break; |
case Aipi: // (An)+ |
printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg); |
break; |
case Apdi: // -(An) |
printf ("\tuaecptr %sa;\n", name); |
switch (size) { |
case sz_byte: |
if (movem) |
printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg); |
else |
printf ("\t%sa = m68k_areg (regs, %s) - areg_byteinc[%s];\n", name, reg, reg); |
break; |
case sz_word: |
printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 2); |
break; |
case sz_long: |
printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 4); |
break; |
default: |
abort (); |
} |
if (!(flags & GF_APDI)) { |
addcycles000 (2); |
insn_n_cycles += 2; |
count_cycles_ea += 2; |
} |
break; |
case Ad16: // (d16,An) |
printf ("\tuaecptr %sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags & GF_NOREFILL)); |
count_read_ea++; |
break; |
case Ad8r: // (d8,An,Xn) |
printf ("\tuaecptr %sa;\n", name); |
if (cpu_level > 1) { |
if (next_cpu_level < 1) |
next_cpu_level = 1; |
sync_m68k_pc (); |
start_brace (); |
/* This would ordinarily be done in gen_nextiword, which we bypass. */ |
insn_n_cycles += 4; |
if (using_ce020) |
printf ("\t%sa = get_disp_ea_020ce (m68k_areg (regs, %s), next_iword_020ce ());\n", name, reg); |
else if (using_mmu) |
printf ("\t%sa = get_disp_ea_040mmu (m68k_areg (regs, %s), next_iword_mmu ());\n", name, reg); |
else |
printf ("\t%sa = get_disp_ea_020 (m68k_areg (regs, %s), next_iword ());\n", name, reg); |
} else { |
printf ("\t%sa = get_disp_ea_000 (m68k_areg (regs, %s), %s);\n", name, reg, gen_nextiword (flags & GF_NOREFILL)); |
count_read_ea++; |
} |
if (!(flags & GF_AD8R)) { |
addcycles000 (2); |
insn_n_cycles += 2; |
count_cycles_ea += 2; |
} |
break; |
case PC16: // (d16,PC,Xn) |
printf ("\tuaecptr %sa = m68k_getpc () + %d;\n", name, m68k_pc_offset); |
printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags & GF_NOREFILL)); |
break; |
case PC8r: // (d8,PC,Xn) |
printf ("\tuaecptr tmppc;\n"); |
printf ("\tuaecptr %sa;\n", name); |
if (cpu_level > 1) { |
if (next_cpu_level < 1) |
next_cpu_level = 1; |
sync_m68k_pc (); |
start_brace (); |
/* This would ordinarily be done in gen_nextiword, which we bypass. */ |
insn_n_cycles += 4; |
printf ("\ttmppc = m68k_getpc ();\n"); |
if (using_ce020) |
printf ("\t%sa = get_disp_ea_020ce (tmppc, next_iword_020ce ());\n", name); |
else if (using_mmu) |
printf ("\t%sa = get_disp_ea_040mmu (tmppc, next_iword_mmu ());\n", name); |
else |
printf ("\t%sa = get_disp_ea_020 (tmppc, next_iword ());\n", name); |
} else { |
printf ("\ttmppc = m68k_getpc () + %d;\n", m68k_pc_offset); |
printf ("\t%sa = get_disp_ea_000 (tmppc, %s);\n", name, gen_nextiword (flags & GF_NOREFILL)); |
} |
if (!(flags & GF_PC8R)) { |
addcycles000 (2); |
insn_n_cycles += 2; |
count_cycles_ea += 2; |
} |
|
break; |
case absw: |
printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags & GF_NOREFILL)); |
break; |
case absl: |
gen_nextilong ("uaecptr", namea, flags & GF_NOREFILL); |
count_read_ea += 2; |
break; |
case imm: |
if (getv != 1) |
abort (); |
insn_n_cycles020++; |
switch (size) { |
case sz_byte: |
printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags & GF_NOREFILL)); |
count_read_ea++; |
break; |
case sz_word: |
printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags & GF_NOREFILL)); |
count_read_ea++; |
break; |
case sz_long: |
gen_nextilong ("uae_s32", name, flags & GF_NOREFILL); |
count_read_ea += 2; |
break; |
default: |
abort (); |
} |
return; |
case imm0: |
if (getv != 1) |
abort (); |
printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags & GF_NOREFILL)); |
count_read_ea++; |
return; |
case imm1: |
if (getv != 1) |
abort (); |
printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags & GF_NOREFILL)); |
count_read_ea++; |
return; |
case imm2: |
if (getv != 1) |
abort (); |
gen_nextilong ("uae_s32", name, flags & GF_NOREFILL); |
count_read_ea += 2; |
return; |
case immi: |
if (getv != 1) |
abort (); |
printf ("\tuae_u32 %s = %s;\n", name, reg); |
return; |
default: |
abort (); |
} |
|
/* We get here for all non-reg non-immediate addressing modes to |
* actually fetch the value. */ |
|
if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && size != sz_byte) { |
printf ("\tif (%sa & 1) {\n", name); |
//AO extra, m68k_pc_offset_last -> mk68k_pc_offset |
if(getv == 4 && size == sz_word && mode == Apdi) |
printf ("\t\texception3write (opcode, m68k_getpc () + %d, %sa - 2);\n", |
m68k_pc_offset + e3fudge, name); |
else if(getv == 4 && size == sz_long && mode == Apdi) |
printf ("\t\texception3write (opcode, m68k_getpc () + %d, %sa - 4);\n", |
m68k_pc_offset + e3fudge, name); |
else if(getv == 3 || getv == 4) |
printf ("\t\texception3write (opcode, m68k_getpc () + %d, %sa);\n", |
m68k_pc_offset + e3fudge, name); |
else if(mode == PC16 || mode == PC8r) |
printf ("\t\texception3i (opcode, m68k_getpc () + %d, %sa);\n", |
m68k_pc_offset + e3fudge, name); |
else |
printf ("\t\texception3 (opcode, m68k_getpc () + %d, %sa);\n", |
m68k_pc_offset + e3fudge, name); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
need_endlabel = 1; |
start_brace (); |
} |
|
if (flags & GF_PREFETCH) |
fill_prefetch_next (); |
|
if (getv == 1) { |
start_brace (); |
if (using_ce020) { |
switch (size) { |
case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_ce020 (%sa);\n", name, name); count_read++; break; |
case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_ce020 (%sa);\n", name, name); count_read++; break; |
case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_ce020 (%sa);\n", name, name); count_read += 2; break; |
default: abort (); |
} |
} else if (using_ce) { |
switch (size) { |
case sz_byte: printf ("\tuae_s8 %s = get_byte_ce (%sa);\n", name, name); count_read++; break; |
case sz_word: printf ("\tuae_s16 %s = get_word_ce (%sa);\n", name, name); count_read++; break; |
case sz_long: printf ("\tuae_s32 %s = get_word_ce (%sa) << 16; %s |= get_word_ce (%sa + 2);\n", name, name, name, name); count_read += 2; break; |
default: abort (); |
} |
} else if (using_mmu) { |
if (flags & GF_FC) { |
switch (size) { |
case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = sfc_get_byte (%sa);\n", name, name); break; |
case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = sfc_get_word (%sa);\n", name, name); break; |
case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = sfc_get_long (%sa);\n", name, name); break; |
default: abort (); |
} |
} else { |
switch (size) { |
case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_mmu (%sa);\n", name, name); break; |
case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_mmu (%sa);\n", name, name); break; |
case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_mmu (%sa);\n", name, name); break; |
default: abort (); |
} |
} |
} else { |
switch (size) { |
case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte (%sa);\n", name, name); count_read++; break; |
case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word (%sa);\n", name, name); count_read++; break; |
case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long (%sa);\n", name, name); count_read += 2; break; |
default: abort (); |
} |
} |
} |
|
/* We now might have to fix up the register for pre-dec or post-inc |
* addressing modes. */ |
if (!movem) |
switch (mode) { |
case Aipi: |
if (fixup == 1) { |
printf ("\tmmufixup[%d].reg = %s;\n", fixupcnt, reg); |
printf ("\tmmufixup[%d].value = m68k_areg (regs, %s);\n", fixupcnt, reg); |
} |
switch (size) { |
case sz_byte: |
printf ("\tm68k_areg (regs, %s) += areg_byteinc[%s];\n", reg, reg); |
break; |
case sz_word: |
printf ("\tm68k_areg (regs, %s) += 2;\n", reg); |
break; |
case sz_long: |
printf ("\tm68k_areg (regs, %s) += 4;\n", reg); |
break; |
default: |
abort (); |
} |
break; |
case Apdi: |
if (fixup == 1) { |
printf ("\tmmufixup[%d].reg = %s;\n", fixupcnt, reg); |
printf ("\tmmufixup[%d].value = m68k_areg (regs, %s);\n", fixupcnt, reg); |
} |
printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name); |
break; |
default: |
break; |
} |
} |
|
static void genamode_fixup (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int fixup) |
{ |
if (fixup != 2) { |
genamode2 (mode, reg, size, name, getv, movem, flags, fixup, 0); |
} else { |
if (!movem) { |
switch (mode) |
{ |
case Aipi: |
case Apdi: |
printf ("\tmmufixup[0].reg = -1;\n", fixupcnt); |
break; |
} |
} |
} |
} |
|
static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags) |
{ |
genamode2 (mode, reg, size, name, getv, movem, flags, 0, 0); |
} |
static void genamode_pre (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags) |
{ |
genamode_fixup (mode, reg, size, name, getv, movem, flags, using_mmu ? 1 : 0); |
} |
static void genamode_post (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags) |
{ |
if (using_mmu) |
genamode_fixup (mode, reg, size, name, getv, movem, flags, 2); |
} |
static void genamode_e3 (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags, int e3fudge) |
{ |
genamode2 (mode, reg, size, name, getv, movem, flags, 0, e3fudge); |
} |
|
static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, char *to, int store_dir, int flags) |
{ |
switch (mode) { |
case Dreg: |
switch (size) { |
case sz_byte: |
printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from); |
break; |
case sz_word: |
printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from); |
break; |
case sz_long: |
printf ("\tm68k_dreg (regs, %s) = (%s);\n", reg, from); |
break; |
default: |
abort (); |
} |
break; |
case Areg: |
switch (size) { |
case sz_word: |
printf ("\tm68k_areg (regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from); |
break; |
case sz_long: |
printf ("\tm68k_areg (regs, %s) = (%s);\n", reg, from); |
break; |
default: |
abort (); |
} |
break; |
case Aind: |
case Aipi: |
case Apdi: |
case Ad16: |
case Ad8r: |
case absw: |
case absl: |
case PC16: |
case PC8r: |
gen_set_fault_pc (); |
if (using_ce020) { |
switch (size) { |
case sz_byte: |
printf ("\tput_byte_ce020 (%sa,%s);\n", to, from); |
count_write++; |
break; |
case sz_word: |
if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) |
abort (); |
printf ("\tput_word_ce020 (%sa,%s);\n", to, from); |
count_write++; |
break; |
case sz_long: |
if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) |
abort (); |
printf ("\tput_long_ce020 (%sa, %s);\n", to, from); |
count_write += 2; |
break; |
default: |
abort (); |
} |
} else if (using_ce) { |
switch (size) { |
case sz_byte: |
printf ("\tput_byte_ce (%sa,%s);\n", to, from); |
count_write++; |
break; |
case sz_word: |
if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) |
abort (); |
printf ("\tput_word_ce (%sa,%s);\n", to, from); |
count_write++; |
break; |
case sz_long: |
if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) |
abort (); |
if (store_dir) |
printf ("\tput_word_ce (%sa + 2, %s); put_word_ce (%sa, %s >> 16);\n", to, from, to, from); |
else |
printf ("\tput_word_ce (%sa, %s >> 16); put_word_ce (%sa + 2, %s);\n", to, from, to, from); |
count_write += 2; |
break; |
default: |
abort (); |
} |
} else if (using_mmu) { |
switch (size) { |
case sz_byte: |
insn_n_cycles += 4; |
if (flags & GF_FC) |
printf ("\tdfc_put_byte (%sa,%s);\n", to, from); |
else |
printf ("\tput_byte_mmu (%sa,%s);\n", to, from); |
break; |
case sz_word: |
insn_n_cycles += 4; |
if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) |
abort (); |
if (flags & GF_FC) |
printf ("\tdfc_put_word (%sa,%s);\n", to, from); |
else |
printf ("\tput_word_mmu (%sa,%s);\n", to, from); |
break; |
case sz_long: |
insn_n_cycles += 8; |
if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) |
abort (); |
if (flags & GF_FC) |
printf ("\tdfc_put_long (%sa,%s);\n", to, from); |
else |
printf ("\tput_long_mmu (%sa,%s);\n", to, from); |
break; |
default: |
abort (); |
} |
} else { |
switch (size) { |
case sz_byte: |
insn_n_cycles += 4; |
printf ("\tput_byte (%sa,%s);\n", to, from); |
count_write++; |
break; |
case sz_word: |
insn_n_cycles += 4; |
if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) |
abort (); |
printf ("\tput_word (%sa,%s);\n", to, from); |
count_write++; |
break; |
case sz_long: |
insn_n_cycles += 8; |
if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) |
abort (); |
printf ("\tput_long (%sa,%s);\n", to, from); |
count_write += 2; |
break; |
default: |
abort (); |
} |
} |
break; |
case imm: |
case imm0: |
case imm1: |
case imm2: |
case immi: |
abort (); |
break; |
default: |
abort (); |
} |
} |
|
static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to) |
{ |
genastore_2 (from, mode, reg, size, to, 0, 0); |
} |
static void genastore_rev (char *from, amodes mode, char *reg, wordsizes size, char *to) |
{ |
genastore_2 (from, mode, reg, size, to, 1, 0); |
} |
static void genastore_fc (char *from, amodes mode, char *reg, wordsizes size, char *to) |
{ |
genastore_2 (from, mode, reg, size, to, 1, GF_FC); |
} |
|
static void genmovemel (uae_u16 opcode) |
{ |
char getcode[100]; |
int size = table68k[opcode].size == sz_long ? 4 : 2; |
|
if (using_mmu) { |
if (table68k[opcode].size == sz_long) { |
strcpy (getcode, "get_long_mmu (srca)"); |
} else { |
strcpy (getcode, "(uae_s32)(uae_s16)get_word_mmu (srca)"); |
} |
} else { |
if (table68k[opcode].size == sz_long) { |
strcpy (getcode, "get_long (srca)"); |
} else { |
strcpy (getcode, "(uae_s32)(uae_s16)get_word (srca)"); |
} |
} |
count_read += table68k[opcode].size == sz_long ? 2 : 1; |
printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); |
printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); |
genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0); |
start_brace (); |
printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask]; }\n", |
getcode, size); |
printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask]; }\n", |
getcode, size); |
|
if (table68k[opcode].dmode == Aipi) { |
printf ("\tm68k_areg (regs, dstreg) = srca;\n"); |
count_read++; |
} |
fill_prefetch_next (); |
count_ncycles++; |
} |
|
static void genmovemel_ce (uae_u16 opcode) |
{ |
int size = table68k[opcode].size == sz_long ? 4 : 2; |
printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); |
printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); |
printf ("\tuae_u32 v;\n"); |
genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA); |
if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r) |
addcycles000 (2); |
start_brace (); |
if (table68k[opcode].size == sz_long) { |
printf ("\twhile (dmask) { v = get_word_ce(srca) << 16; v |= get_word_ce(srca + 2); m68k_dreg (regs, movem_index1[dmask]) = v; srca += %d; dmask = movem_next[dmask]; }\n", |
size); |
printf ("\twhile (amask) { v = get_word_ce(srca) << 16; v |= get_word_ce(srca + 2); m68k_areg (regs, movem_index1[amask]) = v; srca += %d; amask = movem_next[amask]; }\n", |
size); |
} else { |
printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = (uae_s32)(uae_s16)get_word_ce(srca); srca += %d; dmask = movem_next[dmask]; }\n", |
size); |
printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = (uae_s32)(uae_s16)get_word_ce(srca); srca += %d; amask = movem_next[amask]; }\n", |
size); |
} |
printf ("\tget_word_ce (srca);\n"); // and final extra word fetch that goes nowhere.. |
count_read++; |
if (table68k[opcode].dmode == Aipi) |
printf ("\tm68k_areg (regs, dstreg) = srca;\n"); |
fill_prefetch_next (); |
count_ncycles++; |
} |
|
static void genmovemle (uae_u16 opcode) |
{ |
char *putcode; |
int size = table68k[opcode].size == sz_long ? 4 : 2; |
|
if (using_mmu) { |
if (table68k[opcode].size == sz_long) { |
putcode = "put_long_mmu (srca"; |
} else { |
putcode = "put_word_mmu (srca"; |
} |
} else { |
if (table68k[opcode].size == sz_long) { |
putcode = "put_long (srca"; |
} else { |
putcode = "put_word (srca"; |
} |
} |
count_write += table68k[opcode].size == sz_long ? 2 : 1; |
|
printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); |
//AO extra: 2->4 |
genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 4, 1, 0); |
start_brace (); |
if (table68k[opcode].dmode == Apdi) { |
printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); |
if (!using_mmu) |
printf ("\tint type = get_cpu_model() >= 68020;\n"); |
printf ("\twhile (amask) {\n"); |
printf ("\t\tsrca -= %d;\n", size); |
if (!using_mmu) |
printf ("\t\tif (type) m68k_areg (regs, dstreg) = srca;\n"); |
printf ("\t\t%s, m68k_areg (regs, movem_index2[amask]));\n", putcode); |
printf ("\t\tamask = movem_next[amask];\n"); |
printf ("\t}\n"); |
printf ("\twhile (dmask) { srca -= %d; %s, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", |
size, putcode); |
printf ("\tm68k_areg (regs, dstreg) = srca;\n"); |
} else { |
printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); |
printf ("\twhile (dmask) { %s, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", |
putcode, size); |
printf ("\twhile (amask) { %s, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", |
putcode, size); |
} |
if (using_prefetch) { |
sync_m68k_pc (); |
fill_prefetch_next (); |
} |
count_ncycles++; |
} |
|
static void genmovemle_ce (uae_u16 opcode) |
{ |
int size = table68k[opcode].size == sz_long ? 4 : 2; |
printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); |
genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA); |
|
if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r) { |
addcycles000 (2); |
} |
start_brace (); |
if (table68k[opcode].size == sz_long) { |
if (table68k[opcode].dmode == Apdi) { |
printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); |
printf ("\twhile (amask) { srca -= %d; put_word_ce (srca, m68k_areg (regs, movem_index2[amask]) >> 16); put_word_ce (srca + 2, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n", |
size); |
printf ("\twhile (dmask) { srca -= %d; put_word_ce (srca, m68k_dreg (regs, movem_index2[dmask]) >> 16); put_word_ce (srca + 2, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", |
size); |
printf ("\tm68k_areg (regs, dstreg) = srca;\n"); |
} else { |
printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); |
printf ("\twhile (dmask) { put_word_ce (srca, m68k_dreg (regs, movem_index1[dmask]) >> 16); put_word_ce (srca + 2, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", |
size); |
printf ("\twhile (amask) { put_word_ce (srca, m68k_areg (regs, movem_index1[amask]) >> 16); put_word_ce (srca + 2, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", |
size); |
} |
} else { |
if (table68k[opcode].dmode == Apdi) { |
printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); |
printf ("\twhile (amask) { srca -= %d; put_word_ce (srca, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n", |
size); |
printf ("\twhile (dmask) { srca -= %d; put_word_ce (srca, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", |
size); |
printf ("\tm68k_areg (regs, dstreg) = srca;\n"); |
} else { |
printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); |
printf ("\twhile (dmask) { put_word_ce (srca, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", |
size); |
printf ("\twhile (amask) { put_word_ce (srca, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", |
size); |
} |
} |
fill_prefetch_next (); |
count_ncycles++; |
} |
|
static void duplicate_carry (int n) |
{ |
int i; |
for (i = 0; i <= n; i++) |
printf ("\t"); |
printf ("COPY_CARRY ();\n"); |
} |
|
typedef enum |
{ |
flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_z, flag_zn, |
flag_av, flag_sv |
} |
flagtypes; |
|
static void genflags_normal (flagtypes type, wordsizes size, char *value, char *src, char *dst) |
{ |
char vstr[100], sstr[100], dstr[100]; |
char usstr[100], udstr[100]; |
char unsstr[100], undstr[100]; |
|
switch (size) { |
case sz_byte: |
strcpy (vstr, "((uae_s8)("); |
strcpy (usstr, "((uae_u8)("); |
break; |
case sz_word: |
strcpy (vstr, "((uae_s16)("); |
strcpy (usstr, "((uae_u16)("); |
break; |
case sz_long: |
strcpy (vstr, "((uae_s32)("); |
strcpy (usstr, "((uae_u32)("); |
break; |
default: |
abort (); |
} |
strcpy (unsstr, usstr); |
|
strcpy (sstr, vstr); |
strcpy (dstr, vstr); |
strcat (vstr, value); |
strcat (vstr, "))"); |
strcat (dstr, dst); |
strcat (dstr, "))"); |
strcat (sstr, src); |
strcat (sstr, "))"); |
|
strcpy (udstr, usstr); |
strcat (udstr, dst); |
strcat (udstr, "))"); |
strcat (usstr, src); |
strcat (usstr, "))"); |
|
strcpy (undstr, unsstr); |
strcat (unsstr, "-"); |
strcat (undstr, "~"); |
strcat (undstr, dst); |
strcat (undstr, "))"); |
strcat (unsstr, src); |
strcat (unsstr, "))"); |
|
switch (type) { |
case flag_logical_noclobber: |
case flag_logical: |
case flag_z: |
case flag_zn: |
case flag_av: |
case flag_sv: |
case flag_addx: |
case flag_subx: |
break; |
|
case flag_add: |
start_brace (); |
printf ("uae_u32 %s = %s + %s;\n", value, dstr, sstr); |
break; |
case flag_sub: |
case flag_cmp: |
start_brace (); |
printf ("uae_u32 %s = %s - %s;\n", value, dstr, sstr); |
break; |
} |
|
switch (type) { |
case flag_logical_noclobber: |
case flag_logical: |
case flag_zn: |
break; |
|
case flag_add: |
case flag_sub: |
case flag_addx: |
case flag_subx: |
case flag_cmp: |
case flag_av: |
case flag_sv: |
start_brace (); |
printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr); |
printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr); |
printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr); |
break; |
} |
|
switch (type) { |
case flag_logical: |
printf ("\tCLEAR_CZNV ();\n"); |
printf ("\tSET_ZFLG (%s == 0);\n", vstr); |
printf ("\tSET_NFLG (%s < 0);\n", vstr); |
break; |
case flag_logical_noclobber: |
printf ("\tSET_ZFLG (%s == 0);\n", vstr); |
printf ("\tSET_NFLG (%s < 0);\n", vstr); |
break; |
case flag_av: |
printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); |
break; |
case flag_sv: |
printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); |
break; |
case flag_z: |
printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr); |
break; |
case flag_zn: |
printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr); |
printf ("\tSET_NFLG (%s < 0);\n", vstr); |
break; |
case flag_add: |
printf ("\tSET_ZFLG (%s == 0);\n", vstr); |
printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); |
printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr); |
duplicate_carry (0); |
printf ("\tSET_NFLG (flgn != 0);\n"); |
break; |
case flag_sub: |
printf ("\tSET_ZFLG (%s == 0);\n", vstr); |
printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); |
printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr); |
duplicate_carry (0); |
printf ("\tSET_NFLG (flgn != 0);\n"); |
break; |
case flag_addx: |
printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */ |
printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */ |
duplicate_carry (0); |
break; |
case flag_subx: |
printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */ |
printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */ |
duplicate_carry (0); |
break; |
case flag_cmp: |
printf ("\tSET_ZFLG (%s == 0);\n", vstr); |
printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n"); |
printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr); |
printf ("\tSET_NFLG (flgn != 0);\n"); |
break; |
} |
} |
|
static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) |
{ |
/* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have |
them in the appropriate m68k.h files and use just one copy of this |
code here. The API can be changed if necessary. */ |
if (optimized_flags) { |
switch (type) { |
case flag_add: |
case flag_sub: |
start_brace (); |
printf ("\tuae_u32 %s;\n", value); |
break; |
|
default: |
break; |
} |
|
/* At least some of those casts are fairly important! */ |
switch (type) { |
case flag_logical_noclobber: |
printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n"); |
if (strcmp (value, "0") == 0) { |
printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n"); |
} else { |
switch (size) { |
case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break; |
case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break; |
case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break; |
} |
printf ("\tIOR_CZNV (oldcznv);\n"); |
} |
printf ("\t}\n"); |
return; |
case flag_logical: |
if (strcmp (value, "0") == 0) { |
printf ("\tSET_CZNV (FLAGVAL_Z);\n"); |
} else { |
switch (size) { |
case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break; |
case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break; |
case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break; |
} |
} |
return; |
|
case flag_add: |
switch (size) { |
case sz_byte: printf ("\toptflag_addb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; |
case sz_word: printf ("\toptflag_addw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; |
case sz_long: printf ("\toptflag_addl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; |
} |
return; |
|
case flag_sub: |
switch (size) { |
case sz_byte: printf ("\toptflag_subb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; |
case sz_word: printf ("\toptflag_subw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; |
case sz_long: printf ("\toptflag_subl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; |
} |
return; |
|
case flag_cmp: |
switch (size) { |
case sz_byte: printf ("\toptflag_cmpb (regs, (uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break; |
case sz_word: printf ("\toptflag_cmpw (regs, (uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break; |
case sz_long: printf ("\toptflag_cmpl (regs, (uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break; |
} |
return; |
|
default: |
break; |
} |
} |
|
genflags_normal (type, size, value, src, dst); |
} |
|
static void force_range_for_rox (const char *var, wordsizes size) |
{ |
/* Could do a modulo operation here... which one is faster? */ |
switch (size) { |
case sz_long: |
printf ("\tif (%s >= 33) %s -= 33;\n", var, var); |
break; |
case sz_word: |
printf ("\tif (%s >= 34) %s -= 34;\n", var, var); |
printf ("\tif (%s >= 17) %s -= 17;\n", var, var); |
break; |
case sz_byte: |
printf ("\tif (%s >= 36) %s -= 36;\n", var, var); |
printf ("\tif (%s >= 18) %s -= 18;\n", var, var); |
printf ("\tif (%s >= 9) %s -= 9;\n", var, var); |
break; |
} |
} |
|
static const char *cmask (wordsizes size) |
{ |
switch (size) { |
case sz_byte: return "0x80"; |
case sz_word: return "0x8000"; |
case sz_long: return "0x80000000"; |
default: abort (); |
} |
} |
|
static int source_is_imm1_8 (struct instr *i) |
{ |
return i->stype == 3; |
} |
|
static void shift_ce (amodes dmode, int size) |
{ |
if (using_ce && isreg (dmode)) { |
int c = size == sz_long ? 4 : 2; |
printf ("\t{\n"); |
printf ("\t\tint cycles = %d;\n", c); |
printf ("\t\tcycles += 2 * ccnt;\n"); |
addcycles000_3 ("\t\t"); |
printf ("\t}\n"); |
count_cycles += c; |
} |
} |
|
// BCHG/BSET/BCLR Dx,Dx or #xx,Dx adds 2 cycles if bit number > 15 |
static void bsetcycles (struct instr *curi) |
{ |
if (curi->size == sz_byte) { |
printf ("\tsrc &= 7;\n"); |
} else { |
printf ("\tsrc &= 31;\n"); |
if (isreg (curi->dmode)) { |
addcycles000 (2); |
if (curi->mnemo != i_BTST && using_ce) { |
printf ("\tif (src > 15) do_cycles_ce000 (2);\n"); |
count_ncycles++; |
} |
} |
} |
} |
|
static int islongimm (struct instr *curi) |
{ |
return (curi->size == sz_long && (curi->smode == Dreg || curi->smode == imm)); |
} |
|
static void gen_opcode (unsigned long int opcode) |
{ |
struct instr *curi = table68k + opcode; |
char *srcl, *dstl; |
char *srcw, *dstw; |
char *srcb, *dstb; |
|
insn_n_cycles = using_prefetch ? 0 : 4; |
|
if (using_ce020) { |
srcl = "get_long_ce020"; |
dstl = "put_long_ce020"; |
srcw = "get_word_ce020"; |
dstw = "put_word_ce020"; |
srcb = "get_byte_ce020"; |
dstb = "put_byte_ce020"; |
} else if (using_mmu) { |
srcl = "get_long_mmu"; |
dstl = "put_long_mmu"; |
srcw = "get_word_mmu"; |
dstw = "put_word_mmu"; |
srcb = "get_byte_mmu"; |
dstb = "put_byte_mmu"; |
} else if (using_ce) { |
srcl = "get_long_ce"; |
dstl = "put_long_ce"; |
srcw = "get_word_ce"; |
dstw = "put_word_ce"; |
srcb = "get_byte_ce"; |
dstb = "put_byte_ce"; |
} else { |
srcl = "get_long"; |
dstl = "put_long"; |
srcw = "get_word"; |
dstw = "put_word"; |
srcb = "get_byte"; |
dstb = "put_byte"; |
} |
|
insn_n_cycles020 = 0; |
|
start_brace (); |
m68k_pc_offset = 2; |
switch (curi->plev) { |
case 0: /* not privileged */ |
break; |
case 1: /* unprivileged only on 68000 */ |
if (cpu_level == 0) |
break; |
if (next_cpu_level < 0) |
next_cpu_level = 0; |
|
/* fall through */ |
case 2: /* priviledged */ |
printf ("if (!regs.s) { Exception (8, 0); goto %s; }\n", endlabelstr); |
need_endlabel = 1; |
start_brace (); |
break; |
case 3: /* privileged if size == word */ |
if (curi->size == sz_byte) |
break; |
printf ("if (!regs.s) { Exception (8, 0); goto %s; }\n", endlabelstr); |
need_endlabel = 1; |
start_brace (); |
break; |
} |
switch (curi->mnemo) { |
case i_OR: |
case i_AND: |
case i_EOR: |
{ |
int c = 0; |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^'); |
genflags (flag_logical, curi->size, "src", "", ""); |
if (curi->dmode == Dreg && curi->size == sz_long) { |
c += 2; |
if (curi->smode == imm || curi->smode == Dreg) |
c += 2; |
} |
if (c > 0) |
addcycles000 (c); |
fill_prefetch_next (); |
genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
} |
case i_ORSR: |
case i_EORSR: |
printf ("\tMakeSR ();\n"); |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
if (curi->size == sz_byte) { |
printf ("\tsrc &= 0xFF;\n"); |
} |
addcycles000 (4); |
fill_prefetch_next (); |
printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|'); |
printf ("\tMakeFromSR ();\n"); |
break; |
case i_ANDSR: |
printf ("\tMakeSR ();\n"); |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
if (curi->size == sz_byte) { |
printf ("\tsrc |= 0xFF00;\n"); |
} |
addcycles000 (4); |
fill_prefetch_next (); |
printf ("\tregs.sr &= src;\n"); |
printf ("\tMakeFromSR ();\n"); |
break; |
case i_SUB: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
if (curi->dmode == Dreg) { |
int c = 0; |
if (curi->size == sz_long) { |
c += 2; |
if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg) |
c += 2; |
} |
if (c > 0) |
addcycles000 (c); |
} |
fill_prefetch_next (); |
start_brace (); |
genflags (flag_sub, curi->size, "newv", "src", "dst"); |
genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_SUBA: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); |
if (curi->smode == immi) { |
int c = 4; |
if (c > 0) |
addcycles000 (c); |
} else { |
int c = curi->size == sz_long ? 2 : 4; |
if (islongimm (curi)) |
c += 2; |
if (c > 0) |
addcycles000 (c); |
} |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u32 newv = dst - src;\n"); |
genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); |
break; |
case i_SUBX: |
genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); |
genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
if (curi->size == sz_long && isreg (curi->smode)) |
addcycles000 (4); |
if (!isreg (curi->smode)) |
addcycles000 (2); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u32 newv = dst - src - (GET_XFLG () ? 1 : 0);\n"); |
genflags (flag_subx, curi->size, "newv", "src", "dst"); |
genflags (flag_zn, curi->size, "newv", "", ""); |
genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_SBCD: |
genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); |
genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n"); |
printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n"); |
printf ("\tuae_u16 newv, tmp_newv;\n"); |
printf ("\tint bcd = 0;\n"); |
printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n"); |
printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n"); |
printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG () ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n"); |
printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG () ? 1 : 0)) & 0x300) > 0xFF);\n"); |
duplicate_carry (0); |
/* Manual says bits NV are undefined though a real 68040/060 don't change them */ |
if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { |
if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) |
next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; |
genflags (flag_z, curi->size, "newv", "", ""); |
} else { |
genflags (flag_zn, curi->size, "newv", "", ""); |
printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); |
} |
addcycles000 (2); |
genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_ADD: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
if (curi->dmode == Dreg) { |
int c = 0; |
if (curi->size == sz_long) { |
c += 2; |
if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg) |
c += 2; |
} |
if (c > 0) |
addcycles000 (c); |
} |
fill_prefetch_next (); |
start_brace (); |
genflags (flag_add, curi->size, "newv", "src", "dst"); |
genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_ADDA: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); |
if (curi->smode == immi) { |
int c = curi->size == sz_long ? 4 : 0; |
if (islongimm (curi)) |
c += 2; |
if (c > 0) |
addcycles000 (c); |
} else { |
int c = curi->size == sz_long ? 2 : 4; |
if (islongimm (curi)) |
c += 2; |
if (c > 0) |
addcycles000 (c); |
} |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u32 newv = dst + src;\n"); |
genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); |
break; |
case i_ADDX: |
genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); |
genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
if (curi->size == sz_long && isreg (curi->smode)) |
addcycles000 (4); |
if (!isreg (curi->smode)) |
addcycles000 (2); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u32 newv = dst + src + (GET_XFLG () ? 1 : 0);\n"); |
genflags (flag_addx, curi->size, "newv", "src", "dst"); |
genflags (flag_zn, curi->size, "newv", "", ""); |
genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_ABCD: |
genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); |
genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG () ? 1 : 0);\n"); |
printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n"); |
printf ("\tuae_u16 newv, tmp_newv;\n"); |
printf ("\tint cflg;\n"); |
printf ("\tnewv = tmp_newv = newv_hi + newv_lo;"); |
printf ("\tif (newv_lo > 9) { newv += 6; }\n"); |
printf ("\tcflg = (newv & 0x3F0) > 0x90;\n"); |
printf ("\tif (cflg) newv += 0x60;\n"); |
printf ("\tSET_CFLG (cflg);\n"); |
duplicate_carry (0); |
/* Manual says bits NV are undefined though a real 68040 don't change them */ |
if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { |
if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) |
next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; |
genflags (flag_z, curi->size, "newv", "", ""); |
} |
else { |
genflags (flag_zn, curi->size, "newv", "", ""); |
printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); |
} |
addcycles000 (2); |
genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_NEG: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
if (isreg (curi->smode) && curi->size == sz_long) |
addcycles000 (2); |
fill_prefetch_next (); |
start_brace (); |
genflags (flag_sub, curi->size, "dst", "src", "0"); |
genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); |
break; |
case i_NEGX: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
if (isreg (curi->smode) && curi->size == sz_long) |
addcycles000 (2); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n"); |
genflags (flag_subx, curi->size, "newv", "src", "0"); |
genflags (flag_zn, curi->size, "newv", "", ""); |
genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src"); |
break; |
case i_NBCD: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
if (isreg (curi->smode)) |
addcycles000 (2); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n"); |
printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n"); |
printf ("\tuae_u16 newv;\n"); |
printf ("\tint cflg;\n"); |
printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n"); |
printf ("\tnewv = newv_hi + newv_lo;"); |
printf ("\tcflg = (newv & 0x1F0) > 0x90;\n"); |
printf ("\tif (cflg) newv -= 0x60;\n"); |
printf ("\tSET_CFLG (cflg);\n"); |
duplicate_carry(0); |
/* Manual says bits NV are undefined though a real 68040 don't change them */ |
if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { |
if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) |
next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; |
genflags (flag_z, curi->size, "newv", "", ""); |
} |
else { |
genflags (flag_zn, curi->size, "newv", "", ""); |
} |
genastore ("newv", curi->smode, "srcreg", curi->size, "src"); |
break; |
case i_CLR: |
genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0); |
if (isreg (curi->smode) && curi->size == sz_long) |
addcycles000 (2); |
fill_prefetch_next (); |
genflags (flag_logical, curi->size, "0", "", ""); |
genastore_rev ("0", curi->smode, "srcreg", curi->size, "src"); |
break; |
case i_NOT: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
if (isreg (curi->smode) && curi->size == sz_long) |
addcycles000 (2); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u32 dst = ~src;\n"); |
genflags (flag_logical, curi->size, "dst", "", ""); |
genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); |
break; |
case i_TST: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
fill_prefetch_next (); |
genflags (flag_logical, curi->size, "src", "", ""); |
break; |
case i_BTST: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
fill_prefetch_next (); |
bsetcycles (curi); |
printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); |
break; |
case i_BCHG: |
case i_BCLR: |
case i_BSET: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
bsetcycles (curi); |
if (curi->mnemo == i_BCLR && curi->dmode == Dreg) |
addcycles000 (2); |
fill_prefetch_next (); |
if (curi->mnemo == i_BCHG) { |
printf ("\tdst ^= (1 << src);\n"); |
printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n"); |
} else if (curi->mnemo == i_BCLR) { |
printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); |
printf ("\tdst &= ~(1 << src);\n"); |
} else if (curi->mnemo == i_BSET) { |
printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); |
printf ("\tdst |= (1 << src);\n"); |
} |
genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_CMPM: |
genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); |
genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); |
fill_prefetch_next (); |
start_brace (); |
genflags (flag_cmp, curi->size, "newv", "src", "dst"); |
break; |
case i_CMP: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
if (curi->dmode == Dreg && curi->size == sz_long) |
addcycles000 (2); |
fill_prefetch_next (); |
start_brace (); |
genflags (flag_cmp, curi->size, "newv", "src", "dst"); |
break; |
case i_CMPA: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); |
fill_prefetch_next (); |
addcycles000 (2); |
start_brace (); |
genflags (flag_cmp, sz_long, "newv", "src", "dst"); |
break; |
/* The next two are coded a little unconventional, but they are doing |
* weird things... */ |
case i_MVPRM: // MOVEP R->M |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
printf ("\tuaecptr memp = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0)); |
if (curi->size == sz_word) { |
printf ("\t%s (memp, src >> 8); %s (memp + 2, src);\n", dstb, dstb); |
count_write += 2; |
} else { |
printf ("\t%s (memp, src >> 24); %s (memp + 2, src >> 16);\n", dstb, dstb); |
printf ("\t%s (memp + 4, src >> 8); %s (memp + 6, src);\n", dstb, dstb); |
count_write += 4; |
} |
fill_prefetch_next (); |
break; |
case i_MVPMR: // MOVEP M->R |
printf ("\tuaecptr memp = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0)); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); |
if (curi->size == sz_word) { |
printf ("\tuae_u16 val = (%s (memp) << 8) + %s (memp + 2);\n", srcb, srcb); |
count_read += 2; |
} else { |
printf ("\tuae_u32 val = (%s (memp) << 24) + (%s (memp + 2) << 16)\n", srcb, srcb); |
printf (" + (%s (memp + 4) << 8) + %s (memp + 6);\n", srcb, srcb); |
count_read += 4; |
} |
fill_prefetch_next (); |
genastore ("val", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_MOVE: |
case i_MOVEA: |
{ |
/* 2 MOVE instructions have special prefetch sequence: |
* - MOVE <ea>,-(An) = prefetch is before writes (Apdi) |
* - MOVE memory,(xxx).L, the most stupid ever. 2 prefetches after write |
* - all others = prefetch is done after writes |
*/ |
int prefetch_done = 0; |
int dualprefetch = curi->dmode == absl && (curi->smode != Dreg && curi->smode != Areg && curi->smode != imm); |
genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
/* MOVE.L dx,(ax) exception3 PC points to next instruction. hackhackhack */ |
//AO extra: 2->3; (Aind ? 2) -> (Aind ? 0) |
genamode_e3 (curi->dmode, "dstreg", curi->size, "dst", 3, 0, 1 | (dualprefetch ? GF_NOREFILL : 0), curi->smode == Dreg && curi->dmode == Aind ? 0 : 0); |
genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
if (curi->mnemo == i_MOVEA && curi->size == sz_word) |
printf ("\tsrc = (uae_s32)(uae_s16)src;\n"); |
if (curi->dmode == Apdi) { |
fill_prefetch_next (); |
prefetch_done = 1; |
} |
if (curi->mnemo == i_MOVE) |
genflags (flag_logical, curi->size, "src", "", ""); |
genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); |
sync_m68k_pc (); |
if (dualprefetch) { |
fill_prefetch_full (); |
prefetch_done = 1; |
} |
if (!prefetch_done) |
fill_prefetch_next (); |
} |
break; |
case i_MVSR2: // MOVE FROM SR (like CLR, does dummy read first on 68000) |
//AO extra: (cpu_level == 0 ? 1 : 2) -> 3 |
genamode (curi->smode, "srcreg", sz_word, "src", 3, 0, 0); |
if (isreg (curi->smode)) |
addcycles000 (2); |
fill_prefetch_next (); |
printf ("\tMakeSR ();\n"); |
if (curi->size == sz_byte) |
genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src"); |
else |
genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src"); |
break; |
case i_MV2SR: // MOVE TO SR |
genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); |
if (curi->size == sz_byte) { |
addcycles000 (8); |
printf ("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n"); |
} else { |
addcycles000 (4); |
printf ("\tregs.sr = src;\n"); |
} |
fill_prefetch_next (); |
printf ("\tMakeFromSR ();\n"); |
break; |
case i_SWAP: |
genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n"); |
genflags (flag_logical, sz_long, "dst", "", ""); |
genastore ("dst", curi->smode, "srcreg", sz_long, "src"); |
break; |
case i_EXG: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
addcycles000 (2); |
fill_prefetch_next (); |
genastore ("dst", curi->smode, "srcreg", curi->size, "src"); |
genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_EXT: |
genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break; |
case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break; |
case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break; |
default: abort (); |
} |
genflags (flag_logical, |
curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); |
genastore ("dst", curi->smode, "srcreg", |
curi->size == sz_word ? sz_word : sz_long, "src"); |
break; |
case i_MVMEL: |
if (using_ce) |
genmovemel_ce (opcode); |
else |
genmovemel (opcode); |
break; |
case i_MVMLE: |
if (using_ce) |
genmovemle_ce (opcode); |
else |
genmovemle (opcode); |
break; |
case i_TRAP: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
gen_set_fault_pc (); |
sync_m68k_pc (); |
printf ("\tException (src + 32, 0);\n"); |
did_prefetch = 1; |
m68k_pc_offset = 0; |
break; |
case i_MVR2USP: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
fill_prefetch_next (); |
printf ("\tregs.usp = src;\n"); |
break; |
case i_MVUSP2R: |
genamode (curi->smode, "srcreg", curi->size, "src", 2, 0, 0); |
fill_prefetch_next (); |
genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src"); |
break; |
case i_RESET: |
fill_prefetch_next (); |
printf ("\tcpureset ();\n"); |
addcycles000 (128); |
if (using_prefetch) |
printf ("\tregs.irc = get_iword (4);\n"); |
break; |
case i_NOP: |
fill_prefetch_next (); |
break; |
case i_STOP: |
if (using_prefetch) { |
printf ("\tregs.sr = regs.irc;\n"); |
m68k_pc_offset += 2; |
} else { |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
printf ("\tregs.sr = src;\n"); |
} |
printf ("\tMakeFromSR ();\n"); |
printf ("\tm68k_setstopped ();\n"); |
sync_m68k_pc (); |
// STOP does not prefetch anything |
did_prefetch = -1; |
break; |
case i_LPSTOP: /* 68060 */ |
printf ("\tuae_u16 sw = get_iword (2);\n"); |
printf ("\tuae_u16 sr;\n"); |
printf ("\tif (sw != (0x100|0x80|0x40)) { Exception (4, 0); goto %s; }\n", endlabelstr); |
printf ("\tsr = get_iword (4);\n"); |
printf ("\tif (!(sr & 0x8000)) { Exception (8, 0); goto %s; }\n", endlabelstr); |
printf ("\tregs.sr = sr;\n"); |
printf ("\tMakeFromSR ();\n"); |
printf ("\tm68k_setstopped();\n"); |
m68k_pc_offset += 4; |
sync_m68k_pc (); |
fill_prefetch_full (); |
break; |
case i_RTE: |
if (cpu_level == 0) { |
genamode (Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL); |
genamode (Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL); |
printf ("\tregs.sr = sr;\n"); |
//AO extra start |
printf ("\tMakeFromSR ();\n"); |
printf ("\tif (pc & 1)\n"); |
printf ("\t\texception3i(0x%04X, m68k_getpc () + 2, pc);\n", opcode); |
printf ("\telse\n"); |
//AO extra end |
setpc ("pc"); |
//printf ("\tMakeFromSR ();\n"); |
} else { |
int old_brace_level = n_braces; |
if (next_cpu_level < 0) |
next_cpu_level = 0; |
genamode (Aipi, "7", sz_word, "sr", 1, 0, 0); |
genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); |
genamode (Aipi, "7", sz_word, "format", 1, 0, 0); |
printf ("\tm68k_do_rte (pc, sr, format, 0x%04x);\n", opcode); |
} |
/* PC is set and prefetch filled. */ |
m68k_pc_offset = 0; |
fill_prefetch_full (); |
break; |
case i_RTD: |
if (using_mmu) { |
genamode (curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); |
genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); |
printf ("\tm68k_areg(regs, 7) += offs;\n"); |
setpc ("pc"); |
} else { |
genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); |
genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0); |
printf ("\tm68k_areg (regs, 7) += offs;\n"); |
printf ("\tif (pc & 1)\n"); |
printf ("\t\texception3 (0x%04X, m68k_getpc (), pc);\n", opcode); |
printf ("\telse\n"); |
setpc ("pc"); |
} |
/* PC is set and prefetch filled. */ |
m68k_pc_offset = 0; |
fill_prefetch_full (); |
break; |
case i_LINK: |
if (using_mmu) { |
genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); |
genamode (Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, 0); |
genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); |
genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src"); |
printf ("\tm68k_areg(regs, 7) += offs;\n"); |
genastore ("src", Apdi, "7", sz_long, "old"); |
} else { |
//AO extra: 2->3 |
genamode (Apdi, "7", sz_long, "old", 3, 0, GF_AA); |
genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA); |
genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0); |
genastore ("src", Apdi, "7", sz_long, "old"); |
genastore ("m68k_areg (regs, 7)", curi->smode, "srcreg", sz_long, "src"); |
printf ("\tm68k_areg (regs, 7) += offs;\n"); |
fill_prefetch_next (); |
} |
break; |
case i_UNLK: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
printf ("\tm68k_areg (regs, 7) = src;\n"); |
genamode (Aipi, "7", sz_long, "old", 1, 0, 0); |
fill_prefetch_next (); |
genastore ("old", curi->smode, "srcreg", curi->size, "src"); |
break; |
case i_RTS: |
if (using_ce) |
printf ("\tm68k_do_rts_ce ();\n"); |
else if (using_indirect) |
printf ("\tm68k_do_rtsi ();\n"); |
else if (using_mmu) |
printf ("\tm68k_do_rts_mmu ();\n"); |
else |
printf ("\tm68k_do_rts ();\n"); |
count_read += 2; |
m68k_pc_offset = 0; |
fill_prefetch_full (); |
break; |
case i_TRAPV: |
sync_m68k_pc (); |
//fill_prefetch_next (); |
printf ("\tif (GET_VFLG ()) {\n"); |
printf ("\t\tException (7, m68k_getpc ());\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
//AO extra |
fill_prefetch_next (); |
need_endlabel = 1; |
break; |
case i_RTR: |
printf ("\tMakeSR ();\n"); |
genamode_pre (Aipi, "7", sz_word, "sr", 1, 0, 0); |
genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); |
genamode_post (Aipi, "7", sz_word, "sr", 1, 0, 0); |
printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n"); |
printf ("\tregs.sr |= sr;\n"); |
//AO extra start |
printf ("\tMakeFromSR ();\n"); |
printf ("\tif (pc & 1)\n"); |
printf ("\t\texception3i(0x%04X, m68k_getpc () + 2, pc);\n", opcode); |
printf ("\telse\n"); |
//AO extra end |
setpc ("pc"); |
//printf ("\tMakeFromSR ();\n"); |
m68k_pc_offset = 0; |
fill_prefetch_full (); |
break; |
case i_JSR: // TODO: check stack write order |
genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL); |
start_brace (); |
printf ("\tuaecptr oldpc = m68k_getpc () + %d;\n", m68k_pc_offset); |
if (using_exception_3) { |
printf ("\tif (srca & 1) {\n"); |
printf ("\t\texception3i (opcode, oldpc, srca);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
need_endlabel = 1; |
} |
if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16) |
addcycles000 (2); |
|
setpc ("srca"); |
m68k_pc_offset = 0; |
fill_prefetch_1 (0); |
if (curi->smode == Ad8r || curi->smode == PC8r) |
addcycles000 (6); |
|
//AO extra start |
genamode (Apdi, "7", sz_long, "dst", 3, 0, GF_AA); |
genastore ("oldpc", Apdi, "7", sz_long, "dst"); |
//AO extra end |
|
//printf ("\tm68k_areg (regs, 7) -= 4;\n"); |
//if (using_ce) { |
// printf ("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n"); |
// printf ("\tput_word_ce (m68k_areg (regs, 7) + 2, oldpc);\n"); |
//} else { |
// printf ("\t%s (m68k_areg (regs, 7), oldpc);\n", dstl); |
//} |
count_write += 2; |
fill_prefetch_next (); |
break; |
case i_JMP: |
genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA | ((curi->smode == Ad8r || curi->smode == PC8r) ? 0 : GF_NOREFILL)); |
if (using_exception_3) { |
printf ("\tif (srca & 1) {\n"); |
//AO extra 6->2 |
printf ("\t\texception3i (opcode, m68k_getpc () + %d, srca);\n", m68k_pc_offset); |
//printf ("\t\texception3i (opcode, m68k_getpc () + 6, srca);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
need_endlabel = 1; |
} |
if (curi->smode == Ad16 || curi->smode == Ad8r || curi->smode == absw || curi->smode == PC16 || curi->smode == PC8r) |
addcycles000 (2); |
setpc ("srca"); |
m68k_pc_offset = 0; |
fill_prefetch_full (); |
break; |
case i_BSR: |
//AO extra |
if(curi->size == sz_long) { |
printf ("\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 1);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
need_endlabel = 1; |
break; |
} |
//AO extra end |
printf ("\tuae_s32 s;\n"); |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL); |
printf ("\ts = (uae_s32)src + 2;\n"); |
if (using_exception_3) { |
printf ("\tif (src & 1) {\n"); |
//AO extra |
printf ("\t\texception3i (opcode, m68k_getpc () + %d, m68k_getpc () + s);\n", m68k_pc_offset); |
//printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + s);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
need_endlabel = 1; |
} |
addcycles000 (2); |
if (using_ce) { |
printf ("\tm68k_do_bsr_ce (m68k_getpc () + %d, s);\n", m68k_pc_offset); |
} else if (using_indirect) { |
printf ("\tm68k_do_bsri (m68k_getpc () + %d, s);\n", m68k_pc_offset); |
} else if (using_mmu) { |
printf ("\tm68k_do_bsr_mmu (m68k_getpc () + %d, s);\n", m68k_pc_offset); |
} else { |
printf ("\tm68k_do_bsr (m68k_getpc () + %d, s, opcode);\n", m68k_pc_offset); |
} |
count_write += 2; |
m68k_pc_offset = 0; |
fill_prefetch_full (); |
break; |
case i_Bcc: |
if (curi->size == sz_long) { |
if (cpu_level < 2) { |
addcycles000 (2); |
printf ("\tif (cctrue (%d)) {\n", curi->cc); |
printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 1);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
sync_m68k_pc (); |
irc2ir (); |
fill_prefetch_2 (); |
printf ("\tgoto %s;\n", endlabelstr); |
need_endlabel = 1; |
} else { |
if (next_cpu_level < 1) |
next_cpu_level = 1; |
} |
} |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); |
addcycles000 (2); |
printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc); |
if (using_exception_3) { |
printf ("\tif (src & 1) {\n"); |
//AO extra |
printf ("\t\texception3i (opcode, m68k_getpc () + %d, m68k_getpc () + 2 + (uae_s32)src);\n", m68k_pc_offset); |
//printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 2 + (uae_s32)src);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
need_endlabel = 1; |
} |
if (using_prefetch) { |
incpc ("(uae_s32)src + 2"); |
fill_prefetch_full (); |
if (using_ce) |
printf ("\treturn;\n"); |
else |
printf ("\treturn 10 * CYCLE_UNIT / 2;\n"); |
} else { |
incpc ("(uae_s32)src + 2"); |
returncycles ("\t", 10); |
} |
printf ("didnt_jump:;\n"); |
need_endlabel = 1; |
sync_m68k_pc (); |
if (curi->size == sz_byte) { |
addcycles000 (2); |
irc2ir (); |
fill_prefetch_2 (); |
} else if (curi->size == sz_word) { |
addcycles000 (2); |
fill_prefetch_full (); |
} else { |
fill_prefetch_full (); |
} |
insn_n_cycles = curi->size == sz_byte ? 8 : 12; |
break; |
case i_LEA: |
genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA); |
if (curi->smode == Ad8r || curi->smode == PC8r) |
addcycles000 (2); |
fill_prefetch_next (); |
if (curi->smode == Ad8r || curi->smode == PC8r) |
addcycles000 (2); |
genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); |
break; |
case i_PEA: |
genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA); |
//AO extra: 3 |
genamode (Apdi, "7", sz_long, "dst", 3, 0, GF_AA); |
if (curi->smode == Ad8r || curi->smode == PC8r) |
addcycles000 (2); |
if (!(curi->smode == absw || curi->smode == absl)) |
fill_prefetch_next (); |
if (curi->smode == Ad8r || curi->smode == PC8r) |
addcycles000 (2); |
genastore ("srca", Apdi, "7", sz_long, "dst"); |
if ((curi->smode == absw || curi->smode == absl)) |
fill_prefetch_next (); |
break; |
case i_DBcc: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); |
genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL); |
printf ("\tuaecptr oldpc = m68k_getpc ();\n"); |
addcycles000 (2); |
printf ("\tif (!cctrue (%d)) {\n", curi->cc); |
incpc ("(uae_s32)offs + 2"); |
//AO extra: comment out |
//printf ("\t"); fill_prefetch_1 (0); |
printf ("\t"); genastore ("(src - 1)", curi->smode, "srcreg", curi->size, "src"); |
|
printf ("\t\tif (src) {\n"); |
addcycles_ce020 (4); |
if (using_exception_3) { |
printf ("\t\t\tif (offs & 1) {\n"); |
//AO extra: (m68k_getpc () + 2 + (uae_s32)offs + 2) -> m68k_getpc (); (m68k_getpc () + 2) -> oldpc |
printf ("\t\t\t\texception3i (opcode, oldpc + 2, m68k_getpc ());\n"); |
printf ("\t\t\t\tgoto %s;\n", endlabelstr); |
printf ("\t\t\t}\n"); |
need_endlabel = 1; |
} |
irc2ir (); |
fill_prefetch_1 (2); |
returncycles ("\t\t\t", 12); |
if (using_ce) |
printf ("\t\t\treturn;\n"); |
printf ("\t\t}\n"); |
addcycles_ce020 (8); |
printf ("\t} else {\n"); |
addcycles000_2 ("\t\t", 2); |
addcycles_ce020 (4); |
printf ("\t}\n"); |
setpc ("oldpc + %d", m68k_pc_offset); |
m68k_pc_offset = 0; |
fill_prefetch_full (); |
insn_n_cycles = 12; |
need_endlabel = 1; |
break; |
case i_Scc: |
genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0); |
start_brace (); |
fill_prefetch_next(); |
start_brace (); |
printf ("\tint val = cctrue (%d) ? 0xff : 0;\n", curi->cc); |
if (using_ce) { |
printf ("\tint cycles = 0;\n"); |
if (isreg (curi->smode)) |
printf ("\tif (val) cycles += 2;\n"); |
addcycles000_3 ("\t"); |
} |
genastore ("val", curi->smode, "srcreg", curi->size, "src"); |
break; |
case i_DIVU: |
printf ("\tuaecptr oldpc = m68k_getpc ();\n"); |
genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); |
printf ("\tCLEAR_CZNV ();\n"); |
printf ("\tif (src == 0) {\n"); |
if (cpu_level > 0) { |
/* 68020 sets V when dividing by zero and N if dst is negative |
* 68000 clears both |
*/ |
printf("\t\tSET_VFLG (1);\n"); |
printf("\t\tif (dst < 0) SET_NFLG (1);\n"); |
} |
incpc ("%d", m68k_pc_offset); |
printf ("\t\tException (5, oldpc);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t} else {\n"); |
printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n"); |
printf ("\t\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n"); |
fill_prefetch_next (); |
if (using_ce) { |
start_brace (); |
printf ("\t\tint cycles = (getDivu68kCycles((uae_u32)dst, (uae_u16)src));\n"); |
addcycles000_3 ("\t\t"); |
} else if (using_ce020) { |
addcycles_ce020 (36); |
} |
/* The N flag appears to be set each time there is an overflow. |
* Weird. but 68020 only sets N when dst is negative.. */ |
printf ("\t\tif (newv > 0xffff) {\n"); |
printf ("\t\t\tSET_VFLG (1);\n"); |
#ifdef UNDEF68020 |
if (cpu_level >= 2) |
printf ("\t\t\tif (currprefs.cpu_level == 0 || dst < 0) SET_NFLG (®s, 1);\n"); |
else /* ??? some 68000 revisions may not set NFLG when overflow happens.. */ |
#endif |
printf ("\t\t\tSET_NFLG (1);\n"); |
printf ("\t\t} else {\n"); |
printf ("\t\t"); genflags (flag_logical, sz_word, "newv", "", ""); |
printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); |
printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); |
printf ("\t\t}\n"); |
sync_m68k_pc (); |
printf ("\t}\n"); |
count_ncycles++; |
insn_n_cycles += 136 - (136 - 76) / 2; /* average */ |
need_endlabel = 1; |
break; |
case i_DIVS: |
printf ("\tuaecptr oldpc = m68k_getpc ();\n"); |
genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); |
printf ("\tCLEAR_CZNV ();\n"); |
printf ("\tif (src == 0) {\n"); |
if (cpu_level > 0) { |
/* 68020 sets V when dividing by zero. Z is also set. |
* 68000 clears both |
*/ |
printf("\t\tSET_VFLG (1);\n"); |
printf("\t\tSET_ZFLG (1);\n"); |
} |
incpc ("%d", m68k_pc_offset); |
printf ("\t\tException (5, oldpc);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t} else {\n"); |
printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n"); |
printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n"); |
fill_prefetch_next (); |
if (using_ce) { |
start_brace (); |
printf ("\t\tint cycles = (getDivs68kCycles((uae_s32)dst, (uae_s16)src));\n"); |
addcycles000_3 ("\t\t"); |
} else if (using_ce020) { |
addcycles_ce020 (46); |
} |
printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n"); |
printf ("\t\t\tSET_VFLG (1);\n"); |
#ifdef UNDEF68020 |
if (cpu_level > 0) |
printf ("\t\t\tif (currprefs.cpu_level == 0) SET_NFLG (®s, 1);\n"); |
else |
#endif |
printf ("\t\t\tSET_NFLG (1);\n"); |
printf ("\t\t} else {\n"); |
printf ("\t\t\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n"); |
genflags (flag_logical, sz_word, "newv", "", ""); |
printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); |
printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); |
printf ("\t\t}\n"); |
sync_m68k_pc (); |
printf ("\t}\n"); |
count_ncycles++; |
insn_n_cycles += 156 - (156 - 120) / 2; /* average */ |
need_endlabel = 1; |
break; |
case i_MULU: |
genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0); |
fill_prefetch_next(); |
start_brace (); |
printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n"); |
if (using_ce) |
printf ("\tint cycles = 38 - 4, bits;\n"); |
genflags (flag_logical, sz_long, "newv", "", ""); |
if (using_ce) { |
printf ("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n"); |
printf ("\t\tif (src & 1) cycles += 2;\n"); |
addcycles000_3 ("\t"); |
} else if (using_ce020) { |
addcycles_ce020 (20); |
} |
genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); |
sync_m68k_pc (); |
count_cycles += 38 - 4; |
count_ncycles++; |
insn_n_cycles += (70 - 38) / 2 + 38; /* average */ |
break; |
case i_MULS: |
genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0); |
fill_prefetch_next(); |
start_brace (); |
printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n"); |
if (using_ce) { |
printf ("\tint cycles = 38 - 4, bits;\n"); |
printf ("\tuae_u32 usrc;\n"); |
} |
genflags (flag_logical, sz_long, "newv", "", ""); |
if (using_ce) { |
printf ("\tusrc = ((uae_u32)src) << 1;\n"); |
printf ("\tfor(bits = 0; bits < 16 && usrc; bits++, usrc >>= 1)\n"); |
printf ("\t\tif ((usrc & 3) == 1 || (usrc & 3) == 2) cycles += 2;\n"); |
addcycles000_3 ("\t"); |
} else if (using_ce020) { |
addcycles_ce020 (20); |
} |
genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); |
count_cycles += 38 - 4; |
count_ncycles++; |
insn_n_cycles += (70 - 38) / 2 + 38; /* average */ |
break; |
case i_CHK: |
printf ("\tuaecptr oldpc = m68k_getpc ();\n"); |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
sync_m68k_pc (); |
addcycles000 (4); |
printf ("\tif (dst > src) {\n"); |
printf ("\t\tSET_NFLG (0);\n"); |
printf ("\t\tException (6, oldpc);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
addcycles000 (2); |
printf ("\tif ((uae_s32)dst < 0) {\n"); |
printf ("\t\tSET_NFLG (1);\n"); |
printf ("\t\tException (6, oldpc);\n"); |
printf ("\t\tgoto %s;\n", endlabelstr); |
printf ("\t}\n"); |
fill_prefetch_next (); |
need_endlabel = 1; |
break; |
case i_CHK2: |
printf ("\tuaecptr oldpc = m68k_getpc ();\n"); |
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); |
fill_prefetch_0 (); |
printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n"); |
switch (curi->size) { |
case sz_byte: |
printf ("\tlower = (uae_s32)(uae_s8)%s (dsta); upper = (uae_s32)(uae_s8)%s (dsta + 1);\n", srcb, srcb); |
printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s8)reg;\n"); |
break; |
case sz_word: |
printf ("\tlower = (uae_s32)(uae_s16)%s (dsta); upper = (uae_s32)(uae_s16)%s (dsta + 2);\n", srcw, srcw); |
printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s16)reg;\n"); |
break; |
case sz_long: |
printf ("\tlower = %s (dsta); upper = %s (dsta + 4);\n", srcl, srcl); |
break; |
default: |
abort (); |
} |
printf ("\tSET_ZFLG (upper == reg || lower == reg);\n"); |
printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n"); |
printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception (6, oldpc); goto %s; }\n}\n", endlabelstr); |
need_endlabel = 1; |
break; |
|
case i_ASR: |
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next(); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1); |
printf ("\tint ccnt = cnt & 63;\n"); |
printf ("\tcnt &= 63;\n"); |
printf ("\tCLEAR_CZNV ();\n"); |
printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); |
printf ("\t\tval = %s & (uae_u32)-sign;\n", bit_mask (curi->size)); |
printf ("\t\tSET_CFLG (sign);\n"); |
duplicate_carry (1); |
if (source_is_imm1_8 (curi)) |
printf ("\t} else {\n"); |
else |
printf ("\t} else if (cnt > 0) {\n"); |
printf ("\t\tval >>= cnt - 1;\n"); |
printf ("\t\tSET_CFLG (val & 1);\n"); |
duplicate_carry (1); |
printf ("\t\tval >>= 1;\n"); |
printf ("\t\tval |= (%s << (%d - cnt)) & (uae_u32)-sign;\n", |
bit_mask (curi->size), |
bit_size (curi->size)); |
printf ("\t\tval &= %s;\n", bit_mask (curi->size)); |
printf ("\t}\n"); |
genflags (flag_logical_noclobber, curi->size, "val", "", ""); |
shift_ce (curi->dmode, curi->size); |
genastore ("val", curi->dmode, "dstreg", curi->size, "data"); |
break; |
case i_ASL: |
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next(); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tint ccnt = cnt & 63;\n"); |
printf ("\tcnt &= 63;\n"); |
printf ("\tCLEAR_CZNV ();\n"); |
printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); |
printf ("\t\tSET_VFLG (val != 0);\n"); |
printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", |
bit_size (curi->size)); |
duplicate_carry (1); |
printf ("\t\tval = 0;\n"); |
if (source_is_imm1_8 (curi)) |
printf ("\t} else {\n"); |
else |
printf ("\t} else if (cnt > 0) {\n"); |
printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n", |
bit_mask (curi->size), |
bit_size (curi->size) - 1, |
bit_mask (curi->size)); |
printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n"); |
printf ("\t\tval <<= cnt - 1;\n"); |
printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); |
duplicate_carry (1); |
printf ("\t\tval <<= 1;\n"); |
printf ("\t\tval &= %s;\n", bit_mask (curi->size)); |
printf ("\t}\n"); |
genflags (flag_logical_noclobber, curi->size, "val", "", ""); |
shift_ce (curi->dmode, curi->size); |
genastore ("val", curi->dmode, "dstreg", curi->size, "data"); |
break; |
case i_LSR: |
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next(); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tint ccnt = cnt & 63;\n"); |
printf ("\tcnt &= 63;\n"); |
printf ("\tCLEAR_CZNV ();\n"); |
printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); |
printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n", |
bit_size (curi->size), bit_size (curi->size) - 1); |
duplicate_carry (1); |
printf ("\t\tval = 0;\n"); |
if (source_is_imm1_8 (curi)) |
printf ("\t} else {\n"); |
else |
printf ("\t} else if (cnt > 0) {\n"); |
printf ("\t\tval >>= cnt - 1;\n"); |
printf ("\t\tSET_CFLG (val & 1);\n"); |
duplicate_carry (1); |
printf ("\t\tval >>= 1;\n"); |
printf ("\t}\n"); |
genflags (flag_logical_noclobber, curi->size, "val", "", ""); |
shift_ce (curi->dmode, curi->size); |
genastore ("val", curi->dmode, "dstreg", curi->size, "data"); |
break; |
case i_LSL: |
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next(); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tint ccnt = cnt & 63;\n"); |
printf ("\tcnt &= 63;\n"); |
printf ("\tCLEAR_CZNV ();\n"); |
printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); |
printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", bit_size (curi->size)); |
duplicate_carry (1); |
printf ("\t\tval = 0;\n"); |
if (source_is_imm1_8 (curi)) |
printf ("\t} else {\n"); |
else |
printf ("\t} else if (cnt > 0) {\n"); |
printf ("\t\tval <<= (cnt - 1);\n"); |
printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); |
duplicate_carry (1); |
printf ("\t\tval <<= 1;\n"); |
printf ("\tval &= %s;\n", bit_mask (curi->size)); |
printf ("\t}\n"); |
genflags (flag_logical_noclobber, curi->size, "val", "", ""); |
shift_ce (curi->dmode, curi->size); |
genastore ("val", curi->dmode, "dstreg", curi->size, "data"); |
break; |
case i_ROL: |
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tint ccnt = cnt & 63;\n"); |
printf ("\tcnt &= 63;\n"); |
printf ("\tCLEAR_CZNV ();\n"); |
if (source_is_imm1_8 (curi)) |
printf ("{"); |
else |
printf ("\tif (cnt > 0) {\n"); |
printf ("\tuae_u32 loval;\n"); |
printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); |
printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size)); |
printf ("\tval <<= cnt;\n"); |
printf ("\tval |= loval;\n"); |
printf ("\tval &= %s;\n", bit_mask (curi->size)); |
printf ("\tSET_CFLG (val & 1);\n"); |
printf ("}\n"); |
genflags (flag_logical_noclobber, curi->size, "val", "", ""); |
shift_ce (curi->dmode, curi->size); |
genastore ("val", curi->dmode, "dstreg", curi->size, "data"); |
break; |
case i_ROR: |
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tint ccnt = cnt & 63;\n"); |
printf ("\tcnt &= 63;\n"); |
printf ("\tCLEAR_CZNV ();\n"); |
if (source_is_imm1_8 (curi)) |
printf ("{"); |
else |
printf ("\tif (cnt > 0) {"); |
printf ("\tuae_u32 hival;\n"); |
printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); |
printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size)); |
printf ("\tval >>= cnt;\n"); |
printf ("\tval |= hival;\n"); |
printf ("\tval &= %s;\n", bit_mask (curi->size)); |
printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); |
printf ("\t}\n"); |
genflags (flag_logical_noclobber, curi->size, "val", "", ""); |
shift_ce (curi->dmode, curi->size); |
genastore ("val", curi->dmode, "dstreg", curi->size, "data"); |
break; |
case i_ROXL: |
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tint ccnt = cnt & 63;\n"); |
printf ("\tcnt &= 63;\n"); |
printf ("\tCLEAR_CZNV ();\n"); |
if (source_is_imm1_8 (curi)) |
printf ("{"); |
else { |
force_range_for_rox ("cnt", curi->size); |
printf ("\tif (cnt > 0) {\n"); |
} |
printf ("\tcnt--;\n"); |
printf ("\t{\n\tuae_u32 carry;\n"); |
printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1); |
printf ("\tcarry = loval & 1;\n"); |
printf ("\tval = (((val << 1) | GET_XFLG ()) << cnt) | (loval >> 1);\n"); |
printf ("\tSET_XFLG (carry);\n"); |
printf ("\tval &= %s;\n", bit_mask (curi->size)); |
printf ("\t} }\n"); |
printf ("\tSET_CFLG (GET_XFLG ());\n"); |
genflags (flag_logical_noclobber, curi->size, "val", "", ""); |
shift_ce (curi->dmode, curi->size); |
genastore ("val", curi->dmode, "dstreg", curi->size, "data"); |
break; |
case i_ROXR: |
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tint ccnt = cnt & 63;\n"); |
printf ("\tcnt &= 63;\n"); |
printf ("\tCLEAR_CZNV ();\n"); |
if (source_is_imm1_8 (curi)) |
printf ("{"); |
else { |
force_range_for_rox ("cnt", curi->size); |
printf ("\tif (cnt > 0) {\n"); |
} |
printf ("\tcnt--;\n"); |
printf ("\t{\n\tuae_u32 carry;\n"); |
printf ("\tuae_u32 hival = (val << 1) | GET_XFLG ();\n"); |
printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1); |
printf ("\tval >>= cnt;\n"); |
printf ("\tcarry = val & 1;\n"); |
printf ("\tval >>= 1;\n"); |
printf ("\tval |= hival;\n"); |
printf ("\tSET_XFLG (carry);\n"); |
printf ("\tval &= %s;\n", bit_mask (curi->size)); |
printf ("\t} }\n"); |
printf ("\tSET_CFLG (GET_XFLG ());\n"); |
genflags (flag_logical_noclobber, curi->size, "val", "", ""); |
shift_ce (curi->dmode, curi->size); |
genastore ("val", curi->dmode, "dstreg", curi->size, "data"); |
break; |
case i_ASRW: |
genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); |
printf ("\tuae_u32 cflg = val & 1;\n"); |
printf ("\tval = (val >> 1) | sign;\n"); |
genflags (flag_logical, curi->size, "val", "", ""); |
printf ("\tSET_CFLG (cflg);\n"); |
duplicate_carry (0); |
genastore ("val", curi->smode, "srcreg", curi->size, "data"); |
break; |
case i_ASLW: |
genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); |
printf ("\tuae_u32 sign2;\n"); |
printf ("\tval <<= 1;\n"); |
genflags (flag_logical, curi->size, "val", "", ""); |
printf ("\tsign2 = %s & val;\n", cmask (curi->size)); |
printf ("\tSET_CFLG (sign != 0);\n"); |
duplicate_carry (0); |
|
printf ("\tSET_VFLG (GET_VFLG () | (sign2 != sign));\n"); |
genastore ("val", curi->smode, "srcreg", curi->size, "data"); |
break; |
case i_LSRW: |
genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; |
case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 carry = val & 1;\n"); |
printf ("\tval >>= 1;\n"); |
genflags (flag_logical, curi->size, "val", "", ""); |
printf ("\tSET_CFLG (carry);\n"); |
duplicate_carry (0); |
genastore ("val", curi->smode, "srcreg", curi->size, "data"); |
break; |
case i_LSLW: |
genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u8 val = data;\n"); break; |
case sz_word: printf ("\tuae_u16 val = data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); |
printf ("\tval <<= 1;\n"); |
genflags (flag_logical, curi->size, "val", "", ""); |
printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); |
duplicate_carry (0); |
genastore ("val", curi->smode, "srcreg", curi->size, "data"); |
break; |
case i_ROLW: |
genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u8 val = data;\n"); break; |
case sz_word: printf ("\tuae_u16 val = data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); |
printf ("\tval <<= 1;\n"); |
printf ("\tif (carry) val |= 1;\n"); |
genflags (flag_logical, curi->size, "val", "", ""); |
printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); |
genastore ("val", curi->smode, "srcreg", curi->size, "data"); |
break; |
case i_RORW: |
genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u8 val = data;\n"); break; |
case sz_word: printf ("\tuae_u16 val = data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 carry = val & 1;\n"); |
printf ("\tval >>= 1;\n"); |
printf ("\tif (carry) val |= %s;\n", cmask (curi->size)); |
genflags (flag_logical, curi->size, "val", "", ""); |
printf ("\tSET_CFLG (carry);\n"); |
genastore ("val", curi->smode, "srcreg", curi->size, "data"); |
break; |
case i_ROXLW: |
genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u8 val = data;\n"); break; |
case sz_word: printf ("\tuae_u16 val = data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); |
printf ("\tval <<= 1;\n"); |
printf ("\tif (GET_XFLG ()) val |= 1;\n"); |
genflags (flag_logical, curi->size, "val", "", ""); |
printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); |
duplicate_carry (0); |
genastore ("val", curi->smode, "srcreg", curi->size, "data"); |
break; |
case i_ROXRW: |
genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
switch (curi->size) { |
case sz_byte: printf ("\tuae_u8 val = data;\n"); break; |
case sz_word: printf ("\tuae_u16 val = data;\n"); break; |
case sz_long: printf ("\tuae_u32 val = data;\n"); break; |
default: abort (); |
} |
printf ("\tuae_u32 carry = val & 1;\n"); |
printf ("\tval >>= 1;\n"); |
printf ("\tif (GET_XFLG ()) val |= %s;\n", cmask (curi->size)); |
genflags (flag_logical, curi->size, "val", "", ""); |
printf ("\tSET_CFLG (carry);\n"); |
duplicate_carry (0); |
genastore ("val", curi->smode, "srcreg", curi->size, "data"); |
break; |
case i_MOVEC2: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tint regno = (src >> 12) & 15;\n"); |
printf ("\tuae_u32 *regp = regs.regs + regno;\n"); |
printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr); |
break; |
case i_MOVE2C: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
fill_prefetch_next (); |
start_brace (); |
printf ("\tint regno = (src >> 12) & 15;\n"); |
printf ("\tuae_u32 *regp = regs.regs + regno;\n"); |
printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr); |
break; |
case i_CAS: |
{ |
int old_brace_level; |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
fill_prefetch_0 (); |
start_brace (); |
printf ("\tint ru = (src >> 6) & 7;\n"); |
printf ("\tint rc = src & 7;\n"); |
genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, rc)", "dst"); |
printf ("\tif (GET_ZFLG ())"); |
old_brace_level = n_braces; |
start_brace (); |
genastore ("(m68k_dreg (regs, ru))", curi->dmode, "dstreg", curi->size, "dst"); |
pop_braces (old_brace_level); |
printf ("else"); |
start_brace (); |
printf ("m68k_dreg (regs, rc) = dst;\n"); |
pop_braces (old_brace_level); |
} |
break; |
case i_CAS2: |
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n"); |
printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n"); |
if (curi->size == sz_word) { |
int old_brace_level = n_braces; |
printf ("\tuae_u16 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcw, srcw); |
genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1"); |
printf ("\tif (GET_ZFLG ()) {\n"); |
genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2"); |
printf ("\tif (GET_ZFLG ()) {\n"); |
printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstw); |
printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 6) & 7));\n", dstw); |
printf ("\t}}\n"); |
pop_braces (old_brace_level); |
printf ("\tif (! GET_ZFLG ()) {\n"); |
printf ("\tm68k_dreg (regs, (extra >> 22) & 7) = (m68k_dreg (regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n"); |
printf ("\tm68k_dreg (regs, (extra >> 6) & 7) = (m68k_dreg (regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n"); |
printf ("\t}\n"); |
} else { |
int old_brace_level = n_braces; |
printf ("\tuae_u32 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcl, srcl); |
genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1"); |
printf ("\tif (GET_ZFLG ()) {\n"); |
genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2"); |
printf ("\tif (GET_ZFLG ()) {\n"); |
printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstl); |
printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 6) & 7));\n", dstl); |
printf ("\t}}\n"); |
pop_braces (old_brace_level); |
printf ("\tif (! GET_ZFLG ()) {\n"); |
printf ("\tm68k_dreg (regs, (extra >> 22) & 7) = dst1;\n"); |
printf ("\tm68k_dreg (regs, (extra >> 6) & 7) = dst2;\n"); |
printf ("\t}\n"); |
} |
break; |
case i_MOVES: /* ignore DFC and SFC when using_mmu == false */ |
{ |
int old_brace_level; |
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
printf ("\tif (extra & 0x800)\n"); |
{ |
int old_m68k_pc_offset = m68k_pc_offset; |
old_brace_level = n_braces; |
start_brace (); |
printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n"); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); |
genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst"); |
pop_braces (old_brace_level); |
m68k_pc_offset = old_m68k_pc_offset; |
} |
printf ("else"); |
{ |
start_brace (); |
genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0, GF_FC); |
printf ("\tif (extra & 0x8000) {\n"); |
switch (curi->size) { |
case sz_byte: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break; |
case sz_word: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break; |
case sz_long: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = src;\n"); break; |
default: abort (); |
} |
printf ("\t} else {\n"); |
genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, ""); |
printf ("\t}\n"); |
sync_m68k_pc (); |
pop_braces (old_brace_level); |
} |
} |
break; |
case i_BKPT: /* only needed for hardware emulators */ |
sync_m68k_pc (); |
printf ("\top_illg (opcode);\n"); |
break; |
case i_CALLM: /* not present in 68030 */ |
sync_m68k_pc (); |
printf ("\top_illg (opcode);\n"); |
break; |
case i_RTM: /* not present in 68030 */ |
sync_m68k_pc (); |
printf ("\top_illg (opcode);\n"); |
break; |
case i_TRAPcc: |
if (curi->smode != am_unknown && curi->smode != am_illg) |
genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); |
fill_prefetch_0 (); |
printf ("\tif (cctrue (%d)) { Exception (7, m68k_getpc ()); goto %s; }\n", curi->cc, endlabelstr); |
need_endlabel = 1; |
break; |
case i_DIVL: |
printf ("\tuaecptr oldpc = m68k_getpc ();\n"); |
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
if (using_ce020) { |
addcycles_ce020 (70); |
} |
sync_m68k_pc (); |
printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n"); |
break; |
case i_MULL: |
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); |
if (using_ce020) { |
addcycles_ce020 (40); |
} |
sync_m68k_pc (); |
printf ("\tm68k_mull(opcode, dst, extra);\n"); |
break; |
case i_BFTST: |
case i_BFEXTU: |
case i_BFCHG: |
case i_BFEXTS: |
case i_BFCLR: |
case i_BFFFO: |
case i_BFSET: |
case i_BFINS: |
{ |
char *getb, *putb; |
|
if (using_mmu) { |
getb = "get_bitfield_040mmu"; |
putb = "put_bitfield_040mmu"; |
} else if (using_ce020) { |
getb = "get_bitfield_020ce"; |
putb = "put_bitfield_020ce"; |
} else { |
getb = "get_bitfield"; |
putb = "put_bitfield"; |
} |
|
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0, 0); |
start_brace (); |
printf ("\tuae_u32 bdata[2];\n"); |
printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n"); |
printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n"); |
if (curi->dmode == Dreg) { |
printf ("\tuae_u32 tmp = m68k_dreg(regs, dstreg);\n"); |
printf ("\toffset &= 0x1f;\n"); |
printf ("\ttmp = (tmp << offset) | (tmp >> (32 - offset));\n"); |
printf ("\tbdata[0] = tmp & ((1 << (32 - width)) - 1);\n"); |
} else { |
printf ("\tuae_u32 tmp;\n"); |
printf ("\tdsta += offset >> 3;\n"); |
printf ("\ttmp = %s (dsta, bdata, offset, width);\n", getb); |
} |
printf ("\tSET_NFLG_ALWAYS (((uae_s32)tmp) < 0 ? 1 : 0);\n"); |
if (curi->mnemo == i_BFEXTS) |
printf ("\ttmp = (uae_s32)tmp >> (32 - width);\n"); |
else |
printf ("\ttmp >>= (32 - width);\n"); |
printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n"); |
switch (curi->mnemo) { |
case i_BFTST: |
break; |
case i_BFEXTU: |
case i_BFEXTS: |
printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = tmp;\n"); |
break; |
case i_BFCHG: |
printf ("\ttmp = tmp ^ (0xffffffffu >> (32 - width));\n"); |
break; |
case i_BFCLR: |
printf ("\ttmp = 0;\n"); |
break; |
case i_BFFFO: |
printf ("\t{ uae_u32 mask = 1 << (width - 1);\n"); |
printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n"); |
printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = offset;\n"); |
break; |
case i_BFSET: |
printf ("\ttmp = 0xffffffffu >> (32 - width);\n"); |
break; |
case i_BFINS: |
printf ("\ttmp = m68k_dreg (regs, (extra >> 12) & 7);\n"); |
printf ("\ttmp = tmp & (0xffffffffu >> (32 - width));\n"); |
printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n"); |
printf ("\tSET_ZFLG (tmp == 0);\n"); |
break; |
default: |
break; |
} |
if (curi->mnemo == i_BFCHG |
|| curi->mnemo == i_BFCLR |
|| curi->mnemo == i_BFSET |
|| curi->mnemo == i_BFINS) { |
if (curi->dmode == Dreg) { |
printf ("\ttmp = bdata[0] | (tmp << (32 - width));\n"); |
printf ("\tm68k_dreg(regs, dstreg) = (tmp >> offset) | (tmp << (32 - offset));\n"); |
} else { |
printf ("\t%s(dsta, bdata, tmp, offset, width);\n", putb); |
} |
} |
} |
break; |
case i_PACK: |
if (curi->smode == Dreg) { |
printf ("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0)); |
printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n"); |
} else { |
printf ("\tuae_u16 val;\n"); |
printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); |
printf ("\tval = (uae_u16)%s (m68k_areg (regs, srcreg));\n", srcb); |
printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); |
printf ("\tval = (val | ((uae_u16)%s (m68k_areg (regs, srcreg)) << 8)) + %s;\n", srcb, gen_nextiword (0)); |
printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); |
gen_set_fault_pc (); |
printf ("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb); |
} |
break; |
case i_UNPK: |
if (curi->smode == Dreg) { |
printf ("\tuae_u16 val = m68k_dreg (regs, srcreg);\n"); |
printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0)); |
printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffff0000) | (val & 0xffff);\n"); |
} else { |
printf ("\tuae_u16 val;\n"); |
printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); |
printf ("\tval = (uae_u16)%s (m68k_areg (regs, srcreg));\n", srcb); |
printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0)); |
if (cpu_level >= 2) { |
printf ("\tm68k_areg (regs, dstreg) -= 2 * areg_byteinc[dstreg];\n"); |
printf ("\t%s (m68k_areg (regs, dstreg) + areg_byteinc[dstreg], val);\n", dstb); |
printf ("\t%s (m68k_areg (regs, dstreg), val >> 8);\n", dstb); |
} else { |
printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); |
printf ("\t%s (m68k_areg (regs, dstreg),val);\n", dstb); |
printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); |
gen_set_fault_pc (); |
printf ("\t%s (m68k_areg (regs, dstreg),val >> 8);\n", dstb); |
} |
} |
break; |
case i_TAS: |
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); |
genflags (flag_logical, curi->size, "src", "", ""); |
if (!isreg (curi->smode)) |
addcycles000 (2); |
fill_prefetch_next (); |
printf ("\tsrc |= 0x80;\n"); |
if (cpu_level >= 2 || curi->smode == Dreg || !using_ce) { |
if (next_cpu_level < 2) |
next_cpu_level = 2 - 1; |
genastore ("src", curi->smode, "srcreg", curi->size, "src"); |
} else { |
printf ("\tif (!is_cycle_ce ()) {\n"); |
genastore ("src", curi->smode, "srcreg", curi->size, "src"); |
printf ("\t} else {\n"); |
printf ("\t\tdo_cycles_ce000 (4);\n"); |
printf ("\t}\n"); |
} |
break; |
case i_FPP: |
fpulimit(); |
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
sync_m68k_pc (); |
printf ("\tfpuop_arithmetic(opcode, extra);\n"); |
break; |
case i_FDBcc: |
fpulimit(); |
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
sync_m68k_pc (); |
printf ("\tfpuop_dbcc (opcode, extra);\n"); |
break; |
case i_FScc: |
fpulimit(); |
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); |
sync_m68k_pc (); |
printf ("\tfpuop_scc (opcode, extra);\n"); |
break; |
case i_FTRAPcc: |
fpulimit(); |
printf ("\tuaecptr oldpc = m68k_getpc ();\n"); |
printf ("\tuae_u16 extra = %s;\n", gen_nextiword (0)); |
if (curi->smode != am_unknown && curi->smode != am_illg) |
genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); |
sync_m68k_pc (); |
printf ("\tfpuop_trapcc (opcode, oldpc, extra);\n"); |
break; |
case i_FBcc: |
fpulimit(); |
sync_m68k_pc (); |
start_brace (); |
printf ("\tuaecptr pc = m68k_getpc ();\n"); |
genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0); |
sync_m68k_pc (); |
printf ("\tfpuop_bcc (opcode, pc,extra);\n"); |
break; |
case i_FSAVE: |
fpulimit(); |
sync_m68k_pc (); |
printf ("\tfpuop_save (opcode);\n"); |
break; |
case i_FRESTORE: |
fpulimit(); |
sync_m68k_pc (); |
printf ("\tfpuop_restore (opcode);\n"); |
break; |
|
case i_CINVL: |
case i_CINVP: |
case i_CINVA: |
case i_CPUSHL: |
case i_CPUSHP: |
case i_CPUSHA: |
if (using_mmu) |
printf ("\tflush_mmu(m68k_areg (regs, opcode & 3), (opcode >> 6) & 3);\n"); |
printf ("\tif (opcode & 0x80)\n"); |
printf ("\t\tflush_icache(m68k_areg (regs, opcode & 3), (opcode >> 6) & 3);\n"); |
break; |
|
case i_MOVE16: |
{ |
if ((opcode & 0xfff8) == 0xf620) { |
/* MOVE16 (Ax)+,(Ay)+ */ |
printf ("\tuae_u32 v1, v2, v3, v4;\n"); |
printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n"); |
printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0)); |
printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n"); |
printf ("\tv1 = %s (mems);\n", srcl); |
printf ("\tv2 = %s (mems + 4);\n", srcl); |
printf ("\tv3 = %s (mems + 8);\n", srcl); |
printf ("\tv4 = %s (mems + 12);\n", srcl); |
printf ("\t%s (memd , v1);\n", dstl); |
printf ("\t%s (memd + 4, v2);\n", dstl); |
printf ("\t%s (memd + 8, v3);\n", dstl); |
printf ("\t%s (memd + 12, v4);\n", dstl); |
printf ("\tif (srcreg != dstreg)\n"); |
printf ("\t\tm68k_areg (regs, srcreg) += 16;\n"); |
printf ("\tm68k_areg (regs, dstreg) += 16;\n"); |
} else { |
/* Other variants */ |
printf ("\tuae_u32 v1, v2, v3, v4;\n"); |
genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0); |
genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0); |
printf ("\tmemsa &= ~15;\n"); |
printf ("\tmemda &= ~15;\n"); |
printf ("\tv1 = %s (memsa);\n", srcl); |
printf ("\tv2 = %s (memsa + 4);\n", srcl); |
printf ("\tv3 = %s (memsa + 8);\n", srcl); |
printf ("\tv4 = %s (memsa + 12);\n", srcl); |
printf ("\t%s (memda , v1);\n", dstl); |
printf ("\t%s (memda + 4, v2);\n", dstl); |
printf ("\t%s (memda + 8, v3);\n", dstl); |
printf ("\t%s (memda + 12, v4);\n", dstl); |
if ((opcode & 0xfff8) == 0xf600) |
printf ("\tm68k_areg (regs, srcreg) += 16;\n"); |
else if ((opcode & 0xfff8) == 0xf608) |
printf ("\tm68k_areg (regs, dstreg) += 16;\n"); |
} |
} |
break; |
|
case i_PFLUSHN: |
case i_PFLUSH: |
case i_PFLUSHAN: |
case i_PFLUSHA: |
case i_PLPAR: |
case i_PLPAW: |
case i_PTESTR: |
case i_PTESTW: |
sync_m68k_pc (); |
printf ("\tmmu_op (opcode, 0);\n"); |
break; |
case i_MMUOP030: |
printf ("\tuaecptr pc = m68k_getpc ();\n"); |
printf ("\tuae_u16 extra = get_word (pc + 2);\n"); |
m68k_pc_offset += 2; |
sync_m68k_pc (); |
if (curi->smode == Areg || curi->smode == Dreg) |
printf("\tuae_u16 extraa = 0;\n"); |
else |
genamode (curi->smode, "srcreg", curi->size, "extra", 0, 0, 0); |
sync_m68k_pc (); |
printf ("\tmmu_op30 (pc, opcode, extra, extraa);\n"); |
break; |
default: |
abort (); |
break; |
} |
finish_braces (); |
if (limit_braces) { |
printf ("\n#endif\n"); |
n_braces = limit_braces; |
limit_braces = 0; |
finish_braces (); |
} |
if (did_prefetch >= 0) |
fill_prefetch_finish (); |
if (!count_cycles) |
addcycles_ce020 (2); |
sync_m68k_pc (); |
did_prefetch = 0; |
} |
|
static void generate_includes (FILE * f) |
{ |
//AO68000 |
fprintf(f, "#include \"ao.h\"\n"); |
/// fprintf (f, "#include \"sysconfig.h\"\n"); |
/// fprintf (f, "#include \"sysdeps.h\"\n"); |
/// fprintf (f, "#include \"options.h\"\n"); |
// fprintf (f, "#include \"memory.h\"\n"); |
/// fprintf (f, "#include \"custom.h\"\n"); |
/// fprintf (f, "#include \"events.h\"\n"); |
/// fprintf (f, "#include \"newcpu.h\"\n"); |
/// fprintf (f, "#include \"cpu_prefetch.h\"\n"); |
fprintf (f, "#include \"cputbl.h\"\n"); |
/// fprintf (f, "#include \"cpummu.h\"\n"); |
//AO68000 end |
|
|
fprintf (f, "#define CPUFUNC(x) x##_ff\n" |
"#define SET_CFLG_ALWAYS(x) SET_CFLG(x)\n" |
"#define SET_NFLG_ALWAYS(x) SET_NFLG(x)\n" |
"#ifdef NOFLAGS\n" |
"#include \"noflags.h\"\n" |
"#endif\n"); |
} |
|
static int postfix; |
|
|
static char *decodeEA (amodes mode, wordsizes size) |
{ |
static char buffer[80]; |
|
buffer[0] = 0; |
switch (mode){ |
case Dreg: |
strcpy (buffer,"Dn"); |
break; |
case Areg: |
strcpy (buffer,"An"); |
break; |
case Aind: |
strcpy (buffer,"(An)"); |
break; |
case Aipi: |
strcpy (buffer,"(An)+"); |
break; |
case Apdi: |
strcpy (buffer,"-(An)"); |
break; |
case Ad16: |
strcpy (buffer,"(d16,An)"); |
break; |
case Ad8r: |
strcpy (buffer,"(d8,An,Xn)"); |
break; |
case PC16: |
strcpy (buffer,"(d16,PC)"); |
break; |
case PC8r: |
strcpy (buffer,"(d8,PC,Xn)"); |
break; |
case absw: |
strcpy (buffer,"(xxx).W"); |
break; |
case absl: |
strcpy (buffer,"(xxx).L"); |
break; |
case imm: |
switch (size){ |
case sz_byte: |
strcpy (buffer,"#<data>.B"); |
break; |
case sz_word: |
strcpy (buffer,"#<data>.W"); |
break; |
case sz_long: |
strcpy (buffer,"#<data>.L"); |
break; |
default: |
break; |
} |
break; |
case imm0: |
strcpy (buffer,"#<data>.B"); |
break; |
case imm1: |
strcpy (buffer,"#<data>.W"); |
break; |
case imm2: |
strcpy (buffer,"#<data>.L"); |
break; |
case immi: |
strcpy (buffer,"#<data>"); |
break; |
|
default: |
break; |
} |
return buffer; |
} |
|
static char *outopcode (int opcode) |
{ |
static char out[100]; |
struct instr *ins; |
int i; |
|
ins = &table68k[opcode]; |
for (i = 0; lookuptab[i].name[0]; i++) { |
if (ins->mnemo == lookuptab[i].mnemo) |
break; |
} |
{ |
char *s = ua (lookuptab[i].name); |
strcpy (out, s); |
xfree (s); |
} |
if (ins->smode == immi) |
strcat (out, "Q"); |
if (ins->size == sz_byte) |
strcat (out,".B"); |
if (ins->size == sz_word) |
strcat (out,".W"); |
if (ins->size == sz_long) |
strcat (out,".L"); |
strcat (out," "); |
if (ins->suse) |
strcat (out, decodeEA (ins->smode, ins->size)); |
if (ins->duse) { |
if (ins->suse) strcat (out,","); |
strcat (out, decodeEA (ins->dmode, ins->size)); |
} |
return out; |
} |
|
static void generate_one_opcode (int rp) |
{ |
int idx; |
uae_u16 smsk, dmsk; |
long int opcode = opcode_map[rp]; |
int i68000 = table68k[opcode].clev > 0; |
|
if (table68k[opcode].mnemo == i_ILLG |
|| table68k[opcode].clev > cpu_level) |
return; |
|
for (idx = 0; lookuptab[idx].name[0]; idx++) { |
if (table68k[opcode].mnemo == lookuptab[idx].mnemo) |
break; |
} |
|
if (table68k[opcode].handler != -1) |
return; |
|
if (opcode_next_clev[rp] != cpu_level) { |
char *name = ua (lookuptab[idx].name); |
if (generate_stbl) |
fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n", |
(using_ce || using_ce020) ? "(cpuop_func*)" : "", |
opcode, opcode_last_postfix[rp], |
opcode, name); |
xfree (name); |
return; |
} |
fprintf (headerfile, "extern %s op_%04lx_%d_nf;\n", |
(using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix); |
fprintf (headerfile, "extern %s op_%04lx_%d_ff;\n", |
(using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix); |
printf ("/* %s */\n", outopcode (opcode)); |
if (i68000) |
printf("#ifndef CPUEMU_68000_ONLY\n"); |
printf ("%s REGPARAM2 CPUFUNC(op_%04lx_%d)(uae_u32 opcode)\n{\n", (using_ce || using_ce020) ? "void" : "unsigned long", opcode, postfix); |
|
switch (table68k[opcode].stype) { |
case 0: smsk = 7; break; |
case 1: smsk = 255; break; |
case 2: smsk = 15; break; |
case 3: smsk = 7; break; |
case 4: smsk = 7; break; |
case 5: smsk = 63; break; |
case 7: smsk = 3; break; |
default: abort (); |
} |
dmsk = 7; |
|
next_cpu_level = -1; |
if (table68k[opcode].suse |
&& table68k[opcode].smode != imm && table68k[opcode].smode != imm0 |
&& table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 |
&& table68k[opcode].smode != absw && table68k[opcode].smode != absl |
&& table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) |
{ |
if (table68k[opcode].spos == -1) { |
if (((int) table68k[opcode].sreg) >= 128) |
printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); |
else |
printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg); |
} else { |
char source[100]; |
int pos = table68k[opcode].spos; |
|
if (pos) |
sprintf (source, "((opcode >> %d) & %d)", pos, smsk); |
else |
sprintf (source, "(opcode & %d)", smsk); |
|
if (table68k[opcode].stype == 3) |
printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source); |
else if (table68k[opcode].stype == 1) |
printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); |
else |
printf ("\tuae_u32 srcreg = %s;\n", source); |
} |
} |
if (table68k[opcode].duse |
/* Yes, the dmode can be imm, in case of LINK or DBcc */ |
&& table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 |
&& table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 |
&& table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) |
{ |
if (table68k[opcode].dpos == -1) { |
if (((int) table68k[opcode].dreg) >= 128) |
printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); |
else |
printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg); |
} else { |
int pos = table68k[opcode].dpos; |
if (pos) |
printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", |
pos, dmsk); |
else |
printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); |
} |
} |
need_endlabel = 0; |
endlabelno++; |
sprintf (endlabelstr, "endlabel%d", endlabelno); |
count_read = count_write = count_ncycles = count_cycles = 0; |
count_read_ea = count_write_ea = count_cycles_ea = 0; |
gen_opcode (opcode); |
if (need_endlabel) |
printf ("%s: ;\n", endlabelstr); |
returncycles ("", insn_n_cycles); |
printf ("}"); |
if (using_ce || using_prefetch) { |
if (count_read + count_write + count_cycles == 0) |
count_cycles = 4; |
printf (" /* %d%s (%d/%d)", |
(count_read + count_write) * 4 + count_cycles, count_ncycles ? "+" : "", count_read, count_write); |
printf (" */\n"); |
} else { |
printf("\n"); |
} |
printf ("\n"); |
if (i68000) |
printf("#endif\n"); |
opcode_next_clev[rp] = next_cpu_level; |
opcode_last_postfix[rp] = postfix; |
|
if (generate_stbl) { |
char *name = ua (lookuptab[idx].name); |
if (i68000) |
fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n"); |
fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n", |
(using_ce || using_ce020) ? "(cpuop_func*)" : "", |
opcode, postfix, opcode, name); |
if (i68000) |
fprintf (stblfile, "#endif\n"); |
xfree (name); |
} |
} |
|
static void generate_func (void) |
{ |
int j, rp; |
|
/* sam: this is for people with low memory (eg. me :)) */ |
printf ("\n" |
"#if !defined(PART_1) && !defined(PART_2) && " |
"!defined(PART_3) && !defined(PART_4) && " |
"!defined(PART_5) && !defined(PART_6) && " |
"!defined(PART_7) && !defined(PART_8)" |
"\n" |
"#define PART_1 1\n" |
"#define PART_2 1\n" |
"#define PART_3 1\n" |
"#define PART_4 1\n" |
"#define PART_5 1\n" |
"#define PART_6 1\n" |
"#define PART_7 1\n" |
"#define PART_8 1\n" |
"#endif\n\n"); |
|
rp = 0; |
for(j = 1; j <= 8; ++j) { |
int k = (j * nr_cpuop_funcs) / 8; |
printf ("#ifdef PART_%d\n",j); |
for (; rp < k; rp++) |
generate_one_opcode (rp); |
printf ("#endif\n\n"); |
} |
|
if (generate_stbl) |
fprintf (stblfile, "{ 0, 0 }};\n"); |
} |
|
int main (int argc, char **argv) |
{ |
int i, rp, postfix2; |
char fname[100]; |
|
read_table68k (); |
do_merges (); |
|
opcode_map = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs); |
opcode_last_postfix = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs); |
opcode_next_clev = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs); |
counts = (unsigned long *) xmalloc (65536 * sizeof (unsigned long)); |
read_counts (); |
|
/* It would be a lot nicer to put all in one file (we'd also get rid of |
* cputbl.h that way), but cpuopti can't cope. That could be fixed, but |
* I don't dare to touch the 68k version. */ |
|
headerfile = fopen ("cputbl.h", "wb"); |
|
stblfile = fopen ("cpustbl.c", "wb"); |
generate_includes (stblfile); |
|
using_prefetch = 0; |
using_indirect = 0; |
using_exception_3 = 1; |
using_ce = 0; |
|
postfix2 = -1; |
for (i = 0; i < 32; i++) { |
postfix = i; |
if ((i >= 6 && i < 11) || (i > 12 && i < 20) || (i > 23 && i < 31)) |
continue; |
generate_stbl = 1; |
if (i == 0 || i == 11 || i == 12 || i == 20 || i == 31) { |
if (generate_stbl) |
fprintf (stblfile, "#ifdef CPUEMU_%d\n", postfix); |
postfix2 = postfix; |
sprintf (fname, "cpuemu_%d.c", postfix); |
freopen (fname, "wb", stdout); |
generate_includes (stdout); |
} |
using_mmu = 0; |
using_prefetch = 0; |
using_ce = 0; |
using_ce020 = 0; |
using_mmu = 0; |
cpu_level = 5 - i; |
if (i == 11 || i == 12) { |
cpu_level = 0; |
using_prefetch = 1; |
using_exception_3 = 1; |
if (i == 12) |
using_ce = 1; |
for (rp = 0; rp < nr_cpuop_funcs; rp++) |
opcode_next_clev[rp] = 0; |
} else if (i >= 20 && i < 30) { |
cpu_level = 25 - i; |
using_ce020 = 1; |
if (i == 20) |
read_counts (); |
} else if (i >= 31 && i < 40) { |
cpu_level = 4; |
using_mmu = 1; |
if (i == 31) |
read_counts (); |
for (rp = 0; rp < nr_cpuop_funcs; rp++) |
opcode_next_clev[rp] = 4; |
} |
|
if (generate_stbl) { |
if ((i > 0 && i < 10) || (i >= 20)) |
fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n"); |
fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix); |
} |
generate_func (); |
if (generate_stbl) { |
if ((i > 0 && i < 10) || (i >= 20)) |
fprintf (stblfile, "#endif /* CPUEMU_68000_ONLY */\n"); |
if (postfix2 >= 0) |
fprintf (stblfile, "#endif /* CPUEMU_%d */\n", postfix2); |
} |
postfix2 = -1; |
} |
|
free (table68k); |
return 0; |
} |
/trunk/bench/sw_emulators/winuae/readcpu.c
0,0 → 1,881
/* |
* UAE - The Un*x Amiga Emulator |
* |
* Read 68000 CPU specs from file "table68k" |
* |
* Copyright 1995,1996 Bernd Schmidt |
*/ |
|
//AO#include "sysconfig.h" |
//AO#include "sysdeps.h" |
#include "ao.h" |
#include <ctype.h> |
|
#include "readcpu.h" |
|
int nr_cpuop_funcs; |
|
struct mnemolookup lookuptab[] = { |
{ i_ILLG, L"ILLEGAL" }, |
{ i_OR, L"OR" }, |
{ i_CHK, L"CHK" }, |
{ i_CHK2, L"CHK2" }, |
{ i_AND, L"AND" }, |
{ i_EOR, L"EOR" }, |
{ i_ORSR, L"ORSR" }, |
{ i_ANDSR, L"ANDSR" }, |
{ i_EORSR, L"EORSR" }, |
{ i_SUB, L"SUB" }, |
{ i_SUBA, L"SUBA" }, |
{ i_SUBX, L"SUBX" }, |
{ i_SBCD, L"SBCD" }, |
{ i_ADD, L"ADD" }, |
{ i_ADDA, L"ADDA" }, |
{ i_ADDX, L"ADDX" }, |
{ i_ABCD, L"ABCD" }, |
{ i_NEG, L"NEG" }, |
{ i_NEGX, L"NEGX" }, |
{ i_NBCD, L"NBCD" }, |
{ i_CLR, L"CLR" }, |
{ i_NOT, L"NOT" }, |
{ i_TST, L"TST" }, |
{ i_BTST, L"BTST" }, |
{ i_BCHG, L"BCHG" }, |
{ i_BCLR, L"BCLR" }, |
{ i_BSET, L"BSET" }, |
{ i_CMP, L"CMP" }, |
{ i_CMPM, L"CMPM" }, |
{ i_CMPA, L"CMPA" }, |
{ i_MVPRM, L"MVPRM" }, |
{ i_MVPMR, L"MVPMR" }, |
{ i_MOVE, L"MOVE" }, |
{ i_MOVEA, L"MOVEA" }, |
{ i_MVSR2, L"MVSR2" }, |
{ i_MV2SR, L"MV2SR" }, |
{ i_SWAP, L"SWAP" }, |
{ i_EXG, L"EXG" }, |
{ i_EXT, L"EXT" }, |
{ i_MVMEL, L"MVMEL", L"MOVEM" }, |
{ i_MVMLE, L"MVMLE", L"MOVEM" }, |
{ i_TRAP, L"TRAP" }, |
{ i_MVR2USP, L"MVR2USP" }, |
{ i_MVUSP2R, L"MVUSP2R" }, |
{ i_NOP, L"NOP" }, |
{ i_RESET, L"RESET" }, |
{ i_RTE, L"RTE" }, |
{ i_RTD, L"RTD" }, |
{ i_LINK, L"LINK" }, |
{ i_UNLK, L"UNLK" }, |
{ i_RTS, L"RTS" }, |
{ i_STOP, L"STOP" }, |
{ i_TRAPV, L"TRAPV" }, |
{ i_RTR, L"RTR" }, |
{ i_JSR, L"JSR" }, |
{ i_JMP, L"JMP" }, |
{ i_BSR, L"BSR" }, |
{ i_Bcc, L"Bcc" }, |
{ i_LEA, L"LEA" }, |
{ i_PEA, L"PEA" }, |
{ i_DBcc, L"DBcc" }, |
{ i_Scc, L"Scc" }, |
{ i_DIVU, L"DIVU" }, |
{ i_DIVS, L"DIVS" }, |
{ i_MULU, L"MULU" }, |
{ i_MULS, L"MULS" }, |
{ i_ASR, L"ASR" }, |
{ i_ASL, L"ASL" }, |
{ i_LSR, L"LSR" }, |
{ i_LSL, L"LSL" }, |
{ i_ROL, L"ROL" }, |
{ i_ROR, L"ROR" }, |
{ i_ROXL, L"ROXL" }, |
{ i_ROXR, L"ROXR" }, |
{ i_ASRW, L"ASRW" }, |
{ i_ASLW, L"ASLW" }, |
{ i_LSRW, L"LSRW" }, |
{ i_LSLW, L"LSLW" }, |
{ i_ROLW, L"ROLW" }, |
{ i_RORW, L"RORW" }, |
{ i_ROXLW, L"ROXLW" }, |
{ i_ROXRW, L"ROXRW" }, |
|
{ i_MOVE2C, L"MOVE2C", L"MOVEC" }, |
{ i_MOVEC2, L"MOVEC2", L"MOVEC" }, |
{ i_CAS, L"CAS" }, |
{ i_CAS2, L"CAS2" }, |
{ i_MULL, L"MULL" }, |
{ i_DIVL, L"DIVL" }, |
{ i_BFTST, L"BFTST" }, |
{ i_BFEXTU, L"BFEXTU" }, |
{ i_BFCHG, L"BFCHG" }, |
{ i_BFEXTS, L"BFEXTS" }, |
{ i_BFCLR, L"BFCLR" }, |
{ i_BFFFO, L"BFFFO" }, |
{ i_BFSET, L"BFSET" }, |
{ i_BFINS, L"BFINS" }, |
{ i_PACK, L"PACK" }, |
{ i_UNPK, L"UNPK" }, |
{ i_TAS, L"TAS" }, |
{ i_BKPT, L"BKPT" }, |
{ i_CALLM, L"CALLM" }, |
{ i_RTM, L"RTM" }, |
{ i_TRAPcc, L"TRAPcc" }, |
{ i_MOVES, L"MOVES" }, |
{ i_FPP, L"FPP" }, |
{ i_FDBcc, L"FDBcc" }, |
{ i_FScc, L"FScc" }, |
{ i_FTRAPcc, L"FTRAPcc" }, |
{ i_FBcc, L"FBcc" }, |
{ i_FBcc, L"FBcc" }, |
{ i_FSAVE, L"FSAVE" }, |
{ i_FRESTORE, L"FRESTORE" }, |
|
{ i_CINVL, L"CINVL" }, |
{ i_CINVP, L"CINVP" }, |
{ i_CINVA, L"CINVA" }, |
{ i_CPUSHL, L"CPUSHL" }, |
{ i_CPUSHP, L"CPUSHP" }, |
{ i_CPUSHA, L"CPUSHA" }, |
{ i_MOVE16, L"MOVE16" }, |
|
{ i_MMUOP030, L"MMUOP030" }, |
{ i_PFLUSHN, L"PFLUSHN" }, |
{ i_PFLUSH, L"PFLUSH" }, |
{ i_PFLUSHAN, L"PFLUSHAN" }, |
{ i_PFLUSHA, L"PFLUSHA" }, |
|
{ i_PLPAR, L"PLPAR" }, |
{ i_PLPAW, L"PLPAW" }, |
{ i_PTESTR, L"PTESTR" }, |
{ i_PTESTW, L"PTESTW" }, |
|
{ i_LPSTOP, L"LPSTOP" }, |
{ i_ILLG, L"" }, |
}; |
|
struct instr *table68k; |
|
static int specialcase (uae_u16 opcode, int cpu_lev) |
{ |
int mode = (opcode >> 3) & 7; |
int reg = opcode & 7; |
|
if (cpu_lev >= 2) |
return cpu_lev; |
/* TST.W A0, TST.L A0, TST.x (d16,PC) and TST.x (d8,PC,Xn) are 68020+ only */ |
if ((opcode & 0xff00) == 0x4a00) { |
if (mode == 7 && (reg == 4 || reg == 2 || reg == 3)) |
return 2; |
if (mode == 1) /* Ax */ |
return 2; |
} |
/* CMPI.W #x,(d16,PC) and CMPI.W #x,(d8,PC,Xn) are 68020+ only */ |
if ((opcode & 0xff00) == 0x0c00) { |
if (mode == 7 && (reg == 2 || reg == 3)) |
return 2; |
} |
return cpu_lev; |
} |
|
static amodes mode_from_str (const TCHAR *str) |
{ |
if (_tcsncmp (str, L"Dreg", 4) == 0) return Dreg; |
if (_tcsncmp (str, L"Areg", 4) == 0) return Areg; |
if (_tcsncmp (str, L"Aind", 4) == 0) return Aind; |
if (_tcsncmp (str, L"Apdi", 4) == 0) return Apdi; |
if (_tcsncmp (str, L"Aipi", 4) == 0) return Aipi; |
if (_tcsncmp (str, L"Ad16", 4) == 0) return Ad16; |
if (_tcsncmp (str, L"Ad8r", 4) == 0) return Ad8r; |
if (_tcsncmp (str, L"absw", 4) == 0) return absw; |
if (_tcsncmp (str, L"absl", 4) == 0) return absl; |
if (_tcsncmp (str, L"PC16", 4) == 0) return PC16; |
if (_tcsncmp (str, L"PC8r", 4) == 0) return PC8r; |
if (_tcsncmp (str, L"Immd", 4) == 0) return imm; |
abort (); |
return 0; |
} |
|
STATIC_INLINE amodes mode_from_mr (int mode, int reg) |
{ |
switch (mode) { |
case 0: return Dreg; |
case 1: return Areg; |
case 2: return Aind; |
case 3: return Aipi; |
case 4: return Apdi; |
case 5: return Ad16; |
case 6: return Ad8r; |
case 7: |
switch (reg) { |
case 0: return absw; |
case 1: return absl; |
case 2: return PC16; |
case 3: return PC8r; |
case 4: return imm; |
case 5: |
case 6: |
case 7: return am_illg; |
} |
} |
abort (); |
return 0; |
} |
|
static void build_insn (int insn) |
{ |
int find = -1; |
int variants; |
int isjmp = 0; |
struct instr_def id; |
const TCHAR *opcstr; |
int i; |
|
int flaglive = 0, flagdead = 0; |
|
id = defs68k[insn]; |
|
/* Note: We treat anything with unknown flags as a jump. That |
is overkill, but "the programmer" was lazy quite often, and |
*this* programmer can't be bothered to work out what can and |
can't trap. Usually, this will be overwritten with the gencomp |
based information, anyway. */ |
|
for (i = 0; i < 5; i++) { |
switch (id.flaginfo[i].flagset){ |
case fa_unset: break; |
case fa_isjmp: isjmp = 1; break; |
case fa_isbranch: isjmp = 1; break; |
case fa_zero: flagdead |= 1 << i; break; |
case fa_one: flagdead |= 1 << i; break; |
case fa_dontcare: flagdead |= 1 << i; break; |
case fa_unknown: isjmp = 1; flagdead = -1; goto out1; |
case fa_set: flagdead |= 1 << i; break; |
} |
} |
|
out1: |
for (i = 0; i < 5; i++) { |
switch (id.flaginfo[i].flaguse) { |
case fu_unused: break; |
case fu_isjmp: isjmp = 1; flaglive |= 1 << i; break; |
case fu_maybecc: isjmp = 1; flaglive |= 1 << i; break; |
case fu_unknown: isjmp = 1; flaglive |= 1 << i; break; |
case fu_used: flaglive |= 1 << i; break; |
} |
} |
|
opcstr = id.opcstr; |
for (variants = 0; variants < (1 << id.n_variable); variants++) { |
int bitcnt[lastbit]; |
int bitval[lastbit]; |
int bitpos[lastbit]; |
int i; |
uae_u16 opc = id.bits; |
uae_u16 msk, vmsk; |
int pos = 0; |
int mnp = 0; |
int bitno = 0; |
TCHAR mnemonic[10]; |
|
wordsizes sz = sz_long; |
int srcgather = 0, dstgather = 0; |
int usesrc = 0, usedst = 0; |
int srctype = 0; |
int srcpos = -1, dstpos = -1; |
|
amodes srcmode = am_unknown, destmode = am_unknown; |
int srcreg = -1, destreg = -1; |
|
for (i = 0; i < lastbit; i++) |
bitcnt[i] = bitval[i] = 0; |
|
vmsk = 1 << id.n_variable; |
|
for (i = 0, msk = 0x8000; i < 16; i++, msk >>= 1) { |
if (!(msk & id.mask)) { |
int currbit = id.bitpos[bitno++]; |
int bit_set; |
vmsk >>= 1; |
bit_set = variants & vmsk ? 1 : 0; |
if (bit_set) |
opc |= msk; |
bitpos[currbit] = 15 - i; |
bitcnt[currbit]++; |
bitval[currbit] <<= 1; |
bitval[currbit] |= bit_set; |
} |
} |
|
if (bitval[bitj] == 0) bitval[bitj] = 8; |
/* first check whether this one does not match after all */ |
if (bitval[bitz] == 3 || bitval[bitC] == 1) |
continue; |
if (bitcnt[bitI] && (bitval[bitI] == 0x00 || bitval[bitI] == 0xff)) |
continue; |
|
/* bitI and bitC get copied to biti and bitc */ |
if (bitcnt[bitI]) { |
bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; |
} |
if (bitcnt[bitC]) |
bitval[bitc] = bitval[bitC]; |
|
pos = 0; |
while (opcstr[pos] && !_istspace(opcstr[pos])) { |
if (opcstr[pos] == '.') { |
pos++; |
switch (opcstr[pos]) { |
|
case 'B': sz = sz_byte; break; |
case 'W': sz = sz_word; break; |
case 'L': sz = sz_long; break; |
case 'z': |
switch (bitval[bitz]) { |
case 0: sz = sz_byte; break; |
case 1: sz = sz_word; break; |
case 2: sz = sz_long; break; |
default: abort(); |
} |
break; |
default: abort(); |
} |
} else { |
mnemonic[mnp] = opcstr[pos]; |
if (mnemonic[mnp] == 'f') { |
find = -1; |
switch (bitval[bitf]) { |
case 0: mnemonic[mnp] = 'R'; break; |
case 1: mnemonic[mnp] = 'L'; break; |
default: abort(); |
} |
} |
mnp++; |
} |
pos++; |
} |
mnemonic[mnp] = 0; |
|
/* now, we have read the mnemonic and the size */ |
while (opcstr[pos] && _istspace(opcstr[pos])) |
pos++; |
|
/* A goto a day keeps the D******a away. */ |
if (opcstr[pos] == 0) |
goto endofline; |
|
/* parse the source address */ |
usesrc = 1; |
switch (opcstr[pos++]) { |
case 'D': |
srcmode = Dreg; |
switch (opcstr[pos++]) { |
case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; |
case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; |
default: abort(); |
} |
break; |
case 'A': |
srcmode = Areg; |
switch (opcstr[pos++]) { |
case 'r': srcreg = bitval[bitr]; srcgather = 1; srcpos = bitpos[bitr]; break; |
case 'R': srcreg = bitval[bitR]; srcgather = 1; srcpos = bitpos[bitR]; break; |
default: abort(); |
} |
switch (opcstr[pos]) { |
case 'p': srcmode = Apdi; pos++; break; |
case 'P': srcmode = Aipi; pos++; break; |
case 'a': srcmode = Aind; pos++; break; |
} |
break; |
case 'L': |
srcmode = absl; |
break; |
case '#': |
switch (opcstr[pos++]) { |
case 'z': srcmode = imm; break; |
case '0': srcmode = imm0; break; |
case '1': srcmode = imm1; break; |
case '2': srcmode = imm2; break; |
case 'i': srcmode = immi; srcreg = (uae_s32)(uae_s8)bitval[biti]; |
if (CPU_EMU_SIZE < 4) { |
/* Used for branch instructions */ |
srctype = 1; |
srcgather = 1; |
srcpos = bitpos[biti]; |
} |
break; |
case 'j': srcmode = immi; srcreg = bitval[bitj]; |
if (CPU_EMU_SIZE < 3) { |
/* 1..8 for ADDQ/SUBQ and rotshi insns */ |
srcgather = 1; |
srctype = 3; |
srcpos = bitpos[bitj]; |
} |
break; |
case 'J': srcmode = immi; srcreg = bitval[bitJ]; |
if (CPU_EMU_SIZE < 5) { |
/* 0..15 */ |
srcgather = 1; |
srctype = 2; |
srcpos = bitpos[bitJ]; |
} |
break; |
case 'k': srcmode = immi; srcreg = bitval[bitk]; |
if (CPU_EMU_SIZE < 3) { |
srcgather = 1; |
srctype = 4; |
srcpos = bitpos[bitk]; |
} |
break; |
case 'K': srcmode = immi; srcreg = bitval[bitK]; |
if (CPU_EMU_SIZE < 5) { |
/* 0..15 */ |
srcgather = 1; |
srctype = 5; |
srcpos = bitpos[bitK]; |
} |
break; |
case 'p': srcmode = immi; srcreg = bitval[bitK]; |
if (CPU_EMU_SIZE < 5) { |
/* 0..3 */ |
srcgather = 1; |
srctype = 7; |
srcpos = bitpos[bitp]; |
} |
break; |
default: abort(); |
} |
break; |
case 'd': |
srcreg = bitval[bitD]; |
srcmode = mode_from_mr(bitval[bitd],bitval[bitD]); |
if (srcmode == am_illg) |
continue; |
if (CPU_EMU_SIZE < 2 && |
(srcmode == Areg || srcmode == Dreg || srcmode == Aind |
|| srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi |
|| srcmode == Apdi)) |
{ |
srcgather = 1; srcpos = bitpos[bitD]; |
} |
if (opcstr[pos] == '[') { |
pos++; |
if (opcstr[pos] == '!') { |
/* exclusion */ |
do { |
pos++; |
if (mode_from_str(opcstr+pos) == srcmode) |
goto nomatch; |
pos += 4; |
} while (opcstr[pos] == ','); |
pos++; |
} else { |
if (opcstr[pos+4] == '-') { |
/* replacement */ |
if (mode_from_str(opcstr+pos) == srcmode) |
srcmode = mode_from_str(opcstr+pos+5); |
else |
goto nomatch; |
pos += 10; |
} else { |
/* normal */ |
while(mode_from_str(opcstr+pos) != srcmode) { |
pos += 4; |
if (opcstr[pos] == ']') |
goto nomatch; |
pos++; |
} |
while(opcstr[pos] != ']') pos++; |
pos++; |
break; |
} |
} |
} |
/* Some addressing modes are invalid as destination */ |
if (srcmode == imm || srcmode == PC16 || srcmode == PC8r) |
goto nomatch; |
break; |
case 's': |
srcreg = bitval[bitS]; |
srcmode = mode_from_mr(bitval[bits],bitval[bitS]); |
|
if (srcmode == am_illg) |
continue; |
if (CPU_EMU_SIZE < 2 && |
(srcmode == Areg || srcmode == Dreg || srcmode == Aind |
|| srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi |
|| srcmode == Apdi)) |
{ |
srcgather = 1; srcpos = bitpos[bitS]; |
} |
if (opcstr[pos] == '[') { |
pos++; |
if (opcstr[pos] == '!') { |
/* exclusion */ |
do { |
pos++; |
if (mode_from_str(opcstr+pos) == srcmode) |
goto nomatch; |
pos += 4; |
} while (opcstr[pos] == ','); |
pos++; |
} else { |
if (opcstr[pos+4] == '-') { |
/* replacement */ |
if (mode_from_str(opcstr+pos) == srcmode) |
srcmode = mode_from_str(opcstr+pos+5); |
else |
goto nomatch; |
pos += 10; |
} else { |
/* normal */ |
while(mode_from_str(opcstr+pos) != srcmode) { |
pos += 4; |
if (opcstr[pos] == ']') |
goto nomatch; |
pos++; |
} |
while(opcstr[pos] != ']') pos++; |
pos++; |
} |
} |
} |
break; |
default: abort(); |
} |
/* safety check - might have changed */ |
if (srcmode != Areg && srcmode != Dreg && srcmode != Aind |
&& srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi |
&& srcmode != Apdi && srcmode != immi) |
{ |
srcgather = 0; |
} |
if (srcmode == Areg && sz == sz_byte) |
goto nomatch; |
|
if (opcstr[pos] != ',') |
goto endofline; |
pos++; |
|
/* parse the destination address */ |
usedst = 1; |
switch (opcstr[pos++]) { |
case 'D': |
destmode = Dreg; |
switch (opcstr[pos++]) { |
case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; |
case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; |
default: abort(); |
} |
if (dstpos < 0 || dstpos >= 32) |
abort (); |
break; |
case 'A': |
destmode = Areg; |
switch (opcstr[pos++]) { |
case 'r': destreg = bitval[bitr]; dstgather = 1; dstpos = bitpos[bitr]; break; |
case 'R': destreg = bitval[bitR]; dstgather = 1; dstpos = bitpos[bitR]; break; |
case 'x': destreg = 0; dstgather = 0; dstpos = 0; break; |
default: abort(); |
} |
if (dstpos < 0 || dstpos >= 32) |
abort (); |
switch (opcstr[pos]) { |
case 'p': destmode = Apdi; pos++; break; |
case 'P': destmode = Aipi; pos++; break; |
} |
break; |
case 'L': |
destmode = absl; |
break; |
case '#': |
switch (opcstr[pos++]) { |
case 'z': destmode = imm; break; |
case '0': destmode = imm0; break; |
case '1': destmode = imm1; break; |
case '2': destmode = imm2; break; |
case 'i': destmode = immi; destreg = (uae_s32)(uae_s8)bitval[biti]; break; |
case 'j': destmode = immi; destreg = bitval[bitj]; break; |
case 'J': destmode = immi; destreg = bitval[bitJ]; break; |
case 'k': destmode = immi; destreg = bitval[bitk]; break; |
case 'K': destmode = immi; destreg = bitval[bitK]; break; |
default: abort(); |
} |
break; |
case 'd': |
destreg = bitval[bitD]; |
destmode = mode_from_mr(bitval[bitd],bitval[bitD]); |
if (destmode == am_illg) |
continue; |
if (CPU_EMU_SIZE < 1 && |
(destmode == Areg || destmode == Dreg || destmode == Aind |
|| destmode == Ad16 || destmode == Ad8r || destmode == Aipi |
|| destmode == Apdi)) |
{ |
dstgather = 1; dstpos = bitpos[bitD]; |
} |
|
if (opcstr[pos] == '[') { |
pos++; |
if (opcstr[pos] == '!') { |
/* exclusion */ |
do { |
pos++; |
if (mode_from_str(opcstr+pos) == destmode) |
goto nomatch; |
pos += 4; |
} while (opcstr[pos] == ','); |
pos++; |
} else { |
if (opcstr[pos+4] == '-') { |
/* replacement */ |
if (mode_from_str(opcstr+pos) == destmode) |
destmode = mode_from_str(opcstr+pos+5); |
else |
goto nomatch; |
pos += 10; |
} else { |
/* normal */ |
while(mode_from_str(opcstr+pos) != destmode) { |
pos += 4; |
if (opcstr[pos] == ']') |
goto nomatch; |
pos++; |
} |
while(opcstr[pos] != ']') pos++; |
pos++; |
break; |
} |
} |
} |
/* Some addressing modes are invalid as destination */ |
if (destmode == imm || destmode == PC16 || destmode == PC8r) |
goto nomatch; |
break; |
case 's': |
destreg = bitval[bitS]; |
destmode = mode_from_mr(bitval[bits],bitval[bitS]); |
|
if (destmode == am_illg) |
continue; |
if (CPU_EMU_SIZE < 1 && |
(destmode == Areg || destmode == Dreg || destmode == Aind |
|| destmode == Ad16 || destmode == Ad8r || destmode == Aipi |
|| destmode == Apdi)) |
{ |
dstgather = 1; dstpos = bitpos[bitS]; |
} |
|
if (opcstr[pos] == '[') { |
pos++; |
if (opcstr[pos] == '!') { |
/* exclusion */ |
do { |
pos++; |
if (mode_from_str(opcstr+pos) == destmode) |
goto nomatch; |
pos += 4; |
} while (opcstr[pos] == ','); |
pos++; |
} else { |
if (opcstr[pos+4] == '-') { |
/* replacement */ |
if (mode_from_str(opcstr+pos) == destmode) |
destmode = mode_from_str(opcstr+pos+5); |
else |
goto nomatch; |
pos += 10; |
} else { |
/* normal */ |
while(mode_from_str(opcstr+pos) != destmode) { |
pos += 4; |
if (opcstr[pos] == ']') |
goto nomatch; |
pos++; |
} |
while(opcstr[pos] != ']') pos++; |
pos++; |
} |
} |
} |
break; |
default: abort(); |
} |
/* safety check - might have changed */ |
if (destmode != Areg && destmode != Dreg && destmode != Aind |
&& destmode != Ad16 && destmode != Ad8r && destmode != Aipi |
&& destmode != Apdi) |
{ |
dstgather = 0; |
} |
|
if (destmode == Areg && sz == sz_byte) |
goto nomatch; |
#if 0 |
if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) { |
dstgather = 0; |
} |
#endif |
endofline: |
/* now, we have a match */ |
if (table68k[opc].mnemo != i_ILLG) |
;//write_log (L"Double match: %x: %s\n", opc, opcstr); |
if (find == -1) { |
for (find = 0;; find++) { |
if (_tcscmp (mnemonic, lookuptab[find].name) == 0) { |
table68k[opc].mnemo = lookuptab[find].mnemo; |
break; |
} |
if (_tcslen (lookuptab[find].name) == 0) |
abort(); |
} |
} |
else { |
table68k[opc].mnemo = lookuptab[find].mnemo; |
} |
table68k[opc].cc = bitval[bitc]; |
if (table68k[opc].mnemo == i_BTST |
|| table68k[opc].mnemo == i_BSET |
|| table68k[opc].mnemo == i_BCLR |
|| table68k[opc].mnemo == i_BCHG) |
{ |
sz = destmode == Dreg ? sz_long : sz_byte; |
} |
table68k[opc].size = sz; |
table68k[opc].sreg = srcreg; |
table68k[opc].dreg = destreg; |
table68k[opc].smode = srcmode; |
table68k[opc].dmode = destmode; |
table68k[opc].spos = srcgather ? srcpos : -1; |
table68k[opc].dpos = dstgather ? dstpos : -1; |
table68k[opc].suse = usesrc; |
table68k[opc].duse = usedst; |
table68k[opc].stype = srctype; |
table68k[opc].plev = id.plevel; |
table68k[opc].clev = specialcase(opc, id.cpulevel); |
|
#if 0 |
for (i = 0; i < 5; i++) { |
table68k[opc].flaginfo[i].flagset = id.flaginfo[i].flagset; |
table68k[opc].flaginfo[i].flaguse = id.flaginfo[i].flaguse; |
} |
#endif |
table68k[opc].flagdead = flagdead; |
table68k[opc].flaglive = flaglive; |
table68k[opc].isjmp = isjmp; |
nomatch: |
/* FOO! */; |
} |
} |
|
|
void read_table68k (void) |
{ |
int i; |
|
free (table68k); |
table68k = (struct instr *)xmalloc (65536 * sizeof (struct instr)); |
for (i = 0; i < 65536; i++) { |
table68k[i].mnemo = i_ILLG; |
table68k[i].handler = -1; |
} |
for (i = 0; i < n_defs68k; i++) { |
build_insn (i); |
} |
} |
|
static int mismatch; |
|
static void handle_merges (long int opcode) |
{ |
uae_u16 smsk; |
uae_u16 dmsk; |
int sbitdst, dstend; |
int srcreg, dstreg; |
|
if (table68k[opcode].spos == -1) { |
sbitdst = 1; smsk = 0; |
} else { |
switch (table68k[opcode].stype) { |
case 0: |
smsk = 7; sbitdst = 8; break; |
case 1: |
smsk = 255; sbitdst = 256; break; |
case 2: |
smsk = 15; sbitdst = 16; break; |
case 3: |
smsk = 7; sbitdst = 8; break; |
case 4: |
smsk = 7; sbitdst = 8; break; |
case 5: |
smsk = 63; sbitdst = 64; break; |
case 7: |
smsk = 3; sbitdst = 4; break; |
default: |
smsk = 0; sbitdst = 0; |
abort(); |
break; |
} |
smsk <<= table68k[opcode].spos; |
} |
if (table68k[opcode].dpos == -1) { |
dstend = 1; dmsk = 0; |
} else { |
dmsk = 7 << table68k[opcode].dpos; |
dstend = 8; |
} |
for (srcreg=0; srcreg < sbitdst; srcreg++) { |
for (dstreg=0; dstreg < dstend; dstreg++) { |
uae_u16 code = (uae_u16)opcode; |
|
code = (code & ~smsk) | (srcreg << table68k[opcode].spos); |
code = (code & ~dmsk) | (dstreg << table68k[opcode].dpos); |
|
/* Check whether this is in fact the same instruction. |
* The instructions should never differ, except for the |
* Bcc.(BW) case. */ |
if (table68k[code].mnemo != table68k[opcode].mnemo |
|| table68k[code].size != table68k[opcode].size |
|| table68k[code].suse != table68k[opcode].suse |
|| table68k[code].duse != table68k[opcode].duse) |
{ |
mismatch++; continue; |
} |
if (table68k[opcode].suse |
&& (table68k[opcode].spos != table68k[code].spos |
|| table68k[opcode].smode != table68k[code].smode |
|| table68k[opcode].stype != table68k[code].stype)) |
{ |
mismatch++; continue; |
} |
if (table68k[opcode].duse |
&& (table68k[opcode].dpos != table68k[code].dpos |
|| table68k[opcode].dmode != table68k[code].dmode)) |
{ |
mismatch++; continue; |
} |
|
if (code != opcode) |
table68k[code].handler = opcode; |
} |
} |
} |
|
void do_merges (void) |
{ |
long int opcode; |
int nr = 0; |
mismatch = 0; |
for (opcode = 0; opcode < 65536; opcode++) { |
if (table68k[opcode].handler != -1 || table68k[opcode].mnemo == i_ILLG) |
continue; |
nr++; |
handle_merges (opcode); |
} |
nr_cpuop_funcs = nr; |
} |
|
int get_no_mismatches (void) |
{ |
return mismatch; |
} |
/trunk/bench/sw_emulators/winuae/ao.h
0,0 → 1,231
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
#ifndef __AO_H__ |
#define __AO_H__ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <stdarg.h> |
#include <string.h> |
#include <wchar.h> |
#include <assert.h> |
|
//from sysdeps.h ----------------------- |
|
#define ENUMDECL typedef enum |
#define ENUMNAME(name) name |
|
typedef unsigned char uae_u8; |
typedef signed char uae_s8; |
|
typedef unsigned short uae_u16; |
typedef short uae_s16; |
|
typedef unsigned int uae_u32; |
typedef int uae_s32; |
|
typedef uae_u32 uaecptr; |
|
typedef wchar_t TCHAR; |
|
#define CPU_EMU_SIZE 0 |
#define CYCLE_UNIT 512 |
|
#define STATIC_INLINE static __inline__ __attribute__ ((always_inline)) |
|
//------------------------------------- |
|
#define _vsnprintf vsnprintf |
#define xfree free |
#define xmalloc malloc |
#define _tcsncmp wcsncmp |
#define _istspace iswspace |
#define _tcscmp wcscmp |
#define _tcslen wcslen |
|
STATIC_INLINE char *ua (const TCHAR *str) { |
int len; |
|
len = wcslen(str); |
char *result = (char*)xmalloc(len); |
|
const wchar_t *ptr = str; |
wcsrtombs(result, &ptr, len, NULL); |
return result; |
} |
|
|
// z newcpu.h ---------- |
#define get_iword(o) get_wordi((uaecptr)((regs).pc_p + (o))) |
|
#define REGPARAM |
#define REGPARAM2 |
#define REGPARAM3 |
typedef unsigned long REGPARAM3 cpuop_func (uae_u32) REGPARAM; |
typedef void REGPARAM3 cpuop_func_ce (uae_u32) REGPARAM; |
|
struct cputbl { |
cpuop_func *handler; |
uae_u16 opcode; |
}; |
|
typedef uae_u8 flagtype; |
|
extern struct regstruct |
{ |
uae_u32 regs[16]; |
|
uae_u32 pc; |
uae_u8 *pc_p; |
uae_u8 *pc_oldp; |
|
uae_u16 irc, ir; |
uae_u32 spcflags; |
|
uaecptr usp, isp, msp; |
uae_u16 sr; |
flagtype t1; |
flagtype t0; |
flagtype s; |
flagtype m; |
flagtype x; |
flagtype stopped; |
int intmask; |
|
uae_u32 vbr, sfc, dfc; |
|
#ifdef FPUEMU |
fptype fp[8]; |
fptype fp_result; |
|
uae_u32 fpcr, fpsr, fpiar; |
uae_u32 fpsr_highbyte; |
#endif |
#ifndef CPUEMU_68000_ONLY |
uae_u32 cacr, caar; |
uae_u32 itt0, itt1, dtt0, dtt1; |
uae_u32 tcr, mmusr, urp, srp, buscr; |
uae_u32 mmu_fslw, mmu_fault_addr; |
uae_u16 mmu_ssw; |
uae_u32 wb3_data; |
uae_u16 wb3_status; |
int mmu_enabled; |
int mmu_pagesize_8k; |
uae_u32 fault_pc; |
#endif |
|
uae_u32 pcr; |
uae_u32 address_space_mask; |
|
uae_u8 panic; |
uae_u32 panic_pc, panic_addr; |
|
uae_u32 prefetch020data; |
uae_u32 prefetch020addr; |
int ce020memcycles; |
|
} regs, lastint_regs, mmu_backup_regs; |
|
#define m68k_dreg(r,num) ((r).regs[(num)]) |
#define m68k_areg(r,num) (((r).regs + 8)[(num)]) |
|
extern const int imm8_table[]; |
extern const int areg_byteinc[]; |
|
extern int movem_index1[256]; |
extern int movem_index2[256]; |
extern int movem_next[256]; |
|
//m68k.h |
struct flag_struct { |
unsigned int c; |
unsigned int z; |
unsigned int n; |
unsigned int v; |
unsigned int x; |
}; |
|
extern struct flag_struct regflags; |
|
#define ZFLG (regflags.z) |
#define NFLG (regflags.n) |
#define CFLG (regflags.c) |
#define VFLG (regflags.v) |
#define XFLG (regflags.x) |
|
static __inline__ int cctrue(const int cc) |
{ |
switch(cc){ |
case 0: return 1; /* T */ |
case 1: return 0; /* F */ |
case 2: return !CFLG && !ZFLG; /* HI */ |
case 3: return CFLG || ZFLG; /* LS */ |
case 4: return !CFLG; /* CC */ |
case 5: return CFLG; /* CS */ |
case 6: return !ZFLG; /* NE */ |
case 7: return ZFLG; /* EQ */ |
case 8: return !VFLG; /* VC */ |
case 9: return VFLG; /* VS */ |
case 10:return !NFLG; /* PL */ |
case 11:return NFLG; /* MI */ |
case 12:return NFLG == VFLG; /* GE */ |
case 13:return NFLG != VFLG; /* LT */ |
case 14:return !ZFLG && (NFLG == VFLG); /* GT */ |
case 15:return ZFLG || (NFLG != VFLG); /* LE */ |
} |
abort(); |
return 0; |
} |
|
//newcpu.h |
#define SET_CFLG(x) (CFLG = (x)) |
#define SET_NFLG(x) (NFLG = (x)) |
#define SET_VFLG(x) (VFLG = (x)) |
#define SET_ZFLG(x) (ZFLG = (x)) |
#define SET_XFLG(x) (XFLG = (x)) |
|
#define GET_CFLG() CFLG |
#define GET_NFLG() NFLG |
#define GET_VFLG() VFLG |
#define GET_ZFLG() ZFLG |
#define GET_XFLG() XFLG |
|
#define CLEAR_CZNV() do { \ |
SET_CFLG (0); \ |
SET_ZFLG (0); \ |
SET_NFLG (0); \ |
SET_VFLG (0); \ |
} while (0) |
|
#define COPY_CARRY() (SET_XFLG (GET_CFLG ())) |
|
//...newcpu.h |
|
#define m68k_incpc(o) ((regs).pc_p += (o)) |
|
#define get_cpu_model() 68000 |
|
#endif // __AO_H__ |
|
/trunk/bench/sw_emulators/winuae/readcpu.h
0,0 → 1,105
ENUMDECL { |
Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r, |
absw, absl, PC16, PC8r, imm, imm0, imm1, imm2, immi, am_unknown, am_illg |
} ENUMNAME (amodes); |
|
ENUMDECL { |
i_ILLG, |
|
i_OR, i_AND, i_EOR, i_ORSR, i_ANDSR, i_EORSR, |
i_SUB, i_SUBA, i_SUBX, i_SBCD, |
i_ADD, i_ADDA, i_ADDX, i_ABCD, |
i_NEG, i_NEGX, i_NBCD, i_CLR, i_NOT, i_TST, |
i_BTST, i_BCHG, i_BCLR, i_BSET, |
i_CMP, i_CMPM, i_CMPA, |
i_MVPRM, i_MVPMR, i_MOVE, i_MOVEA, i_MVSR2, i_MV2SR, |
i_SWAP, i_EXG, i_EXT, i_MVMEL, i_MVMLE, |
i_TRAP, i_MVR2USP, i_MVUSP2R, i_RESET, i_NOP, i_STOP, i_RTE, i_RTD, |
i_LINK, i_UNLK, |
i_RTS, i_TRAPV, i_RTR, |
i_JSR, i_JMP, i_BSR, i_Bcc, |
i_LEA, i_PEA, i_DBcc, i_Scc, |
i_DIVU, i_DIVS, i_MULU, i_MULS, |
i_ASR, i_ASL, i_LSR, i_LSL, i_ROL, i_ROR, i_ROXL, i_ROXR, |
i_ASRW, i_ASLW, i_LSRW, i_LSLW, i_ROLW, i_RORW, i_ROXLW, i_ROXRW, |
i_CHK,i_CHK2, |
i_MOVEC2, i_MOVE2C, i_CAS, i_CAS2, i_DIVL, i_MULL, |
i_BFTST,i_BFEXTU,i_BFCHG,i_BFEXTS,i_BFCLR,i_BFFFO,i_BFSET,i_BFINS, |
i_PACK, i_UNPK, i_TAS, i_BKPT, i_CALLM, i_RTM, i_TRAPcc, i_MOVES, |
i_FPP, i_FDBcc, i_FScc, i_FTRAPcc, i_FBcc, i_FSAVE, i_FRESTORE, |
i_CINVL, i_CINVP, i_CINVA, i_CPUSHL, i_CPUSHP, i_CPUSHA, i_MOVE16, |
i_MMUOP030, i_PFLUSHN, i_PFLUSH, i_PFLUSHAN, i_PFLUSHA, |
i_PLPAR, i_PLPAW, i_PTESTR, i_PTESTW, |
i_LPSTOP |
} ENUMNAME (instrmnem); |
|
extern struct mnemolookup { |
instrmnem mnemo; |
const TCHAR *name; |
const TCHAR *friendlyname; |
} lookuptab[]; |
|
ENUMDECL { |
sz_byte, sz_word, sz_long |
} ENUMNAME (wordsizes); |
|
ENUMDECL { |
fa_set, fa_unset, fa_zero, fa_one, fa_dontcare, fa_unknown, fa_isjmp, |
fa_isbranch |
} ENUMNAME (flagaffect); |
|
ENUMDECL { |
fu_used, fu_unused, fu_maybecc, fu_unknown, fu_isjmp |
} ENUMNAME (flaguse); |
|
ENUMDECL { |
bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bitk, bitK, |
bits, bitS, bitd, bitD, bitr, bitR, bitz, bitp, lastbit |
} ENUMNAME (bitvals); |
|
struct instr_def { |
unsigned int bits; |
int n_variable; |
uae_u8 bitpos[16]; |
unsigned int mask; |
int cpulevel; |
int plevel; |
struct { |
unsigned int flaguse:3; |
unsigned int flagset:3; |
} flaginfo[5]; |
uae_u8 sduse; |
const TCHAR *opcstr; |
}; |
|
extern struct instr_def defs68k[]; |
extern int n_defs68k; |
|
extern struct instr { |
long int handler; |
unsigned char dreg; |
unsigned char sreg; |
signed char dpos; |
signed char spos; |
unsigned char sduse; |
int flagdead:8, flaglive:8; |
unsigned int mnemo:8; |
unsigned int cc:4; |
unsigned int plev:2; |
unsigned int size:2; |
unsigned int smode:5; |
unsigned int stype:3; |
unsigned int dmode:5; |
unsigned int suse:1; |
unsigned int duse:1; |
unsigned int unused1:1; |
unsigned int clev:3; |
unsigned int isjmp:1; |
unsigned int unused2:4; |
} *table68k; |
|
extern void read_table68k (void); |
extern void do_merges (void); |
extern int get_no_mismatches (void); |
extern int nr_cpuop_funcs; |
|
/trunk/bench/sw_emulators/winuae/build68k.c
0,0 → 1,261
/* |
* UAE - The Un*x Amiga Emulator |
* |
* Read 68000 CPU specs from file "table68k" and build table68k.c |
* |
* Copyright 1995,1996 Bernd Schmidt |
*/ |
|
#include <stdlib.h> |
//AO#include <tchar.h> |
#include <assert.h> |
#include <ctype.h> |
|
//AO#define TCHAR char |
|
//AO#include "sysconfig.h" |
//AO#include "sysdeps.h" |
#include "ao.h" |
|
#include "readcpu.h" |
|
static FILE *tablef; |
static int nextch = 0; |
|
static void getnextch(void) |
{ |
do { |
nextch = fgetc(tablef); |
if (nextch == '%') { |
do { |
nextch = fgetc(tablef); |
} while (nextch != EOF && nextch != '\n'); |
} |
} while (nextch != EOF && isspace(nextch)); |
} |
|
static int nextchtohex(void) |
{ |
switch (isupper (nextch) ? tolower (nextch) : nextch) { |
case '0': return 0; |
case '1': return 1; |
case '2': return 2; |
case '3': return 3; |
case '4': return 4; |
case '5': return 5; |
case '6': return 6; |
case '7': return 7; |
case '8': return 8; |
case '9': return 9; |
case 'a': return 10; |
case 'b': return 11; |
case 'c': return 12; |
case 'd': return 13; |
case 'e': return 14; |
case 'f': return 15; |
default: abort(); |
} |
} |
|
int main(int argc, char **argv) |
{ |
int no_insns = 0; |
//AO68000 |
// printf ("#include \"sysconfig.h\"\n"); |
// printf ("#include \"sysdeps.h\"\n"); |
printf ("#include \"ao.h\"\n"); |
//AO68000 end |
printf ("#include \"readcpu.h\"\n"); |
printf ("struct instr_def defs68k[] = {\n"); |
#if 0 |
tablef = fopen("table68k","r"); |
if (tablef == NULL) { |
fprintf(stderr, "table68k not found\n"); |
exit(1); |
} |
#else |
tablef = stdin; |
#endif |
getnextch(); |
while (nextch != EOF) { |
int cpulevel, plevel, sduse; |
int i; |
|
char patbits[16]; |
char opcstr[256]; |
int bitpos[16]; |
int flagset[5], flaguse[5]; |
|
unsigned int bitmask,bitpattern; |
int n_variable; |
|
n_variable = 0; |
bitmask = bitpattern = 0; |
memset (bitpos, 0, sizeof(bitpos)); |
for(i=0; i<16; i++) { |
int currbit; |
bitmask <<= 1; |
bitpattern <<= 1; |
|
switch (nextch) { |
case '0': currbit = bit0; bitmask |= 1; break; |
case '1': currbit = bit1; bitmask |= 1; bitpattern |= 1; break; |
case 'c': currbit = bitc; break; |
case 'C': currbit = bitC; break; |
case 'f': currbit = bitf; break; |
case 'i': currbit = biti; break; |
case 'I': currbit = bitI; break; |
case 'j': currbit = bitj; break; |
case 'J': currbit = bitJ; break; |
case 'k': currbit = bitk; break; |
case 'K': currbit = bitK; break; |
case 's': currbit = bits; break; |
case 'S': currbit = bitS; break; |
case 'd': currbit = bitd; break; |
case 'D': currbit = bitD; break; |
case 'r': currbit = bitr; break; |
case 'R': currbit = bitR; break; |
case 'z': currbit = bitz; break; |
case 'p': currbit = bitp; break; |
default: abort(); |
} |
if (!(bitmask & 1)) { |
bitpos[n_variable] = currbit; |
n_variable++; |
} |
|
if (nextch == '0' || nextch == '1') |
bitmask |= 1; |
if (nextch == '1') |
bitpattern |= 1; |
patbits[i] = nextch; |
getnextch(); |
} |
|
while (isspace(nextch) || nextch == ':') /* Get CPU and privilege level */ |
getnextch(); |
|
switch (nextch) { |
case '0': cpulevel = 0; break; |
case '1': cpulevel = 1; break; |
case '2': cpulevel = 2; break; |
case '3': cpulevel = 3; break; |
case '4': cpulevel = 4; break; |
case '5': cpulevel = 5; break; |
case '6': cpulevel = 6; break; |
case '7': cpulevel = 7; break; |
default: abort(); |
} |
getnextch(); |
|
switch (nextch) { |
case '0': plevel = 0; break; |
case '1': plevel = 1; break; |
case '2': plevel = 2; break; |
case '3': plevel = 3; break; |
default: abort(); |
} |
getnextch(); |
|
while (isspace(nextch)) /* Get flag set information */ |
getnextch(); |
|
if (nextch != ':') |
abort(); |
|
for(i = 0; i < 5; i++) { |
getnextch(); |
switch(nextch){ |
case '-': flagset[i] = fa_unset; break; |
case '/': flagset[i] = fa_isjmp; break; |
case '+': flagset[i] = fa_isbranch; break; |
case '0': flagset[i] = fa_zero; break; |
case '1': flagset[i] = fa_one; break; |
case 'x': flagset[i] = fa_dontcare; break; |
case '?': flagset[i] = fa_unknown; break; |
default: flagset[i] = fa_set; break; |
} |
} |
|
getnextch(); |
while (isspace(nextch)) |
getnextch(); |
|
if (nextch != ':') /* Get flag used information */ |
abort(); |
|
for(i = 0; i < 5; i++) { |
getnextch(); |
switch(nextch){ |
case '-': flaguse[i] = fu_unused; break; |
case '/': flaguse[i] = fu_isjmp; break; |
case '+': flaguse[i] = fu_maybecc; break; |
case '?': flaguse[i] = fu_unknown; break; |
default: flaguse[i] = fu_used; break; |
} |
} |
|
getnextch(); |
while (isspace(nextch)) |
getnextch(); |
|
if (nextch != ':') /* Get source/dest usage information */ |
abort(); |
|
getnextch(); |
sduse = nextchtohex() << 4; |
getnextch(); |
sduse |= nextchtohex(); |
|
getnextch(); |
while (isspace(nextch)) |
getnextch(); |
|
if (nextch != ':') |
abort(); |
|
fgets(opcstr, 250, tablef); |
getnextch(); |
{ |
int j; |
/* Remove superfluous spaces from the string */ |
char *opstrp = opcstr, *osendp; |
char tmp[100], *p; |
int slen = 0; |
|
while (isspace(*opstrp)) |
opstrp++; |
|
osendp = opstrp; |
while (*osendp) { |
if (!isspace (*osendp)) |
slen = osendp - opstrp + 1; |
osendp++; |
} |
opstrp[slen] = 0; |
|
if (no_insns > 0) |
printf(",\n"); |
no_insns++; |
strcpy (tmp, opstrp); |
strcat (tmp, " "); |
p = tmp; |
while (!isspace(*p++)); |
*p = 0; |
printf("/* %s */\n", tmp); |
printf("{0x%04X,%2d,{", bitpattern, n_variable); |
for (j = 0; j < 16; j++) { |
printf("%2d", bitpos[j]); |
if (j < 15) |
printf(","); |
} |
printf ("},0x%04X,%d,%d,{", bitmask, cpulevel, plevel); |
for(i = 0; i < 5; i++) { |
printf("{%d,%d}%s", flaguse[i], flagset[i], i == 4 ? "" : ","); |
} |
printf("},%2d,L\"%s\"}", sduse, opstrp); |
} |
} |
printf("};\nint n_defs68k = %d;\n", no_insns); |
return 0; |
} |
/trunk/bench/sw_emulators/winuae/Makefile
0,0 → 1,29
all: ao.o cpustbl.o cpuemu_11.o table68k.o readcpu.o |
gcc -o ao ao.o cpustbl.o cpuemu_11.o table68k.o readcpu.o |
|
cpustbl.c: gencpu |
./gencpu |
|
cpuemu_11.c: gencpu |
|
gencpu: gencpu.o readcpu.o table68k.o |
gcc -o gencpu gencpu.o readcpu.o table68k.o |
|
table68k.c: table68k build68k |
./build68k < $< > table68k.c |
|
build68k: build68k.o |
gcc -o build68k build68k.o |
|
%.o: %.c |
gcc -DCPUEMU_68000_ONLY -DCPUEMU_11 -I$(VPATH) -c $< |
|
clean: |
rm -f *.o |
rm -f ao |
rm -f gencpu |
rm -f build68k |
rm -f cpuemu_*.c |
rm -f table68k.c |
rm -f cputbl.h |
rm -f cpustbl.c |
/trunk/bench/verilog/tb_ao68000/tb_ao68000.v
0,0 → 1,269
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
`timescale 10ns / 1ns |
|
`include "microcode/microcode_locations.v" |
|
module tb_ao68000(); |
|
// inputs |
reg clk; |
reg rst; |
reg [31:0] data_in; |
reg ack; |
wire err; |
wire rty; |
wire [2:0] ipl; |
|
// outputs |
wire cyc; |
wire [31:2] addr; |
wire [31:0] data_out; |
wire [3:0] sel; |
wire stb; |
wire we; |
wire sgl; |
wire blk; |
wire rmw; |
wire [2:0] cti; |
wire [1:0] bte; |
wire [2:0] fc; |
wire reset_output; |
wire blocked_output; |
|
ao68000 ao68000_m( |
.CLK_I(clk), |
.RST_I(rst), |
|
.DAT_I(data_in), |
.ACK_I(ack), |
.ERR_I(err), |
.RTY_I(rty), |
|
|
.CYC_O(cyc), |
.ADR_O(addr), |
.DAT_O(data_out), |
.SEL_O(sel), |
.STB_O(stb), |
.WE_O(we), |
|
.SGL_O(sgl), |
.BLK_O(blk), |
.RMW_O(rmw), |
.CTI_O(cti), |
.BTE_O(bte), |
|
.fc_o(fc), |
|
.ipl_i(ipl), |
.reset_o(reset_output), |
.blocked_o(blocked_output) |
); |
|
initial begin |
clk = 1'b0; |
forever #5 clk = ~clk; |
end |
|
reg [87:0] string; |
reg [31:0] write_data_selected; |
|
always @(posedge clk) begin |
if(stb == 1'b1 && we == 1'b0 && addr == 30'd0 && ao68000_m.microcode_branch_m.micro_pc_0 == 9'd1) begin |
#5 |
data_in = get_argument("SSP"); |
ack = 1'b1; |
#10 |
data_in = 32'd0; |
ack = 1'b0; |
end |
else if(stb == 1'b1 && we == 1'b0 && addr == 30'd1 && ao68000_m.microcode_branch_m.micro_pc_0 == 9'd1) begin |
#5 |
data_in = get_argument("PC"); |
ack = 1'b1; |
#10 |
data_in = 32'd0; |
ack = 1'b0; |
end |
|
else if(stb == 1'b1 && we == 1'b0) begin |
$display("memory read: address=%h, select=%h", addr, sel); |
|
$sformat(string, "MEM%h", addr); |
|
#5 |
data_in = get_argument(string); |
ack = 1'b1; |
#10 |
data_in = 32'd0; |
ack = 1'b0; |
end |
|
else if(stb == 1'b1 && we == 1'b1) begin |
if(sel == 4'd0) write_data_selected = 32'd0; |
else if(sel == 4'd1) write_data_selected = { 24'd0, data_out[7:0] }; |
else if(sel == 4'd2) write_data_selected = { 16'd0, data_out[15:8], 8'd0 }; |
else if(sel == 4'd3) write_data_selected = { 16'd0, data_out[15:0] }; |
else if(sel == 4'd4) write_data_selected = { 8'd0, data_out[23:16], 16'd0 }; |
else if(sel == 4'd5) write_data_selected = { 8'd0, data_out[23:16], 8'd0, data_out[7:0] }; |
else if(sel == 4'd6) write_data_selected = { 8'd0, data_out[23:8], 8'd0 }; |
else if(sel == 4'd7) write_data_selected = { 8'd0, data_out[23:0] }; |
else if(sel == 4'd8) write_data_selected = { data_out[31:24], 24'd0 }; |
else if(sel == 4'd9) write_data_selected = { data_out[31:24], 16'd0, data_out[7:0] }; |
else if(sel == 4'd10) write_data_selected = { data_out[31:24], 8'd0, data_out[15:8], 8'd0 }; |
else if(sel == 4'd11) write_data_selected = { data_out[31:24], 8'd0, data_out[15:0] }; |
else if(sel == 4'd12) write_data_selected = { data_out[31:16], 16'd0 }; |
else if(sel == 4'd13) write_data_selected = { data_out[31:16], 8'd0, data_out[7:0] }; |
else if(sel == 4'd14) write_data_selected = { data_out[31:8], 8'd0 }; |
else if(sel == 4'd15) write_data_selected = data_out[31:0]; |
|
$display("memory write address=%h, select=%h: value=%h", addr, sel, write_data_selected); |
|
#5 |
ack = 1'b1; |
#10 |
ack = 1'b0; |
end |
|
end |
|
function [31:0] get_argument(input [87:0] name); |
reg [31:0] result; |
begin |
if( $value$plusargs({name, "=%h"}, result) == 0 ) begin |
$display("Missing argument: %s", name); |
$finish_and_return(-1); |
end |
get_argument = result; |
end |
endfunction |
|
task load_state; |
begin |
ao68000_m.memory_registers_m.an_ram.ram.mem_data[0] = get_argument("A0"); |
ao68000_m.memory_registers_m.an_ram.ram.mem_data[1] = get_argument("A1"); |
ao68000_m.memory_registers_m.an_ram.ram.mem_data[2] = get_argument("A2"); |
ao68000_m.memory_registers_m.an_ram.ram.mem_data[3] = get_argument("A3"); |
ao68000_m.memory_registers_m.an_ram.ram.mem_data[4] = get_argument("A4"); |
ao68000_m.memory_registers_m.an_ram.ram.mem_data[5] = get_argument("A5"); |
ao68000_m.memory_registers_m.an_ram.ram.mem_data[6] = get_argument("A6"); |
ao68000_m.memory_registers_m.an_ram.ram.mem_data[7] = get_argument("SSP"); |
ao68000_m.memory_registers_m.usp = get_argument("USP"); |
|
ao68000_m.memory_registers_m.dn_ram.ram.mem_data[0] = get_argument("D0"); |
ao68000_m.memory_registers_m.dn_ram.ram.mem_data[1] = get_argument("D1"); |
ao68000_m.memory_registers_m.dn_ram.ram.mem_data[2] = get_argument("D2"); |
ao68000_m.memory_registers_m.dn_ram.ram.mem_data[3] = get_argument("D3"); |
ao68000_m.memory_registers_m.dn_ram.ram.mem_data[4] = get_argument("D4"); |
ao68000_m.memory_registers_m.dn_ram.ram.mem_data[5] = get_argument("D5"); |
ao68000_m.memory_registers_m.dn_ram.ram.mem_data[6] = get_argument("D6"); |
ao68000_m.memory_registers_m.dn_ram.ram.mem_data[7] = get_argument("D7"); |
|
ao68000_m.registers_m.pc = get_argument("PC"); |
|
ao68000_m.alu_m.sr = 16'd0; |
ao68000_m.alu_m.sr[0] = get_argument("C"); |
ao68000_m.alu_m.sr[1] = get_argument("V"); |
ao68000_m.alu_m.sr[2] = get_argument("Z"); |
ao68000_m.alu_m.sr[3] = get_argument("N"); |
ao68000_m.alu_m.sr[4] = get_argument("X"); |
ao68000_m.alu_m.sr[10:8] = get_argument("IPM"); |
ao68000_m.alu_m.sr[13] = get_argument("S"); |
ao68000_m.alu_m.sr[15] = get_argument("T"); |
end |
endtask |
|
task dump_state; |
begin |
$write("A0: %h\n", ao68000_m.memory_registers_m.an_ram.ram.mem_data[0]); |
$write("A1: %h\n", ao68000_m.memory_registers_m.an_ram.ram.mem_data[1]); |
$write("A2: %h\n", ao68000_m.memory_registers_m.an_ram.ram.mem_data[2]); |
$write("A3: %h\n", ao68000_m.memory_registers_m.an_ram.ram.mem_data[3]); |
$write("A4: %h\n", ao68000_m.memory_registers_m.an_ram.ram.mem_data[4]); |
$write("A5: %h\n", ao68000_m.memory_registers_m.an_ram.ram.mem_data[5]); |
$write("A6: %h\n", ao68000_m.memory_registers_m.an_ram.ram.mem_data[6]); |
$write("SSP: %h\n", ao68000_m.memory_registers_m.an_ram.ram.mem_data[7]); |
$write("USP: %h\n", ao68000_m.memory_registers_m.usp); |
|
$write("D0: %h\n", ao68000_m.memory_registers_m.dn_ram.ram.mem_data[0]); |
$write("D1: %h\n", ao68000_m.memory_registers_m.dn_ram.ram.mem_data[1]); |
$write("D2: %h\n", ao68000_m.memory_registers_m.dn_ram.ram.mem_data[2]); |
$write("D3: %h\n", ao68000_m.memory_registers_m.dn_ram.ram.mem_data[3]); |
$write("D4: %h\n", ao68000_m.memory_registers_m.dn_ram.ram.mem_data[4]); |
$write("D5: %h\n", ao68000_m.memory_registers_m.dn_ram.ram.mem_data[5]); |
$write("D6: %h\n", ao68000_m.memory_registers_m.dn_ram.ram.mem_data[6]); |
$write("D7: %h\n", ao68000_m.memory_registers_m.dn_ram.ram.mem_data[7]); |
|
$write("PC: %h\n", ao68000_m.registers_m.pc_valid); |
|
$write("C: %h\n", ao68000_m.alu_m.sr[0]); |
$write("V: %h\n", ao68000_m.alu_m.sr[1]); |
$write("Z: %h\n", ao68000_m.alu_m.sr[2]); |
$write("N: %h\n", ao68000_m.alu_m.sr[3]); |
$write("X: %h\n", ao68000_m.alu_m.sr[4]); |
$write("IPM: %h\n", ao68000_m.alu_m.sr[10:8]); |
$write("S: %h\n", ao68000_m.alu_m.sr[13]); |
$write("T: %h\n", ao68000_m.alu_m.sr[15]); |
end |
endtask |
|
initial begin |
$dumpfile("./../vcd/tb_ao68000.vcd"); |
$dumpvars(0); |
$dumpon(); |
|
rst = 1'b1; |
#10 rst = 1'b0; |
|
while(ao68000_m.microcode_branch_m.micro_pc_0 != `MICROPC_MAIN_LOOP) #10; |
|
load_state(); |
|
$display("START TEST"); |
|
while(ao68000_m.microcode_branch_m.micro_pc_0 == `MICROPC_MAIN_LOOP) #10; |
while(ao68000_m.microcode_branch_m.micro_pc_0 != `MICROPC_MAIN_LOOP) #10; |
|
dump_state(); |
|
$dumpoff(); |
|
$finish(); |
end |
|
initial begin |
#3000 |
if(blocked_output == 1'b1) begin |
dump_state(); |
$display("processor blocked: yes"); |
end |
else begin |
$display("Time limit exceeded."); |
end |
$finish(); |
end |
|
endmodule |
/trunk/bench/verilog/tb_ao68000/Makefile
0,0 → 1,20
ifndef AO68000_BASE |
AO68000_BASE := $(CURDIR)/../../.. |
endif |
|
all: tb_ao68000.v |
ifndef QUARTUS_ROOTDIR |
@echo "Environment variable QUARTUS_ROOTDIR not set. Please set it to point to Altera Quartus II rootdir." |
@exit 1 |
endif |
ln -s -f $(QUARTUS_ROOTDIR)/eda/sim_lib/altera_mf.v altsyncram.v |
ln -s -f $(QUARTUS_ROOTDIR)/eda/sim_lib/220model.v lpm_mult.v |
ln -s -f $(QUARTUS_ROOTDIR)/eda/sim_lib/220model.v lpm_divide.v |
iverilog -y. -y$(AO68000_BASE)/rtl/verilog/ao68000 -y$(AO68000_BASE)/rtl/verilog/ao68000/altera_specific -I$(AO68000_BASE)/rtl/verilog/ao68000 -o tb_ao68000 $< |
|
clean: |
rm -f tb_ao68000 |
rm -f altsyncram.v |
rm -f lpm_mult.v |
rm -f lpm_divide.v |
|
/trunk/rtl/verilog/full_system/serial_txd.v
0,0 → 1,81
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
module serial_txd( |
input CLK_I, |
input RST_I, |
|
//slave |
input [7:0] DAT_I, |
output reg ACK_O, |
|
input CYC_I, |
input STB_I, |
input WE_I, |
|
//serial output |
input uart_rxd, |
input uart_rts, |
output reg uart_txd, |
output uart_cts |
); |
|
assign uart_cts = uart_rts; |
|
reg [12:0] counter; |
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
ACK_O <= 1'b0; |
uart_txd <= 1'b1; |
counter <= 13'd0; |
end |
|
else if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0) begin |
if(counter < 13'd8191) counter <= counter + 13'd1; |
|
if(counter < 434*1) uart_txd <= 1'b0; |
else if(counter < 434*2) uart_txd <= DAT_I[0]; |
else if(counter < 434*3) uart_txd <= DAT_I[1]; |
else if(counter < 434*4) uart_txd <= DAT_I[2]; |
else if(counter < 434*5) uart_txd <= DAT_I[3]; |
else if(counter < 434*6) uart_txd <= DAT_I[4]; |
else if(counter < 434*7) uart_txd <= DAT_I[5]; |
else if(counter < 434*8) uart_txd <= DAT_I[6]; |
else if(counter < 434*9) uart_txd <= DAT_I[7]; |
else if(counter < 434*10) uart_txd <= 1'b1; |
else begin |
uart_txd <= 1'b1; |
ACK_O <= 1'b1; |
end |
end |
else begin |
ACK_O <= 1'b0; |
uart_txd <= 1'b1; |
counter <= 13'd0; |
end |
end |
|
endmodule |
|
/trunk/rtl/verilog/full_system/early_boot.v
0,0 → 1,173
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
module early_boot( |
input CLK_I, |
input RST_I, |
|
output reg CYC_O, |
output reg [31:0] DAT_O, |
output reg STB_O, |
output reg WE_O, |
output reg [31:2] ADR_O, |
output [3:0] SEL_O, |
|
input [31:0] DAT_I, |
input ACK_I, |
input ERR_I, |
input RTY_I, |
|
//****************** OTHER |
//finished loading |
output loading_finished_o |
); |
assign SEL_O = 4'b1111; |
|
assign loading_finished_o = (state == S_FINISHED) ? 1'b1 : 1'b0; |
|
reg [3:0] state; |
reg [9:0] wait_counter; |
|
parameter [3:0] |
S_CHECK_STATUS = 4'd0, |
S_CHECK_STATUS_2 = 4'd1, |
S_CHECK_STATUS_3 = 4'd2, |
S_SET_SIZE = 4'd3, |
S_SET_SIZE_2 = 4'd4, |
S_SET_CONTROL = 4'd5, |
S_SET_CONTROL_2 = 4'd6, |
S_CHECK_FINISHED = 4'd7, |
S_CHECK_FINISHED_2 = 4'd8, |
S_CHECK_FINISHED_3 = 4'd9, |
S_FINISHED = 4'd10; |
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
CYC_O <= 1'b0; |
DAT_O <= 32'd0; |
STB_O <= 1'b0; |
WE_O <= 1'b0; |
ADR_O <= 30'd0; |
state <= S_CHECK_STATUS; |
wait_counter <= 10'd0; |
end |
else if(state == S_CHECK_STATUS) begin |
CYC_O <= 1'b1; |
DAT_O <= 32'd0; |
STB_O <= 1'b1; |
WE_O <= 1'b0; |
ADR_O <= 30'h30000000; |
|
state <= S_CHECK_STATUS_2; |
end |
else if(state == S_CHECK_STATUS_2) begin |
if(ACK_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
if(DAT_I == 32'd2) begin |
state <= S_SET_SIZE; |
end |
else begin |
state <= S_CHECK_STATUS_3; |
end |
end |
end |
else if(state == S_CHECK_STATUS_3) begin |
if(wait_counter == 10'd1023) begin |
wait_counter <= 10'd0; |
state <= S_CHECK_STATUS; |
end |
else wait_counter <= wait_counter + 10'd1; |
end |
else if(state == S_SET_SIZE) begin |
CYC_O <= 1'b1; |
DAT_O <= 32'd2048; |
STB_O <= 1'b1; |
WE_O <= 1'b1; |
ADR_O <= 30'h30000002; |
|
state <= S_SET_SIZE_2; |
end |
else if(state == S_SET_SIZE_2) begin |
if(ACK_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
state <= S_SET_CONTROL; |
end |
end |
else if(state == S_SET_CONTROL) begin |
CYC_O <= 1'b1; |
DAT_O <= 32'd2; |
STB_O <= 1'b1; |
WE_O <= 1'b1; |
ADR_O <= 30'h30000003; |
|
state <= S_SET_CONTROL_2; |
end |
else if(state == S_SET_CONTROL_2) begin |
if(ACK_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
state <= S_CHECK_FINISHED; |
end |
end |
else if(state == S_CHECK_FINISHED) begin |
CYC_O <= 1'b1; |
DAT_O <= 32'd0; |
STB_O <= 1'b1; |
WE_O <= 1'b0; |
ADR_O <= 30'h30000000; |
|
state <= S_CHECK_FINISHED_2; |
end |
else if(state == S_CHECK_FINISHED_2) begin |
if(ACK_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
if(DAT_I == 32'd2) begin //idle |
state <= S_FINISHED; |
end |
else begin |
state <= S_CHECK_FINISHED_3; |
end |
end |
end |
else if(state == S_CHECK_FINISHED_3) begin |
if(wait_counter == 10'd1023) begin |
wait_counter <= 10'd0; |
state <= S_CHECK_FINISHED; |
end |
else wait_counter <= wait_counter + 10'd1; |
end |
else if(state == S_FINISHED) begin |
end |
|
end |
|
endmodule |
|
/trunk/rtl/verilog/full_system/timer.v
0,0 → 1,63
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
module timer( |
input CLK_I, |
input RST_I, |
|
input [31:2] ADR_I, |
input CYC_I, |
input STB_I, |
input WE_I, |
|
output reg RTY_O, |
output reg interrupt_o |
); |
|
reg [27:0] counter; |
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
RTY_O <= 1'b0; |
interrupt_o <= 1'b0; |
counter <= 28'd0; |
end |
else if(counter == 28'h00FFFFF) begin |
if(ADR_I == { 27'b1111_1111_1111_1111_1111_1111_111, 3'b001 } && CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b0 && interrupt_o == 1'b1) begin |
RTY_O <= 1'b1; |
interrupt_o <= 1'b0; |
counter <= 28'd0; |
end |
else begin |
interrupt_o <= 1'b1; |
end |
end |
else begin |
RTY_O <= 1'b0; |
counter <= counter + 28'd1; |
end |
end |
|
endmodule |
|
/trunk/rtl/verilog/full_system/ssram.v
0,0 → 1,167
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
module ssram( |
input CLK_I, |
input RST_I, |
|
//slave |
output reg [31:0] DAT_O, |
input [31:0] DAT_I, |
output reg ACK_O, |
|
input CYC_I, |
input [20:2] ADR_I, |
input STB_I, |
input WE_I, |
input [3:0] SEL_I, |
|
//ssram interface |
output [18:0] ssram_address, |
output reg ssram_oe_n, |
output reg ssram_writeen_n, |
output reg ssram_byteen0_n, |
output reg ssram_byteen1_n, |
output reg ssram_byteen2_n, |
output reg ssram_byteen3_n, |
|
inout [31:0] ssram_data, |
|
output ssram_clk, |
output ssram_mode, |
output ssram_zz, |
output ssram_globalw_n, |
output ssram_advance_n, |
output reg ssram_adsp_n, |
output ssram_adsc_n, |
output ssram_ce1_n, |
output ssram_ce2, |
output ssram_ce3_n |
); |
|
assign ssram_address = ADR_I; |
|
assign ssram_clk = CLK_I; |
assign ssram_mode = 1'b0; |
assign ssram_zz = 1'b0; |
assign ssram_globalw_n = 1'b1; |
assign ssram_advance_n = 1'b1; |
assign ssram_adsc_n = 1'b1; |
assign ssram_ce1_n = 1'b0; |
assign ssram_ce2 = 1'b1; |
assign ssram_ce3_n = 1'b0; |
|
reg [31:0] ssram_data_o; |
assign ssram_data = (ssram_oe_n == 1'b1) ? ssram_data_o : 32'dZ; |
|
reg [2:0] counter; |
|
//reg second; |
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
DAT_O <= 32'd0; |
ACK_O <= 1'b0; |
//ssram_address <= 19'd0; |
ssram_oe_n <= 1'b1; |
ssram_writeen_n <= 1'b1; |
ssram_byteen0_n <= 1'b1; |
ssram_byteen1_n <= 1'b1; |
ssram_byteen2_n <= 1'b1; |
ssram_byteen3_n <= 1'b1; |
ssram_data_o <= 32'd0; |
ssram_adsp_n <= 1'b1; |
counter <= 3'd0; |
|
//second <= 1'b0; |
end |
else begin |
|
if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b0 && ACK_O == 1'b0) begin |
|
if(counter == 3'd0) begin |
ssram_adsp_n <= 1'b0; |
//ssram_address <= ADR_I; |
|
counter <= counter + 3'd1; |
end |
else if(counter == 3'd1) begin |
ssram_adsp_n <= 1'b1; |
ssram_writeen_n <= 1'b1; |
ssram_byteen0_n <= 1'b0; |
ssram_byteen1_n <= 1'b0; |
ssram_byteen2_n <= 1'b0; |
ssram_byteen3_n <= 1'b0; |
|
counter <= counter + 3'd1; |
end |
else if(counter == 3'd2) begin |
ssram_oe_n <= 1'b0; |
|
counter <= counter + 3'd1; |
end |
else if(counter == 3'd3) begin |
ssram_oe_n <= 1'b1; |
|
counter <= 3'd0; |
DAT_O <= ssram_data; |
ACK_O <= 1'b1; |
end |
|
end |
else if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1 && ACK_O == 1'b0) begin |
|
if(counter == 3'd0) begin |
ssram_adsp_n <= 1'b0; |
//ssram_address <= ADR_I[20:2]; |
ssram_oe_n <= 1'b1; |
|
counter <= counter + 3'd1; |
end |
else if(counter == 3'd1) begin |
ssram_adsp_n <= 1'b1; |
ssram_writeen_n <= 1'b0; |
ssram_byteen0_n <= (SEL_I[0] == 1'b1) ? 1'b0 : 1'b1; |
ssram_byteen1_n <= (SEL_I[1] == 1'b1) ? 1'b0 : 1'b1; |
ssram_byteen2_n <= (SEL_I[2] == 1'b1) ? 1'b0 : 1'b1; |
ssram_byteen3_n <= (SEL_I[3] == 1'b1) ? 1'b0 : 1'b1; |
ssram_data_o <= DAT_I; |
|
counter <= counter + 3'd1; |
end |
else if(counter == 3'd2) begin |
ssram_writeen_n <= 1'b1; |
|
counter <= 3'd0; |
ACK_O <= 1'b1; |
end |
end |
else begin |
ACK_O <= 1'b0; |
end |
end |
end |
|
|
endmodule |
/trunk/rtl/verilog/full_system/full_system.v
0,0 → 1,356
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
module full_system( |
input clk_i, |
input rst_i, |
|
//ssram interface |
output [18:0] ssram_address, |
output ssram_oe_n, |
output ssram_writeen_n, |
output ssram_byteen0_n, |
output ssram_byteen1_n, |
output ssram_byteen2_n, |
output ssram_byteen3_n, |
|
inout [31:0] ssram_data, |
|
output ssram_clk, |
//output ssram_mode, |
//output ssram_zz, |
output ssram_globalw_n, |
output ssram_advance_n, |
output ssram_adsp_n, |
output ssram_adsc_n, |
output ssram_ce1_n, |
output ssram_ce2, |
output ssram_ce3_n, |
|
//sd interface |
output sd_clk_o, |
inout sd_cmd_io, |
inout sd_dat_io, |
|
//serial interface |
input uart_rxd, |
input uart_rts, |
output uart_txd, |
output uart_cts, |
|
//debug |
output [5:0] sd_debug, |
output [7:0] pc_debug |
); |
|
assign pc_debug = 8'd0; |
|
/* |
MASTER ao68000 connected with SLAVES: ssram, serial_txd |
MASTER sd connected with SLAVES: ssram |
MASTER early_boot connected with SLAVES: sd |
|
Address space: |
SLAVE sd: 0x30000000 - 0x30000003 /not used - point to point connection/ |
SLAVE ssram: 0x00000000 - 0x00100000 |
SLAVE serial_txt: 0x38000000 - 0x38000000 |
*/ |
|
|
/*********************************************************************************************************************** |
* MASTER ao68000 |
**********************************************************************************************************************/ |
|
//------------------------------------- global wires |
//output |
wire ao68000_cyc_o; |
wire [31:2] ao68000_adr_o; |
wire [31:0] ao68000_dat_o; |
wire [3:0] ao68000_sel_o; |
wire ao68000_stb_o; |
wire ao68000_we_o; |
|
ao68000 m_ao68000( |
//****************** WISHBONE |
.CLK_I(clk_i), |
.RST_I((early_boot_loading_finished_o == 1'b1) ? 1'b0 : 1'b1), |
|
.CYC_O(ao68000_cyc_o), |
.ADR_O(ao68000_adr_o), |
.DAT_O(ao68000_dat_o), |
.DAT_I( ssram_dat_o ), |
.SEL_O(ao68000_sel_o), |
.STB_O(ao68000_stb_o), |
.WE_O(ao68000_we_o), |
|
.ACK_I( (ao68000_adr_o[31:2] == 30'h38000000) ? serial_txd_ack_o : ssram_ack_o ), |
.ERR_I(1'b0), |
.RTY_I(timer_rty_o), |
|
// TAG_TYPE: TGC_O |
.SGL_O(), |
.BLK_O(), |
.RMW_O(), |
|
// TAG_TYPE: TGA_O |
.CTI_O(), |
.BTE_O(), |
|
// TAG_TYPE: TGC_O |
.fc_o(), |
|
//****************** OTHER |
/* interrupt acknowlege: |
* ACK_I: interrupt vector on DAT_I[7:0] |
* ERR_I: spurious interrupt |
* RTY_I: autovector |
*/ |
.ipl_i( {2'b00, timer_interrupt_o} ), |
.reset_o(), |
.blocked_o() |
); |
|
/*********************************************************************************************************************** |
* SLAVE timer |
**********************************************************************************************************************/ |
|
//------------------------------------- global wires |
//output |
wire timer_interrupt_o; |
wire timer_rty_o; |
|
//input |
|
timer m_timer( |
.CLK_I(clk_i), |
.RST_I(rst_i), |
|
.ADR_I(ao68000_adr_o), |
.CYC_I(ao68000_cyc_o), |
.STB_I(ao68000_stb_o), |
.WE_I(ao68000_we_o), |
|
.RTY_O(timer_rty_o), |
.interrupt_o(timer_interrupt_o) |
); |
|
/*********************************************************************************************************************** |
* SLAVE ssram |
**********************************************************************************************************************/ |
|
//------------------------------------- global wires |
//output |
wire [31:0] ssram_dat_o; |
wire ssram_ack_o; |
|
//input |
|
|
ssram m_ssram( |
.CLK_I(clk_i), |
.RST_I(rst_i), |
|
//slave |
.DAT_O(ssram_dat_o), |
.DAT_I((early_boot_loading_finished_o == 1'b1) ? ao68000_dat_o : sd_dat_o), |
.ACK_O(ssram_ack_o), |
|
.CYC_I((early_boot_loading_finished_o == 1'b1) ? |
( (ao68000_adr_o[31:2] >= 30'h0 && ao68000_adr_o[31:2] < 30'h00080000) ? ao68000_cyc_o : 1'b0 ) : |
sd_cyc_o |
), |
.ADR_I((early_boot_loading_finished_o == 1'b1) ? ao68000_adr_o[20:2] : sd_adr_o[20:2]), |
.STB_I((early_boot_loading_finished_o == 1'b1) ? |
( (ao68000_adr_o[31:2] >= 30'h0 && ao68000_adr_o[31:2] < 30'h00080000) ? ao68000_stb_o : 1'b0 ) : |
sd_stb_o |
), |
.WE_I((early_boot_loading_finished_o == 1'b1) ? ao68000_we_o : sd_we_o), |
.SEL_I((early_boot_loading_finished_o == 1'b1) ? ao68000_sel_o : sd_sel_o), |
|
//ssram interface |
.ssram_address(ssram_address), |
.ssram_oe_n(ssram_oe_n), |
.ssram_writeen_n(ssram_writeen_n), |
.ssram_byteen0_n(ssram_byteen0_n), |
.ssram_byteen1_n(ssram_byteen1_n), |
.ssram_byteen2_n(ssram_byteen2_n), |
.ssram_byteen3_n(ssram_byteen3_n), |
|
.ssram_data(ssram_data), |
|
.ssram_clk(ssram_clk), |
.ssram_mode(), //ssram_mode), |
.ssram_zz(), //ssram_zz), |
.ssram_globalw_n(ssram_globalw_n), |
.ssram_advance_n(ssram_advance_n), |
.ssram_adsp_n(ssram_adsp_n), |
.ssram_adsc_n(ssram_adsc_n), |
.ssram_ce1_n(ssram_ce1_n), |
.ssram_ce2(ssram_ce2), |
.ssram_ce3_n(ssram_ce3_n) |
); |
|
/*********************************************************************************************************************** |
* MASTER and SLAVE sd |
**********************************************************************************************************************/ |
|
//------------------------------------- global wires: master |
//output |
wire sd_cyc_o; |
wire [31:0] sd_dat_o; |
wire sd_stb_o; |
wire sd_we_o; |
wire [31:2] sd_adr_o; |
wire [3:0] sd_sel_o; |
|
//input |
|
//------------------------------------- global wires: slave |
//output |
wire [31:0] sd_slave_dat_o; |
wire sd_ack_o; |
|
sd m_sd( |
.CLK_I(clk_i), |
.RST_I(rst_i), |
|
.CYC_O(sd_cyc_o), |
.DAT_O(sd_dat_o), |
.STB_O(sd_stb_o), |
.WE_O(sd_we_o), |
.ADR_O(sd_adr_o), |
.SEL_O(sd_sel_o), |
|
.DAT_I(ssram_dat_o), |
.ACK_I( (early_boot_loading_finished_o == 1'b1) ? 1'b0 : ssram_ack_o), |
.ERR_I(1'b0), |
.RTY_I(1'b0), |
|
// TAG_TYPE: TGC_O |
.SGL_O(), |
.BLK_O(), |
.RMW_O(), |
|
// TAG_TYPE: TGA_O |
.CTI_O(), |
.BTE_O(), |
|
//slave |
.slave_DAT_O(sd_slave_dat_o), |
.slave_DAT_I(early_boot_dat_o), |
.ACK_O(sd_ack_o), |
.ERR_O(), |
.RTY_O(), |
|
.CYC_I(early_boot_cyc_o), |
.ADR_I(early_boot_adr_o[3:2]), |
.STB_I(early_boot_stb_o), |
.WE_I(early_boot_we_o), |
.SEL_I(early_boot_sel_o), |
|
|
//sd bus 1-bit interface |
.sd_clk_o(sd_clk_o), |
.sd_cmd_io(sd_cmd_io), |
.sd_dat_io(sd_dat_io), |
|
.debug_leds(sd_debug) |
); |
|
/*********************************************************************************************************************** |
* SLAVE serial_txd |
**********************************************************************************************************************/ |
|
//------------------------------------- global wires |
//output |
wire serial_txd_ack_o; |
|
//input |
|
serial_txd m_serial_txd( |
.CLK_I(clk_i), |
.RST_I(rst_i), |
|
//slave |
.DAT_I( (ao68000_adr_o[31:2] == 30'h38000000) ? |
( |
(ao68000_sel_o[3] == 1'b1) ? ao68000_dat_o[31:24] : |
(ao68000_sel_o[2] == 1'b1) ? ao68000_dat_o[23:16] : |
(ao68000_sel_o[1] == 1'b1) ? ao68000_dat_o[15:8] : |
(ao68000_sel_o[0] == 1'b1) ? ao68000_dat_o[7:0] : |
8'hFF |
) : |
8'hFE ), |
.ACK_O(serial_txd_ack_o), |
|
.CYC_I( (ao68000_adr_o[31:2] == 30'h38000000) ? ao68000_cyc_o : 1'b0 ), |
.STB_I( (ao68000_adr_o[31:2] == 30'h38000000) ? ao68000_stb_o : 1'b0 ), |
.WE_I( ao68000_we_o ), |
|
//serial interface |
.uart_rxd(uart_rxd), |
.uart_rts(uart_rts), |
.uart_txd(uart_txd), |
.uart_cts(uart_cts) |
); |
|
/*********************************************************************************************************************** |
* MASTER early_boot |
**********************************************************************************************************************/ |
|
//------------------------------------- global wires |
//output |
wire early_boot_cyc_o; |
wire [31:0] early_boot_dat_o; |
wire early_boot_stb_o; |
wire early_boot_we_o; |
wire [31:2] early_boot_adr_o; |
wire [3:0] early_boot_sel_o; |
|
wire early_boot_loading_finished_o; |
|
//input |
|
early_boot m_early_boot( |
.CLK_I(clk_i), |
.RST_I(rst_i), |
|
.CYC_O(early_boot_cyc_o), |
.DAT_O(early_boot_dat_o), |
.STB_O(early_boot_stb_o), |
.WE_O(early_boot_we_o), |
.ADR_O(early_boot_adr_o), |
.SEL_O(early_boot_sel_o), |
|
.DAT_I(sd_slave_dat_o), |
.ACK_I(sd_ack_o), |
.ERR_I(1'b0), |
.RTY_I(1'b0), |
|
//****************** OTHER |
.loading_finished_o(early_boot_loading_finished_o) |
); |
|
endmodule |
|
/trunk/rtl/verilog/full_system/sd.v
0,0 → 1,1018
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
module sd( |
input CLK_I, |
input RST_I, |
|
output reg CYC_O, |
output reg [31:0] DAT_O, |
output reg STB_O, |
output reg WE_O, |
output [31:2] ADR_O, |
output [3:0] SEL_O, |
|
input [31:0] DAT_I, |
input ACK_I, |
input ERR_I, |
input RTY_I, |
|
// TAG_TYPE: TGC_O |
output SGL_O, |
output BLK_O, |
output RMW_O, |
|
// TAG_TYPE: TGA_O |
output [2:0] CTI_O, |
output [1:0] BTE_O, |
|
//slave |
output [31:0] slave_DAT_O, |
input [31:0] slave_DAT_I, |
output reg ACK_O, |
output ERR_O, |
output RTY_O, |
|
input CYC_I, |
input [3:2] ADR_I, |
input STB_I, |
input WE_I, |
input [3:0] SEL_I, |
|
|
//sd bus 1-bit interface |
output reg sd_clk_o = 1'b0, |
inout sd_cmd_io, |
inout sd_dat_io, |
|
output [5:0] debug_leds |
); |
|
/*********************************************************************************************************************** |
* Wishbone interface |
**********************************************************************************************************************/ |
|
assign debug_leds = { (RST_I == 1'b1), (error_count == 16'd65535), control_state }; |
|
//---------------------------------------------------- wishbone master |
assign SGL_O = 1'b1; |
assign BLK_O = 1'b0; |
assign RMW_O = 1'b0; |
assign SEL_O = 4'b1111; |
assign BTE_O = 2'b00; |
assign CTI_O = 3'b000; |
assign ADR_O = wb_address[31:2] + { 23'b0, part_counter }; |
|
reg bus_error; |
reg data_read = 1'b0; |
reg data_write = 1'b0; |
reg [31:0] data_part_contents; |
|
//STB_O,CYC_O,WE_O,DAT_O, |
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
STB_O <= 1'b0; |
CYC_O <= 1'b0; |
WE_O <= 1'b0; |
DAT_O <= 32'd0; |
bus_error <= 1'b0; |
data_read <= 1'b0; |
data_write <= 1'b0; |
data_part_contents <= 32'd0; |
end |
else if(data_state == S_DATA_READ_READY_PART && data_read == 1'b0) begin |
if(ACK_I == 1'b1) begin |
STB_O <= 1'b0; |
CYC_O <= 1'b0; |
WE_O <= 1'b0; |
|
data_read <= 1'b1; |
end |
else if(RTY_I == 1'b1) begin |
STB_O <= 1'b0; |
CYC_O <= 1'b0; |
WE_O <= 1'b0; |
end |
else if(ERR_I == 1'b1) begin |
STB_O <= 1'b0; |
CYC_O <= 1'b0; |
WE_O <= 1'b0; |
|
data_read <= 1'b1; |
bus_error <= 1'b1; |
end |
else begin |
STB_O <= 1'b1; |
CYC_O <= 1'b1; |
WE_O <= 1'b1; |
DAT_O <= data_part; |
end |
end |
else if(data_state == S_DATA_WRITE_READY_PART && data_write == 1'b0) begin |
if(ACK_I == 1'b1) begin |
STB_O <= 1'b0; |
CYC_O <= 1'b0; |
WE_O <= 1'b0; |
data_part_contents <= DAT_I; |
|
data_write <= 1'b1; |
end |
else if(RTY_I == 1'b1) begin |
STB_O <= 1'b0; |
CYC_O <= 1'b0; |
WE_O <= 1'b0; |
end |
else if(ERR_I == 1'b1) begin |
STB_O <= 1'b0; |
CYC_O <= 1'b0; |
WE_O <= 1'b0; |
|
data_write <= 1'b1; |
bus_error <= 1'b1; |
end |
else begin |
STB_O <= 1'b1; |
CYC_O <= 1'b1; |
WE_O <= 1'b0; |
end |
end |
else if(data_state != S_DATA_READ_READY_PART && data_state != S_DATA_WRITE_READY_PART) begin |
if(status == STATUS_ERROR) begin |
bus_error <= 1'b0; |
end |
|
data_read <= 1'b0; |
data_write <= 1'b0; |
end |
end |
|
//---------------------------------------------------- wishbone slave |
assign ERR_O = 1'b0; |
assign RTY_O = 1'b0; |
assign slave_DAT_O = {29'd0, status[2:0]}; |
|
//write only |
reg [31:0] wb_address; |
reg [31:0] sd_address; |
reg [31:0] sd_block_count; |
reg [1:0] control; |
|
reg [3:0] last_control_state; |
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
wb_address <= 32'd0; |
sd_address <= 32'd0; |
sd_block_count <= 32'd0; |
control <= 2'd0; |
ACK_O <= 1'b0; |
last_control_state <= 4'd0; |
end |
else begin |
last_control_state <= control_state; |
|
if( (last_control_state == S_CTRL_CMD17_READ || last_control_state == S_CTRL_CMD24_WRITE) && |
control_state == S_CTRL_PRE_IDLE |
) begin |
sd_block_count <= sd_block_count - 32'd1; |
sd_address <= sd_address + 32'd1; |
wb_address <= wb_address + 32'd512; |
|
ACK_O <= 1'b0; |
end |
else if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1) begin |
ACK_O <= 1'b1; |
|
if(ADR_I[3:2] == 2'b00) begin |
wb_address[31:24] <= (SEL_I[3] == 1'b1) ? slave_DAT_I[31:24] : wb_address[31:24]; |
wb_address[23:16] <= (SEL_I[2] == 1'b1) ? slave_DAT_I[23:16] : wb_address[23:16]; |
wb_address[15:8] <= (SEL_I[1] == 1'b1) ? slave_DAT_I[15:8] : wb_address[15:8]; |
wb_address[7:0] <= (SEL_I[0] == 1'b1) ? slave_DAT_I[7:0] : wb_address[7:0]; |
end |
else if(ADR_I[3:2] == 2'b01) begin |
sd_address[31:24] <= (SEL_I[3] == 1'b1) ? slave_DAT_I[31:24] : sd_address[31:24]; |
sd_address[23:16] <= (SEL_I[2] == 1'b1) ? slave_DAT_I[23:16] : sd_address[23:16]; |
sd_address[15:8] <= (SEL_I[1] == 1'b1) ? slave_DAT_I[15:8] : sd_address[15:8]; |
sd_address[7:0] <= (SEL_I[0] == 1'b1) ? slave_DAT_I[7:0] : sd_address[7:0]; |
end |
else if(ADR_I[3:2] == 2'b10) begin |
sd_block_count[31:24] <= (SEL_I[3] == 1'b1) ? slave_DAT_I[31:24] : sd_block_count[31:24]; |
sd_block_count[23:16] <= (SEL_I[2] == 1'b1) ? slave_DAT_I[23:16] : sd_block_count[23:16]; |
sd_block_count[15:8] <= (SEL_I[1] == 1'b1) ? slave_DAT_I[15:8] : sd_block_count[15:8]; |
sd_block_count[7:0] <= (SEL_I[0] == 1'b1) ? slave_DAT_I[7:0] : sd_block_count[7:0]; |
end |
else if(ADR_I[3:2] == 2'b11) begin |
control[1:0] <= (SEL_I[0] == 1'b1) ? slave_DAT_I[1:0] : control[1:0]; |
end |
end |
else if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b0 && ADR_I[3:2] == 2'b00) begin |
ACK_O <= 1'b1; |
end |
else begin |
ACK_O <= 1'b0; |
end |
end |
|
end |
|
/*********************************************************************************************************************** |
* Control state machine |
**********************************************************************************************************************/ |
|
reg [3:0] control_state; |
reg [15:0] error_count; |
reg [2:0] status; |
reg [37:0] cmd_send_contents; |
|
reg start_cmd = 1'b0; |
reg start_read = 1'b0; |
reg start_write = 1'b0; |
|
`define CRC7_REVERSE crc7[0],crc7[1],crc7[2],crc7[3],crc7[4],crc7[5],crc7[6] |
|
parameter [3:0] |
S_CTRL_INIT = 4'd0, |
S_CTRL_CMD0 = 4'd1, |
S_CTRL_CMD8 = 4'd2, |
S_CTRL_CMD55 = 4'd3, |
S_CTRL_ACMD41 = 4'd4, |
S_CTRL_CMD2 = 4'd5, |
S_CTRL_CMD3 = 4'd6, |
S_CTRL_CMD7 = 4'd7, |
|
S_CTRL_PRE_IDLE = 4'd8, |
S_CTRL_IDLE = 4'd9, |
S_CTRL_CMD17_READ = 4'd10, |
S_CTRL_CMD24_WRITE = 4'd11; |
|
parameter [2:0] |
STATUS_INIT = 3'd0, |
STATUS_INIT_ERROR = 3'd1, |
STATUS_IDLE = 3'd2, |
STATUS_READ = 3'd3, |
STATUS_WRITE = 3'd4, |
STATUS_ERROR = 3'd4; |
|
parameter [1:0] |
CONTROL_IDLE = 2'd0, |
CONTROL_REINIT = 2'd1, |
CONTROL_READ = 2'd2, |
CONTROL_WRITE = 2'd3; |
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
control_state <= S_CTRL_INIT; |
status <= STATUS_INIT; |
cmd_send_contents <= 38'd0; |
start_cmd <= 1'b0; |
start_read <= 1'b0; |
start_write <= 1'b0; |
error_count <= 16'd0; |
end |
else if(control_state == S_CTRL_INIT && error_count == 16'd65535) begin |
status <= STATUS_INIT_ERROR; |
|
if(control == CONTROL_REINIT) begin |
error_count <= 16'd0; |
control_state <= S_CTRL_INIT; |
end |
end |
else if(control_state == S_CTRL_INIT) begin |
status <= STATUS_INIT; |
start_cmd <= 1'b1; |
|
if(cmd_state == S_CMD_IDLE) begin |
//CMD0, no arguments |
cmd_send_contents <= { 6'd0, 32'd0 }; |
control_state <= S_CTRL_CMD0; |
end |
end |
else if(control_state == S_CTRL_CMD0) begin |
|
if(cmd_state == S_CMD_REPLY_ERROR) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_INIT; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin |
start_cmd <= 1'b1; |
//CMD8, supply voltage, check pattern |
cmd_send_contents <= { 6'd8, 20'd0, 4'b0001, 8'b10101010 }; |
control_state <= S_CTRL_CMD8; |
end |
else start_cmd <= 1'b0; |
end |
else if(control_state == S_CTRL_CMD8) begin |
if(start_cmd == 1'b1) begin |
start_cmd <= 1'b0; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR || |
(cmd_state == S_CMD_IDLE && cmd_reply != { 1'b0, 1'b0, 6'd8, 20'd0, 4'b0001, 8'b10101010, `CRC7_REVERSE, 1'b1 }) |
) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_INIT; |
end |
else if(cmd_state == S_CMD_IDLE) begin |
start_cmd <= 1'b1; |
//CMD55, RCA |
cmd_send_contents <= { 6'd55, 16'd0, 16'd0}; |
control_state <= S_CTRL_CMD55; |
end |
end |
else if(control_state == S_CTRL_CMD55) begin |
if(start_cmd == 1'b1) begin |
start_cmd <= 1'b0; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR || |
(cmd_state == S_CMD_IDLE && |
(cmd_reply[47:40] != { 1'b0, 1'b0, 6'd55 } || cmd_reply[39:27] != 13'b0 || cmd_reply[24:21] != 4'b0 || |
cmd_reply[13] != 1'b1 || cmd_reply[11] != 1'b0 || cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 } |
) |
) |
) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_INIT; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin |
start_cmd <= 1'b1; |
//ACMD41, |
cmd_send_contents <= { 6'd41, //command index |
1'b0, //reserved bit |
1'b1, //host capacity support HCS(OCR[30]) |
6'b0, //reserved bits |
24'b0001_0000_0000_0000_0000_0000 //VDD voltage window OCR[23:0] |
}; |
control_state <= S_CTRL_ACMD41; |
end |
end |
else if(control_state == S_CTRL_ACMD41) begin |
if(start_cmd == 1'b1) begin |
start_cmd <= 1'b0; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR || |
(cmd_state == S_CMD_IDLE && (cmd_reply[47:40] != { 1'b0, 1'b0, 6'b111111 } || |
cmd_reply[39:38] != 2'b11 || cmd_reply[7:0] != {7'b1111111, 1'b1 }) |
) |
) begin |
if(error_count == 16'd65535) begin |
control_state <= S_CTRL_INIT; |
end |
else begin |
error_count <= error_count + 16'd1; |
start_cmd <= 1'b1; |
//CMD55, RCA |
cmd_send_contents <= { 6'd55, 16'd0, 16'd0}; |
control_state <= S_CTRL_CMD55; |
end |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin |
start_cmd <= 1'b1; |
//CMD2, no arguments |
cmd_send_contents <= { 6'd2, 32'd0 }; |
control_state <= S_CTRL_CMD2; |
end |
end |
else if(control_state == S_CTRL_CMD2) begin |
if(start_cmd == 1'b1) begin |
start_cmd <= 1'b0; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR || |
(cmd_state == S_CMD_IDLE && cmd_reply[0] != 1'b1) |
) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_INIT; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin |
start_cmd <= 1'b1; |
//CMD3, no arguments |
cmd_send_contents <= { 6'd3, 32'd0 }; |
control_state <= S_CTRL_CMD3; |
end |
end |
else if(control_state == S_CTRL_CMD3) begin |
if(start_cmd == 1'b1) begin |
start_cmd <= 1'b0; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR || |
(cmd_state == S_CMD_IDLE && |
(cmd_reply[47:40] != { 1'b0, 1'b0, 6'd3 } || |
/*23:8= 23,22,19,12:0 from card status*/ |
cmd_reply[23:21] != 3'b0 || cmd_reply[13] != 1'b0 || cmd_reply[11] != 1'b0 || |
cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 } |
) |
) |
) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_INIT; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin |
|
start_cmd <= 1'b1; |
//CMD7, no arguments |
cmd_send_contents <= { 6'd7, //command index |
cmd_reply[39:24], //RCA |
16'd0 //stuff bits |
}; |
control_state <= S_CTRL_CMD7; |
end |
end |
else if(control_state == S_CTRL_CMD7) begin |
if(start_cmd == 1'b1) begin |
start_cmd <= 1'b0; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR || |
(cmd_state == S_CMD_IDLE && |
(cmd_reply[47:40] != { 1'b0, 1'b0, 6'd7 } || cmd_reply[39:27] != 13'b0 || cmd_reply[24:21] != 4'b0 || |
cmd_reply[13] != 1'b0 || cmd_reply[11] != 1'b0 || cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 } |
) |
) |
) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_INIT; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0) begin |
start_cmd <= 1'b0; |
|
error_count <= 16'd0; |
control_state <= S_CTRL_IDLE; |
end |
end |
else if(control_state == S_CTRL_PRE_IDLE) begin |
control_state <= S_CTRL_IDLE; |
|
if(bus_error == 1'b1) error_count <= 16'd65535; |
end |
else if(control_state == S_CTRL_IDLE && error_count == 16'd65535) begin |
status <= STATUS_ERROR; |
|
if(control == CONTROL_IDLE) begin |
control_state <= S_CTRL_IDLE; |
error_count <= 16'd0; |
end |
else if(control == CONTROL_REINIT) begin |
control_state <= S_CTRL_INIT; |
error_count <= 16'd0; |
end |
end |
else if(control_state == S_CTRL_IDLE) begin |
if(control == CONTROL_READ && sd_block_count != 32'd0) begin |
status <= STATUS_READ; |
start_cmd <= 1'b1; |
start_read <= 1'b1; |
//CMD17, sector address |
cmd_send_contents <= { 6'd17, //command index |
sd_address[31:0] //sector address |
}; |
control_state <= S_CTRL_CMD17_READ; |
end |
else if(control == CONTROL_WRITE && sd_block_count != 32'd0) begin |
status <= STATUS_WRITE; |
start_cmd <= 1'b1; |
start_write <= 1'b1; |
//CMD24, sector address |
cmd_send_contents <= { 6'd24, //command index |
sd_address[31:0] //sector address |
}; |
control_state <= S_CTRL_CMD24_WRITE; |
end |
else begin |
status <= STATUS_IDLE; |
end |
end |
else if(control_state == S_CTRL_CMD17_READ) begin |
if(start_cmd == 1'b1) begin |
start_cmd <= 1'b0; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR || |
(cmd_state == S_CMD_IDLE && |
(cmd_reply[47:40] != { 1'b0, 1'b0, 6'd17 } || cmd_reply[39:27] != 13'b0 || cmd_reply[24:21] != 4'b0 || |
cmd_reply[13] != 1'b0 || cmd_reply[11] != 1'b0 || cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 } |
) |
) |
) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_IDLE; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_read == 1'b1) begin |
start_read <= 1'b0; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_read == 1'b0 && data_state == S_DATA_READ_ERROR) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_IDLE; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_read == 1'b0 && data_state == S_DATA_IDLE) begin |
error_count <= 16'd0; |
control_state <= S_CTRL_PRE_IDLE; |
end |
end |
else if(control_state == S_CTRL_CMD24_WRITE) begin |
if(start_cmd == 1'b1) begin |
start_cmd <= 1'b0; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR || |
(cmd_state == S_CMD_IDLE && |
(cmd_reply[47:40] != { 1'b0, 1'b0, 6'd24 } || cmd_reply[39:27] != 13'b0 || cmd_reply[24:21] != 4'b0 || |
cmd_reply[13] != 1'b0 || cmd_reply[11] != 1'b0 || cmd_reply[7:0] != { `CRC7_REVERSE, 1'b1 } |
) |
) |
) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_IDLE; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_write == 1'b1) begin |
start_write <= 1'b0; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_write == 1'b0 && data_state == S_DATA_WRITE_ERROR) begin |
error_count <= error_count + 16'd1; |
control_state <= S_CTRL_IDLE; |
end |
else if(cmd_state == S_CMD_IDLE && start_cmd == 1'b0 && start_write == 1'b0 && data_state == S_DATA_IDLE) begin |
error_count <= 16'd0; |
control_state <= S_CTRL_PRE_IDLE; |
end |
end |
end |
|
/*********************************************************************************************************************** |
* SD interface |
**********************************************************************************************************************/ |
|
reg sd_cmd_o = 1'b1; |
reg sd_dat_o = 1'b1; |
|
assign sd_cmd_io = (sd_cmd_enable == 1'b1) ? sd_cmd_o : 1'bZ; |
assign sd_dat_io = (sd_data_enable == 1'b1) ? sd_dat_o : 1'bZ; |
|
//CID register not interpreted: CRC7 not checked, always accepted |
|
//---------------------------------------------------- SD data |
|
reg sd_data_enable; |
reg [3:0] data_state; |
reg [15:0] data_counter; |
reg [6:0] part_counter; |
reg [15:0] crc16; |
reg [31:0] data_part; |
reg clk_data_ena; |
reg clk_master_ena = 1'b1; |
|
parameter [3:0] |
S_DATA_IDLE = 4'd0, |
S_DATA_READ_START_BIT = 4'd1, |
S_DATA_READ_CONTENTS = 4'd2, |
S_DATA_READ_READY_PART = 4'd3, |
S_DATA_READ_READY_PART_CONTINUE = 4'd4, |
S_DATA_READ_CRC16_END_BIT = 4'd5, |
S_DATA_READ_ERROR = 4'd6, |
S_DATA_WRITE_START_BIT = 4'd7, |
S_DATA_WRITE_READY_PART = 4'd8, |
S_DATA_WRITE_CONTENTS = 4'd9, |
S_DATA_WRITE_CRC16_END_BIT = 4'd10, |
S_DATA_WRITE_CRC_STATUS_START = 4'd11, |
S_DATA_WRITE_CRC_STATUS_CONTENTS_END_BIT = 4'd12, |
S_DATA_WRITE_BUSY_START = 4'd13, |
S_DATA_WRITE_BUSY_WAIT = 4'd14, |
S_DATA_WRITE_ERROR = 4'd15; |
|
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
sd_data_enable <= 1'b0; |
data_state <= S_DATA_IDLE; |
data_counter <= 16'd0; |
part_counter <= 7'd0; |
crc16 <= 16'd0; |
data_part <= 32'd0; |
clk_data_ena <= 1'b0; |
clk_master_ena <= 1'b1; |
sd_dat_o <= 1'b1; |
end |
|
|
else if(clk_counter == 2'd0) begin |
|
if(data_state == S_DATA_IDLE) begin |
if(start_read == 1'b1) begin |
crc16 <= 16'd0; |
data_state <= S_DATA_READ_START_BIT; |
end |
else if(start_write == 1'b1 && start_cmd == 1'b0 && cmd_state == S_CMD_IDLE) begin |
crc16 <= 16'd0; |
clk_data_ena <= 1'b1; |
data_state <= S_DATA_WRITE_START_BIT; |
end |
end |
|
//wait for response and data simultaneously (data read) |
else if(data_state == S_DATA_READ_START_BIT) begin |
clk_data_ena <= 1'b1; |
|
if(sd_dat_io == 1'b0) begin |
crc16 <= { sd_dat_io ^ crc16[0], crc16[15:12], sd_dat_io ^ crc16[11] ^ crc16[0], crc16[10:5], |
sd_dat_io ^ crc16[4] ^ crc16[0], crc16[3:1] }; |
|
data_state <= S_DATA_READ_CONTENTS; |
data_counter <= 16'd0; |
end |
else if(data_counter == 16'd65535) begin |
crc16 <= 16'd0; |
data_state <= S_DATA_READ_ERROR; |
data_counter <= 16'd0; |
end |
else data_counter <= data_counter + 16'd1; |
end |
else if(data_state == S_DATA_READ_CONTENTS) begin |
crc16 <= { sd_dat_io ^ crc16[0], crc16[15:12], sd_dat_io ^ crc16[11] ^ crc16[0], |
crc16[10:5], sd_dat_io ^ crc16[4] ^ crc16[0], crc16[3:1] }; |
data_part <= { data_part[30:0], sd_dat_io }; |
|
if(data_counter == 16'd30) begin |
clk_master_ena <= 1'b0; |
data_counter <= data_counter + 16'd1; |
end |
else if(data_counter == 16'd31) begin |
data_state <= S_DATA_READ_READY_PART; |
data_counter <= 16'd0; |
end |
else data_counter <= data_counter + 16'd1; |
end |
else if(data_state == S_DATA_READ_READY_PART) begin |
if(data_read == 1'b1) begin |
clk_master_ena <= 1'b1; |
data_state <= S_DATA_READ_READY_PART_CONTINUE; |
end |
end |
else if(data_state == S_DATA_READ_READY_PART_CONTINUE) begin |
if(part_counter == 7'd127) begin |
data_state <= S_DATA_READ_CRC16_END_BIT; |
part_counter <= 7'd0; |
end |
else begin |
data_state <= S_DATA_READ_CONTENTS; |
part_counter <= part_counter + 7'd1; |
end |
end |
else if(data_state == S_DATA_READ_CRC16_END_BIT) begin |
data_part <= { sd_dat_io, data_part[31:1] }; |
|
if(data_counter == 16'd16) begin |
if(data_part[31:16] != crc16[15:0] || sd_dat_io != 1'b1) begin |
data_state <= S_DATA_READ_ERROR; |
data_counter <= 16'd0; |
end |
else begin |
clk_data_ena <= 1'b0; |
data_state <= S_DATA_IDLE; |
data_counter <= 16'd0; |
end |
end |
else data_counter <= data_counter + 16'd1; |
end |
else if(data_state == S_DATA_READ_ERROR) begin |
if(start_read == 1'b1 || start_write == 1'b1) begin |
clk_data_ena <= 1'b0; |
data_state <= S_DATA_IDLE; |
data_counter <= 16'd0; |
end |
end |
|
//send data on data line, wait for crc status, wait for busy on data line (data write) |
else if(data_state == S_DATA_WRITE_START_BIT) begin |
sd_dat_o <= 1'b0; |
crc16 <= { 1'b0 ^ crc16[0], crc16[15:12], 1'b0 ^ crc16[11] ^ crc16[0], crc16[10:5], |
1'b0 ^ crc16[4] ^ crc16[0], crc16[3:1] }; |
|
sd_data_enable <= 1'b1; |
clk_data_ena <= 1'b0; |
data_counter <= 16'd0; |
data_state <= S_DATA_WRITE_READY_PART; |
end |
else if(data_state == S_DATA_WRITE_READY_PART) begin |
if(data_write == 1'b1) begin |
data_state <= S_DATA_WRITE_CONTENTS; |
data_part <= data_part_contents; |
end |
end |
else if(data_state == S_DATA_WRITE_CONTENTS) begin |
sd_dat_o <= data_part[31]; |
crc16 <= { data_part[31] ^ crc16[0], crc16[15:12], data_part[31] ^ crc16[11] ^ crc16[0], crc16[10:5], |
data_part[31] ^ crc16[4] ^ crc16[0], crc16[3:1] }; |
data_part <= { data_part[30:0], 1'b0 }; |
|
if(data_counter == 16'd31) begin |
data_counter <= 16'd0; |
|
if(part_counter == 7'd127) begin |
part_counter <= 7'd0; |
data_state <= S_DATA_WRITE_CRC16_END_BIT; |
end |
else begin |
part_counter <= part_counter + 7'd1; |
data_state <= S_DATA_WRITE_READY_PART; |
end |
end |
else data_counter <= data_counter + 16'd1; |
end |
|
else if(data_state == S_DATA_WRITE_CRC16_END_BIT) begin |
sd_dat_o <= crc16[0]; |
|
if(data_counter == 16'd17) begin |
crc16 <= 16'd0; |
data_state <= S_DATA_WRITE_CRC_STATUS_START; |
end |
else begin |
crc16 <= { 1'b1, crc16[15:1] }; |
data_counter <= data_counter + 16'd1; |
end |
|
end |
else if(data_state == S_DATA_WRITE_CRC_STATUS_START) begin |
sd_data_enable <= 1'b0; |
|
if(sd_dat_io == 1'b0) begin |
data_state <= S_DATA_WRITE_CRC_STATUS_CONTENTS_END_BIT; |
data_counter <= 16'b0; |
end |
else if(data_counter == 16'd65535) begin |
data_state <= S_DATA_WRITE_ERROR; |
data_counter <= 16'b0; |
end |
else data_counter <= data_counter + 16'd1; |
end |
|
else if(data_state == S_DATA_WRITE_CRC_STATUS_CONTENTS_END_BIT) begin |
data_part <= { data_part[30:0], sd_dat_io }; |
|
if(data_counter == 16'd3) begin |
data_state <= S_DATA_WRITE_BUSY_START; |
data_counter <= 16'b0; |
end |
else data_counter <= data_counter + 16'd1; |
end |
else if(data_state == S_DATA_WRITE_BUSY_START) begin |
|
if(sd_dat_io == 1'b0) begin |
data_state <= S_DATA_WRITE_BUSY_WAIT; |
data_counter <= 16'b0; |
end |
else if(data_counter == 16'd65535) begin |
data_state <= S_DATA_WRITE_ERROR; |
data_counter <= 16'b0; |
end |
else data_counter <= data_counter + 16'd1; |
end |
else if(data_state == S_DATA_WRITE_BUSY_WAIT) begin |
if(sd_dat_io == 1'b1 && data_part[3:0] != 4'b0010) begin |
data_state <= S_DATA_WRITE_ERROR; |
data_counter <= 16'd0; |
end |
else if(sd_dat_io == 1'b1) begin |
clk_data_ena <= 1'b0; |
data_state <= S_DATA_IDLE; |
data_counter <= 16'd0; |
end |
else if(data_counter == 16'd65535) begin |
data_state <= S_DATA_WRITE_ERROR; |
data_counter <= 16'd0; |
end |
else data_counter <= data_counter + 16'd1; |
end |
else if(data_state == S_DATA_WRITE_ERROR) begin |
if(start_read == 1'b1 || start_write == 1'b1) begin |
clk_data_ena <= 1'b0; |
data_state <= S_DATA_IDLE; |
data_counter <= 16'd0; |
end |
end |
end |
end |
|
//---------------------------------------------------- SD command |
|
reg sd_cmd_enable; |
reg [37:0] cmd_send; |
reg [47:0] cmd_reply; |
reg [7:0] cmd_state; |
reg [7:0] cmd_counter; |
reg [6:0] crc7; |
reg clk_cmd_ena; |
|
parameter [7:0] |
S_CMD_IDLE = 8'd0, |
S_CMD_SEND_START_ONES = 8'd1, |
S_CMD_SEND_START_BIT = 8'd2, |
S_CMD_SEND_START_HOST = 8'd3, |
S_CMD_SEND_CONTENTS = 8'd4, |
S_CMD_SEND_CRC7 = 8'd5, |
S_CMD_SEND_END_BIT = 8'd6, |
S_CMD_SEND_END_ONES = 8'd7, |
S_CMD_REPLY_START_BIT = 8'd8, |
S_CMD_REPLY_CONTENTS = 8'd9, |
S_CMD_REPLY_CRC7_END_BIT = 8'd10, |
S_CMD_REPLY_FINISH_ONES = 8'd11, |
S_CMD_REPLY_ERROR = 8'd12; |
|
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
sd_cmd_enable <= 1'b0; |
cmd_send <= 38'd0; |
cmd_reply <= 48'd0; |
cmd_state <= S_CMD_IDLE; |
cmd_counter <= 8'd0; |
crc7 <= 7'd0; |
clk_cmd_ena <= 1'b0; |
sd_cmd_o <= 1'b1; |
end |
else if(cmd_state == S_CMD_IDLE) begin |
if(start_cmd == 1'b1) begin |
cmd_state <= S_CMD_SEND_START_ONES; |
end |
end |
else if(clk_counter == 2'd0 && clk_master_ena == 1'b1) begin |
|
//send command |
if(cmd_state == S_CMD_SEND_START_ONES) begin |
sd_cmd_enable <= 1'b1; |
sd_cmd_o <= 1'b1; |
clk_cmd_ena <= 1'b1; |
crc7 <= 7'd0; |
|
if(cmd_counter == 8'd7) begin |
cmd_state <= S_CMD_SEND_START_BIT; |
cmd_counter <= 8'd0; |
end |
else cmd_counter <= cmd_counter + 8'd1; |
end |
else if(cmd_state == S_CMD_SEND_START_BIT) begin |
sd_cmd_o <= 1'b0; |
crc7 <= { 1'b0 ^ crc7[0], crc7[6:5], 1'b0 ^ crc7[4] ^ crc7[0], crc7[3:1] }; |
|
cmd_state <= S_CMD_SEND_START_HOST; |
end |
else if(cmd_state == S_CMD_SEND_START_HOST) begin |
sd_cmd_o <= 1'b1; |
crc7 <= { 1'b1 ^ crc7[0], crc7[6:5], 1'b1 ^ crc7[4] ^ crc7[0], crc7[3:1] }; |
|
cmd_send <= cmd_send_contents; |
cmd_state <= S_CMD_SEND_CONTENTS; |
end |
else if(cmd_state == S_CMD_SEND_CONTENTS) begin |
sd_cmd_o <= cmd_send[37]; |
crc7 <= { cmd_send[37] ^ crc7[0], crc7[6:5], cmd_send[37] ^ crc7[4] ^ crc7[0], crc7[3:1] }; |
cmd_send <= { cmd_send[36:0], 1'b0 }; |
|
if(cmd_counter == 8'd37) begin |
cmd_state <= S_CMD_SEND_CRC7; |
cmd_counter <= 8'd0; |
end |
else cmd_counter <= cmd_counter + 8'd1; |
end |
else if(cmd_state == S_CMD_SEND_CRC7) begin |
sd_cmd_o <= crc7[0]; |
crc7 <= { 1'b0, crc7[6:1] }; |
|
if(cmd_counter == 8'd6) begin |
cmd_state <= S_CMD_SEND_END_BIT; |
cmd_counter <= 8'd0; |
end |
else cmd_counter <= cmd_counter + 8'd1; |
end |
else if(cmd_state == S_CMD_SEND_END_BIT) begin |
sd_cmd_o <= 1'b1; |
|
// if CMD0: send ones |
if(control_state == S_CTRL_CMD0) begin |
cmd_state <= S_CMD_SEND_END_ONES; |
end |
else begin |
crc7 <= 7'd0; |
cmd_state <= S_CMD_REPLY_START_BIT; |
end |
end |
else if(cmd_state == S_CMD_SEND_END_ONES) begin |
sd_cmd_enable <= 1'b0; |
sd_cmd_o <= 1'b1; |
|
if(cmd_counter == 8'd7) begin |
clk_cmd_ena <= 1'b0; |
cmd_state <= S_CMD_IDLE; |
cmd_counter <= 8'd0; |
end |
else cmd_counter <= cmd_counter + 8'd1; |
end |
|
//wait for response: 48-bits with CRC7 |
//wait for response: 48-bits without CRC7 |
//wait for response: 136-bits (CMD2/R2) |
//wait for response and busy on data line simultaneously: (CMD7/R1b) |
else if(cmd_state == S_CMD_REPLY_START_BIT) begin |
sd_cmd_enable <= 1'b0; |
|
if(sd_cmd_io == 1'b0) begin |
crc7 <= { sd_cmd_io ^ crc7[0], crc7[6:5], sd_cmd_io ^ crc7[4] ^ crc7[0], crc7[3:1] }; |
cmd_reply <= { cmd_reply[46:0], sd_cmd_io }; |
|
cmd_state <= S_CMD_REPLY_CONTENTS; |
cmd_counter <= 8'd0; |
end |
else if(cmd_counter == 8'd255) begin |
crc7 <= 7'd0; |
cmd_state <= S_CMD_REPLY_ERROR; |
cmd_counter <= 8'd0; |
end |
else cmd_counter <= cmd_counter + 8'd1; |
end |
else if(cmd_state == S_CMD_REPLY_CONTENTS) begin |
crc7 <= { sd_cmd_io ^ crc7[0], crc7[6:5], sd_cmd_io ^ crc7[4] ^ crc7[0], crc7[3:1] }; |
cmd_reply <= { cmd_reply[46:0], sd_cmd_io }; |
|
if( (control_state != S_CTRL_CMD2 && cmd_counter == 8'd38) || |
(control_state == S_CTRL_CMD2 && cmd_counter == 8'd134) |
) begin |
cmd_state <= S_CMD_REPLY_CRC7_END_BIT; |
cmd_counter <= 8'd0; |
end |
else cmd_counter <= cmd_counter + 8'd1; |
end |
else if(cmd_state == S_CMD_REPLY_CRC7_END_BIT) begin |
cmd_reply <= { cmd_reply[46:0], sd_cmd_io }; |
|
if(cmd_counter == 8'd7) begin |
cmd_state <= S_CMD_REPLY_FINISH_ONES; |
cmd_counter <= 8'd0; |
end |
else cmd_counter <= cmd_counter + 8'd1; |
end |
//at least 2 clock cycles required for data write |
else if(cmd_state == S_CMD_REPLY_FINISH_ONES) begin |
//check is sd_dat_io busy for CMD7 |
if(cmd_counter >= 8'd7 && (control_state != S_CTRL_CMD7 || sd_dat_io == 1'b1)) begin |
clk_cmd_ena <= 1'b0; |
cmd_state <= S_CMD_IDLE; |
cmd_counter <= 8'd0; |
end |
else if(cmd_counter == 8'd255) begin |
cmd_state <= S_CMD_REPLY_ERROR; |
cmd_counter <= 8'd0; |
end |
else cmd_counter <= cmd_counter + 8'd1; |
end |
else if(cmd_state == S_CMD_REPLY_ERROR) begin |
if(start_cmd == 1'b1) begin |
clk_cmd_ena <= 1'b0; |
cmd_state <= S_CMD_IDLE; |
cmd_counter <= 8'd0; |
end |
end |
end |
end |
|
//---------------------------------------------------- SD clock |
|
reg [1:0] clk_counter; |
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
sd_clk_o <= 1'b0; |
clk_counter <= 2'd0; |
end |
else if(clk_counter == 2'd0) begin |
sd_clk_o <= 1'd0; |
if(clk_master_ena == 1'b1 && (clk_cmd_ena == 1'b1 || clk_data_ena == 1'b1)) begin |
clk_counter <= clk_counter + 2'd1; |
end |
end |
else if(clk_counter == 2'd1) begin |
sd_clk_o <= 1'b1; |
clk_counter <= clk_counter + 2'd1; |
end |
else if(clk_counter == 2'd2) begin //was 5 |
sd_clk_o <= 1'b0; |
clk_counter <= clk_counter + 2'd1; |
end |
else clk_counter <= clk_counter + 2'd1; |
end |
|
endmodule |
/trunk/rtl/verilog/ao68000/ao68000.v
0,0 → 1,3002
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
/*! \file ao68000.v |
* \brief Main ao68000 IP Core source file. |
*/ |
|
`include "microcode_params.v" |
`include "microcode/microcode_locations.v" |
|
/*! \brief ao68000 top level module. |
* |
* This module contains only instantiations of sub-modules and wire declarations. |
*/ |
module ao68000 ( |
//****************** WISHBONE |
input CLK_I, //% \copydoc CLK_I |
input RST_I, //% \copydoc RST_I |
|
output CYC_O, //% \copydoc CYC_O |
output [31:2] ADR_O, //% \copydoc ADR_O |
output [31:0] DAT_O, //% \copydoc DAT_O |
input [31:0] DAT_I, //% \copydoc DAT_I |
output [3:0] SEL_O, //% \copydoc SEL_O |
output STB_O, //% \copydoc STB_O |
output WE_O, //% \copydoc WE_O |
|
input ACK_I, //% \copydoc ACK_I |
input ERR_I, //% \copydoc ERR_I |
input RTY_I, //% \copydoc RTY_I |
|
// TAG_TYPE: TGC_O |
output SGL_O, //% \copydoc SGL_O |
output BLK_O, //% \copydoc BLK_O |
output RMW_O, //% \copydoc RMW_O |
|
// TAG_TYPE: TGA_O |
output [2:0] CTI_O, //% \copydoc CTI_O |
output [1:0] BTE_O, //% \copydoc BTE_O |
|
// TAG_TYPE: TGC_O |
output [2:0] fc_o, //% \copydoc fc_o |
|
//****************** OTHER |
/* interrupt acknowlege: |
* ACK_I: interrupt vector on DAT_I[7:0] |
* ERR_I: spurious interrupt |
* RTY_I: autovector |
*/ |
input [2:0] ipl_i, //% \copydoc ipl_i |
output reset_o, //% \copydoc reset_o |
output blocked_o //% \copydoc blocked_o |
); |
|
wire [15:0] sr; |
wire [1:0] size; |
wire [31:0] address; |
wire address_type; |
wire read_modify_write_flag; |
wire [31:0] data_read; |
wire [31:0] data_write; |
wire [31:0] pc; |
wire prefetch_ir_valid; |
wire [79:0] prefetch_ir; |
wire do_reset; |
wire do_read; |
wire do_write; |
wire do_interrupt; |
wire do_blocked; |
wire jmp_address_trap; |
wire jmp_bus_trap; |
wire finished; |
wire [7:0] interrupt_trap; |
wire [2:0] interrupt_mask; |
wire rw_state; |
wire [2:0] fc_state; |
wire [7:0] decoder_trap; |
wire [31:0] usp; |
wire [31:0] Dn_output; |
wire [31:0] An_output; |
wire [31:0] result; |
wire [3:0] An_address; |
wire [31:0] An_input; |
wire [2:0] Dn_address; |
wire [15:0] ir; |
wire [8:0] decoder_micropc; |
wire [1:0] special; |
wire [8:0] load_ea; |
wire [8:0] perform_ea_read; |
wire [8:0] perform_ea_write; |
wire [8:0] save_ea; |
wire trace_flag; |
wire group_0_flag; |
wire stop_flag; |
wire [8:0] micro_pc; |
wire [31:0] operand1; |
wire [31:0] operand2; |
wire [4:0] movem_loop; |
wire [15:0] movem_reg; |
wire condition; |
wire [87:0] micro_data; |
wire [31:0] fault_address_state; |
wire [1:0] pc_change; |
wire prefetch_ir_valid_32; |
wire [3:0] ea_type; |
wire [2:0] ea_mod; |
wire [2:0] ea_reg; |
|
bus_control bus_control_m( |
.CLK_I(CLK_I), |
.RST_I(RST_I), |
.CYC_O(CYC_O), |
.ADR_O(ADR_O), |
.DAT_O(DAT_O), |
.DAT_I(DAT_I), |
.SEL_O(SEL_O), |
.STB_O(STB_O), |
.WE_O(WE_O), |
.ACK_I(ACK_I), |
.ERR_I(ERR_I), |
.RTY_I(RTY_I), |
.SGL_O(SGL_O), |
.BLK_O(BLK_O), |
.RMW_O(RMW_O), |
.CTI_O(CTI_O), |
.BTE_O(BTE_O), |
.fc_o(fc_o), |
.ipl_i(ipl_i), |
.reset_o(reset_o), |
.blocked_o(blocked_o), |
|
.supervisor_i(sr[13]), |
.ipm_i(sr[10:8]), |
.size_i(size), |
.address_i(address), |
.address_type_i(address_type), |
.read_modify_write_i(read_modify_write_flag), |
.data_write_i(data_write), |
.data_read_o(data_read), |
.pc_i(pc), |
.pc_change_i(pc_change), |
.prefetch_ir_o(prefetch_ir), |
.prefetch_ir_valid_32_o(prefetch_ir_valid_32), |
.prefetch_ir_valid_o(prefetch_ir_valid), |
.prefetch_ir_valid_80_o(), |
.do_reset_i(do_reset), |
.do_blocked_i(do_blocked), |
.do_read_i(do_read), |
.do_write_i(do_write), |
.do_interrupt_i(do_interrupt), |
.jmp_address_trap_o(jmp_address_trap), |
.jmp_bus_trap_o(jmp_bus_trap), |
.finished_o(finished), |
.interrupt_trap_o(interrupt_trap), |
.interrupt_mask_o(interrupt_mask), |
.rw_state_o(rw_state), |
.fc_state_o(fc_state), |
.fault_address_state_o(fault_address_state) |
); |
|
registers registers_m( |
.clock(CLK_I), |
.reset(RST_I), |
.data_read(data_read), |
.prefetch_ir(prefetch_ir), |
.prefetch_ir_valid(prefetch_ir_valid), |
.result(result), |
.sr(sr), |
.rw_state(rw_state), |
.fc_state(fc_state), |
.fault_address_state(fault_address_state), |
.interrupt_trap(interrupt_trap), |
.interrupt_mask(interrupt_mask), |
.decoder_trap(decoder_trap), |
.usp(usp), |
.Dn_output(Dn_output), |
.An_output(An_output), |
|
.pc_change(pc_change), |
|
.ea_reg(ea_reg), |
.ea_reg_control(`MICRO_DATA_ea_reg), |
.ea_mod(ea_mod), |
.ea_mod_control(`MICRO_DATA_ea_mod), |
.ea_type(ea_type), |
.ea_type_control(`MICRO_DATA_ea_type), |
.operand1(operand1), |
.operand1_control(`MICRO_DATA_op1), |
.operand2(operand2), |
.operand2_control(`MICRO_DATA_op2), |
.address(address), |
.address_type(address_type), |
.address_control(`MICRO_DATA_address), |
.size(size), |
.size_control(`MICRO_DATA_size), |
.movem_modreg(), |
.movem_modreg_control(`MICRO_DATA_movem_modreg), |
.movem_loop(movem_loop), |
.movem_loop_control(`MICRO_DATA_movem_loop), |
.movem_reg(movem_reg), |
.movem_reg_control(`MICRO_DATA_movem_reg), |
.ir(ir), |
.ir_control(`MICRO_DATA_ir), |
.pc(pc), |
.pc_control(`MICRO_DATA_pc), |
.trap(), |
.trap_control(`MICRO_DATA_trap), |
.offset(), |
.offset_control(`MICRO_DATA_offset), |
.index(), |
.index_control(`MICRO_DATA_index), |
.stop_flag(stop_flag), |
.stop_flag_control(`MICRO_DATA_stop_flag), |
.trace_flag(trace_flag), |
.trace_flag_control(`MICRO_DATA_trace_flag), |
.group_0_flag(group_0_flag), |
.group_0_flag_control(`MICRO_DATA_group_0_flag), |
.instruction_flag(), |
.instruction_flag_control(`MICRO_DATA_instruction_flag), |
.read_modify_write_flag(read_modify_write_flag), |
.read_modify_write_flag_control(`MICRO_DATA_read_modify_write_flag), |
.do_reset_flag(do_reset), |
.do_reset_flag_control(`MICRO_DATA_do_reset_flag), |
.do_interrupt_flag(do_interrupt), |
.do_interrupt_flag_control(`MICRO_DATA_do_interrupt_flag), |
.do_read_flag(do_read), |
.do_read_flag_control(`MICRO_DATA_do_read_flag), |
.do_write_flag(do_write), |
.do_write_flag_control(`MICRO_DATA_do_write_flag), |
.do_blocked_flag(do_blocked), |
.do_blocked_flag_control(`MICRO_DATA_do_blocked_flag), |
.data_write(data_write), |
.data_write_control(`MICRO_DATA_data_write), |
.An_address(An_address), |
.An_address_control(`MICRO_DATA_an_address), |
.An_input(An_input), |
.An_input_control(`MICRO_DATA_an_input), |
.Dn_address(Dn_address), |
.Dn_address_control(`MICRO_DATA_dn_address) |
); |
|
memory_registers memory_registers_m( |
.clock(CLK_I), |
.reset(RST_I), |
.An_address(An_address), |
.An_input(An_input), |
.An_write_enable(`MICRO_DATA_an_write_enable), |
.An_output(An_output), |
.usp(usp), |
.Dn_address(Dn_address), |
.Dn_input(result), |
.Dn_write_enable(`MICRO_DATA_dn_write_enable), |
.Dn_size(size), |
.Dn_output(Dn_output), |
.micro_pc(micro_pc), |
.micro_data(micro_data) |
); |
|
decoder decoder_m( |
.clock(CLK_I), |
.reset(RST_I), |
.supervisor(sr[13]), |
.ir(prefetch_ir[79:64]), |
.decoder_trap(decoder_trap), |
.decoder_micropc(decoder_micropc), |
|
.load_ea(load_ea), |
.perform_ea_read(perform_ea_read), |
.perform_ea_write(perform_ea_write), |
.save_ea(save_ea), |
|
.ea_type(ea_type), |
.ea_mod(ea_mod), |
.ea_reg(ea_reg) |
); |
|
condition condition_m( |
.cond(ir[11:8]), |
.ccr(sr[7:0]), |
.condition(condition) |
); |
|
alu alu_m( |
.clock(CLK_I), |
.reset(RST_I), |
.address(address), |
.ir(ir), |
.size(size), |
.operand1(operand1), |
.operand2(operand2), |
.interrupt_mask(interrupt_mask), |
.alu_control(`MICRO_DATA_alu), |
.sr(sr), |
.result(result), |
.special(special) |
); |
|
microcode_branch microcode_branch_m( |
.clock(CLK_I), |
.reset(RST_I), |
.movem_loop(movem_loop), |
.movem_reg(movem_reg), |
.operand2(operand2), |
.special(special), |
.condition(condition), |
.result(result), |
.overflow(sr[1]), |
.stop_flag(stop_flag), |
.ir(ir), |
.decoder_trap(decoder_trap), |
.trace_flag(trace_flag), |
.group_0_flag(group_0_flag), |
.interrupt_mask(interrupt_mask), |
.load_ea(load_ea), |
.perform_ea_read(perform_ea_read), |
.perform_ea_write(perform_ea_write), |
.save_ea(save_ea), |
.decoder_micropc(decoder_micropc), |
.prefetch_ir_valid_32(prefetch_ir_valid_32), |
.prefetch_ir_valid(prefetch_ir_valid), |
.jmp_address_trap(jmp_address_trap), |
.jmp_bus_trap(jmp_bus_trap), |
.finished(finished), |
.branch_control(`MICRO_DATA_branch), |
.branch_offset(`MICRO_DATA_procedure), |
.micro_pc(micro_pc) |
); |
|
endmodule |
|
/*********************************************************************************************************************** |
* Bus control |
**********************************************************************************************************************/ |
|
/*! \brief Initiate WISHBONE MASTER bus cycles. |
* |
* The bus_control module is the only module that has contact with signals from outside of the IP core. |
* It is responsible for initiating WISHBONE MASTER bus cycles. The cycles can be divided into: |
* - memory read cycles (supervisor data, supervisor program, user data, user program) |
* - memory write cycles (supervisor data, user data), |
* - interrupt acknowledge. |
* |
* Every cycle is supplemented with the following tags: |
* - standard WISHBONE cycle tags: SGL_O, BLK_O, RMW_O, |
* - register feedback WISHBONE address tags: CTI_O and BTE_O, |
* - ao68000 specific cycle tag: fc_o which is equivalent to MC68000 function codes. |
* |
* The bus_control module is also responsible for registering interrupt inputs and initiating the interrupt acknowledge |
* cycle in response to a microcode request. Microcode requests a interrupt acknowledge at the end of instruction |
* processing, when the interrupt privilege level is higher than the current interrupt privilege mask, as specified |
* in the MC68000 User's Manual. |
* |
* Finally, bus_control controls also two ao68000 specific core outputs: |
* - blocked output, high when that the processor is blocked after encountering a double bus error. The only way to leave this block state is by reseting the ao68000 by the WISHBONE RST_I input signal. |
* - reset output, high when processing the RESET instruction. Can be used to reset external devices. |
*/ |
module bus_control( |
//******************************************* external |
//****************** WISHBONE |
input CLK_I, |
input RST_I, |
|
output reg CYC_O, |
output reg [31:2] ADR_O, |
output reg [31:0] DAT_O, |
input [31:0] DAT_I, |
output reg [3:0] SEL_O, |
output reg STB_O, |
output reg WE_O, |
|
input ACK_I, |
input ERR_I, |
input RTY_I, |
|
// TAG_TYPE: TGC_O |
output reg SGL_O, |
output reg BLK_O, |
output reg RMW_O, |
|
// TAG_TYPE: TGA_O |
output reg [2:0] CTI_O, |
output [1:0] BTE_O, |
|
// TAG_TYPE: TGC_O |
output reg [2:0] fc_o, |
|
//****************** OTHER |
input [2:0] ipl_i, |
output reg reset_o = 1'b0, |
output reg blocked_o = 1'b0, |
|
//******************************************* internal |
input supervisor_i, |
input [2:0] ipm_i, |
input [1:0] size_i, |
input [31:0] address_i, |
input address_type_i, |
input read_modify_write_i, |
input [31:0] data_write_i, |
output reg [31:0] data_read_o, |
|
input [31:0] pc_i, |
input [1:0] pc_change_i, |
output reg [79:0] prefetch_ir_o, |
output reg prefetch_ir_valid_32_o = 1'b0, |
output reg prefetch_ir_valid_o = 1'b0, |
output reg prefetch_ir_valid_80_o = 1'b0, |
|
input do_reset_i, |
input do_blocked_i, |
input do_read_i, |
input do_write_i, |
input do_interrupt_i, |
|
output reg jmp_address_trap_o = 1'b0, |
output reg jmp_bus_trap_o = 1'b0, |
// read/write/interrupt |
output reg finished_o, |
|
output reg [7:0] interrupt_trap_o = 8'b0, |
output reg [2:0] interrupt_mask_o = 3'b0, |
|
/* mask==0 && trap==0 nothing |
* mask!=0 interrupt with spurious interrupt |
*/ |
|
// write = 0/read = 1 |
output reg rw_state_o, |
output reg [2:0] fc_state_o, |
output reg [31:0] fault_address_state_o |
); |
|
assign BTE_O = 2'b00; |
|
wire [31:0] pc_i_plus_6; |
assign pc_i_plus_6 = pc_i + 32'd6; |
wire [31:0] pc_i_plus_4; |
assign pc_i_plus_4 = pc_i + 32'd4; |
|
wire [31:0] address_i_plus_4; |
assign address_i_plus_4 = address_i + 32'd4; |
|
reg [1:0] saved_pc_change = 2'b00; |
|
parameter [4:0] |
S_INIT = 5'd0, |
S_RESET = 5'd1, |
S_BLOCKED = 5'd2, |
S_INT_1 = 5'd3, |
S_READ_1 = 5'd4, |
S_READ_2 = 5'd5, |
S_READ_3 = 5'd6, |
S_WAIT = 5'd7, |
S_WRITE_1 = 5'd8, |
S_WRITE_2 = 5'd9, |
S_WRITE_3 = 5'd10, |
S_PC_0 = 5'd11, |
S_PC_1 = 5'd12, |
S_PC_2 = 5'd13, |
S_PC_3 = 5'd14, |
S_PC_4 = 5'd15, |
S_PC_5 = 5'd16, |
S_PC_6 = 5'd17; |
|
parameter [2:0] |
FC_USER_DATA = 3'd1, |
FC_USER_PROGRAM = 3'd2, |
FC_SUPERVISOR_DATA = 3'd5, // all exception vector entries except reset |
FC_SUPERVISOR_PROGRAM = 3'd6, // exception vector for reset |
FC_CPU_SPACE = 3'd7; // interrupt acknowlege bus cycle |
|
parameter [2:0] |
CTI_CLASSIC_CYCLE = 3'd0, |
CTI_CONST_CYCLE = 3'd1, |
CTI_INCR_CYCLE = 3'd2, |
CTI_END_OF_BURST = 3'd7; |
|
parameter [7:0] |
VECTOR_BUS_TRAP = 8'd2, |
VECTOR_ADDRESS_TRAP = 8'd3; |
|
reg [4:0] current_state; |
reg [7:0] reset_counter; |
|
reg [2:0] last_interrupt_mask; |
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
interrupt_mask_o <= 3'b000; |
last_interrupt_mask <= 3'b000; |
end |
else if(ipl_i > ipm_i && do_interrupt_i == 1'b0) begin |
interrupt_mask_o <= ipl_i; |
last_interrupt_mask <= interrupt_mask_o; |
end |
else if(do_interrupt_i == 1'b1) begin |
interrupt_mask_o <= last_interrupt_mask; |
end |
else begin |
interrupt_mask_o <= 3'b000; |
last_interrupt_mask <= 3'b000; |
end |
end |
|
// change pc_i in middle of prefetch operation: undefined |
|
always @(posedge CLK_I) begin |
if(RST_I == 1'b1) begin |
current_state <= S_INIT; |
interrupt_trap_o <= 8'd0; |
prefetch_ir_valid_o <= 1'b0; |
prefetch_ir_valid_32_o <= 1'b0; |
prefetch_ir_valid_80_o <= 1'b0; |
|
jmp_address_trap_o <= 1'b0; |
jmp_bus_trap_o <= 1'b0; |
|
CYC_O <= 1'b0; |
ADR_O <= 30'd0; |
DAT_O <= 32'd0; |
SEL_O <= 4'b0; |
STB_O <= 1'b0; |
WE_O <= 1'b0; |
SGL_O <= 1'b0; |
BLK_O <= 1'b0; |
RMW_O <= 1'b0; |
CTI_O <= 3'd0; |
fc_o <= 3'd0; |
reset_o <= 1'b0; |
blocked_o <= 1'b0; |
data_read_o <= 32'd0; |
finished_o <= 1'b0; |
rw_state_o <= 1'b0; |
fc_state_o <= 3'd0; |
fault_address_state_o <= 32'd0; |
saved_pc_change <= 2'b0; |
reset_counter <= 8'd0; |
end |
else begin |
case(current_state) |
S_INIT: begin |
finished_o <= 1'b0; |
jmp_address_trap_o <= 1'b0; |
jmp_bus_trap_o <= 1'b0; |
reset_o <= 1'b0; |
blocked_o <= 1'b0; |
|
// block |
if(do_blocked_i == 1'b1) begin |
blocked_o <= 1'b1; |
current_state <= S_BLOCKED; |
end |
// reset |
else if(do_reset_i == 1'b1) begin |
reset_o <= 1'b1; |
reset_counter <= 8'd124; |
current_state <= S_RESET; |
end |
// read |
else if(do_read_i == 1'b1) begin |
WE_O <= 1'b0; |
if(supervisor_i == 1'b1) fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM; |
else fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM; |
|
if(address_i[0] == 1'b1 && (size_i == 2'b01 || size_i == 2'b10)) begin |
fault_address_state_o <= address_i; |
rw_state_o <= 1'b1; |
fc_state_o <= (supervisor_i == 1'b1) ? ((address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM) : |
((address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM); |
interrupt_trap_o <= VECTOR_ADDRESS_TRAP; |
|
jmp_address_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
else begin |
CYC_O <= 1'b1; |
ADR_O <= address_i[31:2]; |
SEL_O <= 4'b1111; |
STB_O <= 1'b1; |
|
if(read_modify_write_i == 1'b1) begin |
SGL_O <= 1'b0; |
BLK_O <= 1'b0; |
RMW_O <= 1'b1; |
CTI_O <= CTI_END_OF_BURST; |
end |
else if(address_i[1:0] == 2'b10 && size_i == 2'b10) begin |
SGL_O <= 1'b0; |
BLK_O <= 1'b1; |
RMW_O <= 1'b0; |
CTI_O <= CTI_INCR_CYCLE; |
end |
else begin |
SGL_O <= 1'b1; |
BLK_O <= 1'b0; |
RMW_O <= 1'b0; |
CTI_O <= CTI_END_OF_BURST; |
end |
|
current_state <= S_READ_1; |
end |
end |
// write |
else if(do_write_i == 1'b1) begin |
WE_O <= 1'b1; |
if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_DATA; |
else fc_o <= FC_USER_DATA; |
|
if(address_i[0] == 1'b1 && (size_i == 2'b01 || size_i == 2'b10)) begin |
fault_address_state_o <= address_i; |
rw_state_o <= 1'b0; |
fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_DATA : FC_USER_DATA; |
interrupt_trap_o <= VECTOR_ADDRESS_TRAP; |
|
jmp_address_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
else begin |
CYC_O <= 1'b1; |
ADR_O <= address_i[31:2]; |
STB_O <= 1'b1; |
|
if(address_i[1:0] == 2'b10 && size_i == 2'b10) begin |
DAT_O <= { 16'b0, data_write_i[31:16] }; |
SEL_O <= 4'b0011; |
end |
else if(address_i[1:0] == 2'b00 && size_i == 2'b10) begin |
DAT_O <= data_write_i[31:0]; |
SEL_O <= 4'b1111; |
end |
else if(address_i[1:0] == 2'b10 && size_i == 2'b01) begin |
DAT_O <= { 16'b0, data_write_i[15:0] }; |
SEL_O <= 4'b0011; |
end |
else if(address_i[1:0] == 2'b00 && size_i == 2'b01) begin |
DAT_O <= { data_write_i[15:0], 16'b0 }; |
SEL_O <= 4'b1100; |
end |
else if(address_i[1:0] == 2'b11 && size_i == 2'b00) begin |
DAT_O <= { 24'b0, data_write_i[7:0] }; |
SEL_O <= 4'b0001; |
end |
else if(address_i[1:0] == 2'b10 && size_i == 2'b00) begin |
DAT_O <= { 16'b0, data_write_i[7:0], 8'b0 }; |
SEL_O <= 4'b0010; |
end |
else if(address_i[1:0] == 2'b01 && size_i == 2'b00) begin |
DAT_O <= { 8'b0, data_write_i[7:0], 16'b0 }; |
SEL_O <= 4'b0100; |
end |
else if(address_i[1:0] == 2'b00 && size_i == 2'b00) begin |
DAT_O <= { data_write_i[7:0], 24'b0 }; |
SEL_O <= 4'b1000; |
end |
|
if(read_modify_write_i == 1'b1) begin |
SGL_O <= 1'b0; |
BLK_O <= 1'b0; |
RMW_O <= 1'b1; |
CTI_O <= CTI_END_OF_BURST; |
end |
else if(address_i[1:0] == 2'b10 && size_i == 2'b10) begin |
SGL_O <= 1'b0; |
BLK_O <= 1'b1; |
RMW_O <= 1'b0; |
CTI_O <= CTI_INCR_CYCLE; |
end |
else begin |
SGL_O <= 1'b1; |
BLK_O <= 1'b0; |
RMW_O <= 1'b0; |
CTI_O <= CTI_END_OF_BURST; |
end |
|
current_state <= S_WRITE_1; |
end |
end |
// pc |
else if(prefetch_ir_valid_o == 1'b0 || pc_change_i != 2'b00) begin |
|
if(prefetch_ir_valid_o == 1'b0 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin |
// load 4 words: [79:16] in 2,3 cycles |
prefetch_ir_valid_32_o <= 1'b0; |
prefetch_ir_valid_o <= 1'b0; |
prefetch_ir_valid_80_o <= 1'b0; |
|
current_state <= S_PC_0; |
end |
else if(prefetch_ir_valid_80_o == 1'b0 && pc_change_i == 2'b01) begin |
// load 2 words: [31:0] in 1 cycle |
prefetch_ir_valid_32_o <= 1'b1; |
prefetch_ir_valid_o <= 1'b0; |
prefetch_ir_valid_80_o <= 1'b0; |
|
prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 }; |
current_state <= S_PC_0; |
end |
else begin |
// do not load any words |
prefetch_ir_valid_32_o <= 1'b1; |
prefetch_ir_valid_o <= 1'b1; |
prefetch_ir_valid_80_o <= 1'b0; |
|
prefetch_ir_o <= { prefetch_ir_o[63:0], 16'b0 }; |
end |
|
|
end |
// interrupt |
else if(do_interrupt_i == 1'b1) begin |
CYC_O <= 1'b1; |
ADR_O <= { 27'b111_1111_1111_1111_1111_1111_1111, last_interrupt_mask }; |
SEL_O <= 4'b1111; |
STB_O <= 1'b1; |
WE_O <= 1'b0; |
|
SGL_O <= 1'b1; |
BLK_O <= 1'b0; |
RMW_O <= 1'b0; |
CTI_O <= CTI_END_OF_BURST; |
|
fc_o <= FC_CPU_SPACE; |
|
current_state <= S_INT_1; |
end |
end |
|
S_RESET: begin |
reset_counter <= reset_counter - 8'd1; |
|
if(reset_counter == 8'd0) begin |
finished_o <= 1'b1; |
current_state <= S_WAIT; |
end |
end |
|
S_BLOCKED: begin |
end |
|
S_INT_1: begin |
if(ACK_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
interrupt_trap_o <= DAT_I[7:0]; |
|
finished_o <= 1'b1; |
current_state <= S_WAIT; |
end |
else if(RTY_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
interrupt_trap_o <= 8'd24 + { 5'b0, interrupt_mask_o }; |
|
finished_o <= 1'b1; |
current_state <= S_WAIT; |
end |
else if(ERR_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
interrupt_trap_o <= 8'd24; // spurious interrupt |
|
finished_o <= 1'b1; |
current_state <= S_WAIT; |
end |
end |
|
S_PC_0: begin |
WE_O <= 1'b0; |
if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM; |
else fc_o <= FC_USER_PROGRAM; |
|
if(pc_i[0] == 1'b1) begin |
prefetch_ir_valid_32_o <= 1'b1; |
prefetch_ir_valid_o <= 1'b1; |
prefetch_ir_valid_80_o <= 1'b1; |
|
fault_address_state_o <= pc_i; |
rw_state_o <= 1'b1; |
fc_state_o <= (supervisor_i == 1'b1) ? FC_SUPERVISOR_PROGRAM : FC_USER_PROGRAM; |
interrupt_trap_o <= VECTOR_ADDRESS_TRAP; |
|
jmp_address_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
else begin |
CYC_O <= 1'b1; |
if(prefetch_ir_valid_32_o == 1'b0) ADR_O <= pc_i[31:2]; |
else ADR_O <= pc_i_plus_6[31:2]; |
SEL_O <= 4'b1111; |
STB_O <= 1'b1; |
|
if(prefetch_ir_valid_32_o == 1'b0) begin |
SGL_O <= 1'b0; |
BLK_O <= 1'b1; |
RMW_O <= 1'b0; |
CTI_O <= CTI_INCR_CYCLE; |
end |
else begin |
SGL_O <= 1'b1; |
BLK_O <= 1'b0; |
RMW_O <= 1'b0; |
CTI_O <= CTI_END_OF_BURST; |
end |
|
saved_pc_change <= pc_change_i; |
prefetch_ir_valid_32_o <= 1'b0; |
|
current_state <= S_PC_1; |
end |
end |
|
S_PC_1: begin |
if(pc_change_i != 2'b00) saved_pc_change <= pc_change_i; |
|
if(ACK_I == 1'b1) begin |
if(CTI_O == CTI_INCR_CYCLE) begin |
//CYC_O <= 1'b1; |
ADR_O <= pc_i_plus_4[31:2]; |
//SEL_O <= 4'b1111; |
//STB_O <= 1'b1; |
//WE_O <= 1'b0; |
|
if(pc_i[1:0] == 2'b10) begin |
SGL_O <= 1'b0; |
BLK_O <= 1'b1; |
RMW_O <= 1'b0; |
CTI_O <= CTI_INCR_CYCLE; |
end |
else begin |
SGL_O <= 1'b0; |
BLK_O <= 1'b1; |
RMW_O <= 1'b0; |
CTI_O <= CTI_END_OF_BURST; |
end |
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM; |
//else fc_o <= FC_USER_PROGRAM; |
|
if(pc_i[1:0] == 2'b10) prefetch_ir_o <= { DAT_I[15:0], 64'b0 }; |
else prefetch_ir_o <= { DAT_I[31:0], 48'b0 }; |
|
current_state <= S_PC_3; |
end |
else begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
if(saved_pc_change == 2'b10 || saved_pc_change == 2'b11 || pc_change_i == 2'b10 || pc_change_i == 2'b11) begin |
// load 4 words: [79:16] in 2,3 cycles |
prefetch_ir_valid_32_o <= 1'b0; |
prefetch_ir_valid_o <= 1'b0; |
prefetch_ir_valid_80_o <= 1'b0; |
|
current_state <= S_PC_0; |
end |
else if(saved_pc_change == 2'b01 || pc_change_i == 2'b01) begin |
// do not load any words |
prefetch_ir_valid_32_o <= 1'b1; |
prefetch_ir_valid_o <= 1'b1; |
prefetch_ir_valid_80_o <= 1'b0; |
|
prefetch_ir_o <= { prefetch_ir_o[63:32], DAT_I[31:0], 16'b0 }; |
current_state <= S_INIT; |
end |
else begin |
prefetch_ir_valid_32_o <= 1'b1; |
prefetch_ir_valid_o <= 1'b1; |
prefetch_ir_valid_80_o <= 1'b1; |
|
prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] }; |
current_state <= S_INIT; |
end |
end |
end |
else if(RTY_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
current_state <= S_PC_2; |
end |
else if(ERR_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
fault_address_state_o <= { ADR_O, 2'b00 }; |
rw_state_o <= ~WE_O; |
fc_state_o <= fc_o; |
interrupt_trap_o <= VECTOR_BUS_TRAP; |
|
jmp_bus_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
end |
S_PC_2: begin |
CYC_O <= 1'b1; |
STB_O <= 1'b1; |
|
current_state <= S_PC_1; |
end |
S_PC_3: begin |
if(ACK_I == 1'b1) begin |
if(pc_i[1:0] == 2'b10) begin |
//CYC_O <= 1'b1; |
ADR_O <= pc_i_plus_6[31:2]; |
//SEL_O <= 4'b1111; |
//STB_O <= 1'b1; |
//WE_O <= 1'b0; |
|
SGL_O <= 1'b0; |
BLK_O <= 1'b1; |
RMW_O <= 1'b0; |
CTI_O <= CTI_END_OF_BURST; |
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_PROGRAM; |
//else fc_o <= FC_USER_PROGRAM; |
|
prefetch_ir_o <= { prefetch_ir_o[79:64], DAT_I[31:0], 32'b0 }; |
|
current_state <= S_PC_5; |
end |
else begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
prefetch_ir_o <= { prefetch_ir_o[79:48], DAT_I[31:0], 16'b0 }; |
|
prefetch_ir_valid_32_o <= 1'b1; |
prefetch_ir_valid_o <= 1'b1; |
prefetch_ir_valid_80_o <= 1'b0; |
current_state <= S_INIT; |
end |
end |
else if(RTY_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
current_state <= S_PC_4; |
end |
else if(ERR_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
fault_address_state_o <= { ADR_O, 2'b00 }; |
rw_state_o <= ~WE_O; |
fc_state_o <= fc_o; |
interrupt_trap_o <= VECTOR_BUS_TRAP; |
|
jmp_bus_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
end |
S_PC_4: begin |
CYC_O <= 1'b1; |
STB_O <= 1'b1; |
|
current_state <= S_PC_3; |
end |
S_PC_5: begin |
if(ACK_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
prefetch_ir_o <= { prefetch_ir_o[79:32], DAT_I[31:0] }; |
|
prefetch_ir_valid_32_o <= 1'b1; |
prefetch_ir_valid_o <= 1'b1; |
prefetch_ir_valid_80_o <= 1'b1; |
current_state <= S_INIT; |
end |
else if(RTY_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
current_state <= S_PC_6; |
end |
else if(ERR_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
fault_address_state_o <= { ADR_O, 2'b00 }; |
rw_state_o <= ~WE_O; |
fc_state_o <= fc_o; |
interrupt_trap_o <= VECTOR_BUS_TRAP; |
|
jmp_bus_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
end |
S_PC_6: begin |
CYC_O <= 1'b1; |
STB_O <= 1'b1; |
|
current_state <= S_PC_5; |
end |
|
//******************* |
S_READ_1: begin |
if(ACK_I == 1'b1) begin |
if(address_i[1:0] == 2'b10 && size_i == 2'b10) begin |
//CYC_O <= 1'b1; |
ADR_O <= address_i_plus_4[31:2]; |
//SEL_O <= 4'b1111; |
//STB_O <= 1'b1; |
//WE_O <= 1'b0; |
|
//SGL_O <= 1'b0; |
//BLK_O <= 1'b1; |
//RMW_O <= 1'b0; |
CTI_O <= CTI_END_OF_BURST; |
|
//if(supervisor_i == 1'b1) fc_o <= (address_type_i == 1'b0) ? FC_SUPERVISOR_DATA : FC_SUPERVISOR_PROGRAM; |
//else fc_o <= (address_type_i == 1'b0) ? FC_USER_DATA : FC_USER_PROGRAM; |
|
data_read_o <= { DAT_I[15:0], 16'b0 }; |
|
current_state <= S_READ_2; |
end |
else begin |
if(read_modify_write_i == 1'b1) begin |
CYC_O <= 1'b1; |
STB_O <= 1'b0; |
end |
else begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
end |
|
if(address_i[1:0] == 2'b00 && size_i == 2'b10) data_read_o <= DAT_I[31:0]; |
else if(address_i[1:0] == 2'b10 && size_i == 2'b01) data_read_o <= { {16{DAT_I[15]}}, DAT_I[15:0] }; |
else if(address_i[1:0] == 2'b00 && size_i == 2'b01) data_read_o <= { {16{DAT_I[31]}}, DAT_I[31:16] }; |
else if(address_i[1:0] == 2'b11 && size_i == 2'b00) data_read_o <= { {24{DAT_I[7]}}, DAT_I[7:0] }; |
else if(address_i[1:0] == 2'b10 && size_i == 2'b00) data_read_o <= { {24{DAT_I[15]}}, DAT_I[15:8] }; |
else if(address_i[1:0] == 2'b01 && size_i == 2'b00) data_read_o <= { {24{DAT_I[23]}}, DAT_I[23:16] }; |
else if(address_i[1:0] == 2'b00 && size_i == 2'b00) data_read_o <= { {24{DAT_I[31]}}, DAT_I[31:24] }; |
|
finished_o <= 1'b1; |
current_state <= S_WAIT; |
end |
end |
else if(RTY_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
current_state <= S_INIT; |
end |
else if(ERR_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
fault_address_state_o <= { ADR_O, 2'b00 }; |
rw_state_o <= ~WE_O; |
fc_state_o <= fc_o; |
interrupt_trap_o <= VECTOR_BUS_TRAP; |
|
jmp_bus_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
end |
S_READ_2: begin |
if(ACK_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
data_read_o <= { data_read_o[31:16], DAT_I[31:16] }; |
|
finished_o <= 1'b1; |
current_state <= S_WAIT; |
|
end |
else if(RTY_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
current_state <= S_READ_3; |
end |
else if(ERR_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
fault_address_state_o <= { ADR_O, 2'b00 }; |
rw_state_o <= ~WE_O; |
fc_state_o <= fc_o; |
interrupt_trap_o <= VECTOR_BUS_TRAP; |
|
jmp_bus_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
|
end |
S_READ_3: begin |
CYC_O <= 1'b1; |
STB_O <= 1'b1; |
|
current_state <= S_READ_2; |
end |
|
|
S_WAIT: begin |
jmp_address_trap_o <= 1'b0; |
jmp_bus_trap_o <= 1'b0; |
|
if(do_read_i == 1'b0 && do_write_i == 1'b0 && do_interrupt_i == 1'b0 && do_reset_i == 1'b0) begin |
finished_o <= 1'b0; |
current_state <= S_INIT; |
end |
end |
|
//********************** |
S_WRITE_1: begin |
if(ACK_I == 1'b1) begin |
if(address_i[1:0] == 2'b10 && size_i == 2'b10) begin |
//CYC_O <= 1'b1; |
ADR_O <= address_i_plus_4[31:2]; |
//STB_O <= 1'b1; |
//WE_O <= 1'b1; |
|
DAT_O <= { data_write_i[15:0], 16'b0 }; |
SEL_O <= 4'b1100; |
|
//SGL_O <= 1'b0; |
//BLK_O <= 1'b1; |
//RMW_O <= 1'b0; |
CTI_O <= CTI_END_OF_BURST; |
|
//if(supervisor_i == 1'b1) fc_o <= FC_SUPERVISOR_DATA; |
//else fc_o <= FC_USER_DATA; |
|
current_state <= S_WRITE_2; |
end |
else begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
finished_o <= 1'b1; |
current_state <= S_WAIT; |
end |
end |
else if(RTY_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
current_state <= S_INIT; |
end |
else if(ERR_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
fault_address_state_o <= { ADR_O, 2'b00 }; |
rw_state_o <= ~WE_O; |
fc_state_o <= fc_o; |
interrupt_trap_o <= VECTOR_BUS_TRAP; |
|
jmp_bus_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
|
end |
S_WRITE_2: begin |
if(ACK_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
finished_o <= 1'b1; |
current_state <= S_WAIT; |
|
end |
else if(RTY_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
current_state <= S_WRITE_3; |
end |
else if(ERR_I == 1'b1) begin |
CYC_O <= 1'b0; |
STB_O <= 1'b0; |
|
fault_address_state_o <= { ADR_O, 2'b00 }; |
rw_state_o <= ~WE_O; |
fc_state_o <= fc_o; |
interrupt_trap_o <= VECTOR_BUS_TRAP; |
|
jmp_bus_trap_o <= 1'b1; |
current_state <= S_WAIT; |
end |
|
end |
S_WRITE_3: begin |
CYC_O <= 1'b1; |
STB_O <= 1'b1; |
|
current_state <= S_WRITE_2; |
end |
|
endcase |
end |
end |
|
endmodule |
|
/*********************************************************************************************************************** |
* Registers |
**********************************************************************************************************************/ |
|
/*! \brief Microcode controlled registers. |
* |
* Most of the ao68000 IP core registers are located in this module. At every clock cycle the microcode controls what |
* to save into these registers. Some of the most important registers include: |
* - operand1, operand2 registers are inputs to the ALU, |
* - address, size, do_read_flag, do_write_flag, do_interrupt_flag registers tell the bus_control module what kind |
* of bus cycle to perform, |
* - pc register stores the current program counter, |
* - ir register stores the current instruction word, |
* - ea_mod, ea_type registers store the currently selected addressing mode. |
*/ |
module registers( |
input clock, |
input reset, |
|
input [31:0] data_read, |
input [79:0] prefetch_ir, |
input prefetch_ir_valid, |
input [31:0] result, |
input [15:0] sr, |
input rw_state, |
input [2:0] fc_state, |
input [31:0] fault_address_state, |
input [7:0] interrupt_trap, |
input [2:0] interrupt_mask, |
input [7:0] decoder_trap, |
|
input [31:0] usp, |
input [31:0] Dn_output, |
input [31:0] An_output, |
|
output [1:0] pc_change, |
|
output reg [2:0] ea_reg, |
input [2:0] ea_reg_control, |
|
output reg [2:0] ea_mod, |
input [3:0] ea_mod_control, |
|
output reg [3:0] ea_type, |
input [3:0] ea_type_control, |
|
// for DIVU/DIVS simulation, register must be not zero |
output reg [31:0] operand1 = 32'hFFFFFFFF, |
input [3:0] operand1_control, |
|
output reg [31:0] operand2 = 32'hFFFFFFFF, |
input [2:0] operand2_control, |
|
output reg [31:0] address, |
output reg address_type, |
input [3:0] address_control, |
|
output reg [1:0] size, |
input [3:0] size_control, |
|
output reg [5:0] movem_modreg, |
input [2:0] movem_modreg_control, |
|
output reg [4:0] movem_loop, |
input [1:0] movem_loop_control, |
|
output reg [15:0] movem_reg, |
input [1:0] movem_reg_control, |
|
output reg [15:0] ir, |
input [1:0] ir_control, |
|
output reg [31:0] pc, |
input [2:0] pc_control, |
|
output reg [7:0] trap, |
input [3:0] trap_control, |
|
output reg [31:0] offset, |
input [1:0] offset_control, |
|
output reg [31:0] index, |
input [1:0] index_control, |
|
|
output reg stop_flag, |
input [1:0] stop_flag_control, |
|
output reg trace_flag, |
input [1:0] trace_flag_control, |
|
output reg group_0_flag, |
input [1:0] group_0_flag_control, |
|
output reg instruction_flag, |
input [1:0] instruction_flag_control, |
|
output reg read_modify_write_flag, |
input [1:0] read_modify_write_flag_control, |
|
output reg do_reset_flag, |
input [1:0] do_reset_flag_control, |
|
output reg do_interrupt_flag, |
input [1:0] do_interrupt_flag_control, |
|
output reg do_read_flag, |
input [1:0] do_read_flag_control, |
|
output reg do_write_flag, |
input [1:0] do_write_flag_control, |
|
output reg do_blocked_flag, |
input [1:0] do_blocked_flag_control, |
|
output reg [31:0] data_write, |
input [1:0] data_write_control, |
|
|
output [3:0] An_address, |
input [1:0] An_address_control, |
|
output [31:0] An_input, |
input [1:0] An_input_control, |
|
output [2:0] Dn_address, |
input Dn_address_control |
); |
|
always @(posedge clock) begin |
if(reset) size <= 2'b00; |
else if(size_control == `SIZE_BYTE) size <= 2'b00; |
else if(size_control == `SIZE_WORD) size <= 2'b01; |
else if(size_control == `SIZE_LONG) size <= 2'b10; |
else if(size_control == `SIZE_1) size <= ( ir[7:6] == 2'b00 ) ? 2'b01 : 2'b10; |
else if(size_control == `SIZE_1_PLUS) size <= ( ir[7:6] == 2'b10 ) ? 2'b01 : 2'b10; |
else if(size_control == `SIZE_2) size <= ( ir[6] == 1'b0 ) ? 2'b01 : 2'b10; |
else if(size_control == `SIZE_3) size <= ( ir[7:6] == 2'b00 ) ? 2'b00 : ( ( ir[7:6] == 2'b01 ) ? 2'b01 : 2'b10 ); |
else if(size_control == `SIZE_4) size <= ( ir[13:12] == 2'b01 ) ? 2'b00 : ( ( ir[13:12] == 2'b11 ) ? 2'b01 : 2'b10 ); |
else if(size_control == `SIZE_5) size <= ( ir[8] == 1'b0 ) ? 2'b01 : 2'b10; |
else if(size_control == `SIZE_6) size <= ( ir[5:3] != 3'b000 ) ? 2'b00 : 2'b10; |
end |
|
always @(posedge clock) begin |
if(reset) ea_reg <= 3'b000; |
else if(ea_reg_control == `EA_REG_IR_2_0) ea_reg <= ir[2:0]; |
else if(ea_reg_control == `EA_REG_IR_11_9) ea_reg <= ir[11:9]; |
else if(ea_reg_control == `EA_REG_MOVEM_REG_2_0) ea_reg <= movem_modreg[2:0]; |
else if(ea_reg_control == `EA_REG_3b111) ea_reg <= 3'b111; |
else if(ea_reg_control == `EA_REG_3b100) ea_reg <= 3'b100; |
end |
|
always @(posedge clock) begin |
if(reset) ea_mod <= 3'd000; |
else if(ea_mod_control == `EA_MOD_IR_5_3) ea_mod <= ir[5:3]; |
else if(ea_mod_control == `EA_MOD_MOVEM_MOD_5_3) ea_mod <= movem_modreg[5:3]; |
else if(ea_mod_control == `EA_MOD_IR_8_6) ea_mod <= ir[8:6]; |
else if(ea_mod_control == `EA_MOD_PREDEC) ea_mod <= 3'b100; |
else if(ea_mod_control == `EA_MOD_3b111) ea_mod <= 3'b111; |
else if(ea_mod_control == `EA_MOD_DN_PREDEC) ea_mod <= (ir[3] == 1'b0) ? /* Dn */ 3'b000 : /* -(An) */ 3'b100; |
else if(ea_mod_control == `EA_MOD_DN_AN_EXG) ea_mod <= (ir[7:3] == 5'b01000 || ir[7:3] == 5'b10001) ? /* Dn */ 3'b000 : /* An */ 3'b001; |
else if(ea_mod_control == `EA_MOD_POSTINC) ea_mod <= 3'b011; |
else if(ea_mod_control == `EA_MOD_AN) ea_mod <= 3'b001; |
else if(ea_mod_control == `EA_MOD_DN) ea_mod <= 3'b000; |
else if(ea_mod_control == `EA_MOD_INDIRECTOFFSET) ea_mod <= 3'b101; |
end |
|
always @(posedge clock) begin |
if(reset) ea_type <= `EA_TYPE_IDLE; |
else if(ea_type_control == `EA_TYPE_ALL) ea_type <= `EA_TYPE_ALL; |
else if(ea_type_control == `EA_TYPE_CONTROL_POSTINC) ea_type <= `EA_TYPE_CONTROL_POSTINC; |
else if(ea_type_control == `EA_TYPE_CONTROLALTER_PREDEC) ea_type <= `EA_TYPE_CONTROLALTER_PREDEC; |
else if(ea_type_control == `EA_TYPE_CONTROL) ea_type <= `EA_TYPE_CONTROL; |
else if(ea_type_control == `EA_TYPE_DATAALTER) ea_type <= `EA_TYPE_DATAALTER; |
else if(ea_type_control == `EA_TYPE_DN_AN) ea_type <= `EA_TYPE_DN_AN; |
else if(ea_type_control == `EA_TYPE_MEMORYALTER) ea_type <= `EA_TYPE_MEMORYALTER; |
else if(ea_type_control == `EA_TYPE_DATA) ea_type <= `EA_TYPE_DATA; |
end |
|
always @(posedge clock) begin |
if(reset) operand1 <= 32'hFFFFFFFF; |
else if(operand1_control == `OP1_FROM_OP2) operand1 <= operand2; |
else if(operand1_control == `OP1_FROM_ADDRESS) operand1 <= address; |
else if(operand1_control == `OP1_FROM_DATA) operand1 <= |
(size == 2'b00) ? { {24{data_read[7]}}, data_read[7:0] } : |
(size == 2'b01) ? { {16{data_read[15]}}, data_read[15:0] } : |
data_read[31:0]; |
else if(operand1_control == `OP1_FROM_IMMEDIATE) operand1 <= |
(size == 2'b00) ? { {24{prefetch_ir[71]}}, prefetch_ir[71:64] } : |
(size == 2'b01) ? { {16{prefetch_ir[79]}}, prefetch_ir[79:64] } : |
prefetch_ir[79:48]; |
else if(operand1_control == `OP1_FROM_RESULT) operand1 <= result; |
else if(operand1_control == `OP1_MOVEQ) operand1 <= { {24{ir[7]}}, ir[7:0] }; |
else if(operand1_control == `OP1_FROM_PC) operand1 <= pc_valid; |
else if(operand1_control == `OP1_LOAD_ZEROS) operand1 <= 32'b0; |
else if(operand1_control == `OP1_LOAD_ONES) operand1 <= 32'hFFFFFFFF; |
else if(operand1_control == `OP1_FROM_SR) operand1 <= { 16'b0, sr[15], 1'b0, sr[13], 2'b0, sr[10:8], 3'b0, sr[4:0] }; |
else if(operand1_control == `OP1_FROM_USP) operand1 <= usp; |
else if(operand1_control == `OP1_FROM_AN) operand1 <= |
(size == 2'b01) ? { {16{An_output[15]}}, An_output[15:0] } : |
An_output[31:0]; |
else if(operand1_control == `OP1_FROM_DN) operand1 <= |
(size == 2'b00) ? { {24{Dn_output[7]}}, Dn_output[7:0] } : |
(size == 2'b01) ? { {16{Dn_output[15]}}, Dn_output[15:0] } : |
Dn_output[31:0]; |
else if(operand1_control == `OP1_FROM_IR) operand1 <= { 16'b0, ir[15:0] }; |
else if(operand1_control == `OP1_FROM_FAULT_ADDRESS) operand1 <= fault_address_state; |
end |
|
always @(posedge clock) begin |
if(reset) operand2 <= 32'hFFFFFFFF; |
else if(operand2_control == `OP2_FROM_OP1) operand2 <= operand1; |
else if(operand2_control == `OP2_LOAD_1) operand2 <= 32'd1; |
else if(operand2_control == `OP2_LOAD_COUNT) operand2 <= |
(ir[5] == 1'b0) ? ( (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] } ) : |
{ 26'b0, operand2[5:0] }; |
else if(operand2_control == `OP2_ADDQ_SUBQ) operand2 <= (ir[11:9] == 3'b000) ? 32'b1000 : { 29'b0, ir[11:9] }; |
else if(operand2_control == `OP2_MOVE_OFFSET) operand2 <= (ir[7:0] == 8'b0) ? operand2[31:0] : { {24{ir[7]}}, ir[7:0] }; |
else if(operand2_control == `OP2_MOVE_ADDRESS_BUS_INFO) operand2 <= { 16'b0, 11'b0, rw_state, instruction_flag, fc_state}; |
else if(operand2_control == `OP2_DECR_BY_1) operand2 <= operand2 - 32'b1; |
end |
|
always @(posedge clock) begin |
if(reset) address <= 32'b0; |
else if(address_control == `ADDRESS_INCR_BY_SIZE) address <= |
(size == 2'b00 && ea_reg != 3'b111) ? address + 32'd1 : |
(size == 2'b01 || (size == 2'b00 && ea_reg == 3'b111)) ? address + 32'd2 : |
(size == 2'b10) ? address + 32'd4 : |
address; |
else if(address_control == `ADDRESS_DECR_BY_SIZE) address <= |
(size == 2'b00 && ea_reg != 3'b111) ? address - 32'd1 : |
(size == 2'b01 || (size == 2'b00 && ea_reg == 3'b111)) ? address - 32'd2 : |
(size == 2'b10) ? address - 32'd4 : |
address; |
else if(address_control == `ADDRESS_INCR_BY_2) address <= address + 32'd2; |
else if(address_control == `ADDRESS_FROM_AN_OUTPUT) address <= An_output; |
else if(address_control == `ADDRESS_FROM_BASE_INDEX_OFFSET) address <= address + index + offset; |
else if(address_control == `ADDRESS_FROM_IMM_16) address <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] }; |
else if(address_control == `ADDRESS_FROM_IMM_32) address <= prefetch_ir[79:48]; |
else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET) address <= pc_valid + index + offset; |
else if(address_control == `ADDRESS_FROM_TRAP) address <= {22'b0, trap[7:0], 2'b0}; |
end |
|
always @(posedge clock) begin |
if(reset) address_type <= 1'b0; |
else if(address_control == `ADDRESS_FROM_PC_INDEX_OFFSET) address_type <= 1'b1; |
else if(address_control != `ADDRESS_IDLE) address_type <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) movem_modreg <= 6'b0; |
else if(movem_modreg_control == `MOVEM_MODREG_LOAD_0) movem_modreg <= 6'b0; |
else if(movem_modreg_control == `MOVEM_MODREG_LOAD_6b001111) movem_modreg <= 6'b001111; |
else if(movem_modreg_control == `MOVEM_MODREG_INCR_BY_1) movem_modreg <= movem_modreg + 6'd1; |
else if(movem_modreg_control == `MOVEM_MODREG_DECR_BY_1) movem_modreg <= movem_modreg - 6'd1; |
end |
|
always @(posedge clock) begin |
if(reset) movem_loop <= 5'b0; |
else if(movem_loop_control == `MOVEM_LOOP_LOAD_0) movem_loop <= 5'b0; |
else if(movem_loop_control == `MOVEM_LOOP_INCR_BY_1) movem_loop <= movem_loop + 5'd1; |
end |
|
always @(posedge clock) begin |
if(reset) movem_reg <= 16'b0; |
else if(movem_reg_control == `MOVEM_REG_FROM_OP1) movem_reg <= operand1[15:0]; |
else if(movem_reg_control == `MOVEM_REG_SHIFT_RIGHT) movem_reg <= { 1'b0, movem_reg[15:1] }; |
end |
|
always @(posedge clock) begin |
if(reset) ir <= 16'b0; |
else if(ir_control == `IR_LOAD_WHEN_PREFETCH_VALID && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0) |
ir <= prefetch_ir[79:64]; |
end |
|
reg [31:0] pc_valid; |
|
// pc_change connected |
always @(posedge clock) begin |
if(reset) pc = 32'd0; |
else if(pc_control == `PC_FROM_RESULT) pc = result; |
else if(pc_control == `PC_INCR_BY_2) pc = pc + 32'd2; |
else if(pc_control == `PC_INCR_BY_4) pc = pc + 32'd4; |
else if(pc_control == `PC_INCR_BY_SIZE) pc = (size == 2'b00 || size == 2'b01) ? pc + 32'd2 : pc + 32'd4; |
else if(pc_control == `PC_FROM_PREFETCH_IR) pc = prefetch_ir[47:16]; |
else if(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0) |
pc = pc + 32'd2; |
if(reset) pc_valid <= 32'd0; |
else if(pc[0] == 1'b0) pc_valid <= pc; |
end |
|
assign pc_change = |
( pc_control == `PC_INCR_BY_2 || (pc_control == `PC_INCR_BY_SIZE && (size == 2'b00 || size == 2'b01)) || |
(pc_control == `PC_INCR_BY_2_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0) |
) ? 2'b01 : |
( pc_control == `PC_INCR_BY_4 || (pc_control == `PC_INCR_BY_SIZE && size == 2'b10) |
) ? 2'b10 : |
( pc_control == `PC_FROM_RESULT || pc_control == `PC_FROM_PREFETCH_IR |
) ? 2'b11 : |
2'b00; |
|
always @(posedge clock) begin |
if(reset) trap <= 8'd0; |
else if(trap_control == `TRAP_ILLEGAL_INSTR) trap <= 8'd4; |
else if(trap_control == `TRAP_DIV_BY_ZERO) trap <= 8'd5; |
else if(trap_control == `TRAP_CHK) trap <= 8'd6; |
else if(trap_control == `TRAP_TRAPV) trap <= 8'd7; |
else if(trap_control == `TRAP_PRIVIL_VIOLAT) trap <= 8'd8; |
else if(trap_control == `TRAP_TRACE) trap <= 8'd9; |
else if(trap_control == `TRAP_TRAP) trap <= { 4'b0010, ir[3:0] }; |
else if(trap_control == `TRAP_FROM_DECODER) trap <= decoder_trap; |
else if(trap_control == `TRAP_FROM_INTERRUPT) trap <= interrupt_trap; |
end |
|
always @(posedge clock) begin |
if(reset) offset <= 32'd0; |
else if(offset_control == `OFFSET_IMM_8) offset <= { {24{prefetch_ir[71]}}, prefetch_ir[71:64] }; |
else if(offset_control == `OFFSET_IMM_16) offset <= { {16{prefetch_ir[79]}}, prefetch_ir[79:64] }; |
end |
|
always @(posedge clock) begin |
if(reset) index <= 32'd0; |
else if(index_control == `INDEX_0) index <= 32'd0; |
else if(index_control == `INDEX_LOAD_EXTENDED) index <= |
(prefetch_ir[79] == 1'b0) ? |
( (prefetch_ir[75] == 1'b0) ? |
{ {16{Dn_output[15]}}, Dn_output[15:0] } : Dn_output[31:0] |
) : |
( (prefetch_ir[75] == 1'b0) ? |
{ {16{An_output[15]}}, An_output[15:0] } : An_output[31:0] |
); |
end |
|
always @(posedge clock) begin |
if(reset) stop_flag <= 1'b0; |
else if(stop_flag_control == `STOP_FLAG_SET) stop_flag <= 1'b1; |
else if(stop_flag_control == `STOP_FLAG_CLEAR) stop_flag <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) trace_flag <= 1'b0; |
else if(trace_flag_control == `TRACE_FLAG_COPY_WHEN_NO_STOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0) |
trace_flag <= sr[15]; |
end |
|
always @(posedge clock) begin |
if(reset) group_0_flag <= 1'b0; |
else if(group_0_flag_control == `GROUP_0_FLAG_SET) group_0_flag <= 1'b1; |
else if(group_0_flag_control == `GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH && prefetch_ir_valid == 1'b1 && stop_flag == 1'b0) |
group_0_flag <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) instruction_flag <= 1'b0; |
else if(instruction_flag_control == `INSTRUCTION_FLAG_SET) instruction_flag <= 1'b1; |
else if(instruction_flag_control == `INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0 && stop_flag == 1'b0) |
instruction_flag <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) read_modify_write_flag <= 1'b0; |
else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_SET) read_modify_write_flag <= 1'b1; |
else if(read_modify_write_flag_control == `READ_MODIFY_WRITE_FLAG_CLEAR) read_modify_write_flag <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) do_reset_flag <= 1'b0; |
else if(do_reset_flag_control == `DO_RESET_FLAG_SET) do_reset_flag <= 1'b1; |
else if(do_reset_flag_control == `DO_RESET_FLAG_CLEAR) do_reset_flag <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) do_interrupt_flag <= 1'b0; |
else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_SET_IF_ACTIVE) do_interrupt_flag <= (interrupt_mask != 3'b000) ? 1'b1 : 1'b0; |
else if(do_interrupt_flag_control == `DO_INTERRUPT_FLAG_CLEAR) do_interrupt_flag <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) do_read_flag <= 1'b0; |
else if(do_read_flag_control == `DO_READ_FLAG_SET) do_read_flag <= 1'b1; |
else if(do_read_flag_control == `DO_READ_FLAG_CLEAR) do_read_flag <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) do_write_flag <= 1'b0; |
else if(do_write_flag_control == `DO_WRITE_FLAG_SET) do_write_flag <= 1'b1; |
else if(do_write_flag_control == `DO_WRITE_FLAG_CLEAR) do_write_flag <= 1'b0; |
end |
|
always @(posedge clock) begin |
if(reset) do_blocked_flag <= 1'b0; |
else if(do_blocked_flag_control == `DO_BLOCKED_FLAG_SET) do_blocked_flag <= 1'b1; |
end |
|
always @(posedge clock) begin |
if(reset) data_write <= 32'd0; |
else if(data_write_control == `DATA_WRITE_FROM_RESULT) data_write <= result; |
end |
|
assign An_address = |
(An_address_control == `AN_ADDRESS_FROM_EXTENDED) ? { sr[13], prefetch_ir[78:76] } : |
(An_address_control == `AN_ADDRESS_USP) ? 4'b0111 : |
(An_address_control == `AN_ADDRESS_SSP) ? 4'b1111 : |
{ sr[13], ea_reg }; |
|
assign An_input = |
(An_input_control == `AN_INPUT_FROM_ADDRESS) ? address : |
(An_input_control == `AN_INPUT_FROM_PREFETCH_IR) ? prefetch_ir[79:48] : |
result; |
|
assign Dn_address = (Dn_address_control == `DN_ADDRESS_FROM_EXTENDED) ? prefetch_ir[78:76] : ea_reg; |
|
endmodule |
|
/*********************************************************************************************************************** |
* Memory registers |
**********************************************************************************************************************/ |
|
/*! \brief Contains the microcode ROM and D0-D7, A0-A7 registers. |
* |
* The memory_registers module contains: |
* - data and address registers (D0-D7, A0-A7) implemented as an on-chip RAM. |
* - the microcode implemented as an on-chip ROM. |
*/ |
module memory_registers( |
input clock, |
input reset, |
|
// 0000,0001,0010,0011,0100,0101,0110: A0-A6, 0111: USP, 1111: SSP |
input [3:0] An_address, |
input [31:0] An_input, |
input An_write_enable, |
output [31:0] An_output, |
|
output reg [31:0] usp, |
|
input [2:0] Dn_address, |
input [31:0] Dn_input, |
input Dn_write_enable, |
// 00: byte, 01: word, 10: long |
input [1:0] Dn_size, |
output [31:0] Dn_output, |
|
input [8:0] micro_pc, |
output [87:0] micro_data |
); |
|
wire An_ram_write_enable; |
assign An_ram_write_enable = (An_address == 4'b0111) ? 1'b0 : |
An_write_enable; |
|
wire [31:0] An_ram_output; |
assign An_output = (An_address == 4'b0111) ? usp : |
An_ram_output; |
|
register_ram an_ram( |
.clock(clock), |
|
.address(An_address[2:0]), |
.byte_enable(4'b1111), |
.write_enable(An_ram_write_enable), |
.data_input(An_input), |
.data_output(An_ram_output) |
); |
|
always @(posedge clock) begin |
if(reset == 1'b1) usp <= 32'd0; |
else if(An_address == 4'b0111 && An_write_enable) usp <= An_input; |
end |
|
register_ram dn_ram( |
.clock(clock), |
|
.address(Dn_address), |
.byte_enable(dn_byteena), |
.write_enable(Dn_write_enable), |
.data_input(Dn_input), |
.data_output(Dn_output) |
); |
|
wire [3:0] dn_byteena; |
assign dn_byteena = (Dn_size == 2'b00) ? 4'b0001 : |
(Dn_size == 2'b01) ? 4'b0011 : |
(Dn_size == 2'b10) ? 4'b1111 : |
4'b0000; |
|
microcode_rom micro_rom( |
.clock(clock), |
|
.micro_pc(micro_pc), |
.micro_data(micro_data) |
); |
|
endmodule |
|
/*********************************************************************************************************************** |
* Instruction decoder |
**********************************************************************************************************************/ |
|
/*! \brief Decode instruction and addressing mode. |
* |
* The decoder is an instruction and addressing mode decoder. For instructions it takes as input the ir register |
* from the registers module. The output of the decoder, in this case, is a microcode address of the first microcode |
* word that performs the instruction. |
* |
* In case of addressing mode decoding, the output is the address of the first microcode word that performs the operand |
* loading or saving. This address is obtained from the currently selected addressing mode saved in the ea_mod |
* and ea_type registers in the registers module. |
*/ |
module decoder( |
input clock, |
input reset, |
|
input supervisor, |
input [15:0] ir, |
|
// zero: no trap |
output [7:0] decoder_trap, |
output [8:0] decoder_micropc, |
|
output [8:0] save_ea, |
output [8:0] perform_ea_write, |
output [8:0] perform_ea_read, |
output [8:0] load_ea, |
|
input [3:0] ea_type, |
input [2:0] ea_mod, |
input [2:0] ea_reg |
); |
|
parameter [7:0] |
NO_TRAP = 8'd0, |
ILLEGAL_INSTRUCTION_TRAP = 8'd4, |
PRIVILEGE_VIOLATION_TRAP = 8'd8, |
ILLEGAL_1010_INSTRUCTION_TRAP = 8'd10, |
ILLEGAL_1111_INSTRUCTION_TRAP = 8'd11; |
|
parameter [8:0] |
UNUSED_MICROPC = 9'd0; |
|
assign { decoder_trap, decoder_micropc } = |
(reset == 1'b1) ? { NO_TRAP, UNUSED_MICROPC } : |
|
// Privilege violation and illegal instruction |
|
// ANDI to SR,EORI to SR,ORI to SR,RESET,STOP,RTE,MOVE TO SR,MOVE USP TO USP,MOVE USP TO An privileged instructions |
( ( ir[15:0] == 16'b0000_0010_01_111_100 || |
ir[15:0] == 16'b0000_1010_01_111_100 || |
ir[15:0] == 16'b0000_0000_01_111_100 || |
ir[15:0] == 16'b0100_1110_0111_0000 || |
ir[15:0] == 16'b0100_1110_0111_0010 || |
ir[15:0] == 16'b0100_1110_0111_0011 || |
(ir[15:6] == 10'b0100_0110_11 && ir[5:3] != 3'b001 && ir[5:0] != 6'b111_101 && ir[5:0] != 6'b111_110 && ir[5:0] != 6'b111_111) || |
ir[15:3] == 13'b0100_1110_0110_0 || |
ir[15:3] == 13'b0100_1110_0110_1 ) && supervisor == 1'b0 ) ? { PRIVILEGE_VIOLATION_TRAP, UNUSED_MICROPC } : |
// ILLEGAL, illegal instruction |
( ir[15:0] == 16'b0100_1010_11_111100 ) ? { ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC } : |
// 1010 illegal instruction |
( ir[15:12] == 4'b1010 ) ? { ILLEGAL_1010_INSTRUCTION_TRAP, UNUSED_MICROPC } : |
// 1111 illegal instruction |
( ir[15:12] == 4'b1111 ) ? { ILLEGAL_1111_INSTRUCTION_TRAP, UNUSED_MICROPC } : |
|
// instruction decoding |
|
// ANDI,EORI,ORI,ADDI,SUBI |
( ir[15:12] == 4'b0000 && ir[11:9] != 3'b100 && ir[11:9] != 3'b110 && ir[11:9] != 3'b111 && ir[8] == 1'b0 && |
(ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) && |
ir[15:0] != 16'b0000_000_0_00_111100 && ir[15:0] != 16'b0000_000_0_01_111100 && |
ir[15:0] != 16'b0000_001_0_00_111100 && ir[15:0] != 16'b0000_001_0_01_111100 && |
ir[15:0] != 16'b0000_101_0_00_111100 && ir[15:0] != 16'b0000_101_0_01_111100 ) ? { NO_TRAP, `MICROPC_ANDI_EORI_ORI_ADDI_SUBI } : |
// ORI to CCR,ORI to SR,ANDI to CCR,ANDI to SR,EORI to CCR,EORI to SR |
( ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_000_0_01_111100 || |
ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_001_0_01_111100 || |
ir[15:0] == 16'b0000_101_0_00_111100 || ir[15:0] == 16'b0000_101_0_01_111100 ) ? |
{ NO_TRAP, `MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR } : |
// BTST register |
( ir[15:12] == 4'b0000 && ir[8:6] == 3'b100 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_BTST_register } : |
// MOVEP memory to register |
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b00 || ir[7:6] == 2'b01 ) ) ? |
{ NO_TRAP, `MICROPC_MOVEP_memory_to_register } : |
// MOVEP register to memory |
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b10 || ir[7:6] == 2'b11 ) ) ? |
{ NO_TRAP, `MICROPC_MOVEP_register_to_memory } : |
// BCHG,BCLR,BSET register |
( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] != 3'b001 && ir[8:6] != 3'b100 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_register } : |
// BTST immediate |
( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] == 2'b00 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011)) |
) ? { NO_TRAP, `MICROPC_BTST_immediate } : |
// BCHG,BCLR,BSET immediate |
( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] != 2'b00 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_BCHG_BCLR_BSET_immediate } : |
// CMPI |
( ir[15:12] == 4'b0000 && ir[8] == 1'b0 && ir[11:9] == 3'b110 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_CMPI } : |
// MOVE |
( ir[15:14] == 2'b00 && ir[13:12] != 2'b00 && ir[8:6] != 3'b001 && |
(ir[8:6] != 3'b111 || (ir[11:6] == 6'b000_111 || ir[11:6] == 6'b001_111)) && |
(ir[13:12] != 2'b01 || ir[5:3] != 3'b001) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_MOVE } : |
// MOVEA |
( ir[15:14] == 2'b00 && (ir[13:12] == 2'b11 || ir[13:12] == 2'b10) && ir[8:6] == 3'b001 && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_MOVEA } : |
// NEGX,CLR,NEG,NOT,NBCD |
( ir[15:12] == 4'b0100 && ir[5:3] != 3'b001 && (ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001) && |
( (ir[11:8] == 4'b0000 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0010 && ir[7:6] != 2'b11) || |
(ir[11:8] == 4'b0100 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0110 && ir[7:6] != 2'b11) || |
(ir[11:6] == 6'b1000_00) |
) |
) ? { NO_TRAP, `MICROPC_NEGX_CLR_NEG_NOT_NBCD } : |
// MOVE FROM SR |
( ir[15:6] == 10'b0100_0000_11 && ir[5:3] != 3'b001 && (ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001) |
) ? { NO_TRAP, `MICROPC_MOVE_FROM_SR } : |
// CHK |
( ir[15:12] == 4'b0100 && ir[8:6] == 3'b110 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_CHK } : |
// LEA |
( ir[15:12] == 4'b0100 && ir[8:6] == 3'b111 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011)) |
) ? { NO_TRAP, `MICROPC_LEA } : |
// MOVE TO CCR, MOVE TO SR |
( (ir[15:6] == 10'b0100_0100_11 || ir[15:6] == 10'b0100_0110_11) && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_MOVE_TO_CCR_MOVE_TO_SR } : |
// SWAP,EXT |
( ir[15:12] == 4'b0100 && (ir[11:3] == 9'b1000_01_000 || (ir[11:7] == 5'b1000_1 && ir[5:3] == 3'b000) ) ) ? { NO_TRAP, `MICROPC_SWAP_EXT } : |
// PEA |
( ir[15:6] == 10'b0100_1000_01 && ir[5:3] != 3'b000 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011)) |
) ? { NO_TRAP, `MICROPC_PEA } : |
// MOVEM register to memory, predecrement |
( ir[15:7] == 9'b0100_1000_1 && ir[5:3] == 3'b100 ) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_predecrement } : |
// MOVEM register to memory, control |
( ir[15:7] == 9'b0100_1000_1 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) && |
(ir[5:3] != 3'b111 || ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001) |
) ? { NO_TRAP, `MICROPC_MOVEM_register_to_memory_control } : |
// TST |
( ir[15:8] == 8'b0100_1010 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_TST } : |
// TAS |
( ir[15:6] == 10'b0100_1010_11 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_TAS } : |
// MOVEM memory to register |
( ir[15:7] == 9'b0100_1100_1 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b011 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011)) |
) ? { NO_TRAP, `MICROPC_MOVEM_memory_to_register } : |
// TRAP |
( ir[15:4] == 12'b0100_1110_0100 ) ? { NO_TRAP, `MICROPC_TRAP } : |
// LINK |
( ir[15:3] == 13'b0100_1110_0101_0 ) ? { NO_TRAP, `MICROPC_LINK } : |
// UNLK |
( ir[15:3] == 13'b0100_1110_0101_1 ) ? { NO_TRAP, `MICROPC_ULNK } : |
// MOVE USP to USP |
( ir[15:3] == 13'b0100_1110_0110_0 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_USP } : |
// MOVE USP to An |
( ir[15:3] == 13'b0100_1110_0110_1 ) ? { NO_TRAP, `MICROPC_MOVE_USP_to_An } : |
// RESET |
( ir[15:0] == 16'b0100_1110_0111_0000 ) ? { NO_TRAP, `MICROPC_RESET } : |
// NOP |
( ir[15:0] == 16'b0100_1110_0111_0001 ) ? { NO_TRAP, `MICROPC_NOP } : |
// STOP |
( ir[15:0] == 16'b0100_1110_0111_0010 ) ? { NO_TRAP, `MICROPC_STOP } : |
// RTE,RTR |
( ir[15:0] == 16'b0100_1110_0111_0011 || ir[15:0] == 16'b0100_1110_0111_0111 ) ? { NO_TRAP, `MICROPC_RTE_RTR } : |
// RTS |
( ir[15:0] == 16'b0100_1110_0111_0101 ) ? { NO_TRAP, `MICROPC_RTS } : |
// TRAPV |
( ir[15:0] == 16'b0100_1110_0111_0110 ) ? { NO_TRAP, `MICROPC_TRAPV } : |
// JSR |
( ir[15:6] == 10'b0100_1110_10 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011)) |
) ? { NO_TRAP, `MICROPC_JSR } : |
// JMP |
( ir[15:6] == 10'b0100_1110_11 && (ir[5:3] == 3'b010 || ir[5:3] == 3'b101 || ir[5:3] == 3'b110 || ir[5:3] == 3'b111) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011)) |
) ? { NO_TRAP, `MICROPC_JMP } : |
// ADDQ,SUBQ not An |
( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_not_An } : |
// ADDQ,SUBQ An |
( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[7:6] != 2'b00 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_ADDQ_SUBQ_An } : |
// Scc |
( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_Scc } : |
// DBcc |
( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] == 3'b001 ) ? { NO_TRAP, `MICROPC_DBcc } : |
// BSR |
( ir[15:12] == 4'b0110 && ir[11:8] == 4'b0001 ) ? { NO_TRAP, `MICROPC_BSR } : |
// Bcc,BRA |
( ir[15:12] == 4'b0110 && ir[11:8] != 4'b0001 ) ? { NO_TRAP, `MICROPC_Bcc_BRA } : |
// MOVEQ |
( ir[15:12] == 4'b0111 && ir[8] == 1'b0 ) ? { NO_TRAP, `MICROPC_MOVEQ } : |
// CMP |
( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) && |
(ir[8:6] != 3'b000 || ir[5:3] != 3'b001) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_CMP } : |
// CMPA |
( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_CMPA } : |
// CMPM |
( ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001) ? { NO_TRAP, `MICROPC_CMPM } : |
// EOR |
( ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_EOR } : |
// ADD to mem,SUB to mem,AND to mem,OR to mem |
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && |
(ir[8:4] == 5'b10001 || ir[8:4] == 5'b10010 || ir[8:4] == 5'b10011 || |
ir[8:4] == 5'b10101 || ir[8:4] == 5'b10110 || ir[8:4] == 5'b10111 || |
ir[8:4] == 5'b11001 || ir[8:4] == 5'b11010 || ir[8:4] == 5'b11011) && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem } : |
// ADD to Dn,SUB to Dn,AND to Dn,OR to Dn |
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001 || ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && |
(ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010) && |
(ir[12] != 1'b1 || ir[8:6] != 3'b000 || ir[5:3] != 3'b001) && (ir[12] == 1'b1 || ir[5:3] != 3'b001) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn } : |
// ADDA,SUBA |
( (ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:6] == 3'b011 || ir[8:6] == 3'b111) && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_ADDA_SUBA } : |
// ABCD,SBCD,ADDX,SUBX |
( ((ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[8:4] == 5'b10000) || |
((ir[15:12] == 4'b1101 || ir[15:12] == 4'b1001) && (ir[8:4] == 5'b10000 || ir[8:4] == 5'b10100 || ir[8:4] == 5'b11000) ) ) ? |
{ NO_TRAP, `MICROPC_ABCD_SBCD_ADDX_SUBX } : |
// EXG |
( ir[15:12] == 4'b1100 && (ir[8:3] == 6'b101000 || ir[8:3] == 6'b101001 || ir[8:3] == 6'b110001) ) ? { NO_TRAP, `MICROPC_EXG } : |
// MULS,MULU,DIVS,DIVU |
( (ir[15:12] == 4'b1100 || ir[15:12] == 4'b1000) && ir[7:6] == 2'b11 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || |
(ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001 || ir[5:0] == 6'b111_010 || ir[5:0] == 6'b111_011 || ir[5:0] == 6'b111_100)) |
) ? { NO_TRAP, `MICROPC_MULS_MULU_DIVS_DIVU } : |
// ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all memory |
( ir[15:12] == 4'b1110 && ir[11] == 1'b0 && ir[7:6] == 2'b11 && ir[5:3] != 3'b000 && ir[5:3] != 3'b001 && |
(ir[5:3] != 3'b111 || (ir[5:0] == 6'b111_000 || ir[5:0] == 6'b111_001)) |
) ? { NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory } : |
// ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all immediate/register |
( ir[15:12] == 4'b1110 && (ir[7:6] == 2'b00 || ir[7:6] == 2'b01 || ir[7:6] == 2'b10) ) ? |
{ NO_TRAP, `MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register } : |
|
// else |
|
{ ILLEGAL_INSTRUCTION_TRAP, UNUSED_MICROPC } |
; |
|
// load ea |
assign load_ea = |
( |
(ea_type == `EA_TYPE_ALL && (ea_mod == 3'b000 || ea_mod == 3'b001 || (ea_mod == 3'b111 && ea_reg == 3'b100))) || |
(ea_type == `EA_TYPE_DATAALTER && ea_mod == 3'b000) || |
(ea_type == `EA_TYPE_DN_AN && (ea_mod == 3'b000 || ea_mod == 3'b001)) || |
(ea_type == `EA_TYPE_DATA && (ea_mod == 3'b000 || (ea_mod == 3'b111 && ea_reg == 3'b100))) |
) ? 9'd0 // no ea needed |
: |
(ea_mod == 3'b010 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || |
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || |
ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_An // (An) |
: |
(ea_mod == 3'b011 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER || |
ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_An_plus // (An)+ |
: |
(ea_mod == 3'b100 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER || |
ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_minus_An // -(An) |
: |
(ea_mod == 3'b101 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || |
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_d16_An // (d16, An) |
: |
(ea_mod == 3'b110 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || |
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_d8_An_Xn // (d8, An, Xn) |
: |
(ea_mod == 3'b111 && ea_reg == 3'b000 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || |
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_xxx_W // (xxx).W |
: |
(ea_mod == 3'b111 && ea_reg == 3'b001 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || |
ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_xxx_L // (xxx).L |
: |
(ea_mod == 3'b111 && ea_reg == 3'b010 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_d16_PC // (d16, PC) |
: |
(ea_mod == 3'b111 && ea_reg == 3'b011 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_CONTROL || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_LOAD_EA_d8_PC_Xn // (d8, PC, Xn) |
: |
`MICROPC_LOAD_EA_illegal_command // illegal command |
; |
|
// perform ea read |
assign perform_ea_read = |
( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN || |
ea_type == `EA_TYPE_DATA) ) ? |
`MICROPC_PERFORM_EA_READ_Dn : |
( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_READ_An : |
( ea_mod == 3'b111 && ea_reg == 3'b100 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATA) ) ? |
`MICROPC_PERFORM_EA_READ_imm : |
`MICROPC_PERFORM_EA_READ_memory |
; |
|
// perform ea write |
assign perform_ea_write = |
( ea_mod == 3'b000 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DN_AN || |
ea_type == `EA_TYPE_DATA) ) ? |
`MICROPC_PERFORM_EA_WRITE_Dn : |
( ea_mod == 3'b001 && (ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_DN_AN) ) ? `MICROPC_PERFORM_EA_WRITE_An : |
`MICROPC_PERFORM_EA_WRITE_memory |
; |
|
// save ea |
assign save_ea = |
(ea_mod == 3'b011 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROL_POSTINC || ea_type == `EA_TYPE_MEMORYALTER || |
ea_type == `EA_TYPE_DATAALTER || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_SAVE_EA_An_plus // (An)+ |
: |
(ea_mod == 3'b100 && ( |
ea_type == `EA_TYPE_ALL || ea_type == `EA_TYPE_CONTROLALTER_PREDEC || ea_type == `EA_TYPE_DATAALTER || |
ea_type == `EA_TYPE_MEMORYALTER || ea_type == `EA_TYPE_DATA |
)) ? `MICROPC_SAVE_EA_minus_An // -(An) |
: |
9'd0 // no ea needed |
; |
|
endmodule |
|
/*********************************************************************************************************************** |
* Condition |
**********************************************************************************************************************/ |
|
/*! \brief Condition tests. |
* |
* The condition module implements the condition tests of the MC68000. Its inputs are the condition codes |
* and the currently selected test. The output is binary: the test is true or false. The output of the condition module |
* is an input to the microcode_branch module, that decides which microcode word to execute next. |
*/ |
module condition( |
input [3:0] cond, |
input [7:0] ccr, |
output condition |
); |
|
wire C,V,Z,N; |
assign C = ccr[0]; |
assign V = ccr[1]; |
assign Z = ccr[2]; |
assign N = ccr[3]; |
|
assign condition = (cond == 4'b0000) ? 1'b1 : // true |
(cond == 4'b0001) ? 1'b0 : // false |
(cond == 4'b0010) ? ~C & ~Z : // high |
(cond == 4'b0011) ? C | Z : // low or same |
(cond == 4'b0100) ? ~C : // carry clear |
(cond == 4'b0101) ? C : // carry set |
(cond == 4'b0110) ? ~Z : // not equal |
(cond == 4'b0111) ? Z : // equal |
(cond == 4'b1000) ? ~V : // overflow clear |
(cond == 4'b1001) ? V : // overflow set |
(cond == 4'b1010) ? ~N : // plus |
(cond == 4'b1011) ? N : // minus |
(cond == 4'b1100) ? (N & V) | (~N & ~V) : // greater or equal |
(cond == 4'b1101) ? (N & ~V) | (~N & V) : // less than |
(cond == 4'b1110) ? (N & V & ~Z) | (~N & ~V & ~Z) : // greater than |
(cond == 4'b1111) ? (Z) | (N & ~V) | (~N & V) : // less or equal |
1'b0; |
endmodule |
|
/*********************************************************************************************************************** |
* ALU |
**********************************************************************************************************************/ |
|
/*! \brief Arithmetic and Logic Unit. |
* |
* The alu module is responsible for performing all of the arithmetic and logic operations of the ao68000 processor. |
* It operates on two 32-bit registers: operand1 and operand2 from the registers module. The output is saved into |
* a result 32-bit register. This register is located in the alu module. |
* |
* The alu module also contains the status register (SR) with the condition code register. The microcode decides what |
* operation the alu performs. |
*/ |
module alu( |
input clock, |
input reset, |
|
// only zero bit |
input [31:0] address, |
// only ir[11:9] and ir[6] |
input [15:0] ir, |
// byte 2'b00, word 2'b01, long 2'b10 |
input [1:0] size, |
|
input [31:0] operand1, |
input [31:0] operand2, |
|
input [2:0] interrupt_mask, |
input [4:0] alu_control, |
|
output reg [15:0] sr, |
output reg [31:0] result, |
output reg [1:0] special = 2'b00 |
); |
|
wire [31:0] divu_quotient; |
wire [15:0] divu_remainder; |
wire [31:0] divs_quotient; |
wire [15:0] divs_remainder; |
wire [31:0] mulu_result; |
wire [31:0] muls_result; |
|
alu_mult_div alu_mult_div_m ( |
.clock(clock), |
.reset(reset), |
|
.operand1(operand1), |
.operand2(operand2), |
.divu_quotient(divu_quotient), |
.divu_remainder(divu_remainder), |
.divs_quotient(divs_quotient), |
.divs_remainder(divs_remainder), |
.mulu_result(mulu_result), |
.muls_result(muls_result) |
); |
|
// ALU internal defines |
`define Sm ( (size == 2'b00) ? operand2[7] : (size == 2'b01) ? operand2[15] : operand2[31]) |
|
`define Dm ( (size == 2'b00) ? operand1[7] : (size == 2'b01) ? operand1[15] : operand1[31]) |
|
`define Rm ( (size == 2'b00) ? result[7] : (size == 2'b01) ? result[15] : result[31]) |
|
`define Z ( (size == 2'b00) ? (result[7:0] == 8'b0) : (size == 2'b01) ? (result[15:0] == 16'b0) : (result[31:0] == 32'b0)) |
|
// ALU operations |
|
reg [2:0] interrupt_mask_copy; |
reg was_interrupt; |
|
always @(posedge clock) begin |
if(reset == 1'b1) begin |
sr <= { 1'b0, 1'b0, 1'b1, 2'b0, 3'b111, 8'b0 }; |
result <= 32'd0; |
special <= 2'b0; |
interrupt_mask_copy <= 3'b0; |
was_interrupt <= 1'b0; |
end |
else begin |
case(alu_control) |
`ALU_SR_SET_INTERRUPT: begin |
interrupt_mask_copy <= interrupt_mask[2:0]; |
was_interrupt <= 1'b1; |
end |
|
`ALU_SR_SET_TRAP: begin |
if(was_interrupt == 1'b1) begin |
sr <= { 1'b0, sr[14], 1'b1, sr[12:11], interrupt_mask_copy[2:0], sr[7:0] }; |
end |
else begin |
sr <= { 1'b0, sr[14], 1'b1, sr[12:0] }; |
end |
was_interrupt <= 1'b0; |
end |
|
`ALU_MOVEP_M2R_1: begin |
if(ir[6] == 1'b1) result[31:24] <= operand1[7:0]; |
else result[15:8] <= operand1[7:0]; |
//CCR: no change |
end |
`ALU_MOVEP_M2R_2: begin |
if(ir[6] == 1'b1) result[23:16] <= operand1[7:0]; |
else result[7:0] <= operand1[7:0]; |
//CCR: no change |
end |
`ALU_MOVEP_M2R_3: begin |
if(ir[6] == 1'b1) result[15:8] <= operand1[7:0]; |
//CCR: no change |
end |
`ALU_MOVEP_M2R_4: begin |
if(ir[6] == 1'b1) result[7:0] <= operand1[7:0]; |
//CCR: no change |
end |
|
|
`ALU_MOVEP_R2M_1: begin |
if(ir[6] == 1'b1) result[7:0] <= operand1[31:24]; |
else result[7:0] <= operand1[15:8]; |
// CCR: no change |
end |
`ALU_MOVEP_R2M_2: begin |
if(ir[6] == 1'b1) result[7:0] <= operand1[23:16]; |
else result[7:0] <= operand1[7:0]; |
// CCR: no change |
end |
`ALU_MOVEP_R2M_3: begin |
result[7:0] <= operand1[15:8]; |
// CCR: no change |
end |
`ALU_MOVEP_R2M_4: begin |
result[7:0] <= operand1[7:0]; |
// CCR: no change |
end |
|
|
|
`ALU_SIGN_EXTEND: begin |
// move operand1 with sign-extension to result |
if(size == 2'b01) begin |
result <= { {16{operand1[15]}}, operand1[15:0] }; |
end |
else begin |
result <= operand1; |
end |
// CCR: no change |
end |
|
`ALU_ARITHMETIC_LOGIC: begin |
|
// OR,OR to mem,OR to Dn |
if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b000) || |
(ir[15:12] == 4'b1000) |
) result[31:0] = operand1[31:0] | operand2[31:0]; |
// AND,AND to mem,AND to Dn |
else if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b001) || |
(ir[15:12] == 4'b1100) |
) result[31:0] = operand1[31:0] & operand2[31:0]; |
// EORI,EOR |
else if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b101) || |
(ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] != 3'b001) |
) result[31:0] = operand1[31:0] ^ operand2[31:0]; |
// ADD,ADD to mem,ADD to Dn,ADDQ |
else if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b011) || |
(ir[15:12] == 4'b1101) || |
(ir[15:12] == 4'b0101 && ir[8] == 1'b0) |
) result[31:0] = operand1[31:0] + operand2[31:0]; |
// SUBI,CMPI,CMPM,SUB to mem,SUB to Dn,CMP,SUBQ |
else if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b010) || |
(ir[15:12] == 4'b0000 && ir[11:9] == 3'b110) || |
(ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001) || |
(ir[15:12] == 4'b1001) || |
(ir[15:12] == 4'b1011 && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010)) || |
(ir[15:12] == 4'b0101 && ir[8] == 1'b1) |
) result[31:0] = operand1[31:0] - operand2[31:0]; |
|
// Z |
sr[2] <= `Z; |
// N |
sr[3] <= `Rm; |
|
// CMPI,CMPM,CMP |
if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b110) || |
(ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || ir[8:6] == 3'b101 || ir[8:6] == 3'b110) && ir[5:3] == 3'b001) || |
(ir[15:12] == 4'b1011 && (ir[8:6] == 3'b000 || ir[8:6] == 3'b001 || ir[8:6] == 3'b010)) |
) begin |
// C,V |
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); |
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm); |
// X not affected |
end |
// ADDI,ADD to mem,ADD to Dn,ADDQ |
else if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b011) || |
(ir[15:12] == 4'b1101) || |
(ir[15:12] == 4'b0101 && ir[8] == 1'b0) |
) begin |
// C,X,V |
sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); |
sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0]; |
sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm); |
end |
// SUBI,SUB to mem,SUB to Dn,SUBQ |
else if( (ir[15:12] == 4'b0000 && ir[11:9] == 3'b010) || |
(ir[15:12] == 4'b1001) || |
(ir[15:12] == 4'b0101 && ir[8] == 1'b1) |
) begin |
// C,X,V |
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); |
sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0]; |
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm); |
end |
// ANDI,EORI,ORI,EOR,OR to mem,AND to mem,OR to Dn,AND to Dn |
else begin |
// C,V |
sr[0] <= 1'b0; |
sr[1] <= 1'b0; |
// X not affected |
end |
end |
|
`ALU_ABCD_SBCD_ADDX_SUBX: begin // 259 LE |
// ABCD |
if( ir[14:12] == 3'b100 ) begin |
result[13:8] = {1'b0, operand1[3:0]} + {1'b0, operand2[3:0]} + {4'b0, sr[4]}; |
result[19:14] = {1'b0, operand1[7:4]} + {1'b0, operand2[7:4]}; |
|
result[31:23] = operand1[7:0] + operand2[7:0] + {7'b0, sr[4]}; |
|
result[13:8] = (result[13:8] > 6'd9) ? (result[13:8] + 6'd6) : result[13:8]; |
result[19:14] = (result[13:8] > 6'h1F) ? (result[19:14] + 6'd2) : |
(result[13:8] > 6'h0F) ? (result[19:14] + 6'd1) : |
result[19:14]; |
result[19:14] = (result[19:14] > 6'd9) ? (result[19:14] + 6'd6) : result[19:14]; |
|
result[7:4] = result[17:14]; |
result[3:0] = result[11:8]; |
|
// C |
sr[0] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0; |
// X = C |
sr[4] <= (result[19:14] > 6'd9) ? 1'b1 : 1'b0; |
|
// V |
sr[1] <= (result[30] == 1'b0 && result[7] == 1'b1) ? 1'b1 : 1'b0; |
end |
// SBCD |
else if( ir[14:12] == 3'b000 ) begin |
|
result[13:8] = 6'd32 + {2'b0, operand1[3:0]} - {2'b0, operand2[3:0]} - {5'b0, sr[4]}; |
result[19:14] = 6'd32 + {2'b0, operand1[7:4]} - {2'b0, operand2[7:4]}; |
|
result[31:23] = operand1[7:0] - operand2[7:0] - {7'b0, sr[4]}; |
|
result[13:8] = (result[13:8] < 6'd32) ? (result[13:8] - 6'd6) : result[13:8]; |
result[19:14] = (result[13:8] < 6'd16) ? (result[19:14] - 6'd2) : |
(result[13:8] < 6'd32) ? (result[19:14] - 6'd1) : |
result[19:14]; |
result[19:14] = (result[19:14] < 6'd32 && result[31] == 1'b1) ? (result[19:14] - 6'd6) : result[19:14]; |
|
result[7:4] = result[17:14]; |
result[3:0] = result[11:8]; |
|
// C |
sr[0] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0; |
// X = C |
sr[4] <= (result[19:14] < 6'd32) ? 1'b1 : 1'b0; |
|
// V |
sr[1] <= (result[30] == 1'b1 && result[7] == 1'b0) ? 1'b1 : 1'b0; |
end |
// ADDX |
else if( ir[14:12] == 3'b101 ) result[31:0] = operand1[31:0] + operand2[31:0] + sr[4]; |
// SUBX |
else if( ir[14:12] == 3'b001 ) result[31:0] = operand1[31:0] - operand2[31:0] - sr[4]; |
|
// Z |
sr[2] <= sr[2] & `Z; |
// N |
sr[3] <= `Rm; |
|
// ADDX |
if(ir[14:12] == 3'b101 ) begin |
// C,X,V |
sr[0] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); |
sr[4] <= (`Sm & `Dm) | (~`Rm & `Dm) | (`Sm & ~`Rm); //=ccr[0]; |
sr[1] <= (`Sm & `Dm & ~`Rm) | (~`Sm & ~`Dm & `Rm); |
end |
// SUBX |
else if(ir[14:12] == 3'b001 ) begin |
// C,X,V |
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); |
sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0]; |
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm); |
end |
end |
|
`ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare: begin |
|
if(size == 2'b00) result[7:0] = operand1[7:0]; |
else if(size == 2'b01) result[15:0] = operand1[15:0]; |
else if(size == 2'b10) result[31:0] = operand1[31:0]; |
|
// X for ASL |
//if(operand2[5:0] > 6'b0 && ir[8] == 1'b1 && ((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) ) begin |
// X set to Dm |
// sr[4] <= `Dm; |
//end |
// else X not affected |
|
// V cleared |
sr[1] <= 1'b0; |
// C for ROXL,ROXR: set to X |
if( (ir[7:6] == 2'b11 && ir[10:9] == 2'b10) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b10) ) begin |
sr[0] <= sr[4]; |
end |
else begin |
// C cleared |
sr[0] <= 1'b0; |
end |
|
// N set |
sr[3] <= `Rm; |
// Z set |
sr[2] <= `Z; |
end |
|
`ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR: begin |
|
// ASL |
if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b1) begin |
result[31:0] = {operand1[30:0], 1'b0}; |
|
sr[1] <= (sr[1] == 1'b0)? (`Rm != `Dm) : 1'b1; // V |
sr[0] <= `Dm; // C |
sr[4] <= `Dm; // X |
end |
// LSL |
else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b1) begin |
result[31:0] = {operand1[30:0], 1'b0}; |
|
sr[1] <= 1'b0; // V |
sr[0] <= `Dm; // C |
sr[4] <= `Dm; // X |
end |
// ROL |
else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b1) begin |
result[31:0] = {operand1[30:0], `Dm}; |
|
sr[1] <= 1'b0; // V |
sr[0] <= `Dm; // C |
// X not affected |
end |
// ROXL |
else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b1) begin |
result[31:0] = {operand1[30:0], sr[4]}; |
|
sr[1] <= 1'b0; // V |
sr[0] <= `Dm; // C |
sr[4] <= `Dm; // X |
end |
// ASR |
else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b00) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b00)) && ir[8] == 1'b0) begin |
if(size == 2'b00) result[7:0] = { operand1[7], operand1[7:1] }; |
else if(size == 2'b01) result[15:0] = { operand1[15], operand1[15:1] }; |
else if(size == 2'b10) result[31:0] = { operand1[31], operand1[31:1] }; |
|
sr[1] <= 1'b0; // V |
sr[0] <= operand1[0]; // C |
sr[4] <= operand1[0]; // X |
end |
// LSR |
else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b01) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b01)) && ir[8] == 1'b0) begin |
if(size == 2'b00) result[7:0] = { 1'b0, operand1[7:1] }; |
else if(size == 2'b01) result[15:0] = { 1'b0, operand1[15:1] }; |
else if(size == 2'b10) result[31:0] = { 1'b0, operand1[31:1] }; |
|
sr[1] <= 1'b0; // V |
sr[0] <= operand1[0]; // C |
sr[4] <= operand1[0]; // X |
end |
// ROR |
else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b11) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b11)) && ir[8] == 1'b0) begin |
if(size == 2'b00) result[7:0] = { operand1[0], operand1[7:1] }; |
else if(size == 2'b01) result[15:0] = { operand1[0], operand1[15:1] }; |
else if(size == 2'b10) result[31:0] = { operand1[0], operand1[31:1] }; |
|
sr[1] <= 1'b0; // V |
sr[0] <= operand1[0]; // C |
// X not affected |
end |
// ROXR |
else if( ((ir[7:6] == 2'b11 && ir[10:9] == 2'b10) || (ir[7:6] != 2'b11 && ir[4:3] == 2'b10)) && ir[8] == 1'b0) begin |
if(size == 2'b00) result[7:0] = {sr[4], operand1[7:1]}; |
else if(size == 2'b01) result[15:0] = {sr[4], operand1[15:1]}; |
else if(size == 2'b10) result[31:0] = {sr[4], operand1[31:1]}; |
|
sr[1] <= 1'b0; // V |
sr[0] <= operand1[0]; // C |
sr[4] <= operand1[0]; // X |
end |
|
// N set |
sr[3] <= `Rm; |
// Z set |
sr[2] <= `Z; |
end |
|
`ALU_MOVE: begin |
result = operand1; |
|
// X not affected |
// C cleared |
sr[0] <= 1'b0; |
// V cleared |
sr[1] <= 1'b0; |
|
// N set |
sr[3] <= `Rm; |
// Z set |
sr[2] <= `Z; |
end |
|
`ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ: begin |
// ADDA: 1101 |
// CMPA: 1011 |
// SUBA: 1001 |
// ADDQ,SUBQ: 0101 xxx0,1 |
// operation requires that operand2 was sign extended |
|
// ADDA,ADDQ |
if( ir[15:12] == 4'b1101 || (ir[15:12] == 4'b0101 && ir[8] == 1'b0) ) |
result[31:0] = operand1[31:0] + operand2[31:0]; |
// SUBA,CMPA,SUBQ |
else if( ir[15:12] == 4'b1001 || ir[15:12] == 4'b1011 || (ir[15:12] == 4'b0101 && ir[8] == 1'b1) ) |
result[31:0] = operand1[31:0] - operand2[31:0]; |
|
// for CMPA |
if( ir[15:12] == 4'b1011 ) begin |
// Z |
sr[2] <= `Z; |
// N |
sr[3] <= `Rm; |
|
// C,V |
sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); |
sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm); |
// X not affected |
end |
// for ADDA,SUBA,ADDQ,SUBQ: ccr not affected |
end |
|
`ALU_CHK: begin |
result[15:0] = operand1[15:0] - operand2[15:0]; |
|
// undocumented behavior: Z flag, see 68knotes.txt |
//sr[2] <= (operand1[15:0] == 16'b0) ? 1'b1 : 1'b0; |
// undocumented behavior: C,V flags, see 68knotes.txt |
//sr[0] <= 1'b0; |
//sr[1] <= 1'b0; |
|
// C,X,V |
// sr[0] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); |
// sr[4] <= (`Sm & ~`Dm) | (`Rm & ~`Dm) | (`Sm & `Rm); //=ccr[0]; |
// sr[1] <= (~`Sm & `Dm & ~`Rm) | (`Sm & ~`Dm & `Rm); |
// +: 0-1, 0-0=0, 1-1=0 |
// -: 0-0=1, 1-0, 1-1=1 |
// operand1 - operand2 > 0 |
if( operand1[15:0] != operand2[15:0] && ((~`Dm & `Sm) | (~`Dm & ~`Sm & ~`Rm) | (`Dm & `Sm & ~`Rm)) == 1'b1 ) begin |
// clear N |
sr[3] <= 1'b0; |
special <= 2'b01; |
end |
// operand1 < 0 |
else if( operand1[15] == 1'b1 ) begin |
// set N |
sr[3] <= 1'b1; |
special <= 2'b01; |
end |
// no trap |
else begin |
// N undefined: not affected |
special <= 2'b00; |
end |
|
// X not affected |
end |
|
`ALU_MULS_MULU_DIVS_DIVU: begin // 2206 LE, 106 MHz |
|
// division by 0 |
if( ir[15:12] == 4'b1000 && operand2[15:0] == 16'b0 ) begin |
// X not affected |
// C cleared |
sr[0] <= 1'b0; |
// V,Z,N undefined: cleared |
sr[1] <= 1'b0; |
sr[2] <= 1'b0; |
sr[3] <= 1'b0; |
|
// set trap |
special <= 2'b01; |
end |
// division overflow: divu, divs |
else if( ((ir[15:12] == 4'b1000 && ir[8] == 1'b0) && (divu_quotient[31:16] != 16'd0)) || |
((ir[15:12] == 4'b1000 && ir[8] == 1'b1) && (divs_quotient[31:16] != {16{divs_quotient[15]}})) |
) begin |
// X not affected |
// C cleared |
sr[0] <= 1'b0; |
// V set |
sr[1] <= 1'b1; |
// Z,N undefined: cleared and set |
sr[2] <= 1'b0; |
sr[3] <= 1'b1; |
|
// set trap |
special <= 2'b10; |
end |
// division |
else if( ir[15:12] == 4'b1000 ) begin |
result[31:0] <= (ir[8] == 1'b0)? {divu_remainder[15:0], divu_quotient[15:0]} : {divs_remainder[15:0], divs_quotient[15:0]}; |
|
// X not affected |
// C cleared |
sr[0] <= 1'b0; |
// V cleared |
sr[1] <= 1'b0; |
// Z |
sr[2] <= (ir[8] == 1'b0)? (divu_quotient[15:0] == 16'b0) : (divs_quotient[15:0] == 16'b0); |
// N |
sr[3] <= (ir[8] == 1'b0)? (divu_quotient[15] == 1'b1) : (divs_quotient[15] == 1'b1); |
|
// set trap |
special <= 2'b00; |
end |
// multiplication |
else if( ir[15:12] == 4'b1100 ) begin |
result[31:0] <= (ir[8] == 1'b0)? mulu_result[31:0] : muls_result[31:0]; |
|
// X not affected |
// C cleared |
sr[0] <= 1'b0; |
// V cleared |
sr[1] <= 1'b0; |
// Z |
sr[2] <= (ir[8] == 1'b0)? (mulu_result[31:0] == 32'b0) : (muls_result[31:0] == 32'b0); |
// N |
sr[3] <= (ir[8] == 1'b0)? (mulu_result[31] == 1'b1) : (muls_result[31] == 1'b1); |
|
// set trap |
special <= 2'b00; |
end |
end |
|
|
`ALU_BCHG_BCLR_BSET_BTST: begin // 97 LE |
// byte |
if( ir[5:3] != 3'b000 ) begin |
sr[2] <= ~(operand1[ operand2[2:0] ]); |
result = operand1; |
result[ operand2[2:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[2:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1; |
end |
// long |
else if( ir[5:3] == 3'b000 ) begin |
sr[2] <= ~(operand1[ operand2[4:0] ]); |
result = operand1; |
result[ operand2[4:0] ] = (ir[7:6] == 2'b01) ? ~(operand1[ operand2[4:0] ]) : (ir[7:6] == 2'b10) ? 1'b0 : 1'b1; |
end |
|
// C,V,N,X not affected |
end |
|
`ALU_TAS: begin |
result[7:0] <= { 1'b1, operand1[6:0] }; |
|
// X not affected |
// C cleared |
sr[0] <= 1'b0; |
// V cleared |
sr[1] <= 1'b0; |
|
// N set |
sr[3] <= (operand1[7] == 1'b1); |
// Z set |
sr[2] <= (operand1[7:0] == 8'b0); |
end |
|
|
`ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT: begin |
// NEGX |
if( ir[11:8] == 4'b0000 ) result = 32'b0 - operand1[31:0] - sr[4]; |
// CLR |
else if( ir[11:8] == 4'b0010 ) result = 32'b0; |
// NEG |
else if( ir[11:8] == 4'b0100 ) result = 32'b0 - operand1[31:0]; |
// NOT |
else if( ir[11:8] == 4'b0110 ) result = ~operand1[31:0]; |
// NBCD |
else if( ir[11:6] == 6'b1000_00 ) begin |
|
result[3:0] = 5'd25 - operand1[3:0]; |
result[7:4] = (operand1[3:0] > 4'd9) ? (5'd24 - operand1[7:4]) : (5'd25 - operand1[7:4]); |
|
if(sr[4] == 1'b0 && result[3:0] == 4'd9 && result[7:4] == 4'd9) begin |
result[3:0] = 4'd0; |
result[7:4] = 4'd0; |
end |
else if(sr[4] == 1'b0 && (result[3:0] == 4'd9 || result[3:0] == 4'd15)) begin |
result[3:0] = 4'd0; |
result[7:4] = result[7:4] + 4'd1; |
end |
else if(sr[4] == 1'b0) begin |
result[3:0] = result[3:0] + 4'd1; |
end |
|
//V undefined: unchanged |
//Z |
sr[2] <= sr[2] & `Z; |
//C,X |
sr[0] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1; |
sr[4] <= (operand1[7:0] == 8'd0 && sr[4] == 1'b0) ? 1'b0 : 1'b1; //=C |
end |
// SWAP |
else if( ir[11:6] == 6'b1000_01 ) result = { operand1[15:0], operand1[31:16] }; |
// EXT byte to word |
else if( ir[11:6] == 6'b1000_10 ) result = { result[31:16], {8{operand1[7]}}, operand1[7:0] }; |
// EXT word to long |
else if( ir[11:6] == 6'b1000_11 ) result = { {16{operand1[15]}}, operand1[15:0] }; |
|
// N set if negative else clear |
sr[3] <= `Rm; |
|
// CLR,NOT,SWAP,EXT |
if( ir[11:8] == 4'b0010 || ir[11:8] == 4'b0110 || ir[11:6] == 6'b1000_01 || ir[11:7] == 5'b1000_1 ) begin |
// X not affected |
// C,V cleared |
sr[0] <= 1'b0; |
sr[1] <= 1'b0; |
// Z set |
sr[2] <= `Z; |
end |
// NEGX |
else if( ir[11:8] == 4'b0000 ) begin |
// C set if borrow |
sr[0] <= `Dm | `Rm; |
// X=C |
sr[4] <= `Dm | `Rm; |
// V set if overflow |
sr[1] <= `Dm & `Rm; |
// Z cleared if nonzero else unchanged |
sr[2] <= sr[2] & `Z; |
end |
// NEG |
else if( ir[11:8] == 4'b0100 ) begin |
// C clear if zero else set |
sr[0] <= `Dm | `Rm; |
// X=C |
sr[4] <= `Dm | `Rm; |
// V set if overflow |
sr[1] <= `Dm & `Rm; |
// Z set if zero else clear |
sr[2] <= `Z; |
end |
end |
|
|
`ALU_SIMPLE_LONG_ADD: begin |
result <= operand1[31:0] + operand2[31:0]; |
|
// CCR not affected |
end |
|
`ALU_SIMPLE_LONG_SUB: begin |
result <= operand1[31:0] - operand2[31:0]; |
|
// CCR not affected |
end |
|
`ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR: begin |
|
// MOVE TO SR,RTE,STOP,ORI to SR,ANDI to SR,EORI to SR |
if( ir[15:8] == 8'b0100_0110 || ir[15:0] == 16'b0100_1110_0111_0011 || ir[15:0] == 16'b0100_1110_0111_0010 || |
ir[15:0] == 16'b0000_000_0_01_111100 || ir[15:0] == 16'b0000_001_0_01_111100 || ir[15:0] == 16'b0000_101_0_01_111100 |
) sr <= { operand1[15], 1'b0, operand1[13], 2'b0, operand1[10:8], 3'b0, operand1[4:0] }; |
// MOVE TO CCR,RTR,ORI to CCR,ANDI to CCR,EORI to CCR |
else if( ir[15:8] == 8'b0100_0100 || ir[15:0] == 16'b0100_1110_0111_0111 || |
ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_101_0_00_111100 |
) sr <= { sr[15:8], 3'b0, operand1[4:0] }; |
end |
|
`ALU_SIMPLE_MOVE: begin |
result <= operand1; |
|
// CCR not affected |
end |
|
`ALU_LINK_MOVE: begin |
if(ir[3:0] == 3'b111) begin |
result <= operand1 - 32'd4; |
end |
else begin |
result <= operand1; |
end |
|
// CCR not affected |
end |
|
endcase |
end |
end |
|
endmodule |
|
/*********************************************************************************************************************** |
* Microcode branch |
**********************************************************************************************************************/ |
|
/*! \brief Select the next microcode word to execute. |
* |
* The microcode_branch module is responsible for selecting the next microcode word to execute. This decision is based |
* on the value of the current microcode word, the value of the interrupt privilege level, the state of the current |
* bus cycle and other internal signals. |
* |
* The microcode_branch module implements a simple stack for the microcode addresses. This makes it possible to call |
* subroutines inside the microcode. |
*/ |
module microcode_branch( |
input clock, |
input reset, |
|
input [4:0] movem_loop, |
input [15:0] movem_reg, |
input [31:0] operand2, |
input [1:0] special, |
input condition, |
input [31:0] result, |
input overflow, |
input stop_flag, |
input [15:0] ir, |
input [7:0] decoder_trap, |
input trace_flag, |
input group_0_flag, |
input [2:0] interrupt_mask, |
|
input [8:0] load_ea, |
input [8:0] perform_ea_read, |
input [8:0] perform_ea_write, |
input [8:0] save_ea, |
input [8:0] decoder_micropc, |
|
input prefetch_ir_valid_32, |
input prefetch_ir_valid, |
input jmp_address_trap, |
input jmp_bus_trap, |
input finished, |
|
input [3:0] branch_control, |
input [3:0] branch_offset, |
output [8:0] micro_pc |
); |
|
assign micro_pc = |
(reset == 1'b1) ? 9'd0 : |
(jmp_address_trap == 1'b1 || jmp_bus_trap == 1'b1) ? `MICROPC_ADDRESS_BUS_TRAP : |
( (branch_control == `BRANCH_movem_loop && movem_loop == 5'b10000) || |
(branch_control == `BRANCH_movem_reg && movem_reg[0] == 0) || |
(branch_control == `BRANCH_operand2 && operand2[5:0] == 6'b0) || |
(branch_control == `BRANCH_special_01 && special != 2'b01) || |
(branch_control == `BRANCH_special_10 && special == 2'b10) || |
(branch_control == `BRANCH_condition_0 && condition == 1'b0) || |
(branch_control == `BRANCH_condition_1 && condition == 1'b1) || |
(branch_control == `BRANCH_result && result[15:0] == 16'hFFFF) || |
(branch_control == `BRANCH_V && overflow == 1'b0) || |
(branch_control == `BRANCH_movep_16 && ir[6] == 1'b0) || |
(branch_control == `BRANCH_stop_flag_wait_ir_decode && stop_flag == 1'b1) || |
(branch_control == `BRANCH_ir && ir[7:0] != 8'b0) || |
(branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask != 3'b000) || |
(branch_control == `BRANCH_group_0_flag && group_0_flag == 1'b0) |
) ? micro_pc_0 + { 5'd0, branch_offset } : |
(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0) ? decoder_micropc : |
(branch_control == `BRANCH_trace_flag_and_interrupt && trace_flag == 1'b0 && interrupt_mask == 3'b000) ? `MICROPC_MAIN_LOOP : |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_jump_to_main_loop) ? `MICROPC_MAIN_LOOP : |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) ? load_ea : |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_read) ? perform_ea_read : |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_perform_ea_write) ? perform_ea_write : |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) ? save_ea : |
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) ? load_ea : |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) ? perform_ea_read : |
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_write) ? perform_ea_write : |
|
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_call_trap) ? `MICROPC_TRAP_ENTRY : |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_return) ? micro_pc_1 : |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_interrupt_mask && interrupt_mask == 3'b000) ? `MICROPC_MAIN_LOOP : |
( (branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_finished && finished == 1'b0) || |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid && prefetch_ir_valid == 1'b0) || |
(branch_control == `BRANCH_procedure && branch_offset == `PROCEDURE_wait_prefetch_valid_32 && prefetch_ir_valid_32 == 1'b0) || |
(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b0) |
) ? micro_pc_0 : |
micro_pc_0 + 9'd1 |
; |
|
reg [8:0] micro_pc_0 = 9'd0; |
reg [8:0] micro_pc_1; |
reg [8:0] micro_pc_2; |
reg [8:0] micro_pc_3; |
|
always @(posedge clock) begin |
if(reset) micro_pc_0 <= 9'd0; |
else micro_pc_0 <= micro_pc; |
end |
|
always @(posedge clock) begin |
if(reset) begin |
micro_pc_1 <= 9'd0; |
micro_pc_2 <= 9'd0; |
micro_pc_3 <= 9'd0; |
end |
else if(branch_control == `BRANCH_stop_flag_wait_ir_decode && prefetch_ir_valid == 1'b1 && decoder_trap == 8'd0) begin |
micro_pc_1 <= micro_pc_0 + { 5'd0, branch_offset }; |
micro_pc_2 <= micro_pc_1; |
micro_pc_3 <= micro_pc_2; |
end |
else if(branch_control == `BRANCH_procedure) begin |
if(branch_offset == `PROCEDURE_call_read && load_ea != 9'd0) begin |
micro_pc_1 <= perform_ea_read; |
micro_pc_2 <= micro_pc_0 + 9'd1; |
micro_pc_3 <= micro_pc_1; |
end |
else if(branch_offset == `PROCEDURE_call_read && load_ea == 9'd0) begin |
micro_pc_1 <= micro_pc_0 + 9'd1; |
micro_pc_2 <= micro_pc_1; |
micro_pc_3 <= micro_pc_2; |
end |
else if(branch_offset == `PROCEDURE_call_write && save_ea != 9'd0) begin |
micro_pc_1 <= save_ea; |
micro_pc_2 <= micro_pc_1; |
micro_pc_3 <= micro_pc_2; |
end |
else if((branch_offset == `PROCEDURE_call_load_ea && load_ea != 9'd0) || |
(branch_offset == `PROCEDURE_call_perform_ea_read) || |
(branch_offset == `PROCEDURE_call_perform_ea_write) || |
(branch_offset == `PROCEDURE_call_save_ea && save_ea != 9'd0) || |
(branch_offset == `PROCEDURE_call_trap) ) |
begin |
micro_pc_1 <= micro_pc_0 + 9'd1; |
micro_pc_2 <= micro_pc_1; |
micro_pc_3 <= micro_pc_2; |
end |
else if(branch_offset == `PROCEDURE_return) begin |
micro_pc_1 <= micro_pc_2; |
micro_pc_2 <= micro_pc_3; |
micro_pc_3 <= 9'd0; |
end |
else if(branch_offset == `PROCEDURE_push_micropc) begin |
micro_pc_1 <= micro_pc_0; |
micro_pc_2 <= micro_pc_1; |
micro_pc_3 <= micro_pc_2; |
end |
else if(branch_offset == `PROCEDURE_pop_micropc) begin |
micro_pc_1 <= micro_pc_2; |
micro_pc_2 <= micro_pc_3; |
micro_pc_3 <= 9'd0; |
end |
end |
end |
|
endmodule |
|
/trunk/rtl/verilog/ao68000/microcode/microcode_locations.v
0,0 → 1,115
/*! \file microcode_locations.v |
* \brief Definitions of microcode locations. |
*/ |
`define MICRO_DATA_ea_reg micro_data[2:0] |
`define MICRO_DATA_ea_mod micro_data[6:3] |
`define MICRO_DATA_ea_type micro_data[10:7] |
`define MICRO_DATA_op1 micro_data[14:11] |
`define MICRO_DATA_op2 micro_data[17:15] |
`define MICRO_DATA_address micro_data[21:18] |
`define MICRO_DATA_size micro_data[25:22] |
`define MICRO_DATA_movem_modreg micro_data[28:26] |
`define MICRO_DATA_movem_loop micro_data[30:29] |
`define MICRO_DATA_movem_reg micro_data[32:31] |
`define MICRO_DATA_ir micro_data[34:33] |
`define MICRO_DATA_pc micro_data[37:35] |
`define MICRO_DATA_trap micro_data[41:38] |
`define MICRO_DATA_offset micro_data[43:42] |
`define MICRO_DATA_index micro_data[45:44] |
`define MICRO_DATA_stop_flag micro_data[47:46] |
`define MICRO_DATA_trace_flag micro_data[49:48] |
`define MICRO_DATA_group_0_flag micro_data[51:50] |
`define MICRO_DATA_instruction_flag micro_data[53:52] |
`define MICRO_DATA_read_modify_write_flag micro_data[55:54] |
`define MICRO_DATA_do_reset_flag micro_data[57:56] |
`define MICRO_DATA_do_interrupt_flag micro_data[59:58] |
`define MICRO_DATA_do_read_flag micro_data[61:60] |
`define MICRO_DATA_do_write_flag micro_data[63:62] |
`define MICRO_DATA_do_blocked_flag micro_data[65:64] |
`define MICRO_DATA_data_write micro_data[67:66] |
`define MICRO_DATA_an_address micro_data[69:68] |
`define MICRO_DATA_an_write_enable micro_data[70:70] |
`define MICRO_DATA_an_input micro_data[72:71] |
`define MICRO_DATA_dn_address micro_data[73:73] |
`define MICRO_DATA_dn_write_enable micro_data[74:74] |
`define MICRO_DATA_alu micro_data[79:75] |
`define MICRO_DATA_branch micro_data[83:80] |
`define MICRO_DATA_procedure micro_data[87:84] |
|
`define MICROPC_MOVE 9'd231 |
`define MICROPC_MOVE_USP_to_An 9'd403 |
`define MICROPC_TAS 9'd335 |
`define MICROPC_BSR 9'd433 |
`define MICROPC_ADDRESS_BUS_TRAP 9'd3 |
`define MICROPC_MOVEP_register_to_memory 9'd106 |
`define MICROPC_NEGX_CLR_NEG_NOT_NBCD 9'd340 |
`define MICROPC_RTS 9'd474 |
`define MICROPC_MAIN_LOOP 9'd53 |
`define MICROPC_ADDA_SUBA 9'd268 |
`define MICROPC_MOVE_TO_CCR_MOVE_TO_SR 9'd394 |
`define MICROPC_MOVE_FROM_SR 9'd391 |
`define MICROPC_LOAD_EA_d8_PC_Xn 9'd79 |
`define MICROPC_TRAP_ENTRY 9'd35 |
`define MICROPC_PERFORM_EA_READ_memory 9'd89 |
`define MICROPC_RESET 9'd488 |
`define MICROPC_PERFORM_EA_WRITE_Dn 9'd91 |
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory 9'd225 |
`define MICROPC_MOVEA 9'd239 |
`define MICROPC_TST 9'd347 |
`define MICROPC_BTST_register 9'd329 |
`define MICROPC_LOAD_EA_d8_An_Xn 9'd68 |
`define MICROPC_MULS_MULU_DIVS_DIVU 9'd290 |
`define MICROPC_MOVEQ 9'd310 |
`define MICROPC_CMPA 9'd275 |
`define MICROPC_EOR 9'd245 |
`define MICROPC_LOAD_EA_xxx_W 9'd72 |
`define MICROPC_DBcc 9'd377 |
`define MICROPC_CMPI 9'd184 |
`define MICROPC_LOAD_EA_xxx_L 9'd74 |
`define MICROPC_CMPM 9'd205 |
`define MICROPC_MOVE_USP_to_USP 9'd398 |
`define MICROPC_ADDQ_SUBQ_not_An 9'd351 |
`define MICROPC_ULNK 9'd422 |
`define MICROPC_EXG 9'd197 |
`define MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem 9'd250 |
`define MICROPC_Bcc_BRA 9'd365 |
`define MICROPC_PERFORM_EA_READ_An 9'd86 |
`define MICROPC_LOAD_EA_d16_PC 9'd76 |
`define MICROPC_NOP 9'd482 |
`define MICROPC_MOVEM_register_to_memory_predecrement 9'd131 |
`define MICROPC_RTE_RTR 9'd462 |
`define MICROPC_TRAP 9'd483 |
`define MICROPC_ADDQ_SUBQ_An 9'd354 |
`define MICROPC_MOVEM_register_to_memory_control 9'd147 |
`define MICROPC_BTST_immediate 9'd318 |
`define MICROPC_MOVEP_memory_to_register 9'd98 |
`define MICROPC_PERFORM_EA_WRITE_An 9'd92 |
`define MICROPC_CHK 9'd281 |
`define MICROPC_Scc 9'd358 |
`define MICROPC_JMP 9'd445 |
`define MICROPC_PEA 9'd168 |
`define MICROPC_SAVE_EA_minus_An 9'd97 |
`define MICROPC_ANDI_EORI_ORI_ADDI_SUBI 9'd174 |
`define MICROPC_BCHG_BCLR_BSET_immediate 9'd313 |
`define MICROPC_LOAD_EA_An 9'd62 |
`define MICROPC_PERFORM_EA_READ_imm 9'd87 |
`define MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn 9'd255 |
`define MICROPC_LEA 9'd162 |
`define MICROPC_TRAPV 9'd485 |
`define MICROPC_LINK 9'd406 |
`define MICROPC_ABCD_SBCD_ADDX_SUBX 9'd189 |
`define MICROPC_BCHG_BCLR_BSET_register 9'd324 |
`define MICROPC_PERFORM_EA_READ_Dn 9'd85 |
`define MICROPC_LOAD_EA_illegal_command 9'd83 |
`define MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR 9'd178 |
`define MICROPC_CMP 9'd262 |
`define MICROPC_SWAP_EXT 9'd343 |
`define MICROPC_STOP 9'd491 |
`define MICROPC_PERFORM_EA_WRITE_memory 9'd93 |
`define MICROPC_JSR 9'd453 |
`define MICROPC_LOAD_EA_minus_An 9'd63 |
`define MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register 9'd212 |
`define MICROPC_SAVE_EA_An_plus 9'd95 |
`define MICROPC_LOAD_EA_d16_An 9'd65 |
`define MICROPC_LOAD_EA_An_plus 9'd62 |
`define MICROPC_MOVEM_memory_to_register 9'd116 |
/trunk/rtl/verilog/ao68000/microcode/readme.txt
0,0 → 1,115
Files in this directory are auto-generated by software located in ./sw/ao68000_tool/. |
/trunk/rtl/verilog/ao68000/microcode/microcode.mif
0,0 → 1,501
DEPTH = 512; |
WIDTH = 88; |
ADDRESS_RADIX = DEC; |
DATA_RADIX = BIN; |
CONTENT |
BEGIN |
0: 0000000000000000000000000000000000000100000000000000000000000000000000000000000000000000; |
1: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
2: 1001111100000001011100000000000000000000000000000010100000000000000000000000000000000000; |
3: 0010111000000000000000001010100010010000000000100100000000000000000000110000000000000000; |
4: 0110111100000000000000010000000000000000000000000000000000000000000000000000000000000000; |
5: 0000000000000000000000000000000000000100000000000000000000000000000000000000000000000000; |
6: 0000000000000000000000000000000000000000000000000000000000000000000000000011100000000000; |
7: 0000000011010000000000000000000000000000000000000000000000000000000000000101000000000000; |
8: 0000000000010000000000000000000000000000000000000000000000000000000000000000000000000000; |
9: 0000000000000000000000000000000000000000000000000000000000000000110000000000000010100100; |
10: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
11: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
12: 0100111111010000000000000000000000000000000000000000000000000000000000000111000000000000; |
13: 0000000000000000000000000000000000000000000000000000000000000000100000000000000010100100; |
14: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
15: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
16: 0100111111010000000000000000000000000000000000000000000000000000000000000111100000000000; |
17: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
18: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
19: 0100111111010000000000000000000000000000000000000000000000000000000000000000100000000000; |
20: 0000000000000000000000000000000000000000000000000000000000000000110000000000000010100100; |
21: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
22: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
23: 0100111111010000000000000000000000000000000000000000000000000000000000000000000000000000; |
24: 0000000000000000000000000000000000000000000000000000000000000000100000000000000010100100; |
25: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
26: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
27: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
28: 0000000000000000000000000000000000000000000000000000000000000000111001000000000010100100; |
29: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
30: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
31: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
32: 0000000000000000000000000000000000000000000000000000100000000000000000000000000000000000; |
33: 0000000000000000000000000000000000000000000000000000000000000000000000000000100000000000; |
34: 1001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
35: 0000000000000000000000000000000000000000000000000000000000000000000000000011100000000000; |
36: 0000000011010000000000000000000000000000000000000000000000000000000000000101000000000000; |
37: 0000000000010000000000000000000000000000000000000000000000000000000000000000000000000000; |
38: 0000000000000000000000000000000000000000000000000000000000000000110000000000000010100100; |
39: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
40: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
41: 0100111111010000000000000000000000000000000000000000000000000000000000000000000000000000; |
42: 0000000000000000000000000000000000000000000000000000000000000000100000000000000010100100; |
43: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
44: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
45: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
46: 0000000000000000000000000000000000000000000000000000000000000000111001000000000010100100; |
47: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
48: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
49: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
50: 0000000000000000000000000000000000000000000000000000100000000000000000000000000000000000; |
51: 0000000000000000000000000000000000000000000000000000000000000000000000000000100000000000; |
52: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
53: 0011101100000000000000000000000010101001000000000011001000000000000000000000000000000000; |
54: 1011111100000000000000000000000000010000000000100000000000000000000000000000000000000000; |
55: 1001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
56: 0010110100000000000000000000000000010000000000000000000000000000000000000000000000000000; |
57: 1011111100000000000000000000000000000000100000011000000000000000000000000000000000000000; |
58: 1101111100000000000000000000010000000000000000000000000000000000000000000000000000000000; |
59: 0110111100001000000000000000000000000000000000000000000000000000000000000000000000000000; |
60: 1011111100000000000000000000100000000000100000100100000000000000000000000000000000000000; |
61: 1001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
62: 0101111100000000000000000000000000000000000000000000000000000000000100000000000000000000; |
63: 0000000000000000000000000000000000000000000000000000000000000000000100000000000000000000; |
64: 0101111100000000000000000000000000000000000000000000000000000000000010000000000000000000; |
65: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
66: 0000000000000000000000000000000000000000000110000001000000000000000100000000000000000000; |
67: 0101111100000000000000000000000000000000000000000000000000000000000101000000000000000000; |
68: 0111111100000000000000000000000000000000000000000000000000000000000100000000000000000000; |
69: 0000000000000010000100000000000000000000000001000000000000000000000000000000000000000000; |
70: 0000000000000000000100000000000000000000001000000001000000000000000000000000000000000000; |
71: 0101111100000000000000000000000000000000000000000000000000000000000101000000000000000000; |
72: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
73: 0101111100000000000000000000000000000000000000000001000000000000000110000000000000000000; |
74: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
75: 0101111100000000000000000000000000000000000000000001100000000000000111000000000000000000; |
76: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
77: 0000000000000000000000000000000000000000000110000000000000000000000000000000000000000000; |
78: 0101111100000000000000000000000000000000000000000001000000000000001000000000000000000000; |
79: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
80: 0000000000000010000100000000000000000000000001000000000000000000000000000000000000000000; |
81: 0000000000000000000100000000000000000000001000000000000000000000000000000000000000000000; |
82: 0101111100000000000000000000000000000000000000000001000000000000001000000000000000000000; |
83: 1011111100000000000000000000000000000000000000000100000000000000000000000000000000000000; |
84: 1001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
85: 0101111100000000000000000000000000000000000000000000000000000000000000000110100000000000; |
86: 0101111100000000000000000000000000000000000000000000000000000000000000000110000000000000; |
87: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
88: 0101111100000000000000000000000000000000000000000010000000000000000000000010000000000000; |
89: 0110111100000000000000000001000000000000000000000000000000000000000000000000000000000000; |
90: 0101111100000000000000000010000000000000000000000000000000000000000000000001100000000000; |
91: 0101111100000100000000000000000000000000000000000000000000000000000000000000000000000000; |
92: 0101111100000000010000000000000000000000000000000000000000000000000000000000000000000000; |
93: 0110111100000000000001000100000000000000000000000000000000000000000000000000000000000000; |
94: 0101111100000000000000001000000000000000000000000000000000000000000000000000000000000000; |
95: 0000000000000000000000000000000000000000000000000000000000000000000001000000000000000000; |
96: 0101111100000000110000000000000000000000000000000000000000000000000000000000000000000000; |
97: 0101111100000000110000000000000000000000000000000000000000000000000000000000000000000000; |
98: 0000000000000000000000000000000000000000000000000000000000000000010000000000000011011001; |
99: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
100: 0010111100011000000000000000000000000000000000000000000000000000000011000000000000000000; |
101: 0010111100100000000000000000000000000000000000000000000000000000000011000000000000000000; |
102: 0010111100101000000000000000000000000000000000000000000000000000000011000000000000000000; |
103: 0000000000110000000000000000000000000000000000000000000000000001000000000000000011010010; |
104: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
105: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
106: 0000000000000000000000000000000000000000000000000000000000000001010000000000000011010010; |
107: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
108: 0000000000000000000000000000000000000000000000000000000000000000010000000000000011011001; |
109: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
110: 0011111100111000000000000000000000000000000000000000000000000000000000000000000000000000; |
111: 0011111101000000000000000000000000000000000000000000000000000000000011000000000000000000; |
112: 0011101000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
113: 0011111101001000000000000000000000000000000000000000000000000000000011000000000000000000; |
114: 0011111101010000000000000000000000000000000000000000000000000000000011000000000000000000; |
115: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
116: 1000111100000000000000000000000000000000000000000000000000000000100000000000000010101101; |
117: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
118: 0000000000000000000000000000000000000000000000000000000010100101100000000000000100001001; |
119: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
120: 1010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
121: 0111000100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
122: 0101001000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
123: 0000000000000000000000000000000000000000000000000000000000000001100000000000000100001001; |
124: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
125: 0000000001011000000000000000000000000000000000000000000000000000110001000000001100010011; |
126: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
127: 0101111100000000000000000000000000000000000000000000000101001100000000000000000000000000; |
128: 1100111100000000000000000000000000000000000000000000000000000001100000000000000100001001; |
129: 0100111100000000000000000000000000000000000000000000000000000000000010000000000000000000; |
130: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
131: 1000111100000000000000000000000000000000000000000000000000000000100000000000000010101101; |
132: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
133: 0000000000000000000000000000000000000000000000000000000010101001100000000000000110001001; |
134: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
135: 1010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
136: 1000000100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
137: 0110001000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
138: 0000000000000000000000000000000000000000000000000000000000000001100000000000001100010011; |
139: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
140: 0000000001011000000000000000000000000000000000000000000000000001100000000000000110001001; |
141: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
142: 0000000000000000000000000000000000000000000000000000000000000000000010000000000000000000; |
143: 0101111100000000000000000000000000000000000000000000000101010000000000000000000000000000; |
144: 1100111100000000000000000000000000000000000000000000000000000000000001000000000000000000; |
145: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
146: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
147: 1000111100000000000000000000000000000000000000000000000000000000100000000000000010101101; |
148: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
149: 0000000000000000000000000000000000000000000000000000000010100101100000000000000110001001; |
150: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
151: 1010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
152: 1000000100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
153: 0110001000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
154: 0000000000000000000000000000000000000000000000000000000000000001100000000000001100010011; |
155: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
156: 0000000001011000000000000000000000000000000000000000000000000001100000000000000110001001; |
157: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
158: 0000000000000000000000000000000000000000000000000000000000000000000001000000000000000000; |
159: 0101111100000000000000000000000000000000000000000000000101001100000000000000000000000000; |
160: 1100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
161: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
162: 0000000000000000000000000000000000000000000000000000000000000000110000000000001000001001; |
163: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
164: 0000000000000000000000000000000000000000000000000000000000000000000000000001000000000000; |
165: 0000000011010000000000000000000000000000000000000000000000000000110000000000000011001010; |
166: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
167: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
168: 0000000000000000000000000000000000000000000000000000000000000000110000000000001000001001; |
169: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
170: 0000000000000000000000000000000000000000000000000000000000000000000000000001000000000000; |
171: 0000000011010000000000000000000000000000000000000000000000000000110000000000000010100100; |
172: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
173: 1111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
174: 1000111100000000000000000000000000000000000000000000000000000001110000000000000010101101; |
175: 0000000000000000000000000000000000000000000000000010000000000001110000000010001010001001; |
176: 1110111100000000000000000000000000000000000000000000000000000000000000001000000000000000; |
177: 1111111101100000000000000000000000000000000000000000000000000000000000000000000000000000; |
178: 1000111100000000000000000000000000000000000000000000000000000001110000000000000010101101; |
179: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
180: 0000000000000000000000000000000000000000000000000000000000000000000000001101000000000000; |
181: 0000000001100000000000000000000000000000000000000000000000000000000000000000000000000000; |
182: 0000000000000000000000000000000000000000000000000000000000000000000000000010100000000000; |
183: 0101111111001000000000000000000000000000000000000000000000000000000000000000000000000000; |
184: 1000111100000000000000000000000000000000000000000000000000000001110000000000000010101101; |
185: 0000000000000000000000000000000000000000000000000010000000000001110000000010001010001001; |
186: 1110111100000000000000000000000000000000000000000000000000000000000000001000000000000000; |
187: 0100111101100000000000000000000000000000000000000000000000000000000000000000000000000000; |
188: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
189: 0000000000000000000000000000000000000000000000000000000000000001110000000000000010110001; |
190: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
191: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
192: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
193: 0000000000000000000000000000000000000000000000000000000000000001110000001000000010110010; |
194: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
195: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
196: 1111111101101000000000000000000000000000000000000000000000000000000000000000000000000000; |
197: 0000000000000000000000000000000000000000000000000000000000000000110000000000001100001001; |
198: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
199: 0000000011010000000000000000000000000000000000000000000000000000110000000000000010111010; |
200: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
201: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
202: 0000000011010000000000000000000000000000000000000000000000000000110000000000001100001001; |
203: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
204: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
205: 0000000000000000000000000000000000000000000000000000000000000001110000000000000011000001; |
206: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
207: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
208: 0000000000000000000000000000000000000000000000000000000000000001110000001000000011000010; |
209: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
210: 0100111101100000000000000000000000000000000000000000000000000000000000000000000000000000; |
211: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
212: 0000000000000000000000000000000000000000000000000000000000000001110000000000000011010010; |
213: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
214: 0000000000000000000000000000000000000000000000000000000000000001110000001000000011010001; |
215: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
216: 0000000000000000000000000000000000000000000000000000000000000000000000011000000000000000; |
217: 0000000001110000000000000000000000000000000000000000000000000000000000000000000000000000; |
218: 1010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
219: 0011001100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
220: 0000000001111000000000000000000000000000000000000000000000000000000000000000000000000000; |
221: 0101111100000000000000000000000000000000000000000000000000000000000000111010100000000000; |
222: 1100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
223: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
224: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
225: 0000000000000000000000000000000000000000000000000000000000000000100000000000001110001001; |
226: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
227: 0000000000000000000000000000000000000000000000000000000000000000000000010000000000000000; |
228: 0000000001110000000000000000000000000000000000000000000000000000000000000000000000000000; |
229: 0000000001111000000000000000000000000000000000000000000000000000000000000000000000000000; |
230: 1111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
231: 0000000000000000000000000000000000000000000000000000000000000010000000000000000010001001; |
232: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
233: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
234: 0000000011010000000000000000000000000000000000000000000000000010000000000000001010011010; |
235: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
236: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
237: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
238: 0101111110000000000000000000000000000000000000000000000000000000000000000000000000000000; |
239: 0000000000000000000000000000000000000000000000000000000000000010000000000000000010001001; |
240: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
241: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
242: 0000000001011000000000000000000000000000000000000000000000000010000000000000000011001010; |
243: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
244: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
245: 0000000000000000000000000000000000000000000000000000000000000001110000000000000011010010; |
246: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
247: 0000000000000000000000000000000000000000000000000000000000000001110000001000001010001001; |
248: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
249: 1111111101100000000000000000000000000000000000000000000000000000000000000000000000000000; |
250: 0000000000000000000000000000000000000000000000000000000000000001110000000000000011010010; |
251: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
252: 0000000000000000000000000000000000000000000000000000000000000001110000001000001110001001; |
253: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
254: 1111111101100000000000000000000000000000000000000000000000000000000000000000000000000000; |
255: 0000000000000000000000000000000000000000000000000000000000000001110000000000000010001001; |
256: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
257: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
258: 0000000000000000000000000000000000000000000000000000000000000001110000001000000011010010; |
259: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
260: 0011111101100000000000000000000000000000000000000000000000000000000000000000000000000000; |
261: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
262: 0000000000000000000000000000000000000000000000000000000000000001110000000000000010001001; |
263: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
264: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
265: 0000000000000000000000000000000000000000000000000000000000000001110000001000000011010010; |
266: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
267: 0101111101100000000000000000000000000000000000000000000000000000000000000000000000000000; |
268: 0000000000000000000000000000000000000000000000000000000000000010010000000000000010001001; |
269: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
270: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
271: 0000000000000000000000000000000000000000000000000000000000000000110000001000000011001010; |
272: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
273: 0011111110001000000000000000000000000000000000000000000000000000000000000000000000000000; |
274: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
275: 0000000000000000000000000000000000000000000000000000000000000010010000000000000010001001; |
276: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
277: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
278: 0000000000000000000000000000000000000000000000000000000000000000110000001000000011001010; |
279: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
280: 0101111110001000000000000000000000000000000000000000000000000000000000000000000000000000; |
281: 0000000000000000000000000000000000000000000000000000000000000000100000000000010000001001; |
282: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
283: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
284: 0000000000000000000000000000000000000000000000000000000000000000100000001000000011010010; |
285: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
286: 0000000010010000000000000000000000000000000000000000000000000000000000000000000000000000; |
287: 0010010000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
288: 1011111100000000000000000000000000000000000000001100000000000000000000000000000000000000; |
289: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
290: 0000000000000000000000000000000000000000000000000000000000000000100000000000010000001001; |
291: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
292: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
293: 0000000000000000000000000000000000000000000000000000000000000000110000001000000011010010; |
294: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
295: 0000000010011000000000000000000000000000000000000000000000100000000000000000000000000000; |
296: 0011010000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
297: 1011111100000000000000000000000000000000000000001000000000000000000000000000000000000000; |
298: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
299: 1010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
300: 0010000100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
301: 0101111100000000000000000000000000000000000000000000000001000000000000000000000000000000; |
302: 1100111100000000000000000000000000000000000000000000000000100000000000000000000000000000; |
303: 1010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
304: 0010000100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
305: 0101111100000000000000000000000000000000000000000000000001000000000000000000000000000000; |
306: 1100111110011000000000000000000000000000000000000000000000000000000000000000000000000000; |
307: 0010010100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
308: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
309: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
310: 0000000000000000000000000000000000000000000000000000000000000000110000000011000011010010; |
311: 0011111110000000000000000000000000000000000000000000000000000000000000000000000000000000; |
312: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
313: 1000111100000000000000000000000000000000000000000000000000000000010000000000000010101101; |
314: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
315: 0000000000000000000000000000000000000000000000000000000000000010100000001000001010001001; |
316: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
317: 1111111110100000000000000000000000000000000000000000000000000000000000000000000000000000; |
318: 1000111100000000000000000000000000000000000000000000000000000000010000000000000010101101; |
319: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
320: 0000000000000000000000000000000000000000000000000000000000000010100000001000010000001001; |
321: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
322: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
323: 0101111110100000000000000000000000000000000000000000000000000000000000000000000000000000; |
324: 0000000000000000000000000000000000000000000000000000000000000010100000000000000011010010; |
325: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
326: 0000000000000000000000000000000000000000000000000000000000000010100000001000001010001001; |
327: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
328: 1111111110100000000000000000000000000000000000000000000000000000000000000000000000000000; |
329: 0000000000000000000000000000000000000000000000000000000000000010100000000000000011010010; |
330: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
331: 0000000000000000000000000000000000000000000000000000000000000010100000001000010000001001; |
332: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
333: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
334: 0101111110100000000000000000000000000000000000000000000000000000000000000000000000000000; |
335: 0000000000000000000000000000000001000000000000000000000000000000010000000000001010001001; |
336: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
337: 0011111110101000000000000000000000000000000000000000000000000000000000000000000000000000; |
338: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
339: 0101111100000000000000000000000010000000000000000000000000000000000000000000000000000000; |
340: 0000000000000000000000000000000000000000000000000000000000000001110000000000001010001001; |
341: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
342: 1111111110110000000000000000000000000000000000000000000000000000000000000000000000000000; |
343: 0000000000000000000000000000000000000000000000000000000000000001100000000000000011010001; |
344: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
345: 0011111110110000000000000000000000000000000000000000000000000000000000000000000000000000; |
346: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
347: 0000000000000000000000000000000000000000000000000000000000000001110000000000001010001001; |
348: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
349: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
350: 0101111110000000000000000000000000000000000000000000000000000000000000000000000000000000; |
351: 0000000000000000000000000000000000000000000000000000000000000001110000100000001010001001; |
352: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
353: 1111111101100000000000000000000000000000000000000000000000000000000000000000000000000000; |
354: 0000000000000000000000000000000000000000000000000000000000000000110000100000000011001001; |
355: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
356: 0011111110001000000000000000000000000000000000000000000000000000000000000000000000000000; |
357: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
358: 0010011000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
359: 0000000000000000000000000000000000000000000000000000000000000000000000000100100000000000; |
360: 0010011100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
361: 0000000000000000000000000000000000000000000000000000000000000000000000000100000000000000; |
362: 0000000011010000000000000000000000000000000000000000000000000000010000000000001010001001; |
363: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
364: 1111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
365: 0000000000000000000000000000000000000000000000000000000000000000000000000011100000000000; |
366: 0011110011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
367: 1000111100000000000000000000000000000000000000000000000000000000100000000000000010101101; |
368: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
369: 0111011000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
370: 0000000000000000000000000000000000000000000000000000000000000000000000001000000000000000; |
371: 0000000000000000000000000000000000000000000000000000000000000000000000101010100000000000; |
372: 0000000010111000000000000000000000000000000000000000000000000000000000000000000000000000; |
373: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
374: 0000000000000000000000000000000000000000000000000000100000000000000000000000000000000000; |
375: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
376: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
377: 1101011100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
378: 0000000000000000000000000000000000000000000000000000000000000000100000010000000011010001; |
379: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
380: 0000000011000000000000000000000000000000000000000000000000000000000000000000000000000000; |
381: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
382: 1000111100000000000000000000000000000000000000000000000000000000100000000011100010101101; |
383: 0000000011010000000000000000000000000000000000000000000000000000000000000010000000000000; |
384: 0110100000000000000000000000000000000000000000000000000000000000000000000000000000000000; |
385: 0000000000000000000000000000000000000000000000000000000000000000000000001010100000000000; |
386: 0111111110111000000000000000000000000000000000000000000000000000000000000000000000000000; |
387: 0000000000000000000000000000000000000000000000000000100000000000000000000000000000000000; |
388: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
389: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
390: 0101111100000000000000000000000000000000000000000001000000000000000000000000000000000000; |
391: 0000000000000000000000000000000000000000000000000000000000000000100000000101001010001001; |
392: 0001111111010000000000000000000000000000000000000000000000000000000000000000000000000000; |
393: 1111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
394: 0000000000000000000000000000000000000000000000000000000000000000100000000000010000001001; |
395: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
396: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
397: 0101111111001000000000000000000000000000000000000000000000000000000000000000000000000000; |
398: 0000000000000000000000000000000000000000000000000000000000000000110000000000000011001001; |
399: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
400: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
401: 0000000000000000011000000000000000000000000000000000000000000000000000000000000000000000; |
402: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
403: 0000000000000000000000000000000000000000000000000000000000000000110000000101100011001001; |
404: 0011111111010000000000000000000000000000000000000000000000000000000000000000000000000000; |
405: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
406: 0000000000000000000000000000000000000000000000000000000000000000110000000000000011001001; |
407: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
408: 0000000011011000000000000000000000000000000000000000000000000000110000000000000010100100; |
409: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
410: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
411: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
412: 0000000000000000000000000000000000000000000000000000000000000000110000000000000011001100; |
413: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
414: 0000000011010000000000000000000000000000000000000000000000000000110000000000000011001001; |
415: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
416: 1000111100000000000000000000000000000000000000000000000000000000100000000000000010101101; |
417: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
418: 0000000000000000000000000000000000000000000000000000000000000000110000001000000011001100; |
419: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
420: 0011111110111000000000000000000000000000000000000000000000000000000000000000000000000000; |
421: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
422: 0000000000000000000000000000000000000000000000000000000000000000110000000000000011001001; |
423: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
424: 0000000011010000000000000000000000000000000000000000000000000000110000000000000011001100; |
425: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
426: 0000000000000000000000000000000000000000000000000000000000000000110000000000000011000100; |
427: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
428: 0010111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
429: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
430: 0000000011010000000000000000000000000000000000000000000000000000110000000000000011001001; |
431: 0011111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
432: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
433: 0000000000000000000000000000000000000000000000000000000000000000000000000011100000000000; |
434: 0011110011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
435: 1000111100000000000000000000000000000000000000000000000000000000100000000000000010101101; |
436: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
437: 0000000000000000000000000000000000000000000000000000000000000000000000001000000000000000; |
438: 0000000000000000000000000000000000000000000000000000000000000000000000101010100000000000; |
439: 0000000010111000000000000000000000000000000000000000000000000000000000000000000000000000; |
440: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
441: 0000000000000000000000000000000000000000000000000000100000000000000000000011100000000000; |
442: 0000000000000000000000000000000000000000000000000000000000000000110000000000000010100100; |
443: 0001111111010000000000000000000000000000000000000000000000000000000000000000000000000000; |
444: 1111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
445: 0000000000000000000000000000000000000000000000000000000000000000110000000000001000001001; |
446: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
447: 0000000000000000000000000000000000000000000000000000000000000000000000000001000000000000; |
448: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
449: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
450: 0000000000000000000000000000000000000000000000000000100000000000000000000000000000000000; |
451: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
452: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
453: 0000000000000000000000000000000000000000000000000000000000000000110000000000001000001001; |
454: 0001111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
455: 0000000000000000000000000000000000000000000000000000000000000000000000000001000000000000; |
456: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
457: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
458: 0000000000000000000000000000000000000000000000000000100000000000000000000011100000000000; |
459: 0000000000000000000000000000000000000000000000000000000000000000110000000000000010100100; |
460: 0001111111010000000000000000000000000000000000000000000000000000000000000000000000000000; |
461: 1111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
462: 0000000000000000000000000000000000000000000000000000000000000000100000000000000011000100; |
463: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
464: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
465: 0000000011010000000000000000000000000000000000000000000000000000110000000000000011000100; |
466: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
467: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
468: 0000000011010000000000000000000000000000000000000000000000000000000000000010100000000000; |
469: 0000000011001000000000000000000000000000000000000000000000000000000000000000000000000000; |
470: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
471: 0000000000000000000000000000000000000000000000000000100000000000000000000000000000000000; |
472: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
473: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
474: 0000000000000000000000000000000000000000000000000000000000000000110000000000000011000100; |
475: 1110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
476: 0100111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
477: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
478: 0111111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
479: 0000000000000000000000000000000000000000000000000000100000000000000000000000000000000000; |
480: 0000000011010000000000000000000000000000000000000000000000000000000000000000000000000000; |
481: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
482: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
483: 1011111100000000000000000000000000000000000000011100000000000000000000000000000000000000; |
484: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
485: 0010100100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
486: 1011111100000000000000000000000000000000000000010000000000000000000000000000000000000000; |
487: 0101111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
488: 0000000000000000000000000000000100000000000000000000000000000000000000000000000000000000; |
489: 0110111100000000000000000000000000000000000000000000000000000000000000000000000000000000; |
490: 0101111100000000000000000000001000000000000000000000000000000000000000000000000000000000; |
491: 1000111100000000000000000000000000000000000000000000000000000000100000000000000010101101; |
492: 0000000000000000000000000000000000000000000000000010000000000000000000000010000000000000; |
493: 0101111111001000000000000000000000000000010000000000000000000000000000000000000000000000; |
END; |
/trunk/rtl/verilog/ao68000/microcode_params.v
0,0 → 1,273
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
/*! \file microcode_params.v |
* \brief Definitions of microcode operations. |
*/ |
|
`define EA_REG_IDLE 3'd0 |
`define EA_REG_IR_2_0 3'd1 |
`define EA_REG_IR_11_9 3'd2 |
`define EA_REG_MOVEM_REG_2_0 3'd3 |
`define EA_REG_3b111 3'd4 |
`define EA_REG_3b100 3'd5 |
|
`define EA_MOD_IDLE 4'd0 |
`define EA_MOD_IR_5_3 4'd1 |
`define EA_MOD_MOVEM_MOD_5_3 4'd2 |
`define EA_MOD_IR_8_6 4'd3 |
`define EA_MOD_PREDEC 4'd4 // predecrement: -(An) |
`define EA_MOD_3b111 4'd5 // extended mod |
`define EA_MOD_DN_PREDEC 4'd6 // MOD.DN_PREDEC: Dn 3'b000 (ir[3] == 1'b0), -(An) 3'b100 (ir[3] == 1'b1) |
`define EA_MOD_DN_AN_EXG 4'd7 // MOD.DN_AN_EXG: Dn 3'b000 (ir[7:3] == 5'b01000 or 5'b10001), An 3'b001 (ir[7:3] == 5'b01001) |
`define EA_MOD_POSTINC 4'd8 // MOD.POSTINC: postincrement (An)+ 3'b011 |
`define EA_MOD_AN 4'd9 // MOD.AN: An 3'b001, saved result is sign-extended |
`define EA_MOD_DN 4'd10 // MOD.DN: Dn 3'b000 |
`define EA_MOD_INDIRECTOFFSET 4'd11 // MOD.INDIRECTOFFSET: (d16, An) 3'b101 |
|
`define EA_TYPE_IDLE 4'd0 |
`define EA_TYPE_ALL 4'd1 // TYPE.ALL: all |
`define EA_TYPE_CONTROL_POSTINC 4'd2 // TYPE.CONTROL_POSTINC: control or postincrement |
`define EA_TYPE_CONTROLALTER_PREDEC 4'd3 // TYPE.CONTROLALTER_PREDEC: control alter or predecrement |
`define EA_TYPE_CONTROL 4'd4 // TYPE.CONTROL: control |
`define EA_TYPE_DATAALTER 4'd5 // TYPE.DATAALTER: data alter |
`define EA_TYPE_DN_AN 4'd6 // TYPE.DN_AN: Dn, An |
`define EA_TYPE_MEMORYALTER 4'd7 // TYPE.MEMORYALTER: memory alter |
`define EA_TYPE_DATA 4'd8 // TYPE.DATA: data |
|
`define OP1_IDLE 4'd0 |
`define OP1_FROM_OP2 4'd1 // move from operand2 |
`define OP1_FROM_ADDRESS 4'd2 // move from address |
`define OP1_FROM_DATA 4'd3 // move from data, sign extend |
`define OP1_FROM_IMMEDIATE 4'd4 // move immediate, sign extend |
`define OP1_FROM_RESULT 4'd5 // move from result |
`define OP1_MOVEQ 4'd6 // move moveq: { 24{ir[7]}, ir[7:0] } |
`define OP1_FROM_PC 4'd7 // move from PC |
`define OP1_LOAD_ZEROS 4'd8 // load zeros: 32'b0 |
`define OP1_LOAD_ONES 4'd9 // load ones: 32'hFFFFFFFF |
`define OP1_FROM_SR 4'd10 // move from SR |
`define OP1_FROM_USP 4'd11 // move from USP |
`define OP1_FROM_AN 4'd12 // move from An, 32 bits |
`define OP1_FROM_DN 4'd13 // move from Dn, sign extend |
`define OP1_FROM_IR 4'd14 // move from ir[15:0] |
`define OP1_FROM_FAULT_ADDRESS 4'd15 // move from fault_address |
|
`define OP2_IDLE 3'd0 |
`define OP2_FROM_OP1 3'd1 // move from operand1 |
`define OP2_LOAD_1 3'd2 // load: 32'b1 |
`define OP2_LOAD_COUNT 3'd3 // load count |
`define OP2_ADDQ_SUBQ 3'd4 // load addq_subq |
`define OP2_MOVE_OFFSET 3'd5 // move offset |
`define OP2_MOVE_ADDRESS_BUS_INFO 3'd6 // move address_bus_info |
`define OP2_DECR_BY_1 3'd7 // decrement by 1 |
|
`define ADDRESS_IDLE 4'd0 |
`define ADDRESS_INCR_BY_SIZE 4'd1 // increment by size |
`define ADDRESS_DECR_BY_SIZE 4'd2 // decrement by size |
`define ADDRESS_INCR_BY_2 4'd3 // increment by 2 |
`define ADDRESS_FROM_AN_OUTPUT 4'd4 // move from An output |
`define ADDRESS_FROM_BASE_INDEX_OFFSET 4'd5 // move from base+index+offset |
`define ADDRESS_FROM_IMM_16 4'd6 // move from {16{ir1[15]}, ir1[15:0]} |
`define ADDRESS_FROM_IMM_32 4'd7 // move from {ir1[15:0], ir2[15:0]} |
`define ADDRESS_FROM_PC_INDEX_OFFSET 4'd8 // move from pc+index+offset |
`define ADDRESS_FROM_TRAP 4'd9 // move trap {22'b0, trap[7:0], 2'b0} |
|
`define SIZE_IDLE 4'd0 |
`define SIZE_BYTE 4'd1 // load byte: 2'b00 |
`define SIZE_WORD 4'd2 // load word: 2'b01 |
`define SIZE_LONG 4'd3 // load long: 2'b10 |
`define SIZE_1 4'd4 // SIZE.1: word ( ir[7:6] == 2'b00 ), long ( ir[7:6] == 2'b01 ) |
`define SIZE_1_PLUS 4'd5 // SIZE.1+: word ( ir[7:6] == 2'b10 ), long ( ir[7:6] == 2'b11 ) |
`define SIZE_2 4'd6 // SIZE.2: word ( ir[6] == 1'b0 ), long ( ir[6] == 1'b1 ) |
`define SIZE_3 4'd7 // SIZE.3: byte ( ir[7:6] == 2'b00 ), word ( ir[7:6] == 2'b01 ), long ( ir[7:6] == 2'b10 ) |
`define SIZE_4 4'd8 // SIZE.4: byte ( ir[13:12] == 2'b01 ), word( ir[13:12] == 2'b11 ), long ( ir[13:12] == 2'b10 ) |
`define SIZE_5 4'd9 // SIZE.5: word ( ir[8] == 1'b0 ), long ( ir[8] == 1'b1 ) |
`define SIZE_6 4'd10 // SIZE.6: byte ( ir[5:3] != 3'b000 ), long ( ir[5:3] == 3'b000 ) |
|
`define MOVEM_MODREG_IDLE 3'd0 |
`define MOVEM_MODREG_LOAD_0 3'd1 // load 6'b0 |
`define MOVEM_MODREG_LOAD_6b001111 3'd2 // load 6'b001111 |
`define MOVEM_MODREG_INCR_BY_1 3'd3 // increment by 1 |
`define MOVEM_MODREG_DECR_BY_1 3'd4 // decrement by 1 |
|
`define MOVEM_LOOP_IDLE 2'd0 |
`define MOVEM_LOOP_LOAD_0 2'd1 // load 4'b0 |
`define MOVEM_LOOP_INCR_BY_1 2'd2 // increment by 1 |
|
`define MOVEM_REG_IDLE 2'd0 |
`define MOVEM_REG_FROM_OP1 2'd1 // load from operand1[15:0] |
`define MOVEM_REG_SHIFT_RIGHT 2'd2 // shift right |
|
`define IR_IDLE 2'd0 |
`define IR_LOAD_WHEN_PREFETCH_VALID 2'd1 // load from prefetch_ir[79:64] |
|
`define PC_IDLE 3'd0 |
`define PC_FROM_RESULT 3'd1 // move from result |
`define PC_INCR_BY_2 3'd2 // increment by 2 |
`define PC_INCR_BY_4 3'd3 // increment by 4 |
`define PC_INCR_BY_SIZE 3'd4 // increment by size: 2 (size == 2'b00 || size == 2'b01), 4 (size == 2'b10) |
`define PC_FROM_PREFETCH_IR 3'd5 // move from prefetch_ir |
`define PC_INCR_BY_2_IN_MAIN_LOOP 3'd6 // increment by 2, in main loop, when valid prefetch and valid instruction |
|
`define TRAP_IDLE 4'd0 |
`define TRAP_ILLEGAL_INSTR 4'd1 // move illegal_instr: 8'd4 |
`define TRAP_DIV_BY_ZERO 4'd2 // move divide_by_zero: 8'd5 |
`define TRAP_CHK 4'd3 // move chk: 8'd6 |
`define TRAP_TRAPV 4'd4 // move trapv: 8'd7 |
`define TRAP_PRIVIL_VIOLAT 4'd5 // move priv_viol: 8'd8 |
`define TRAP_TRACE 4'd6 // move trace: 8'd9 |
`define TRAP_TRAP 4'd7 // move trap: { 3'b0, 1'b1, ir[3:0] } |
`define TRAP_FROM_DECODER 4'd8 // move from decoder_trap |
`define TRAP_FROM_INTERRUPT 4'd9 // move from interrupt_trap |
|
`define OFFSET_IDLE 2'd0 |
`define OFFSET_IMM_8 2'd1 // { 24{ir1[7]}, ir1[7:0] } |
`define OFFSET_IMM_16 2'd2 // { 16{ir1[15]}, ir1[15:0] } |
|
`define INDEX_IDLE 2'd0 |
`define INDEX_0 2'd1 // 32'b0 |
`define INDEX_LOAD_EXTENDED 2'd2 // load from extended instruction word |
|
`define STOP_FLAG_IDLE 2'd0 |
`define STOP_FLAG_SET 2'd1 // set, continue when: trace,interrupt or reset |
`define STOP_FLAG_CLEAR 2'd2 // clear |
|
`define TRACE_FLAG_IDLE 2'd0 |
`define TRACE_FLAG_COPY_WHEN_NO_STOP 2'd1 // remember trace bit, move from sr[15] |
|
`define GROUP_0_FLAG_IDLE 2'd0 |
`define GROUP_0_FLAG_SET 2'd1 // set, processing group zero exception |
`define GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH 2'd2 // clear |
|
`define INSTRUCTION_FLAG_IDLE 2'd0 |
`define INSTRUCTION_FLAG_SET 2'd1 // set, processing instruction |
`define INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP 2'd2 // clear, in main loop, when valid prefetch and valid instruction |
|
`define READ_MODIFY_WRITE_FLAG_IDLE 2'd0 |
`define READ_MODIFY_WRITE_FLAG_SET 2'd1 // set, execute a RMW cycle |
`define READ_MODIFY_WRITE_FLAG_CLEAR 2'd2 // clear |
|
`define DO_RESET_FLAG_IDLE 2'd0 |
`define DO_RESET_FLAG_SET 2'd1 // set, signal reset |
`define DO_RESET_FLAG_CLEAR 2'd2 // clear |
|
`define DO_INTERRUPT_FLAG_IDLE 2'd0 |
`define DO_INTERRUPT_FLAG_SET_IF_ACTIVE 2'd1 // set if interrupt active |
`define DO_INTERRUPT_FLAG_CLEAR 2'd2 // clear |
|
`define DO_READ_FLAG_IDLE 2'd0 |
`define DO_READ_FLAG_SET 2'd1 // set, perform read operation |
`define DO_READ_FLAG_CLEAR 2'd2 // clear |
|
`define DO_WRITE_FLAG_IDLE 2'd0 |
`define DO_WRITE_FLAG_SET 2'd1 // set, perform write operation |
`define DO_WRITE_FLAG_CLEAR 2'd2 // clear |
|
`define DO_BLOCKED_FLAG_IDLE 2'd0 |
`define DO_BLOCKED_FLAG_SET 2'd1 // set, block processor |
|
`define DATA_WRITE_IDLE 2'd0 |
`define DATA_WRITE_FROM_RESULT 2'd1 // load data write register from result register |
|
`define AN_ADDRESS_IDLE 2'd0 // load from ea_reg, user or supervisor |
`define AN_ADDRESS_FROM_EXTENDED 2'd1 // load from extended instruction word: ir1[14:12], user or supervisor |
`define AN_ADDRESS_USP 2'd2 // load USP address |
`define AN_ADDRESS_SSP 2'd3 // load SSP address |
|
`define AN_WRITE_ENABLE_IDLE 1'd0 |
`define AN_WRITE_ENABLE_SET 1'd1 // set write enable on An register |
|
`define AN_INPUT_IDLE 2'd0 // load from result |
`define AN_INPUT_FROM_ADDRESS 2'd1 // load from address |
`define AN_INPUT_FROM_PREFETCH_IR 2'd2 // load from prefetch_ir, for reset, for SSP |
|
`define DN_ADDRESS_IDLE 1'd0 // load from ea_reg |
`define DN_ADDRESS_FROM_EXTENDED 1'd1 // load from extended instruction word: ir1[14:12] |
|
`define DN_WRITE_ENABLE_IDLE 1'd0 |
`define DN_WRITE_ENABLE_SET 1'd1 // set write enable on Dn register |
|
`define ALU_IDLE 5'd0 |
`define ALU_SR_SET_INTERRUPT 5'd1 |
`define ALU_SR_SET_TRAP 5'd2 |
`define ALU_MOVEP_M2R_1 5'd3 |
`define ALU_MOVEP_M2R_2 5'd4 |
`define ALU_MOVEP_M2R_3 5'd5 |
`define ALU_MOVEP_M2R_4 5'd6 |
`define ALU_MOVEP_R2M_1 5'd7 |
`define ALU_MOVEP_R2M_2 5'd8 |
`define ALU_MOVEP_R2M_3 5'd9 |
`define ALU_MOVEP_R2M_4 5'd10 |
`define ALU_SIGN_EXTEND 5'd11 |
`define ALU_ARITHMETIC_LOGIC 5'd12 |
`define ALU_ABCD_SBCD_ADDX_SUBX 5'd13 |
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare 5'd14 |
`define ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR 5'd15 |
`define ALU_MOVE 5'd16 |
`define ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ 5'd17 |
`define ALU_CHK 5'd18 |
`define ALU_MULS_MULU_DIVS_DIVU 5'd19 |
`define ALU_BCHG_BCLR_BSET_BTST 5'd20 |
`define ALU_TAS 5'd21 |
`define ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT 5'd22 |
`define ALU_SIMPLE_LONG_ADD 5'd23 |
`define ALU_SIMPLE_LONG_SUB 5'd24 |
`define ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR 5'd25 |
`define ALU_SIMPLE_MOVE 5'd26 |
`define ALU_LINK_MOVE 5'd27 |
|
`define BRANCH_IDLE 4'd0 |
`define BRANCH_movem_loop 4'd1 // BRANCH(movem_loop == 4'b1000) |
`define BRANCH_movem_reg 4'd2 // BRANCH(movem_reg[0] == 0) |
`define BRANCH_operand2 4'd3 // BRANCH(operand2[5:0] == 6'b0) |
`define BRANCH_special_01 4'd4 // BRANCH(special != 2'b01) |
`define BRANCH_special_10 4'd5 // BRANCH(special == 2'b10) |
`define BRANCH_condition_0 4'd6 // BRANCH(condition == 1'b0) |
`define BRANCH_condition_1 4'd7 // BRANCH(condition == 1'b1) |
`define BRANCH_result 4'd8 // BRANCH(result[15:0] == 16'hFFFF) |
`define BRANCH_V 4'd9 // BRANCH(V == 1'b0) |
`define BRANCH_movep_16 4'd10 // BRANCH(ir[6] == 0) |
`define BRANCH_stop_flag_wait_ir_decode 4'd11 // BRANCH(stop_flag == 1'b1) if no branch: wait for prefetch ir valid and decode instruction |
`define BRANCH_ir 4'd12 // BRANCH(ir[7:0] != 8'b0) |
`define BRANCH_trace_flag_and_interrupt 4'd13 // BRANCH(trace_flag == 1'b0 && interrupt_mask != 3'b000) if no branch: jump to main loop |
`define BRANCH_group_0_flag 4'd14 // BRANCH(group_0_flag == 0) |
`define BRANCH_procedure 4'd15 // call procedure, return from procedure |
|
`define PROCEDURE_IDLE 4'd0 |
`define PROCEDURE_call_load_ea 4'd1 // load ea |
`define PROCEDURE_call_perform_ea_read 4'd2 // perform_ea_read |
`define PROCEDURE_call_perform_ea_write 4'd3 // perform_ea_write |
`define PROCEDURE_call_save_ea 4'd4 // save ea |
`define PROCEDURE_return 4'd5 // return from procedure |
`define PROCEDURE_wait_finished 4'd6 // wait for finished signal from bus controler |
`define PROCEDURE_wait_prefetch_valid 4'd7 // wait for prefetch ir valid, 64 bits |
`define PROCEDURE_wait_prefetch_valid_32 4'd8 // wait for prefetch ir valid, 32 bits |
`define PROCEDURE_jump_to_main_loop 4'd9 // jump to main loop |
`define PROCEDURE_push_micropc 4'd10 // save current micro_pc |
`define PROCEDURE_call_trap 4'd11 // call trap service procedure |
`define PROCEDURE_pop_micropc 4'd12 // pop most recent micro_pc and forget |
`define PROCEDURE_interrupt_mask 4'd13 // if interrupt active continue, else jump to main loop |
`define PROCEDURE_call_read 4'd14 // load_ea + perform_ea_read |
`define PROCEDURE_call_write 4'd15 // perform_ea_write + save_ea + return |
|
/trunk/rtl/verilog/ao68000/altera_specific/microcode_rom.v
0,0 → 1,53
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
/*! \file microcode_rom.v |
* \brief Altera-specific microcode ROM module. |
*/ |
|
/*! \brief Microcode ROM module. |
* |
* Currently this module contains a <em>altsyncram</em> instantiation |
* from Altera Megafunction/LPM library. |
*/ |
module microcode_rom( |
input clock, |
|
input [8:0] micro_pc, |
output [87:0] micro_data |
); |
|
altsyncram rom( |
.clock0(clock), |
|
.address_a(micro_pc), |
.q_a(micro_data) |
); |
defparam rom.operation_mode = "ROM"; |
defparam rom.width_a = 88; |
defparam rom.widthad_a = 9; |
defparam rom.outdata_reg_a = "UNREGISTERED"; |
defparam rom.init_file = "./../microcode/microcode.mif"; |
|
endmodule |
/trunk/rtl/verilog/ao68000/altera_specific/register_ram.v
0,0 → 1,59
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
/*! \file register_ram.v |
* \brief Altera-specific register set implemented as RAM. |
*/ |
|
/*! \brief Register set implemented as RAM. |
* |
* Currently this module contains a <em>altsyncram</em> instantiation |
* from Altera Megafunction/LPM library. |
*/ |
module register_ram( |
input clock, |
|
input [2:0] address, |
input [3:0] byte_enable, |
input write_enable, |
input [31:0] data_input, |
output [31:0] data_output |
); |
|
altsyncram ram( |
.clock0(clock), |
|
.address_a(address), |
.byteena_a(byte_enable), |
.wren_a(write_enable), |
.data_a(data_input), |
.q_a(data_output) |
); |
defparam ram.operation_mode = "SINGLE_PORT"; |
defparam ram.width_a = 32; |
defparam ram.widthad_a = 3; |
defparam ram.outdata_reg_a = "UNREGISTERED"; |
defparam ram.width_byteena_a = 4; |
|
endmodule |
/trunk/rtl/verilog/ao68000/altera_specific/alu_mult_div.v
0,0 → 1,117
/* |
* Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* |
* 1. Redistributions of source code must retain the above copyright notice, this list of |
* conditions and the following disclaimer. |
* |
* 2. Redistributions in binary form must reproduce the above copyright notice, this list |
* of conditions and the following disclaimer in the documentation and/or other materials |
* provided with the distribution. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
/*! \file alu_mult_div.v |
* \brief Altera-specific multiplication and division modules. |
*/ |
|
/*! \brief Multiplication and division modules. |
* |
* Currently this module contains <em>lpm_divide</em> and <em>lpm_mult</em> instantiations |
* from Altera Megafunction/LPM library. |
* |
* There are separate modules for: |
* - unsigned multiplication, |
* - signed multiplication, |
* - unsigned division, |
* - singed division. |
*/ |
module alu_mult_div( |
input clock, |
input reset, |
|
input [31:0] operand1, |
input [31:0] operand2, |
|
output [31:0] divu_quotient, |
output [15:0] divu_remainder, |
|
output [31:0] divs_quotient, |
output [15:0] divs_remainder, |
|
output [31:0] mulu_result, |
output [31:0] muls_result |
); |
|
// DIVU: 32-bit operand1 unsigned / 16-bit operand2 unsigned = {16-bit remainer unsigned, 16-bit quotient unsigned} |
// DIVU: division by 0: trap, overflow when quotient > 16-bit signed integer, operands not affected |
lpm_divide divu( |
.clock(clock), |
.numer(operand1[31:0]), |
.denom(operand2[15:0]), |
.quotient(divu_quotient), |
.remain(divu_remainder) |
); |
defparam divu.lpm_widthn = 32; |
defparam divu.lpm_widthd = 16; |
defparam divu.lpm_nrepresentation = "UNSIGNED"; |
defparam divu.lpm_drepresentation = "UNSIGNED"; |
defparam divu.lpm_remainderpositive = "TRUE"; |
defparam divs.lpm_hint = "LPM_REMAINDERPOSITIVE=TRUE"; |
defparam divu.lpm_pipeline = 30; |
|
// DIVS: 32-bit operand1 signed / 16-bit operand2 signed = {16-bit remainer signed = sign of dividend, 16-bit quotient signed} |
// DIVS: division by 0: trap, overflow when quotient > 16-bit signed integer, operands not affected |
lpm_divide divs( |
.clock(clock), |
.numer(operand1[31:0]), |
.denom(operand2[15:0]), |
.quotient(divs_quotient), |
.remain(divs_remainder) |
); |
defparam divs.lpm_widthn = 32; |
defparam divs.lpm_widthd = 16; |
defparam divs.lpm_nrepresentation = "SIGNED"; |
defparam divs.lpm_drepresentation = "SIGNED"; |
defparam divs.lpm_remainderpositive = "FALSE"; |
defparam divs.lpm_hint = "LPM_REMAINDERPOSITIVE=FALSE"; |
defparam divs.lpm_pipeline = 30; |
|
// MULU: 16-bit operand1[15:0] unsigned * 16-bit operand2 unsigned = 32-bit result unsigned |
lpm_mult mulu( |
.clock(clock), |
.dataa(operand1[15:0]), |
.datab(operand2[15:0]), |
.result(mulu_result) |
); |
defparam mulu.lpm_widtha = 16; |
defparam mulu.lpm_widthb = 16; |
defparam mulu.lpm_widthp = 32; |
defparam mulu.lpm_representation = "UNSIGNED"; |
defparam mulu.lpm_pipeline = 18; |
|
// MULS: 16-bit operand1[15:0] signed * 16-bit operand2 signed = 32-bit result signed |
lpm_mult muls( |
.clock(clock), |
.dataa(operand1[15:0]), |
.datab(operand2[15:0]), |
.result(muls_result) |
); |
defparam muls.lpm_widtha = 16; |
defparam muls.lpm_widthb = 16; |
defparam muls.lpm_widthp = 32; |
defparam muls.lpm_representation = "SIGNED"; |
defparam muls.lpm_pipeline = 18; |
|
endmodule |
/trunk/doc/doxygen_generated.tar.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/doc/doxygen_generated.tar.gz
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/src/specification_template.odt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/src/specification_template.odt
===================================================================
--- trunk/doc/src/specification_template.odt (nonexistent)
+++ trunk/doc/src/specification_template.odt (revision 2)
trunk/doc/src/specification_template.odt
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/src/directory.txt
===================================================================
--- trunk/doc/src/directory.txt (nonexistent)
+++ trunk/doc/src/directory.txt (revision 2)
@@ -0,0 +1,48 @@
+- bench ........................................................................ Testbench sources
+ - sw_simulators ............................................................ Software MC68000 emulators
+ - winuae ............................................................... WinUAE MC68000 processor emulator
+ - verilog .................................................................. Verilog language testbenches
+ - tb_ao68000 ........................................................... ao68000 testbench for comparison with software emulators
+
+- doc .......................................................................... Project documentation
+ - doxygen .................................................................. Doxygen auto-generated documentation
+ - html ................................................................. Doxygen HTML documentation
+ - img ...................................................................... Documentation images
+ - out ...................................................................... Output of specification extraction tool
+ - src ...................................................................... Documentation sources
+
+- rtl .......................................................................... RTL core sources
+ - verilog .................................................................. Verilog language RTL sources
+ - ao68000 .............................................................. ao68000 core sources
+ - altera_specific .................................................. Altera specific modules
+ - microcode ........................................................ Microcode with locations
+ - full_system .......................................................... System-on-Chip example for ao68000
+
+- sim .......................................................................... Simulation scripts and binaries
+ - rtl_sim .................................................................. RTL simulation scripts
+ - bin .................................................................. Scripts for compiling testbench tb_ao68000
+ - run .................................................................. Testbench build directory
+ - rtl_sw_compare ........................................................... ao68000 RTL comparison with MC68000 software emulators
+ - bin .................................................................. Scripts to prepare the comparison
+ - run .................................................................. Comparison run directory
+ - sw_emulators ............................................................. MC68000 software emulator scripts
+ - bin .................................................................. Scripts for compiling WinUAE software MC68000 emulator
+ - run .................................................................. WinUAE build directory
+
+- sw ........................................................................... Software projects and tools
+ - ao68000_tool ............................................................. ao68000_tool NetBeans project
+ - build ................................................................ Compiled classes
+ - dist ................................................................. Final compiled and assembled JAR
+ - nbproject ............................................................ NetBeans project directory
+ - src .................................................................. ao68000_tool sources
+ - test ................................................................. Tests directory
+ - linux .................................................................... Linux kernel sources for ao68000 support
+ - linux-2.6.33.1-ao68000 ............................................... Linux kernel version 2.6.33.1
+ - nbcd_abcd_sbcd ........................................................... Binary Coded Decimal test tool
+
+- syn .......................................................................... Synthesis directory
+ - altera ................................................................... Altera Quartus II synthesis tool support
+ - bin .................................................................. Synthesis scripts
+ - run .................................................................. System-on-Chip full_system project files
+ - out .................................................................. Synthesis directory
+
Index: trunk/doc/src/old_notes.txt
===================================================================
--- trunk/doc/src/old_notes.txt (nonexistent)
+++ trunk/doc/src/old_notes.txt (revision 2)
@@ -0,0 +1,1348 @@
+*******************************************************************************************************************************************
+NOTE: The information bellow is not current. It is here only for historical reasons.
+*******************************************************************************************************************************************
+
+if( ir[15:12] == 4'b0000 && ir[8] == 1'b0 && ir[11:9] != 3'b100 && ir[11:9] != 3'b110 &&
+ ir[15:0] != 16'b0000_000_0_00_111100 && ir[15:0] != 16'b0000_000_0_01_111100 &&
+ ir[15:0] != 16'b0000_001_0_00_111100 && ir[15:0] != 16'b0000_001_0_01_111100 &&
+ ir[15:0] != 16'b0000_101_0_00_111100 && ir[15:0] != 16'b0000_101_0_01_111100
+)
+ ANDI,EORI,ORI,ADDI,SUBI
++++
+ if( ir[7:6] == 2'b00 ) load ir1[7:0] to operand1[7:0]
+ else if( ir[7:6] == 2'b01 ) load ir1[15:0] to operand1[15:0]
+ else if( ir[7:6] == 2'b10 ) load { ir1, ir2 } to operand1[31:0]
+
+ move operand1 to operand2
+
+ operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ load (ea) from ir[5:0] to operand1: data alter
+ Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+
+ perform ALU operation:
+ if( ir[11:9] == 3'b000 ) OR
+ else if( ir[11:9] == 3'b001 ) AND
+ else if( ir[11:9] == 3'b010 ) SUB
+ else if( ir[11:9] == 3'b011 ) ADD
+ else if( ir[11:9] == 3'b101 ) EOR
+
+ update CCR:
+ ANDI,EORI,ORI: X not affected; C cleared; V cleared; Z set if zero else clear; N set if MSB set else cleared
+ ADDI,SUBI: same as ADD: X=C set if carry[borrow] generated else cleared; V set if overflow else cleared; Z set if result zero else cleared;
+ N set if result negative else cleared
+
+ save result to (ea) from ir[5:0]
+
+ update PC
+
+if( ir[15:0] == 16'b0000_000_0_00_111100 || ir[15:0] == 16'b0000_000_0_01_111100 ||
+ ir[15:0] == 16'b0000_001_0_00_111100 || ir[15:0] == 16'b0000_001_0_01_111100 ||
+ ir[15:0] == 16'b0000_101_0_00_111100 || ir[15:0] == 16'b0000_101_0_01_111100
+)
+ ORI to CCR,ORI to SR,ANDI to CCR,ANDI to SR,EORI to CCR,EORI to SR
++++
+ if( ir[7:6] == 2'b00 ) load ir1[7:0] to operand1[7:0]
+ else if( ir[7:6] == 2'b01 ) load ir1[15:0] to operand1[15:0]
+ else if( ir[7:6] == 2'b10 ) load { ir1, ir2 } to operand1[31:0]
+
+ move operand1 to operand2
+
+ operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ move SR to operand1
+
+ perform ALU operation:
+ if( ir[11:9] == 3'b000 ) OR
+ else if( ir[11:9] == 3'b001 ) AND
+ else if( ir[11:9] == 3'b101 ) EOR
+
+ move result to operand1
+
+ save operand1 to CCR/SR
+
+ update CCR:
+ result
+
+ update PC
+
+if( ir[15:12] == 4'b0000 && ir[8] == 1'b0 && ir[11:9] = 3'b110 )
+ CMPI
++++
+ if( ir[7:6] == 2'b00 ) load ir1[7:0] to operand2[7:0]
+ else if( ir[7:6] == 2'b01 ) load ir1[15:0] to operand2[15:0]
+ else if( ir[7:6] == 2'b10 ) load { ir1, ir2 } to operand2[31:0]
+
+ operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ load (ea) from ir[5:0] to operand1: data alter
+ Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+
+ perform ALU operation:
+ if( ir[11:9] == 3'b110 ) CMP=SUB
+
+ update CCR:
+ CMPI: same as CMP: X not affected; C set if borrow else cleared; V set if overflow else cleared; Z set if zero else cleared;
+ N set if negative else cleared
+
+ update PC
+
+if( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] != 2'b00 )
+ BCHG,BCLR,BSET immediate
++++
+ load ir1[7:0] to operand1[7:0]
+
+ move operand1 to operand2
+
+ load (ea) form ir[5:0] to operand1: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+
+ operation size:
+ if( ir[5:3] == 3'b000 ) long
+ else if( ir[5:3] != 3'b000 ) byte
+
+ perform bit operation:
+ test( of Destination ) -> Z; test( of Destination )[0][1] -> of Destination
+ if( ir[7:6] == 2'b01 ) BCHG
+ else if( ir[7:6] == 2'b10 ) BCLR
+ else if( ir[7:6] == 2'b11 ) BSET
+
+ update CCR: X,N,V,C not affected; Z set if bit tested is zero else cleared
+
+ save result to (ea) form ir[5:0]
+
+ update PC
+
+if( ir[15:12] == 4'b0000 && ir[11:8] == 4'b1000 && ir[7:6] == 2'b00 )
+ BTST immediate
++++
+ load ir1[7:0] to operand1[7:0]
+
+ move operand1 to operand2
+
+ load (ea) form ir[5:0] to operand1: data address
+ data address: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ operation size:
+ if( ir[5:3] == 3'b000 ) long
+ else if( ir[5:3] != 3'b000 ) byte
+
+ perform bit operation:
+ test( of Destination ) -> Z
+ if( ir[7:6] == 2'b00 ) BTST
+
+ update CCR: X,N,V,C not affected; Z set if bit tested is zero else cleared
+
+ update PC
+
+if( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] != 3'b001 && ir[8:6] != 3'b100 )
+ BCHG,BCLR,BSET register
++++
+ load (ea) from ir[11:9] to operand1[7:0]: Dn
+
+ move operand1 to operand2
+
+ load (ea) form ir[5:0] to operand1: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+
+ operation size:
+ if( ir[5:3] == 3'b000 ) long
+ else if( ir[5:3] != 3'b000 ) byte
+
+ perform bit operation:
+ test( of Destination ) -> Z; test( of Destination )[0][1] -> of Destination
+ if( ir[7:6] == 2'b01 ) BCHG
+ else if( ir[7:6] == 2'b10 ) BCLR
+ else if( ir[7:6] == 2'b11 ) BSET
+
+ update CCR: X,N,V,C not affected; Z set if bit tested is zero else cleared
+
+ save result to (ea) form ir[5:0]
+
+ update PC
+
+if( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] != 3'b001 && ir[8:6] == 3'b100 )
+ BTST register
++++
+ load (ea) from ir[11:9] to operand1[7:0]: Dn
+
+ move operand1 to operand2
+
+ load (ea) form ir[5:0] to operand1: data address
+ data address: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ operation size:
+ if( ir[5:3] == 3'b000 ) long
+ else if( ir[5:3] != 3'b000 ) byte
+
+ perform bit operation:
+ test( of Destination ) -> Z
+ if( ir[7:6] == 2'b00 ) BTST
+
+ update CCR: X,N,V,C not affected; Z set if bit tested is zero else cleared
+
+ update PC
+
+if( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b00 || ir[7:6] == 2'b01 ) )
+ MOVEP memory to register
++++
+ operation size:
+ if( ir[7:6] == 2'b00 ) word
+ if( ir[7:6] == 2'b01 ) long
+
+ load ea from ir[2:0] to address register: (d16, An)
+
+ do
+ load from (address) to operand1 register, long
+ move two alternate bytes to result register
+ increment ea by 4
+ repeat for long
+
+ save result to (ea) from ir[11:9]: Dn, word ( ir[7:6] == 2'b00 ), long ( ir[7:6] == 2'b01 )
+
+ update CCR: no change
+ update PC
+
+if( ir[15:12] == 4'b0000 && ir[8] == 1'b1 && ir[5:3] == 3'b001 && ( ir[7:6] == 2'b10 || ir[7:6] == 2'b11 ) )
+ MOVEP register to memory
++++
+ operation size:
+ if( ir[7:6] == 2'b10 ) word
+ if( ir[7:6] == 2'b11 ) long
+
+ load (ea) from ir[11:9] to operand1: Dn, long
+
+ load ea from ir[2:0] to address register: (d16, An)
+
+ do
+ move two alternate bytes to result register
+ save result register to (addreess), long, only selected bytes
+ increment ea by 4
+ repeat for long
+
+ update CCR: no change
+ update PC
+
+if( ir[15:14] == 2'b00 && ir[13:12] != 2'b00 && ir[8:6] != 3'b001)
+ MOVE
++++
+ size of operation: ir[13:12]: 01,11,10 byte,word,long
+
+ load (ea) from ir[5:0] to operand1: all modes.
+ all modes: Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ copy operand1 to result register
+
+ save result to (ea) from ir[11:6]: data alter.
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+
+ update PC
+
+if( ir[15:14] == 2'b00 && (ir[13:12] == 2'b11 || ir[13:12] == 2'b10) && ir[8:6] == 3'b001)
+ MOVEA
++++
+ size of operation: ir[13:12]: 11,10 word,long
+
+ load (ea) from ir[5:0] to operand1: all modes.
+ all modes: Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ copy operand1 to result register
+
+ save result to (ea) from ir[11:6]: An
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:12] == 4'b1100 && (ir[8:4] == 5'b10100 || 5'b11000) )
+ EXG
++++
+ load (ea) from ir[5:0] to operand1: Dn, An
+
+ perform ALU operation: move operand1 to result register
+
+ load (ea) from ir[11:9] with mode in ir[7:3] to operand1: Dn (5'b01000 or 5'b10001), An (5'b01001)
+
+ save result to (ea) from ir[11:9] with mode in ir[7:3]: Dn (5'b01000 or 5'b10001), An (5'b01001),
+
+ perform ALU operation: move operand1 to result register
+
+ save result to (ea) from ir[5:0]: Dn, An
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || 3'b101 || 3'b110) && ir[5:3] == 3'b001 )
+ CMPM
++++
+ load (ea) from ir[2:0] to operand1: postincrement (An)+
+
+ move operand1 to operand2
+
+ load (ea) from ir[11:9] to operand1: postincrement (An)+
+
+ ALU operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ perform ALU operation: CMPM == SUB
+
+ CC: X not affected; C set if borrow else cleared; V set if overflow else cleared; Z set if zero else cleared; N set if negative else cleared
+ Ax dest, Ay source: postincrement: +(An)
+
+ update PC
+
+if( ir[15:12] == 4'b1011 && (ir[8:6] == 3'b100 || 3'b101 || 3'b110) && ir[5:3] != 3'b001 )
+ EOR
++++
+ load (ea) from ir[11:9] to operand1: Dn
+
+ move operand1 to operand2
+
+ load (ea) from ir[5:0] to operand1: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+
+ ALU operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ perform ALU operation: EOR
+
+ CC: X not affected; C cleared; V cleared; Z set if zero else clear; N set if MSB set else cleared
+
+ save result to (ea) from ir[5:0]: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+ update PC
+
+if( (ir[15:12] == 4'b1101 || 4'b1001 || 4'b1100 || 4'b1000) &&
+ (ir[8:4] == 5'b10001 || 5'b10010 || 5'b10011 || 5'b10101 || 5'b10110 || 5'b10111 || 5'b11001 || 5'b11010 || 5'b11011) )
+
+ ADD to mem,SUB to mem,AND to mem,OR to mem
++++
+ load (ea) from ir[11:9] to operand1: Dn
+
+ move operand1 to operand2
+
+ load (ea) indexed by ir[5:0] to operand1: memory alter
+ memory alter: (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+
+ ALU operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ perform ALU operation:
+ if( ir[15:12] == 4'b1101 ) ADD
+ else if( ir[15:12] == 4'b1001 ) SUB
+ else if( ir[15:12] == 4'b1100 ) AND
+ else if( ir[15:12] == 4'b1000 ) OR
+
+ if( ADD,SUB )
+ CC: X=C set if carry[borrow] generated else cleared; V set if overflow else cleared; Z set if result zero else cleared;
+ N set if result negative else cleared
+ else if( AND,OR )
+ CC: X not affected; C cleared; V cleared; Z set if zero else clear; N set if MSB set else cleared
+
+ save result to (ea) from ir[5:0]: memory alter
+ memory alter: (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+
+ update PC
+
+if( (ir[15:12] == 4'b1101 || 4'b1001 || 4'b1100 || 4'b1000) && (ir[8:6] == 3'b000 || 3'b001 || 3'b010) )
+ ADD to Dn,SUB to Dn,AND to Dn,OR to Dn
++++
+ load (ea) from ir[5:0] to operand1: all modes
+ all modes: Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ move operand1 to operand2
+
+ load (ea) from ir[11:9] to operand1: Dn
+
+ ALU operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ perform ALU operation:
+ if( ir[15:12] == 4'b1101 ) ADD
+ else if( ir[15:12] == 4'b1001 ) SUB
+ else if( ir[15:12] == 4'b1100 ) AND
+ else if( ir[15:12] == 4'b1000 ) OR
+
+ if( ADD,SUB )
+ CC: X=C set if carry[borrow] generated else cleared; V set if overflow else cleared; Z set if result zero else cleared;
+ N set if result negative else cleared
+ else if( AND,OR )
+ CC: X not affected; C cleared; V cleared; Z set if zero else clear; N set if MSB set else cleared
+
+ save result to (ea) from ir[11:9]: Dn
+
+ update PC
+
+if( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b000 || 3'b001 || 3'b010) )
+ CMP
++++
+ load (ea) from ir[5:0] to operand1: all modes
+ all modes: Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ move operand1 to operand2
+
+ load (ea) from ir[11:9] to operand1: Dn
+
+ ALU operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ perform ALU operation:
+ if( ir[15:12] == 4'b1011 ) CMP=SUB
+
+ CC: X not affected; C set if borrow else cleared; V set if overflow else cleared; Z set if zero else cleared; N set if negative else cleared
+
+ update PC
+
+if( (ir[15:12] == 4'b1100 || 4'b1000) && ir[7:6] == 2'b11 )
+ MULS,MULU,DIVS,DIVU
++++
+ load (ea) from ir[5:0] to operand1: data
+ data: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ move operand1 to operand2
+
+ load (ea) from ir[11:9] to operand1: Dn
+
+ perform ALU operation:
+ if( ir[15:12] == 4'b1100 && ir[8] == 1'b0 ) MULU
+ else if( ir[15:12] == 4'b1100 && ir[8] == 1'b1 ) MULS
+ else if( ir[15:12] == 4'b1000 && ir[8] == 1'b0 ) DIVU
+ else if( ir[15:12] == 4'b1000 && ir[8] == 1'b1 ) DIVS
+
+ if( MULU/MULS )
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+ else if( DIVU/DIVS )
+ CC: X not affected; C cleared; V set if overflow else if trap undefined else cleared;
+ Z set if quotient zero else if trap or overflow undefined else cleared;
+ N set if quotient negative else if trap or overflow undefined else cleared;
+
+ save result to (ea) from ir[11:9]: Dn
+
+ update PC
+
+if( (ir[15:12] == 4'b1101 || 4'b1001) && (ir[8:6] == 3'b011 || 3'b111) )
+ ADDA,SUBA
++++
+ load (ea) from ir[5:0] to operand1: all modes
+ all modes: Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ move operand1 to operand2
+
+ load (ea) from ir[11:9] to operand1: An
+
+ ALU operation size, source is sign-extended:
+ if( ir[8] == 1'b0 ) word
+ else if( ir[8] == 1'b1 ) long
+
+ perform ALU operation:
+ if( ir[14:12] == 3'b101 ) ADD
+ else if( ir[14:12] == 3'b001 ) SUB
+
+ CC: not affected
+
+ save result sign-extended to (ea) from ir[11:9]: An
+
+ update PC
+
+if( (ir[15:12] == 4'b1011) && (ir[8:6] == 3'b011 || 3'b111) )
+ CMPA
++++
+ load (ea) from ir[5:0] to operand1: all modes
+ all modes: Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ move operand1 to operand2
+
+ load (ea) from ir[11:9] to operand1: An
+
+ ALU operation size, source is sign-extended:
+ if( ir[8] == 1'b0 ) word
+ else if( ir[8] == 1'b1 ) long
+
+ perform ALU operation:
+ if( ir[14:12] == 3'b011 ) CMP==SUB
+
+ CC: X not affected; C set if borrow else cleared; V set if overflow else cleared; Z set if zero else cleared; N set if negative else cleared
+
+ update PC
+
+if( ((ir[15:12] == 4'b1100 || 4'b1000) && ir[8:4] == 5'b10000) || ((if[15:12] == 4'b1101 || 4'b1001) && (ir[8:4] == 5'b10000 || 5'b10100 || 5'b11000) )
+ ABCD,SBCD,ADDX,SUBX
++++
+ load (ea) from ir[2:0] to operand1: Dn (ir[3] == 1'b0), -(An) (ir[3] == 1'b1)
+
+ move operand1 to operand2
+
+ load (ea) from ir[11:9] to operand1: Dn (ir[3] == 1'b0), -(An) (ir[3] == 1'b1)
+
+
+ ALU operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ perform ALU operation:
+ if( ir[14:12] == 3'b100 ) ABCD
+ else if( ir[14:12] == 3'b000 ) SBCD
+ else if( ir[14:12] == 3'b101 ) ADDX
+ else if( ir[14:12] == 3'b001 ) SUBX
+
+ if( ir[12] == 1'b0 /ABCD,SBCD/ )
+ CC: X=C set if decimal carry [borrow] else cleared; Z cleared if result nonzero else unchanged; N,V undefined
+ else
+ CC: X=C set if carry[borrow] else cleared; V set if overflow else cleared; Z cleared if nonzero else unchanged; N set if negative else cleared
+
+ save result to (ea) from ir[11:9]: Dn (ir[3] == 1'b0), -(An) (ir[3] == 1'b1)
+
+ update PC
+
+if( ir[15:12] == 4'b1110 && ir[7:6] == 2'b11 && ir[11] == 1'b0 )
+ ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all memory
++++
+ load (ea) from ir[5:0] to operand1: memory alter
+ memory alter: (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+ load 1'b1 to operand2
+
+ ALU operation size: word
+
+ ALU shift/rotate direction:
+ if( ir[8] == 1'b0 ) right
+ else if( ir[8] == 1'b1 ) left
+
+ perform ALU operation:
+ if( ir[10:9] == 2'b00 ) ASL/ASR
+ else if( ir[10:9] == 2'b01 ) LSL,LSR
+ else if( ir[10:9] == 2'b11 ) ROL,ROR
+ else if( ir[10:9] == 2'b10 ) ROXL,ROXR
+
+ CC: X set to last bit, unchanged if zero shift[same][not affected][same set]; N set if MSB bit is set else cleared; Z set if zero else cleared;
+ V set if MSB bit changed during shift else cleared[cleared][cleared][cleared]; C set to last bit, cleared if zero shift[same][same][set to X]
+
+ save result to (ea) from ir[5:0]: memory alter
+ memory alter: (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+ update PC
+
+if( ir[15:12] == 4'b1110 && (ir[7:6] == 2'b00 || 2'b01 || 2'b10) )
+ ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR all immediate/register
++++
+ load (ea) from ir[11:9] to operand1: Dn
+
+ move operand1 to operand2
+
+ load (ea) from ir[2:0] to operand1: Dn
+
+ if( ir[5] == 1'b0 )
+ if( ir[11:9] == 3'b000 ) load 4'b1000 to operand2
+ else load ir[11:9] to operand2
+ else if( ir[5] == 1'b1 )
+ perform operand2 modulo 64
+
+ ALU operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ ALU shift/rotate direction:
+ if( ir[8] == 1'b0 ) right
+ else if( ir[8] == 1'b1 ) left
+
+ perform ALU operation:
+ if( ir[4:3] == 2'b00 ) ASL/ASR
+ else if( ir[4:3] == 2'b01 ) LSL,LSR
+ else if( ir[4:3] == 2'b11 ) ROL,ROR
+ else if( ir[4:3] == 2'b10 ) ROXL,ROXR
+
+ CC: X set to last bit, unchanged if zero shift[same][not affected][same set]; N set if MSB bit is set else cleared; Z set if zero else cleared;
+ V set if MSB bit changed during shift else cleared[cleared][cleared][cleared]; C set to last bit, cleared if zero shift[same][same][set to X]
+
+ save result to (ea) from ir[2:0]: Dn
+
+ update PC
+
+if( ir[15:12] == 4'b0111 && ir[8] == 1'b0 )
+ MOVEQ
++++
+ load ir[7:0] sign-extended to result register
+
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+
+ save result to (ea) from ir[11:9]: Dn
+
+ update PC
+
+if( ir[15:12] == 4'b0110 && ir[11:8] == 4'b0001 )
+ BSR
++++
+ CC: not affected
+
+ SP -= 4
+
+ move PC to operand1
+ move operand1 to result
+
+ save result to (ea): (SP)
+
+ if( ir[7:0] == 8'b0 )
+ add to PC: ir1[15:0]
+ else
+ add to PC: ir[7:0]
+
+ return
+
+if( ir[15:12] == 4'b0110 && ir[11:8] != 4'b0001 )
+ Bcc,BRA
++++
+ condition: high(!C & !Z) 0010, low or same(C | V) 0011,
+ carry clear(!C) 0100, carry set(C) 0101, not equal(Z) 0110, equal(!Z) 0111,
+ overflow clear(!V) 1000, overflow set(V) 1001, plus(!N) 1010, minus(N) 1011,
+ greater or equal(N & V | !N & !V) 1100, less than(N & !V | !N & V) 1101,
+ greater than(N & V & !Z | !N & !V & !Z) 1110, less or equal(Z | N & !V | !N & V) 1111
+
+ CC: not affected
+
+ if( contidtion on ir[11:8] true )
+ if( ir[7:0] == 8'b0 )
+ add to PC: ir1[15:0]
+ else
+ add to PC: ir[7:0]
+
+ return
+
+ update PC
+
+if( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] != 2'b001 )
+ Scc
++++
+ condition: true(1) 0000, false(0) 0001, high(!C & !Z) 0010, low or same(C | V) 0011,
+ carry clear(!C) 0100, carry set(C) 0101, not equal(Z) 0110, equal(!Z) 0111,
+ overflow clear(!V) 1000, overflow set(V) 1001, plus(!N) 1010, minus(N) 1011,
+ greater or equal(N & V | !N & !V) 1100, less than(N & !V | !N & V),
+ greater than(N & V & !Z | !N & !V & !Z), less or equal(Z | N & !V | !N & V) 1111
+
+ if( contidtion on ir[11:8] false )
+ load 8'b00000000 to result
+ else
+ load 8'b11111111 to result
+
+ operation size: byte
+
+ save result to (ea) from ir[5:0]: data alter.
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+ CC: not affected
+
+ update PC
+
+if( ir[15:12] == 4'b0101 && ir[7:6] == 2'b11 && ir[5:3] == 2'b001 )
+ DBcc
++++
+ condition: true(1) 0000, false(0) 0001, high(!C & !Z) 0010, low or same(C | V) 0011,
+ carry clear(!C) 0100, carry set(C) 0101, not equal(Z) 0110, equal(!Z) 0111,
+ overflow clear(!V) 1000, overflow set(V) 1001, plus(!N) 1010, minus(N) 1011,
+ greater or equal(N & V | !N & !V) 1100, less than(N & !V | !N & V),
+ greater than(N & V & !Z | !N & !V & !Z), less or equal(Z | N & !V | !N & V) 1111
+
+ CC: not affected
+
+ if( condition on ir[11:8] false )
+ load (ea) from ir[2:0] to operand1: Dn
+
+ load 1'b1 to operand2
+
+ ALU operation size: word
+
+ perform ALU operation: SUB
+
+ save result to (ea) from ir[2:0]: Dn
+
+ if( result != -1 )
+ add to PC: ir1[15:0]
+ return
+
+ update PC
+
+if( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[5:3] != 3'b001 )
+ ADDQ,SUBQ not An
++++
+ if( ir[11:9] == 3'b000 )
+ load 4'b1000 to operand2
+ else
+ load ir[11:9] to operand2
+
+ load (ea) from by ir[5:0] to operand1: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+
+ ALU operation size:
+ if( ir[7:6] == 2'b10 ) long
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b00 ) byte
+
+ perform ALU operation:
+ if( ir[8] == 1'b0 ) ADDQ
+ else if( ir[8] == 1'b1 ) SUBQ
+
+ CC: X=C set if carry[borrow] generated else cleared; V set if overflow else cleared; Z set if result zero else cleared;
+ N set if result negative else cleared
+
+ save result to (ea) from ir[5:0]
+
+ update PC
+
+if( ir[15:12] == 4'b0101 && ir[7:6] != 2'b11 && ir[5:3] == 3'b001)
+ ADDQ,SUBQ An
++++
+ if( ir[11:9] == 3'b000 )
+ load 4'b1000 to operand2
+ else
+ load ir[11:9] to operand2
+
+ load (ea) from by ir[2:0] to operand1: An
+
+ ALU operation size: long
+
+ perform ALU operation:
+ if( ir[8] == 1'b0 ) ADD
+ else if( ir[8] == 1'b1 ) SUB
+
+ CC: not affected
+
+ save result to (ea) from ir[2:0]: An
+
+ update PC
+
+if( ir[15:0] == 16'b0100 1110 0111 0001 )
+ NOP
++++
+ CC: not affected
+
+ update PC
+
+if( ir[15:0] == 16'b0100 1110 0111 0000 )
+ RESET
++++
+ hold REST output for 124 clock cycles
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:0] == 16'b0100 1110 0111 0010 )
+ STOP
++++
+ copy ir1[15:0] to SR
+
+ Resume when trace, interrupt or rest.
+
+if( ir[15:5] == 12'b0100 1110 0100 )
+ TRAP
++++
+ TRAP with vector indexed by ir[3:0]
+
+ CC: not affected
+
+if( ir[15:0] == 16'b0100 1110 0111 0110 )
+ TRAPV
++++
+ if( V ) TRAP
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:0] == 16'b0100 1110 0111 0011 || ir[15:0] == 16'b0100 1110 0111 0111 )
+ RTE,RTR
++++
+ load (ea) to operand1: (SP)
+
+ perform ALU operation:
+ if(ir[2] == 1'b0) move operand1 to SR
+ else if(ir[2] == 1'b1) move operand1 to CCR
+
+ SP += 2
+
+ load (ea) to operand1: (SP)
+ move operand1 to result
+ move result to PC
+
+ SP += 4
+
+if( ir[15:0] == 16'b0100 1110 0111 0101 )
+ RTS
++++
+ load (ea) to operand1: (SP)
+ move operand1 to result
+ move result to PC
+
+ SP += 4
+
+if( ir[15:6] == 10'b0100 1110 11 )
+ JMP
++++
+ load (ea) from ir[5:0] to operand1: control
+ control: (An) 010, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ perform ALU operation: move operand1 to result
+
+ copy result register to PC
+
+ CC: not affected
+
+if( ir[15:6] == 10'b0100 1110 10 )
+ JSR
++++
+ SP -= 4
+
+ move PC to operand1
+ move operand1 to result
+ save result to (ea): (SP)
+
+ load (ea) from ir[5:0] to operand1: control
+ control: (An) 010, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ perform ALU operation: move operand1 to result
+
+ copy result register to PC
+
+ CC: not affected
+
+if( ir[15:3] == 13'b0100 1110 0101 0 )
+ LINK
++++
+ SP -= 4
+
+ load (ea) from ir[2:0] to operand1: An
+
+ perform ALU operation: move operand1 to result
+
+ save result to (ea): (SP)
+
+ load (ea) to operand1: SP
+ move operand1 to result
+
+ save result to (ea) from ir[2:0]: An
+
+ add to SP: ir1[15:0]
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:3] == 13'b0100 1110 0101 1 )
+ ULNK
++++
+ load (ea) from ir[2:0] to operand1: An
+
+ perform ALU operation: move operand1 to result
+
+ save result to (ea): SP
+
+ load ea to operand1: (SP)
+ move operand1 to result
+
+ save result to (ea) from ir[2:0]: An
+
+ SP += 4
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:8] == 8'b0100 1010 && ir[7:6] != 2'b11 )
+ TST
++++
+ ea operation size:
+ if( ir[7:6] == 2'b00 ) byte
+ else if( ir[7:6] == 2'b01 ) word
+ else if( ir[7:6] == 2'b10 ) long
+
+ load (ea) from ir[5:0] to operand1: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+
+ perform ALU TST operation: set CC
+
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if MSB bit set else cleared
+
+ update PC
+
+if( ir[15:6] == 10'b0100 1010 11 && ir[5:0] != 6'b111000 )
+ TAS
++++
+ ea operation size: byte
+
+ enable READ-MODIFY-WRITE bus cycle
+
+ load (ea) from ir[5:0] to operand1: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+
+ perform ALU TAS operation: set bit 7 in result register
+
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if MSB bit set else cleared
+
+ save result to (ea) from ir[5:0]: data alter
+
+ disable READ-MODIFY-WRITE bus cycle
+
+ update PC
+
+if( ir[15:12] == 4'b0100 && ir[8:6] == 3'b110 )
+ CHK
++++
+ load (ea) from ir[5:0] to operand1: data
+ data: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ move operand1 to operand2
+
+ load (ea) from ir[11:9] to operand1: Dn
+
+
+ ALU operation size: word
+
+ perform ALU CHK operation: operand1 < 0 or operand1 - operand2 > 0
+
+ CC: X not affected; N set if operand1 < 0; cleared if operand1 - operand2 > 0 else undefined; C,V,Z udefined
+
+ if( ALU check ) trap CHK
+
+ update PC
+
+if( ir[15:12] == 4'b0100 && ir[8:6] == 3'b111 )
+ LEA
++++
+ load ea from ir[5:0] to address register: control
+ control: (An) 010, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ move address register to operand1
+ perform ALU operation: move operand1 to result register
+
+ save result to (ea) from ir[11:9]: An
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:6] == 10'b0100 1000 01 && ir[5:3] != 3'b000 )
+ PEA
++++
+ load ea from ir[5:0] to address register: control
+ control: (An) 010, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ SP -= 4
+
+ move address register to operand1
+ move operand1 to result
+
+ save result to (ea): (SP)
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:6] == 10'b0100 0100 11 || ir[15:6] == 10'b0100 0110 11 )
+ MOVE TO CCR, MOVE TO SR
++++
+ ea operation size: word
+
+ load (ea) from ir[5:0] to operand1: data
+ data: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ if( ir[11:8] == 4'b0110 /MOVE TO SR/ )
+ copy word form operand1 register to SR
+ else
+ copy lower byte form operand1 register to CCR
+
+ update PC
+
+if( ir[15:6] == 10'b0100 0000 11 )
+ MOVE FROM SR
++++
+ copy SR register to result register
+
+ ea operation size: word
+
+ save result to (ea) from ir[5:0]: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:3] == 12'b0100 1110 0110 0 )
+ MOVE USP to USP
++++
+ load (ea) from ir[2:0] to operand1: An
+
+ perform ALU operation: move operand1 to result
+
+ move result to USP
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:3] == 13'b0100 1110 0110 1 )
+ MOVE USP to An
++++
+ move USP to operand1
+
+ perform ALU operation: move operand1 to result
+
+ save result to (ea) from ir[2:0]: An
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:12] == 4'b0100 && ( (ir[11:8] == 4'b0000 && ir[7:6] != 2'b11) || (ir[11:8] == 4'b0010) || (ir[11:8] == 4'b0100 && ir[7:6] != 2'b11) ||
+ (ir[11:8] == 4'b0110 && ir[7:6] != 2'b11) || (ir[11:6] == 6'b1000 00) ) )
++++
+ NEGX,CLR,NEG,NOT,NBCD
+
+ load (ea) from ir[5:0] to operand1: data alter
+ data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+
+ ALU operation size:
+ NEGX: ir[7:6]: 00,01,10 byte,word,long
+ CLR: ir[7:6]: 00,01,10 byte,word,long
+ NEG: ir[7:6]: 00,01,10 byte,word,long
+ NOT: ir[7:6]: 00,01,10 byte,word,long
+ NBCD: ir[7:6]: 00 byte
+
+ perform ALU operation:
+ NEGX: ir[11:8] == 4'b0000
+ CLR: ir[11:8] == 4'b0010
+ NEG: ir[11:8] == 4'b0100
+ NOT: ir[11:8] == 4'b0110
+ NBCD: ir[11:6] == 6'b1000 00
+
+ CC:
+ NEGX: X=C set if borrow else clear; V set if overflow else clear; Z cleared if nonzero else unchanged; N set if negative else clear
+ CLR: X not affected; C cleared; V cleared; Z set; N cleared
+ NEG: X=C clear if zero else set; V set if overflow else clear; Z set if zero else clear; N set if negative else clear
+ NOT: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+ NBCD: X=C set if decimal borrow else cleared; Z cleared if nonzero else unchanged; N,V undefined
+
+ save result to (ea) from ir[5:0]: data alter
+
+ update PC
+
+if( ir[15:12] == 4'b0100 && (ir[11:3] == 9'b1000 01 000 || (ir[11:7] == 5'b1000 1 && ir[5:3] == 3'b000) )
+ SWAP,EXT
++++
+ load (ea) from ir[5:0] to operand1: Dn
+
+ ALU operation size: word
+ SWAP: ir[7:6]: 01 long
+ EXT: ir[7:6]: 10,11 byte to word, word to long
+
+ perform ALU operation:
+ SWAP: ir[11:6] == 6'b1000 01
+ EXT: ir[11:7] == 5'b1000 1
+
+ CC:
+ SWAP: X not affected; C cleared; V cleared; Z set if 32 bits are zero else cleared; N set if result MSB set else cleared
+ EXT: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+
+ save result to (ea) from ir[5:0]: Dn
+
+ update PC
+
+if( ir[15:7] == 9'b0100 1100 1 && ir[5:3] != 3'b000 )
+ MOVEM memory to register
++++
+ operation size:
+ if( ir[6] == 1'b0 ) word
+ else if ir[6] == 1'b1 ) long
+
+ load ea from ir[5:0] to address register: control or postincrement
+ (An) 010, (An)+ 011, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+ register selection order: D0,D1,...D7,A0,A1,...,A7
+
+ do
+ if( ir1[0] == 1'b1 )
+ read from (ea) to operand1
+
+ perform ALU operation: move operand1 with sign-extension to result
+
+ save result to selected register
+
+ update address register
+
+ shift ir1
+ loop 16 times
+
+ if( ir[5:3] == 3'b011 ) save address register back to An indexed by ir[2:0]
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:7] == 9'b0100 1000 1 && ir[5:3] == 3'b100 )
+ MOVEM register to memory, predecrement
++++
+ operation size:
+ if( ir[6] == 1'b0 ) word
+ else if ir[6] == 1'b1 ) long
+
+ load ea from ir[5:0] to address register: control alter or predecrement
+ (An) 010, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+
+ register selection order: A7,A6,..A0,D7,D6,....D0
+
+ do
+ if( ir1[0] == 1'b1 )
+ save selected register to operand1
+
+ perform ALU operation: move operand1 to result
+
+ save result to (ea)
+
+ update address register
+
+ shift ir1
+ loop 16 times
+
+ if( ir[5:3] == 3'b100 ) save address register back to An indexed by ir[2:0]
+
+ CC: not affected
+
+ update PC
+
+if( ir[15:7] == 9'b0100 1000 1 && ir[5:3] != 3'b000 && ir[5:3] != 3b100 )
+ MOVEM register to memory, control
++++
+ operation size:
+ if( ir[6] == 1'b0 ) word
+ else if ir[6] == 1'b1 ) long
+
+ load ea from ir[5:0] to address register: control alter or predecrement
+ (An) 010, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+
+ register selection order: D0,D1,...D7,A0,A1,...,A7
+
+ do
+ if( ir1[0] == 1'b1 )
+ save selected register to operand1
+
+ perform ALU operation: move operand1 to result
+
+ save result to (ea)
+
+ update address register
+
+ shift ir1
+ loop 16 times
+
+ CC: not affected
+
+ update PC
+
+*/
+
+/*
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+microinstructions
+
+MOVE_ea_reg_TO_An_address
+MOVE_ea_reg_TO_Dn_address
+MOVE_ir1_brief_ext_TO_An_Dn_addresses // ir_valid
+MOVE_An_output_TO_address
+MOVE_Dn_output_TO_OP1
+MOVE_An_output_TO_OP1
+MOVE_zeros_TO_index
+MOVE_ir1_brief_ext_TO_index // ir_valid
+MOVE_ir1_byte_TO_offset // ir_valid
+MOVE_ir1_word_TO_offset // ir_valid
+MOVE_base_index_offset_TO_address
+MOVE_ir1_absolute_word_TO_address // ir_valid
+MOVE_ir1_ir2_absolute_long_TO_address // ir_valid
+MOVE_pc_index_offset_TO_address
+MOVE_trap_TO_address
+MOVE_result_TO_An_input
+MOVE_result_TO_Dn_input(size=)
+MOVE_address_TO_An_input
+MOVE_result_TO_data
+
+MOVE_OP1_TO_OP2
+MOVE_OP2_TO_OP1
+MOVE_ADDR_TO_OP1
+MOVE_data_TO_OP1
+MOVE_immediate_TO_OP1(size=)
+MOVE_result_TO_OP1
+MOVE_moveq_TO_OP1
+MOVE_PC_NEXT_TO_OP1
+MOVE_zeros_TO_OP1
+MOVE_ones_TO_OP1
+MOVE_SR_TO_OP1
+MOVE_USP_TO_OP1
+MOVE_ir_TO_OP1
+MOVE_address_bus_info_TO_OP2
+MOVE_1_TO_OP2
+MOVE_offset_TO_OP2
+MOVE_count_TO_OP2
+MOVE_addq_subq_TO_OP2
+MOVE_result_TO_PC
+MOVE_result_TO_USP
+MOVE_zeros_TO_movem_mod_reg
+MOVE_001111_TO_movem_mod_reg
+MOVE_OP1_TO_movem_reg
+MOVE_zeros_TO_movem_loop
+MOVE_prefetch_ir_TO_ir
+MOVE_interrupt_mask_TO_sr
+MOVE_1_0_supervisor_trace_TO_sr
+MOVE_reset_mask_TO_sr
+MOVE_prefetch_ir_TO_PC
+MOVE_prefetch_ir_TO_SSP
+
+MOVE_illegal_instr_TO_TRAP
+MOVE_divide_by_zero_TO_TRAP
+MOVE_chk_TO_TRAP
+MOVE_trapv_TO_TRAP
+MOVE_priv_viol_TO_TRAP
+MOVE_trap_TO_TRAP
+MOVE_decoder_trap_TO_TRAP
+MOVE_trace_TO_TRAP
+MOVE_interrupt_trap_TO_TRAP
+
+MOVE_0_TO_stop_flag
+MOVE_1_TO_stop_flag
+MOVE_sr15_TO_trace_flag
+MOVE_0_TO_group_0_flag
+MOVE_1_TO_group_0_flag
+MOVE_0_TO_read_modify_write_flag
+MOVE_1_TO_read_modify_write_flag
+MOVE_0_TO_instruction_flag
+MOVE_1_TO_instruction_flag
+MOVE_1_TO_blocked_flag
+MOVE_0_TO_read_flag
+MOVE_1_To_read_flag
+MOVE_0_TO_write_flag
+MOVE_1_TO_write_flag
+MOVE_0_TO_interrupt_flag
+MOVE_1_TO_interrupt_flag
+MOVE_1_TO_reset_flag
+MOVE_0_TO_reset_flag
+
+INCR_ADDR_BY_SIZE(size=)
+DECR_ADDR_BY_SIZE(size=)
+DECR_OP2_BY_1
+CALL procedure
+RETURN
+INCR_movem_loop_BY_1
+INCR_movem_mod_reg_BY_1
+DECR_movem_mod_reg_BY_1
+JMP: local label, trap, instr_fin, instr_fin_pc_loaded,
+SHIFT_RIGHT_movem_reg
+INCR_PC_BY_2
+INCR_PC_BY_4
+INCR_PC_BY_size(size=)
+
+BRANCH(movem_loop == 4'b1000)
+BRANCH(movem_reg[0] == 0)
+BRANCH(operand2[5:0] == 6'b0)
+BRANCH(special == 2'b01)
+BRANCH(special == 2'b10)
+BRANCH(condition == 1'b0)
+BRANCH(condition == 1'b1)
+BRANCH(result[15:0] == 16'hFFFF)
+BRANCH(V == 1'b0)
+BRANCH(stop_flag == 1'b1)
+BRANCH(ir[7:0] != 8'b0)
+BRANCH(decoder_trap == 8'b0)
+BRANCH(trace_flag == 1'b0)
+BRANCH(group_0_flag == 0)
+
+WAIT_RESET, WAIT_MEMORY_READ(size, address), WAIT_MEMORY_WRITE(size, address, select), WAIT_interrupt, WAIT_blocked
+WAIT_prefetch_ir_valid
+
+subprocedures:
+ea(size=, reg=, mod=, type=, select=)
+
+LOAD_EA: to address register
+PERFORM_EA_READ: to operand1
+PERFORM_EA_WRITE: from result
+SAVE_EA
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+TYPE.ALL: all
+ Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+TYPE.CONTROL_POSTINC: control or postincrement
+ (An) 010, (An)+ 011, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+TYPE.CONTROLALTER_PREDEC: control alter or predecrement
+ (An) 010, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+TYPE.CONTROL: control
+ (An) 010, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+TYPE.DATAALTER: data alter
+ Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+TYPE.DN_AN: Dn, An
+ Dn 000, An 001
+TYPE.MEMORYALTER: memory alter
+ (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+TYPE.DATA: data
+ Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+
Index: trunk/doc/src/mc68000.txt
===================================================================
--- trunk/doc/src/mc68000.txt (nonexistent)
+++ trunk/doc/src/mc68000.txt (revision 2)
@@ -0,0 +1,1120 @@
+Registers:
+D0,D1,D2,D3,D4,D5,D6,D7 32-bit
+A0,A1,A2,A3,A4,A5,A6 32-bit
+A7 USP 32-bit
+A7' SSP 32-bit
+PC 32-bit
+CCR condition code reg, SR status register 8-bit User, 16-bit Supervisor
+
+Address registers:
+base address registers, word and long-word operations,
+operations always affect 32-bits, word operations sign-extended
+All 16: index registers
+
+SR
+Condition Code Register:
+0: C Carry
+1: V Overflow
+2: Z Zero
+3: N Negative
+4: X Extend
+Status register:
+8-10: I Interrupt mask
+13: S Supervisor
+15: T Trace mode
+
+MC68000 Addressing modes
+ Number of extension words
+Register Direct Addressing
+ Data Register Direct = Dn 0
+ Address Register Direct = An 0
+Absolute Data Addressing
+ Absolute Short = (Next Word) 1
+ Absolute Long = (Next Two Words) 2
+Program Counter Relative Addressing
+ Relative with Offset = (PC + d16) 1
+ Relative with Index and Offset = (PC + Rn + d8) 1*
+Register Indirect Addressing
+ Register Indirect = (An) 0
+ Postincrement Register Indirect = (An), An <- An + N 0
+ Predecrement Register Indirect An <- An–N, = (An) 0
+ Register Indirect with Offset = (An + d16) 1
+ Indexed Register Indirect with Offset = (An + Rn + d8) 1*
+Immediate Data Addressing
+ Immediate DATA = Next Word(s) 1 or 2
+ Quick Immediate Inherent Data 0
+Implied Addressing
+ Implied Register = SR, USP, SSP, PC 0
+
+N = 1 for byte, 2 for word, and 4 for long word. If An is the stack pointer and
+ the operand size is byte, N = 2 to keep the stack pointer on a word
+ boundary.
+
+1*: format of brief extension word
+Data/Address(1 bit) Rn(3 bits) word/long(1 bit) 000 d8(8 bits)
+word/long: size of sign-extended index register
+
+Exceptions
+0 Reset: Initial SSP (Supervisor Program Space)
+1 Reset: Initial PC (Supervisor Program Space)
+
+2 Bus Error From external logic
+3 Address Error Odd address fetch
+4 Illegal Instruction $4AFA, $4AFB, $4AFC
+5 Zero Divide
+6 CHK Instruction Trap check bounds
+7 TRAPV Instruction Trap overflow
+8 Privilege Violation
+9 Trace
+10 Line 1010 Emulator Illegal instruction
+11 Line 1111 Emulator Illegal instruction
+12-14 RESERVED
+15 Uninitialized Interrupt Vector Default for uninitialized ext hw
+16-23 RESERVED
+24 Spurious Interrupt Bus error while int ack cycle
+25 Level 1 Interrupt Autovector
+26 Level 2 Interrupt Autovector
+27 Level 3 Interrupt Autovector
+28 Level 4 Interrupt Autovector
+29 Level 5 Interrupt Autovector
+30 Level 6 Interrupt Autovector
+31 Level 7 Interrupt Autovector
+32-47 Trap Instruction Vectors Trap instruction
+48-63 RESERVED
+64-255 User Interrupt Vectors
+
+Ack cycle: DACK + vector number, VPA, AVEC, BERR
+
+Privilege violations: PC address current
+AND Immediate to SR
+EOR Immediate to SR
+OR Immediate to SR
+MOVE to SR?
+MOVE USP
+RESET
+RTE
+STOP
+
+Tracing
+Not: when interrupt, illegal, privileged, reset, bus error, address error
+Before: pending interrupt
+After: instruction generated exception
+
+Stack Frame
+Reset:
+None
+
+Bus/Address error:
+00. reset, 01. address error, 02. bus error: immediate reaction: abort current bus cycle, abort instruction or exception processing
+if bus error/address error while address error,bus error or reset: block processor
+address error: access word or long operand or instruction from odd address
+bus error: BERR
+processing an instruction: normal state or in group 2 exception
+not processing an instruction: group 0 or 1 exception
+Stack frame:
+Undefined 11 bits, Read/Write bit 4, Instruction/Not bit 3, Function code bits 2-0,
+Access address 32 bits,
+Instruction register 16 bits,
+Status register 16 bits,
+Program counter 32 bits
+
+Rest:
+Status register, Program counter
+
+Processing sequence
+From TRAP: 1 -> S-bit of SR; SSP -= 4; PC -> (SSP); SSP -= 2; SR -> (SSP)
+From ILLEGAL: SSP -= 4; PC -> (SSP); SSP -= 2; SR -> (SSP)
+Copy status register
+Enter Supervisor mode
+Turn off tracing
+Reset, interrupt exceptions: update interrupt priority mask
+Determine vector number
+Save on stack using SSP
+
+PC value in exceptions:
+ usualy: trap: trace: interrupt: with address of next instruction,
+ address and bus errors: advanced 2-10 bytes after first word of current instruction
+ privilege violation: illegal: address of first word of current instruction
+
+
+Without:
+- Function Codes
+- Bus arbitration
+- Synchronous 6800 bus cycles
+
+
+Operation code map:
+0000 Bit Manipulation/MOVEP/Immediate
+0001 Move Byte
+0010 Move Long
+0011 Move Word
+0100 Miscellaneous
+0101 ADDQ/SUBQ/Scc/DBcc/TRAPc
+0110 Bcc/BSR/BRA
+0111 MOVEQ
+1000 OR/DIV/SBCD
+1001 SUB/SUBX
+1010 (Unassigned, Reserved)
+1011 CMP/EOR
+1100 AND/MUL/ABCD/EXG
+1101 ADD/ADDX
+1110 Shift/Rotate/Bit Field
+1111 Coprocessor Interface/MC68040 and CPU32 Extensions
+
+
+*******************************************************************************************************************************************
+*******************************************************************************************************************************************
+*******************************************************************************************************************************************
+
+
+*******************************************************************************************************************************************
+* add, sub
+*******************************************************************************************************************************************
+*
+ABCD Add Decimal with Extend
+[SBCD Subtract Decimal with Extend]
+ Destination10 +[-] Source10 +[-] X -> Destination
+ Byte operation, packed BCD
+ CC: X=C set if decimal carry [borrow] else cleared; Z cleared if result nonzero else unchanged; N,V undefined
+ 1100[1000] Ry dest(3 bits) 1 0000 R/M Rx source(3 bits)
+ R/M = 0 data registers, 1 = address registers predecrement: -(An)
+*
+ADD Add
+[SUB Subtract]
+ Destination +[-] Source -> Destination
+ Byte, Word, Long
+ CC: X=C set if carry[borrow] generated else cleared; V set if overflow else cleared; Z set if result zero else cleared;
+ N set if result negative else cleared
+ 1101[1001] register(3 bits) opmode(3 bits) ea mode register (3,3 bits)
+ register: data reg
+ opmode: 000,001,010 byte,word,long: ea +[-] Dn -> Dn; 100, 101, 110 byte,word,long: Dn +[-] ea -> ea
+ ea source, all modes: Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+ ea dest, memory alter: (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001
+*
+ADDA Add Address
+[SUBA Subtract Address]
+ Destination +[-] Source -> Destination
+ Word, Long
+ CC: not affected
+ 1101[1001] register(3 bits) opmode(3 bits) ea mode register(3,3 bits)
+ register: destination An
+ opmode: 011 word operation sign extended to 32 bits; 111 long operation
+ ea source, all modes.
+*
+ADDI Add Immediate
+[SUBI Subtract Immediate]
+ Destination +[-] Immediate data -> Destination
+ Byte, Word, Long
+ CC: same as ADD
+ 0000 0110[0100] size(2 bits) ea mode register(3,3 bits); imm16 next word, imm8 lower order byte of next word, imm32 two next words
+ size: 00,01,10 byte,word,long
+ ea dest, data alter: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+*
+ADDQ Add Quick
+[SUBQ Subtract Quick]
+ Destination +[-] Immediate data -> Destination
+ Byte, Word, Long
+ CC: same as ADD,ADDA; not affected when destiantion is An
+ 0101 data(3 bits) 0[1] size(2 bits) ea mode register (3,3 bits)
+ data: immediate data: 0=8, 1=1, ..., 7=7
+ size: 00,01,10 byte,word,long
+ ea dest, alter: Dn 000, An (word, long) 001, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+*
+ADDX Add with Extend
+[SUBX Subtract with Extend]
+ Destination +[-] Source +[-] X -> Destination
+ Byte, Word, Long
+ CC: X=C set if carry[borrow] else cleared; V set if overflow else cleared; Z cleared if nonzero else unchanged; N set if negative else cleared
+ 1101[1001] Ry dest(3 bits) 1 size(2 bits) 00 R/M Rx source(3 bits)
+ R/M = 0 data registers, 1 = address registers predecrement: -(An)
+ size: 00,01,10 byte,word,long
+
+*******************************************************************************************************************************************
+* cmp
+*******************************************************************************************************************************************
+*
+CMP Compare
+ Destination - Source -> CC
+ Byte, Word, Long
+ CC: X not affected; C set if borrow else cleared; V set if overflow else cleared; Z set if zero else cleared; N set if negative else cleared
+ 1011 register(3 bits) opmode(3 bits) ea mode register(3,3 bits)
+ register: destination Dn
+ opmode: 000,001,010 byte,word,long: Dn - ea
+ ea source, all modes.
+*
+CMPA Compare Address
+ Destination - Source -> CC
+ CC: same as CMP
+ 1011 register(3 bits) opmode(3 bits) ea mode register(3,3 bits)
+ register: destination An
+ opmode: 011 word operation sign extended to 32 bits; 111 long operation
+ ea source, all modes.
+*
+CMPI Compare Immediate
+ Destination - Immediate Data -> CC
+ Byte, Word, Long
+ CC: same as CMP
+ 0000 1100 size(2 bits) ea mode register(3,3 bits); imm16 next word, imm8 lower order byte of next word, imm32 two next words
+ size: 00,01,10 byte,word,long
+ ea dest, data alter.
+*
+CMPM Compare Memory to Memory
+ Destination - Source -> CC
+ Byte, Word, Long
+ CC: same as CMP
+ 1011 Ax dest(3 bits) 1 size(2 bits) 00 1 Ay source(3 bits)
+ Ax dest, Ay source: postincrement: +(An)
+ size: 00,01,10 byte,word,long
+
+*******************************************************************************************************************************************
+* mul, div
+*******************************************************************************************************************************************
+*
+MULS Signed Multiply
+[MULU Unsigned Multiply]
+ Source x Destination -> Destination
+ Word operation: source and dest 16 bit lower order -> destination 32 bit
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+ 1100 Dn dest(3 bits) 1[0] 11 ea mode register(3,3 bits)
+ ea source, data: Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, #data 111 100, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+
+*
+DIVS Signed Divide
+[DIVU Unsigned Divide]
+ Destination / Source -> Destination
+ Word operation: dest 32 bits, source 16 bits -> 16 bit MSB remainder, 16 bit LSB quotient, sign of remainder = sign of dividend
+ CC: X not affected; C cleared; V set if overflow else if trap undefined else cleared;
+ Z set if quotient zero else if trap or overflow undefined else cleared;
+ Z set if quotient negative else if trap or overflow undefined else cleared;
+ 1000 Dn dest(3 bits) 1[0] 11 ea mode register(3,3 bits)
+ ea source, data.
+
+ Overflow: if quotient larger than a 16-bit signed integer.
+ Division by 0: trap.
+ If overflow detected: operands unaffected.
+
+*******************************************************************************************************************************************
+* ext, neg
+*******************************************************************************************************************************************
+*
+EXT Sign Extend
+ Destination sign-extended -> Destination
+ Word, Long
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+ 0100 100 opmode(3 bits) 00 0 Dn dest(3 bits)
+ opmode: 010,011 byte to word, word to long
+*
+NEGX Negate with Extend
+ 0 - Destination - X -> Destination
+ Byte, Word, Long
+ CC: X=C set if borrow else clear; V set if overflow else clear; Z set if nonzero else unchanged; N set if negative else clear
+ 0100 0000 size(2 bits) ea mode register(3,3 bits)
+ size: 00,01,10 byte,word,long
+ ea dest, data alter.
+*
+NBCD Negate Decimal with Extend
+ 0 - Destination10 - X -> Destination
+ Byte operation
+ CC: X=C set if decimal borrow else cleared; Z cleared if nonzero else unchanged; N,V undefined
+ 0100 1000 00 ea mode register(3,3 bits)
+ ea dest, data alter.
+*
+NEG Negate
+ 0 - Destination -> Destination
+ Byte, Word, Long
+ CC: X=C clear if zero else set; V set if overflow else clear; Z set if zero else clear; N set if negative else clear
+ 0100 0100 size(2 bits) ea mode register(3,3 bits)
+ size: 00,01,10 byte,word,long
+ ea dest, data alter.
+
+*******************************************************************************************************************************************
+* and,eor,or,not
+*******************************************************************************************************************************************
+*
+AND Logical AND
+[OR Logical Inclusive-OR]
+ Source &[|] Destination -> Destination
+ Byte, Word, Long: not on An
+ CC: X not affected; C cleared; V cleared; Z set if zero else clear; N set if MSB set else cleared
+ 1100[1000] Dn register(3 bits) opmode(3 bits) ea mode register(3,3 bits)
+ opmode: 000,001,010 byte,word,long: ea & Dn -> Dn; 100,101,110 byte,word,long: Dn & ea -> ea
+ ea source, data.
+ ea dest, memory alter.
+*
+ANDI Logical AND Immediate
+[EORI Logical Exclusive-OR Immediate]
+[ORI Logical Inclusive-OR Immediate]
+ Immediate data &[^][|] Destination -> Destination
+ Byte, Word, Long
+ CC: X not affected; C cleared; V cleared; Z set if zero else clear; N set if MSB set else cleared
+ 0000 0010[1010][0000] size(2 bits) ea mode register(3,3 bits); imm16 next word, imm8 lower order byte of next word, imm32 two next words
+ size: 00,01,10 byte,word,long
+ ea dest, data alter.
+*
+ANDI to CCR AND Immediate to Condition Code Register
+[EORI to CCR Exclusive-OR Immediate to Condition Code Register]
+[ORI to CCR Inclusive-OR Immediate to Condition Code Register]
+ Source &[^][|] CCR -> CCR
+ Byte operation
+ CC: result
+ 0000 0010[1010][0000] 00 111 100; 0000 0000 data(8 bit)
+*
+ANDI to SR AND Immediate to Status Register/Privilege/
+[EORI to SR Exclusive-OR Immediate to Status Register/Privilege/]
+[ORI to SR Inclusive-OR Immediate to Status Register/Privilege/]
+ Source &[^][|] SR -> SR
+ Word operation
+ CC: result
+ 0000 0010[1010][0000] 01 111 100; data(16 bit)
+*
+EOR Logical Exclusive-OR
+ Source ^ Destination -> Destination
+ Byte, Word, Long
+ CC: X not affected; C cleared; V cleared; Z set if zero else clear; N set if MSB set else cleared
+ 1011 Dn source(3 bits) opmode(3 bits) ea mode register(3,3 bits)
+ opmode: 100,101,110 byte,word,long: ea ^ Dn -> ea
+ ea dest, data alter.
+*
+NOT Logical Complement
+ ~ Destination -> Destination
+ Byte, Word, Long
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+ 0100 0110 size(2 bits) ea mode register(3,3 bits)
+ size: 00,01,10 byte,word,long
+ ea dest, data alter.
+
+*******************************************************************************************************************************************
+* shift,rotate
+*******************************************************************************************************************************************
+*
+ASL, ASR Arithmetic Shift Left and Right
+[LSL, LSR Logical Shift Left and Right]
+[ROL, ROR Rotate Left and Right]
+[ROXL, ROXR Rotate with Extend Left and Right]
+ Destination shifted[shifted][rotated][rotated with X] by count -> Destination
+ Byte, Word, Long, in memory: 1 bit shift[shift][rotate][rotate] and word
+ CC: X set to last bit, unchanged if zero shift[same][not affected][same set]; N set if MSB bit is set else cleared;
+ Z set if zero else cleared; V set if MSB bit changed during shift else cleared[cleared][cleared][cleared];
+ C set to last bit, cleared if zero shift[same][same][set to X]
+ 1110 count/register(3 bits) dr(1 bit) size(2 bits) i/r(1 bit) 00[01][11][10] Dn dest(3 bit)
+ i/r = 0 count/register=count: 0=8, 1=1, ..., 7=7; i/r = 0 count/register=register: modulo 64
+ dr = 0 right shift; dr = 1 left shift
+ size: 00,01,10 byte,word,long
+ 1110 000[001][011][010] dr(1 bit) 11 ea mode register(3,3 bits)
+ dr = 0 right shift; dr = 1 left shift
+ ea dest: memory alter.
+
+*******************************************************************************************************************************************
+* move,clr,exg,swap
+*******************************************************************************************************************************************
+*
+MOVE Move
+ Source -> Destination
+ Byte, Word, Long
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+ 00 size(2 bits) ea dest register mode(3,3 bits) ea source mode register(3,3 bits)
+ size: 01,11,10 byte,word,long
+ ea dest, data alter.
+ ea source, all modes.
+*
+MOVEA Move Address
+ Source -> Destination
+ Word, Long
+ CC: not affected
+ 00 size(2 bits) An dest(3 bits) 0 01 ea source mode register(3,3 bits)
+ size: 11,10 word,long: word operands are sign extended
+ ea source, all modes.
+*
+MOVE to CCR Move to Condition Code Register
+ Source -> CC
+ Word operation: upper byte ignored
+ 0100 0100 11 ea source mode register(3,3 bits)
+ ea source, data.
+*
+MOVE from SR Move from Status Register
+ SR -> Destination
+ Word operation
+ CC: not affected
+ 0100 0000 11 ea dest mode register(3,3 bits)
+ ea dest, data alter.
+*
+MOVE to SR Move to Status Register/Privileged/
+ Source -> SR
+ Word operation
+ CC: result
+ 0100 0110 11 ea source mode register(3,3 bits)
+ ea source, data.
+*
+MOVE USP Move User Stack Pointer/Privileged/
+ USP -> An; An -> USP
+ Long operation
+ CC: not affected
+ 0100 1110 0110 dr(1 bit) An reg(3 bits)
+ dr: 0 An -> USP; 1 USP -> An
+*
+MOVEM Move Multiple Registers
+ Registers -> Destination; Source -> Registers
+ Word, Long: word operations to An or Dn are sign extended
+ CC: not affected
+ 0100 1 dr(1 bit) 00 1 size(1 bit) ea mode register(3,3 bits); register list mask
+ dr: 0 register to memory; 1 memory to register
+ size: 0,1 word,long operation
+ ea dest: register to memory, control alter or predecrement available:
+ (An) 010, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001,
+ ea source: memory to register, control or postincrement available:
+ (An) 010, (An)+ 011, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+ list mask: control or postincrement: A7-A0, D7-D0; predecrement: D0-D7; A0-A7
+*
+MOVEP Move Peripheral
+ Source -> Destination
+ Word, Long
+ CC: not affected
+ 0000 data reg(3 bits) opmode(3 bits) 00 1 address reg(3 bits); 16 bit displacement
+ opmode: 100,101 word,long: memory -> register; 110,111 word,long: register -> memory
+ address reg: (An, d16)
+*
+MOVEQ Move Quick
+ Immediate data -> Destination
+ Long operation; 8 bit data is sign extended to 32 bits
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if negative else cleared
+ 0111 Dn dest(3 bits) 0 data(8 bits)
+*
+CLR Clear
+ 0 -> Destination
+ Byte, Word, Long
+ CC: X not affected; C cleared; V cleared; Z set; N cleared
+ 0100 0010 size(2 bits) ea dest mode register(3,3 bits)
+ size: 00,01,10 byte,word,long
+ ea dest, data alter.
+*
+EXG Exchange Registers
+ Rx <-> Ry
+ Long operation
+ CC: not affected
+ 1100 Rx reg(3 bits) 1 opmode(5 bits) Ry reg(3 bits)
+ Rx reg: if Dn <-> An always Dn
+ Ry reg: if Dn <-> An always An
+ opmode: 01000 data regs; 01001 address regs; 10001 mix regs
+*
+SWAP Swap Register Words
+ Reg 31-16 <-> Reg 15-0
+ Word operation
+ CC: X not affected; C cleared; V cleared; Z set if 32 bits are zero else cleared; N set if result MSB set else cleared
+ 0100 1000 0100 0 reg(3 bits)
+
+*******************************************************************************************************************************************
+* branch,jump
+*******************************************************************************************************************************************
+*
+Bcc Branch Conditionally
+ if condition PC + d8/d16 -> PC
+ Byte, Word
+ CC: not affected
+ 0110 condition(4 bits) disp8(8 bit); 16 bit displacement if disp8 == 0
+ condition: high(!C & !Z) 0010, low or same(C | V) 0011,
+ carry clear(!C) 0100, carry set(C) 0101, not equal(Z) 0110, equal(!Z) 0111,
+ overflow clear(!V) 1000, overflow set(V) 1001, plus(!N) 1010, minus(N) 1011,
+ greater or equal(N & V | !N & !V) 1100, less than(N & !V | !N & V) 1101,
+ greater than(N & V & !Z | !N & !V & !Z) 1110, less or equal(Z | N & !V | !N & V) 1111
+*
+BRA Branch
+ if condition PC + d8/d16 -> PC
+ Byte, Word
+ CC: not affected
+ 0110 0000 disp8(8 bit); 16 bit displacement if disp8 == 0
+*
+BSR Branch to Subroutine
+ SP -= 4; PC -> (SP); PC + d8/d16 -> PC
+ Byte, Word
+ CC: not affected
+ 0110 0001 disp8(8 bit); 16 bit displacement if disp8 == 0
+*
+DBcc Test Condition, Decrement, and Branch
+ if !condition { Dn(lower order 16 bits) -= 1; if Dn != -1 then PC + d16 -> PC }
+ Word operation
+ CC: not affected
+ 0101 condition(4 bits) 1100 1 Dn register(3 bits); 16 bit displacement
+ condition: true(1) 0000, false(0) 0001, high(!C & !Z) 0010, low or same(C | V) 0011,
+ carry clear(!C) 0100, carry set(C) 0101, not equal(Z) 0110, equal(!Z) 0111,
+ overflow clear(!V) 1000, overflow set(V) 1001, plus(!N) 1010, minus(N) 1011,
+ greater or equal(N & V | !N & !V) 1100, less than(N & !V | !N & V),
+ greater than(N & V & !Z | !N & !V & !Z), less or equal(Z | N & !V | !N & V) 1111
+*
+JMP Jump
+ Destination address -> PC
+ Unsized
+ CC: not affected
+ 0100 1110 11 ea mode register(3,3 bits)
+ ea, control: (An) 010, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+*
+JSR Jump to Subroutine
+ SP -= 4; PC -> (SP); Destination address -> PC
+ Unsized
+ CC: not affected
+ 0100 1110 10 ea mode register(3,3 bits)
+ ea, control.
+*
+RTR Return and Restore
+ (SP) -> CC; SP += 2; (SP) -> PC; SP += 4
+ Unsized
+ CC: set from stack; supervisor bits unaffected
+ 0100 1110 0111 0111
+*
+RTS Return from Subroutine
+ (SP) -> PC; SP += 4
+ Unsized
+ CC: not affected
+ 0100 1110 0111 0101
+
+*******************************************************************************************************************************************
+* test bit,test,check
+*******************************************************************************************************************************************
+*
+BCHG Test Bit and Change
+[BCLR Test Bit and Clear]
+[BSET Test Bit and Set]
+[BTST Test Bit]
+ test( of Destination ) -> Z; test( of Destination )[0][1][nothing] -> of Destination
+ Byte, Long
+ CC: X,N,V,C not affected; Z set if bit tested is zero else cleared
+ 0000 Dn reg(3 bits) 101[110][111][100] ea mode register(3,3 bits)
+ Dn reg: bit number
+ ea dest, data alter.[same][same][data address]; Dn is long operation else byte operation
+ 0000 1000 01[10][11][00] ea mode register(3,3 bits); 0000 0000 bit number(8 bits)
+ ea dest, data alter[same][same][data address]; Dn is long operation else byte operation
+
+ ea data address Dn 000, (An) 010, (An)+ 011, -(An) 100, (d16, An) 101, (d8, An, Xn) 110,
+ (xxx).W 111 000, (xxx).L 111 001, (d16, PC) 111 010, (d8, PC, Xn) 111 011
+*
+Scc Set Conditionally
+ if condition 1s -> Destination else 0s -> Destination
+ Byte operation
+ CC: not affected
+ 0101 condition(4 bits) 11 ea mode register(3,3 bits)
+ condition: same as in DBcc
+ ea dest, data alter.
+*
+TAS Test Operand and Set/Read-modify-write bus operation/
+ Destination tested -> CC; 1 -> bit 7 of destination
+ Byte operation
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if MSB bit set else cleared
+ 0100 1010 11 ea mode register(3,3 bits)
+ ea operand, data alter.
+*
+TST Test Operand
+ Destination tested -> CC
+ Byte, Word, Long
+ CC: X not affected; C cleared; V cleared; Z set if zero else cleared; N set if MSB bit set else cleared
+ 0100 1010 size(2 bits) ea mode register(3,3 bits)
+ size: 00,01,10 byte,word,long
+ ea operand, data alter.
+*
+CHK Check Register Against Bound
+ if Dn < 0 or Dn > Source then TRAP
+ Word operation
+ CC: X not affected; N set if Dn < 0; cleared if Dn > Source else undefined; C,V,Z udefined
+ 0100 Dn reg(3 bits) size(2 bits) 0 ea mode register(3,3 bits)
+ size: 11 word
+ ea source, data.
+
+*******************************************************************************************************************************************
+* address,stack
+*******************************************************************************************************************************************
+*
+LEA Load Effective Address
+ ea -> An
+ Long operation
+ CC: not affected
+ 0100 An reg(3 bits) 1 11 ea mode register(3,3 bits)
+ ea, control.
+*
+PEA Push Effective Address
+ SP -= 4; ea -> (SP)
+ Long operation
+ CC: not affected
+ 0100 1000 01 ea mode register(3,3 bits)
+ ea, control.
+*
+LINK Link and Allocate
+ SP -= 4; An -> (SP); SP -> An; SP + d16 -> SP
+ Word operation
+ CC: not affected
+ 0100 1110 0101 0 An reg(3 bits); 16 bit displacement
+*
+UNLK Unlink
+ An -> SP; (SP) -> An; Sp += 4
+ Unsized
+ CC: not affected
+ 0100 1110 0101 1 An reg(3 bits)
+
+*******************************************************************************************************************************************
+* exceptions
+*******************************************************************************************************************************************
+*
+ILLEGAL Take Illegal Instruction Trap
+ SSP -= 4; PC -> (SSP); SSP -= 2; SR -> (SSP)
+ Unsized
+ CC: not affected
+ 0100 1010 1111 1100
+*
+TRAP Trap
+ 1 -> S-bit of SR; SSP -= 4; PC -> (SSP); SSP -= 2; SR -> (SSP)
+ Unsized
+ CC: not affected
+ 0100 1110 0100 vector(4 bits)
+*
+TRAPV Trap on Overflow
+ if V then TRAP
+ Unsized
+ CC: not affected
+ 0100 1110 0111 0110
+*
+RTE Return from Exception/Privileged/
+ if S-bit set in SR then { (SP) -> SR; SP += 2; (SP) -> PC; SP += 4; restore state and dealocate rest of stack according to (SP) } else TRAP
+ Unsized
+ CC: set from stack
+ 0100 1110 0111 0011
+
+*******************************************************************************************************************************************
+* control
+*******************************************************************************************************************************************
+*
+NOP No Operation
+ None
+ Unsized
+ CC: not affected
+ 0100 1110 0111 0001
+*
+RESET Reset External Devices/Privileged/
+ if S-bit set in SR then { assert !RESET line for 124 clock cycles } else TRAP
+ Unsized
+ CC: not affected
+ 0100 1110 0111 0000
+*
+STOP Stop/Privileged/
+ if S-bit set in SR then { immediate data -> SR; STOP } else TRAP
+ Unsized
+ CC: set according to immediate data
+ 0100 1110 0111 0010; 16 bit immediate data
+
+ Resume when trace, interrupt or rest.
+
+*******************************************************************************************************************************************
+*******************************************************************************************************************************************
+*******************************************************************************************************************************************
+
+0000 0010[1010][0000] size(2 bits) ea mode register(3,3 bits); imm16 next word, imm8 lower order byte of next word, imm32 two next words
+ ANDI,EORI,ORI
+
+0000 0010[1010][0000] 00 111 100; 0000 0000 data(8 bit) ANDI to CCR,EORI to CCR,ORI to CCR
+0000 0010[1010][0000] 01 111 100; data(16 bit) ANDI to SR,EORI to SR,ORI to SR
+
+0000 0110[0100] size(2 bits) ea mode register(3,3 bits); imm16 next word, imm8 lower order byte of next word, imm32 two next words
+ ADDI,SUBI
+
+0000 1000 01[10][11][00] ea mode register(3,3 bits); 0000 0000 bit number(8 bits) BCHG,BCLR,BSET,BTST
+
+0000 1100 size(2 bits) ea mode register(3,3 bits); imm16 next word, imm8 lower order byte of next word, imm32 two next words
+ CMPI
+
+0000 Dn reg(3 bits) 101[110][111][100] ea mode register(3,3 bits) BCHG,BCLR,BSET,BTST
+
+0000 Dn reg(3 bits) opmode(3 bits) 001 address reg(3 bits); 16 bit displacement MOVEP
+
+00 size(2 bits) ea dest register mode(3,3 bits) ea source mode register(3,3 bits) MOVE
+00 size(2 bits) An dest(3 bits) 001 ea source mode register(3,3 bits) MOVEA
+
+if( 0000 000 0 ** !111100 ) ORI
+if( 0000 000 0 00 111100 ) ORI to CCR
+if( 0000 000 0 01 111100 ) ORI to SR
+if( 0000 001 0 ** !111100 ) ANDI
+if( 0000 001 0 00 111100 ) ANDI to CCR
+if( 0000 001 0 01 111100 ) ANDI to SR
+if( 0000 010 0 ) SUBI
+if( 0000 011 0 ) ADDI
+if( 0000 100 0 ) BCHG,BCLR,BSET,BTST
+if( 0000 101 0 ** !111100 ) EORI
+if( 0000 101 0 00 111100 ) EORI to CCR
+if( 0000 101 0 01 111100 ) EORI to SR
+if( 0000 110 0 ) CMPI
+if( 0000 *** 1** !001 ) BCHG,BCLR,BSET,BTST
+if( 0000 *** 1** 001 ) MOVEP
+if( 00 !00 *** !001 ) MOVE
+if( 00 !00 *** 001 ) MOVEA
+
+*******************************************************************************************************************************************
+
+0100 0000 size(2 bits) ea mode register(3,3 bits) NEGX
+0100 0000 11 ea dest mode register(3,3 bits) MOVE FROM SR
+
+0100 Dn reg(3 bits) 1 10 ea mode register(3,3 bits) CHK
+0100 An reg(3 bits) 1 11 ea mode register(3,3 bits) LEA
+
+0100 0010 size(2 bits) ea dest mode register(3,3 bits) CLR
+
+0100 0100 size(2 bits) ea mode register(3,3 bits) NEG
+0100 0100 11 ea source mode register(3,3 bits) MOVE TO CCR
+
+0100 0110 size(2 bits) ea mode register(3,3 bits) NOT
+0100 0110 11 ea source mode register(3,3 bits) MOVE TO SR
+
+0100 1000 00 ea mode register(3,3 bits) NBCD
+0100 1000 01 000 reg(3 bits) SWAP
+0100 1000 01 ea mode register(3,3 bits) PEA
+0100 100 opmode(3 bits) 000 Dn dest(3 bits) EXT
+
+0100 1 dr(1 bit) 00 1 size(1 bit) ea mode register(3,3 bits); register list mask MOVEM
+
+0100 1010 size(2 bits) ea mode register(3,3 bits) TST
+0100 1010 11 ea mode register(3,3 bits) TAS
+0100 1010 1111 1100 ILLEGAL
+
+0100 1110 0100 vector(4 bits) TRAP
+
+0100 1110 0101 0 An reg(3 bits); 16 bit displacement LNK
+0100 1110 0101 1 An reg(3 bits) UNLK
+
+0100 1110 0110 dr(1 bit) An reg(3 bits) MOVE USP
+
+0100 1110 0111 0000 RESET
+0100 1110 0111 0001 NOP
+0100 1110 0111 0010 STOP
+0100 1110 0111 0011 RTE
+0100 1110 0111 0101 RTS
+0100 1110 0111 0110 TRAPV
+0100 1110 0111 0111 RTR
+
+0100 1110 10 ea mode register(3,3 bits) JSR
+0100 1110 11 ea mode register(3,3 bits) JMP
+
+if( 0100 0000 00|01|10 ) NEGX
+if( 0100 0000 11 ) MOVE FROM SR
+if( 0100 ***1 10 ) CHK
+if( 0100 ***1 11 ) LEA
+if( 0100 0010 ) CLR
+if( 0100 0100 00|01|10 ) NEG
+if( 0100 0100 11 ) MOVE TO CCR
+if( 0100 0110 00|01|10 ) NOT
+if( 0100 0110 11 ) MOVE TO SR
+if( 0100 1000 00 ) NBCD
+if( 0100 1000 01 000 ) SWAP
+if( 0100 1000 01 !000 ) PEA
+if( 0100 1000 1* 000 ) EXT
+if( 0100 1*00 1* !000 ) MOVEM
+if( 0100 1010 00|01|10 ) TST
+if( 0100 1010 11 !111100 ) TAS
+if( 0100 1010 11 111100 ) ILLEGAL
+if( 0100 1110 0100 ) TRAP
+if( 0100 1110 0101 0 ) LNK
+if( 0100 1110 0101 1 ) ULNK
+if( 0100 1110 0110 ) MOVE USP
+if( 0100 1110 0111 0000 ) RESET
+if( 0100 1110 0111 0001 ) NOP
+if( 0100 1110 0111 0010 ) STOP
+if( 0100 1110 0111 0011 ) RTE
+if( 0100 1110 0111 0101 ) RTS
+if( 0100 1110 0111 0110 ) TRAPV
+if( 0100 1110 0111 0111 ) RTR
+if( 0100 1110 10 ) JSR
+if( 0100 1110 11 ) JMP
+
+*******************************************************************************************************************************************
+
+0101 data(3 bits) 0[1] size(2 bits) ea mode register (3,3 bits) ADDQ,SUBQ
+0101 condition(4 bits) 11 ea mode register(3,3 bits) Scc
+0101 condition(4 bits) 11 001 Dn register(3 bits); 16 bit displacement DBcc
+
+if( 0101 *** 0 !11 ) ADDQ
+if( 0101 *** 1 !11 ) SUBQ
+if( 0101 *** * 11 !001 ) Scc
+if( 0101 *** * 11 001 ) DBcc
+
+*******************************************************************************************************************************************
+
+0110 0000 disp8(8 bit); 16 bit displacement if disp8 == 0 BRA
+0110 0001 disp8(8 bit); 16 bit displacement if disp8 == 0 BSR
+0110 condition(4 bits) disp8(8 bit); 16 bit displacement if disp8 == 0 Bcc
+
+if( 0110 0000 ) BRA
+if( 0110 0001 ) BSR
+if( 0110 !000 ) Bcc
+
+*******************************************************************************************************************************************
+
+0111 Dn dest(3 bits) 0 data(8 bits) MOVEQ
+
+*******************************************************************************************************************************************
+
+1011 register(3 bits) opmode(3 bits) ea mode register(3,3 bits) CMP
+
+1011 Dn source(3 bits) opmode(3 bits) ea mode register(3,3 bits) EOR
+1011 Ax dest(3 bits) 1 size(2 bits) 001 Ay source(3 bits) CMPM
+
+1011 register(3 bits) opmode(3 bits) ea mode register(3,3 bits) CMPA
+
+if( 1011 *** 000|001|010 ) CMP
+if( 1011 *** 100|101|110 001 ) CMPM
+if( 1011 *** 100|101|110 !001 ) EOR
+if( 1011 *** 011|111 ) CMPA
+
+*******************************************************************************************************************************************
+
+1000 Dn dest(3 bits) 1[0] 11 ea mode register(3,3 bits) DIVS,DIVU
+
+1100[1000] Ry dest(3 bits) 1 0000 R/M Rx source(3 bits) ABCD,SBCD
+1100[1000] Dn register(3 bits) opmode(3 bits) ea mode register(3,3 bits) AND,OR
+
+1100 Rx reg(3 bits) 1 opmode(5 bits) Ry reg(3 bits) EXG
+1100 Dn dest(3 bits) 1[0] 11 ea mode register(3,3 bits) MULS,MULU
+
+if( 1000 *** 011 ) DIVU
+if( 1000 *** 111 ) DIVS
+if( 1000 *** 10000 ) SBCD
+if( 1000 *** 000**|001**|010**|10001|10010|10011|101**|110** ) OR
+
+if( 1100 *** 011 ) MULU
+if( 1100 *** 111 ) MULS
+if( 1100 *** 10000 ) ABCD
+if( 1100 *** 000**|001**|010**|10001|10010|10011|10101|10110|10111|11001|11010|11011 ) AND
+if( 1100 *** 10100|11000 ) EXG
+
+*******************************************************************************************************************************************
+
+1101[1001] register(3 bits) opmode(3 bits) ea mode register (3,3 bits) ADD,SUB
+1101[1001] register(3 bits) opmode(3 bits) ea mode register(3,3 bits) ADDA,SUBA
+1101[1001] Ry dest(3 bits) 1 size(2 bits) 00 R/M Rx source(3 bits) ADDX,SUBX
+
+if( 1001 *** 000|001|010|10001|10010|10011|10101|10110|10111|11001|11010|11011 ) SUB
+if( 1001 *** 011|111 ) SUBA
+if( 1001 *** 10000|10100|11000 ) SUBX
+if( 1101 *** 000|001|010|10001|10010|10011|10101|10110|10111|11001|11010|11011 ) ADD
+if( 1101 *** 011|111 ) ADDA
+if( 1101 *** 10000|10100|11000) ADDX
+
+*******************************************************************************************************************************************
+
+1110 count/register(3 bits) dr(1 bit) size(2 bits) i/r(1 bit) 00[01][11][10] Dn dest(3 bit) ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR
+1110 000[001][011][010] dr(1 bit) 11 ea mode register(3,3 bits) ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR
+
+if( 1110 *** * !11 ) ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR
+if( 1110 *** * 11 ) ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR
+
+*******************************************************************************************************************************************
+
+microcode
+instruction: XXXX *** XXX
+
+0000 *** 000 ORI,ORI to CCR,ANDI,ANDI to CCR,SUBI,ADDI,BCHG,BCLR,BSET,BTST,EORI,EORI to CCR,CMPI
+0000 *** 001 ORI,ORI to SR,ANDI,ANDI to SR,SUBI,ADDI,BCHG,BCLR,BSET,BTST,EORI,EORI to SR,CMPI
+0000 *** 010 ORI,ANDI,SUBI,ADDI,BCHG,BCLR,BSET,BTST,EORI,CMPI
+0000 *** 011 ORI,ANDI,SUBI,ADDI,BCHG,BCLR,BSET,BTST,EORI,CMPI
+0000 *** 100 BCHG,BCLR,BSET,BTST,MOVEP
+0000 *** 101 BCHG,BCLR,BSET,BTST,MOVEP
+0000 *** 110 BCHG,BCLR,BSET,BTST,MOVEP
+0000 *** 111 BCHG,BCLR,BSET,BTST,MOVEP
+
+0001 *** 000 MOVE
+0001 *** 001 MOVEA
+0001 *** 010 MOVE
+0001 *** 011 MOVE
+0001 *** 100 MOVE
+0001 *** 101 MOVE
+0001 *** 110 MOVE
+0001 *** 111 MOVE
+
+0010 *** 000 MOVE
+0010 *** 001 MOVEA
+0010 *** 010 MOVE
+0010 *** 011 MOVE
+0010 *** 100 MOVE
+0010 *** 101 MOVE
+0010 *** 110 MOVE
+0010 *** 111 MOVE
+
+0011 *** 000 MOVE
+0011 *** 001 MOVEA
+0011 *** 010 MOVE
+0011 *** 011 MOVE
+0011 *** 100 MOVE
+0011 *** 101 MOVE
+0011 *** 110 MOVE
+0011 *** 111 MOVE
+
+0100 *** 000 NEGX,CLR,NEG,NOT,NBCD,TST
+0100 *** 001 NEGX,CLR,NEG,NOT,SWAP,PEA,TST,TRAP,LNK,ULNK,MOVE USP,RESET,NOP,STOP,RTE,RTS,TRAPV,RTR
+0100 *** 010 NEGX,CLR,NEG,NOT,EXT,MOVEM,TST,JSR
+0100 *** 011 MOVE FROM SR,CLR,MOVE TO CCR,MOVE TO SR,EXT,MOVEM,TAS,ILLEGAL,JMP
+0100 *** 100 invalid
+0100 *** 101 invalid
+0100 *** 110 CHK
+0100 *** 111 LEA
+
+0101 *** 000 ADDQ
+0101 *** 001 ADDQ
+0101 *** 010 ADDQ
+0101 *** 011 Scc,DBcc
+0101 *** 100 SUBQ
+0101 *** 101 SUBQ
+0101 *** 110 SUBQ
+0101 *** 111 Scc,DBcc
+
+0110 *** 000 BRA,Bcc
+0110 *** 001 BRA,Bcc
+0110 *** 010 BRA,Bcc
+0110 *** 011 BRA,Bcc
+0110 *** 100 BSR,Bcc
+0110 *** 101 BSR,Bcc
+0110 *** 110 BSR,Bcc
+0110 *** 111 BSR,Bcc
+
+0111 *** 000 MOVEQ
+0111 *** 001 MOVEQ
+0111 *** 010 MOVEQ
+0111 *** 011 MOVEQ
+0111 *** 100 invalid
+0111 *** 101 invalid
+0111 *** 110 invalid
+0111 *** 111 invalid
+
+1000 *** 000 OR
+1000 *** 001 OR
+1000 *** 010 OR
+1000 *** 011 DIVU
+1000 *** 100 SBCD,OR
+1000 *** 101 OR
+1000 *** 110 OR
+1000 *** 111 DIVS
+
+1001 *** 000 SUB
+1001 *** 001 SUB
+1001 *** 010 SUB
+1001 *** 011 SUBA
+1001 *** 100 SUB,SUBX
+1001 *** 101 SUB,SUBX
+1001 *** 110 SUB,SUBX
+1001 *** 111 SUBA
+
+1010 *** 000 invalid
+1010 *** 001 invalid
+1010 *** 010 invalid
+1010 *** 011 invalid
+1010 *** 100 invalid
+1010 *** 101 invalid
+1010 *** 110 invalid
+1010 *** 111 invalid
+
+1011 *** 000 CMP
+1011 *** 001 CMP
+1011 *** 010 CMP
+1011 *** 011 CMPA
+1011 *** 100 CMPM,EOR
+1011 *** 101 CMPM,EOR
+1011 *** 110 CMPM,EOR
+1011 *** 111 CMPA
+
+1100 *** 000 AND
+1100 *** 001 AND
+1100 *** 010 AND
+1100 *** 011 MULU
+1100 *** 100 ABCD,AND
+1100 *** 101 EXG,AND
+1100 *** 110 EXG,AND
+1100 *** 111 MULS
+
+1101 *** 000 ADD
+1101 *** 001 ADD
+1101 *** 010 ADD
+1101 *** 011 ADDA
+1101 *** 100 ADD,ADDX
+1101 *** 101 ADD,ADDX
+1101 *** 110 ADD,ADDX
+1101 *** 111 ADDA
+
+1110 *** 000 ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR reg
+1110 *** 001 ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR reg
+1110 *** 010 ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR reg
+1110 *** 011 ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR ea
+1110 *** 100 ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR reg
+1110 *** 101 ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR reg
+1110 *** 110 ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR reg
+1110 *** 111 ASL,LSL,ROL,ROXL,ASR,LSR,ROR,ROXR ea
+
+1111 *** 000 invalid
+1111 *** 001 invalid
+1111 *** 010 invalid
+1111 *** 011 invalid
+1111 *** 100 invalid
+1111 *** 101 invalid
+1111 *** 110 invalid
+1111 *** 111 invalid
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Original MC68000 Ports:
+
+Address bus: A23-A1, output
+Data bus: D15-D0, bidirectional
+
+Address Strobe: output
+Read/Write: 0 - write, 1 - read
+Upper and Lower data strobes: output
+
+Data transfer acknowlege: input
+
+A,D,AS,R/W,UDS,LDS: all tri-state
+
+BERR: input
+BERR: perform exception handling, while BERR asserted wait in Hi-Z
+BERR + HALT: retry bus cycle, HALT longer than BERR for at least 1 clock cycle, while HALT asserted wait in Hi-Z,
+ not for read-modify-write, retry count not limited
+
+
+FC[2:0]: valid with Address Strobe
+ 0 - undefined
+ 1 - user data
+ 2 - user program
+ 3 - undefined
+ 4 - undefined
+ 5 - supervisor data : all exception vector entries except reset
+ 6 - supervisor program : exception vector for reset
+ 7 - cpu space : interrupt acknowlege bus cycle
+
+interrupt IPL[2:0]:
+ assert IPL until processor signals interrupt acknowlege
+interrupt acknowlege bus cycle:
+ FC: 7
+ A23-A4: high, A3-A1: interrupt number output
+ D15-D8 ignored, D7-D0 + DACK: vector number
+ input VPA: autovector, complete 6800 read cycle: assert VMA
+ input BERR: spurious interrupt
+
+HALT, RESET: inout
+input HALT + RESET: processor reset
+output RESET: RESET opcode: reset external devices
+output HALT: processor blocked
+input HALT: stop bus activity after current bus cycle, Hi-Z all three-state lines, bus arbitration as usual
+
+
+bus request: input, at any time
+bus grant: output, bus is to be released after current cycle
+bus grant acknowlege: input, bus in use by external device
+
+E: clock: output, 6 clocks low, 4 clocks high
+Valid Peripheral Address: input, use autovector in interrupt acknowlege cycle, device is 6800 type: synchronize data on E
+Valid Memory Address: output, memory address valid and processor synchronized on E
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Backup
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+//----- flip_flop_registers
+//ir1,ir2:
+// required by: ANDI,EORI,ORI,ANDI to CCR,EORI to CCR,ORI to CCR,ANDI to SR,EORI to SR,ORI to SR,ADDI,SUBI
+
Index: trunk/doc/src/openoffice_macro.txt
===================================================================
--- trunk/doc/src/openoffice_macro.txt (nonexistent)
+++ trunk/doc/src/openoffice_macro.txt (revision 2)
@@ -0,0 +1,27 @@
+REM ***** BASIC *****
+
+Sub Main(srcUrl as String, destUrl as String, search as String, replaceUrl as String, doClose as Boolean)
+Dim Doc As Object
+Dim SearchDesc As Object
+Dim Str As String
+Dim Found As Object
+Dim aOptions() As Object
+
+Doc = StarDesktop.loadComponentFromURL(srcUrl, "_blank", 0, aOptions)
+SearchDesc = Doc.createSearchDescriptor
+
+
+SearchDesc.SearchString = search
+
+Found = Doc.findFirst(SearchDesc)
+
+Found.insertDocumentFromURL( replaceUrl, aOptions )
+
+Doc.storeAsURL(destUrl, aOptions)
+
+if(doClose) then
+Doc.close(True)
+endif
+
+End Sub
+
Index: trunk/doc/src/documentation.v
===================================================================
--- trunk/doc/src/documentation.v (nonexistent)
+++ trunk/doc/src/documentation.v (revision 2)
@@ -0,0 +1,579 @@
+/*
+ * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* This file contains only Doxygen documentation.
+*/
+
+/*! \file documentation.v
+ * \brief ao68000 Doxygen documentation.
+ */
+
+/*! \mainpage
+ *
+ *
+ *
+ *
+ * Structure Diagram:
+ * \image html structure.png
+ */
+
+
+/*! \page page_spec_introduction Introduction
+ *
+ * The OpenCores ao68000 IP Core is a Motorola MC68000 compatible processor.
+ *
+ *
+ *
+ */
+
+/*! \page page_directory Directory structure
+ * The ao68000 project consists of the following directories:
+ *
+ * \verbinclude ./doc/src/directory.txt
+ */
+
+/*! \page page_verification Processor verification
+ * The ao68000 IP Core is verified with the WinUAE MC68000 software emulator.
+ * The verification is based on the idea that given the same contents of:
+ * - every register in the processor,
+ * - all memory locations that are read during execution,
+ *
+ * the result of execution, that is the contents of:
+ * - every register in the processor,
+ * - all memory locations written during execution,
+ *
+ * should be the same for the IP Core and the software emulator.
+ *
+ *
+ *
+ *
+ */
+
+/*! \page page_spec_ports IO Ports
+ *
+ *
+ *
+ *
+ *
+ */
+
+/*! \addtogroup CLK_I CLK_I Port
+ * WISHBONE Clock Input
+ */
+/*! \addtogroup RST_I RST_I Port
+ * WISHBONE Reset Input
+ */
+/*! \addtogroup CYC_O CYC_O Port
+ * WISHBONE Master Cycle Output
+ */
+/*! \addtogroup ADR_O ADR_O Port
+ * WISHBONE Master Address Output
+ */
+/*! \addtogroup DAT_O DAT_O Port
+ * WISHBONE Master Data Output
+ */
+/*! \addtogroup DAT_I DAT_I Port
+ * WISHBONE Master Data Input
+ */
+/*! \addtogroup SEL_O SEL_O Port
+ * WISHBONE Master Byte Select
+ */
+/*! \addtogroup STB_O STB_O Port
+ * WISHBONE Master Strobe Output
+ */
+/*! \addtogroup WE_O WE_O Port
+ * WISHBONE Master Write Enable Output
+ */
+/*! \addtogroup ACK_I ACK_I Port
+ * WISHBONE Master Acknowledge Input:
+ * - on normal cycle: acknowledge,
+ * - on interrupt acknowledge cycle: external vector provided on DAT_I[7:0].
+ */
+/*! \addtogroup ERR_I ERR_I Port
+ * WISHBONE Master Error Input
+ * - on normal cycle: bus error,
+ * - on interrupt acknowledge cycle: spurious interrupt.
+ */
+/*! \addtogroup RTY_I RTY_I Port
+ * WISHBONE Master Retry Input
+ * - on normal cycle: retry bus cycle,
+ * - on interrupt acknowledge: use auto-vector.
+ */
+/*! \addtogroup SGL_O SGL_O Port
+ * WISHBONE Cycle Tag, TAG_TYPE: TGC_O, Single Bus Cycle.
+ */
+/*! \addtogroup BLK_O BLK_O Port
+ * WISHBONE Cycle Tag, TAG_TYPE: TGC_O, Block Bus Cycle.
+ */
+/*! \addtogroup RMW_O RMW_O Port
+ * WISHBONE Cycle Tag, TAG_TYPE: TGC_O, Read-Modify-Write Cycle.
+ */
+/*! \addtogroup CTI_O CTI_O Port
+ * WISHBONE Address Tag, TAG_TYPE: TGA_O, Cycle Type Identifier,
+ * Incrementing Bus Cycle or End-of-Burst Cycle.
+ */
+/*! \addtogroup BTE_O BTE_O Port
+ * WISHBONE Address Tag, TAG_TYPE: TGA_O, Burst Type Extension,
+ * always Linear Burst.
+ */
+/*! \addtogroup fc_o fc_o Port
+ * Custom TAG_TYPE: TGC_O, Cycle Tag,
+ * Processor Function Code:
+ * - 1 - user data,
+ * - 2 - user program,
+ * - 5 - supervisor data : all exception vector entries except reset,
+ * - 6 - supervisor program : exception vector for reset,
+ * - 7 - cpu space: interrupt acknowledge.
+ */
+/*! \addtogroup ipl_i ipl_i Port
+ * Interrupt Priority Level
+ * Interrupt acknowledge cycle:
+ * - ACK_I: interrupt vector on DAT_I[7:0],
+ * - ERR_I: spurious interrupt,
+ * - RTY_I: auto-vector.
+ */
+/*! \addtogroup reset_o reset_o Port
+ * External device reset. Output high when processing the RESET instruction.
+ */
+/*! \addtogroup blocked_o blocked_o Port
+ * Processor blocked indicator. The processor is blocked after a double bus error.
+ */
+
+/*! \page page_spec_references References
+ *
+ *
+ *
+ *
+ * - configure and make GCC: + *
+ *
+ *
+ * - patch the Linux kernel sources by copying the contents of the directory ./sw/linux/linux-2.6.33.1-ao68000/ into the Linux kernel + * sources directory, + * - configure and make the Linux kernel:
+ *
+ *
+ * - convert the Linux kernel binary in ELF format into a flat binary format: + *
+ * - synthesise the full_system with the Altera Quartus II tool. The instructions to perform the synthesis are located in the makefile + * located at: ./syn/altera/bin/Makefile, + * - prepare a SDHC card with the software: + * - copy the first 8 bytes of memory form the file ./sw/linux/sector0.dat:
+ *
+ *
+ * - insert the SDHC card into the reader in the Terasic DE2-70 board, + * - load the synthesised SOF file into the FPGA + * - look at the output of the kernel console by opening a serial terminal application and reading the output of the board. + * + *
+
+uClinux/AO68000
+
+Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne
+Built 1 zonelists in Zone order, mobility grouping off. Total pages: 254
+Kernel command line:
+PID hash table entries: 16 (order: -6, 64 bytes)
+Dentry cache hash table entries: 1024 (order: 0, 4096 bytes)
+Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
+Memory available: 400k/1024k RAM, (492k kernel code, 74k data)
+Hierarchical RCU implementation.
+RCU-based detection of stalled CPUs is enabled.
+NR_IRQS:32
+console [ttyDE20] enabled
+Calibrating delay loop... 6.55 BogoMIPS (lpj=32768)
+Mount-cache hash table entries: 512
+Switching to clocksource jiffies
+Freeing unused kernel memory: 20k freed (0x81000 - 0x85000)
+Warning: unable to open an initial console.
+Kernel panic - not syncing: No init found. Try passing init= option to kernel.
+Stack from 000c6f9a:
+ 000c6fca 0007272a 00077560 00087332 00087332 00000400 000765f6 000c6fd6
+ 00000001 00080fb8 00000698 000765ee 00080ff8 00000752 000765f6 000765ee
+ 000765e4 000765da 000765cf 0008691c 000811f8 00000b00 000862d4 00000dc2
+ 00000000
+
+Call Trace with CONFIG_FRAME_POINTER disabled:
+ [0007272a] [00077560] [00000400] [000765f6] [00000698]
+ [000765ee] [00000752] [000765f6] [000765ee] [000765e4]
+ [000765da] [000765cf] [000811f8] [00000b00] [00000dc2]
Index: trunk/doc/specification.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/specification.pdf
===================================================================
--- trunk/doc/specification.pdf (nonexistent)
+++ trunk/doc/specification.pdf (revision 2)
+ * OpenCores ao68000 IP Core.
+ * \author Aleksander Osman, | + * \image html ./doc/img/opencores.jpg + * |
+ * Contents: + * - Specification, automatically generated from: + * - \subpage page_spec_revisions, + * - \subpage page_spec_introduction, + * - \subpage page_spec_architecture, + * - \subpage page_spec_operation, + * - \subpage page_spec_registers, + * - \subpage page_spec_clocks, + * - \subpage page_spec_ports, + * - \subpage page_spec_references. + * - \subpage page_directory, + * - \subpage page_tool, + * - \subpage page_verification, + * - \subpage page_mc68000, + * - \subpage page_old_notes, + * - \subpage page_microcode_compilation, + * - \subpage page_microcode_operations, + * - \subpage page_microcode, + * - \subpage page_soc_linux. + * | + * \image html ./doc/img/wishbone_compatible.png + * |
Features
+ * - CISC processor with microcode, + * - WISHBONE revision B.3 compatible MASTER interface, + * - not cycle exact with the MC68000, some instructions take more cycles to complete, some less, + * - Uses about 7500 LE on Altera Cyclone II and about 45000 bits of RAM for microcode, + * - Tested against the WinUAE M68000 software emulator. Every 16-bit instruction was tested with random register contents and RAM contents + * (\ref page_verification). The result of execution was compared, + * - Runs Linux kernel version 2.6.33.1 up to init process lookup (\ref page_soc_linux), + * - Contains a simple prefetch which is capable of holding up to 5 16-bit instruction words, + * - Document generated by Doxygen (www.doxygen.org) with doxverilog patch (http://developer.berlios.de/projects/doxverilog/). The specification + * is automatically extracted from the Doxygen HTML output. + * + *WISHBONE compatibility
+ * - Version: WISHBONE specification Revision B.3, + * - General description: 32-bit WISHBONE Master interface, + * - WISHBONE signals described in \ref page_spec_ports, + * - Supported cycles: Master Read/Write, Master Block Read/Write, Master Read-Modify-Write for TAS instruction, + * Register Feedback Bus Cycles as described in chapter 4 of the WISHBONE specification, + * - Use of ERR_I: on memory access – bus error, on interrupt acknowledge: spurious interrupt, + * - Use of RTY_I: on memory access – repeat access, on interrupt acknowledge: generate auto-vector, + * - WISHBONE data port size: 32-bit, + * - Data port granularity: 8-bits, + * - Data port maximum operand size: 32-bits, + * - Data transfer ordering: BIG ENDIAN, + * - Data transfer sequencing: UNDEFINED, + * - Constraints on CLK_I signal: described in \ref page_spec_clocks, maximum frequency: about 70 MHz. + * + *Use
+ * The ao68000 can be used as an processor in a System-on-Chip booting Linux kernel up to init program lookup (\ref page_soc_linux). + * + *Similar projects
+ * Other free soft-core implementations of M68000 microprocessor include: + * - OpenCores TG68 (http://www.opencores.org/project,tg68) - runs Amiga software, used as part of the Minimig Core, + * - Suska Atari VHDL WF_68K00_IP Core (http://www.experiment-s.de/en) - runs Atari software, + * - OpenCores K68 (http://www.opencores.org/project,k68) - no user and supervisor modes distinction, executes most instructions, but not all. + * - OpenCores ae68 (http://www.opencores.org/project,ae68) - no files uploaded as of 27.03.2010. + * + *Limitations
+ * - microcode not optimized: some instructions take more cycles to execute than the original MC68000, + * - TRACE not tested, + * - the core is large compared to other implementations. + * + *TODO
+ * - optimize the microcode and count the exact cycle count for every instruction, + * - test TRACE, + * - run WISHBONE verification models, + * - more documentation of the ao68000 module: signal description, operation, FSM in bus_control, + * - describe changes done in WinUAE sources (copy from ao.c), + * - describe microcode words and subprocedures, + * - document the full_system modules, + * - prepare scripts for VATS: run_sim -r -> regresion test, + * - use memories from OpenCore common. + * + *Status
+ * - Tested with WinUAE software MC68000 emulator, + * - Booted Linux kernel up to init process lookup. + * + *Requirements
+ * - Icarus Verilog simulator (http://www.icarus.com/eda/verilog/) is required to compile the tb_ao68000 testbench, + * - Access to Altera Quartus II instalation directory (directory eda/sim_lib/) is required to compile the tb_ao68000 testbench, + * - GCC (http://gcc.gnu.org) is required to compile the WinUAE MC68000 software emulator, + * - Java runtime (http://java.sun.com) is required to run the ao68000_tool (\ref page_tool), + * - Java SDK (http://java.sun.com) is required to compile the ao68000_tool (\ref page_tool), + * - Apache Ant (http://ant.apache.org) is required to compile the ao68000_tool (\ref page_tool), + * - Altera Quartus II synthesis tool (http://www.altera.com) is required to synthesise the full_system System-on-Chip + * (\ref page_soc_linux). + * + *Glossary
+ * - ao68000 - the ao68000 IP Core processor, + * - MC68000 - the original Motorola MC68000 processor. + */ + +/*! \page page_spec_revisions Revision History + *Rev. | Date | Author | Description |
1.0 | 28.03.2010 | Aleksander Osman | First Draft |
Verification procedure
+ * The verification is performed in the following way: + * - the WinUAE MC68000 software emulator is compiled. The sources of the emulator are located at: ./bench/sw_emulators/winuae/. + * The makefile with instructions to compile the emulator are located at: ./sim/sw_emulators/bin/Makefile. + * The compiled binary is located at: ./sim/sw_emulators/run/winuae/ao. + * - the ao68000 testbench is compiled. The sources of the testbench are located at: ./bench/verilog/tb_ao68000/. + * The makefile with instructions to compile the testbench are located at: ./sim/rtl_sim/bin/Makefile. + * The compiled Icarus Verilog script is located at: ./sim/rtl_sim/run/tb_ao68000/tb_ao68000. + * - Both of the above executable programs accept arguments that specify the values of: + * - memory locations that are read during execution, + * - the contents of every register in the processor. + * - The result of executing both of the programs is the contents of: + * - memory locations written during execution, + * - the contents of every register in the processor after execution. + * - The tool ./sw/ao68000_tool/dist/ao68000_tool.jar (\ref page_tool) is used to run both of the executable programs and + * compare the result of execution. The tool is capable of executing multiple concurrent simulations in order to utilize current + * multicore processors. The makefile containing instructions to run the tool is located in: ./sim/rtl_sw_compare/bin/Makefile. + * + *Requirements
+ * - Icarus Verilog simulator (http://www.icarus.com/eda/verilog/) is required to compile the tb_ao68000 testbench, + * - Access to Altera Quartus II instalation (directory eda/sim_lib/) is required to compile the tb_ao68000 testbench, + * - GCC (http://gcc.gnu.org) is required to compile the WinUAE MC68000 software emulator, + * - Java runtime (http://java.sun.com) is required to run the ao68000_tool (\ref page_tool). + */ +/*! \page page_tool ao68000_tool documentation + * + * The ao68000_tool is used to: + * - generate a microcode operations Java file, which contains all available microcode operations (\ref page_microcode_operations): + * ./sw/ao68000_tool/src/ao68000_tool/Parser.java. It is generated from ./rtl/verilog/ao68000/microcode_params.v, + * - generate microcode for ao680000 (\ref page_microcode_compilation) with microcode locations. The microcode + * is generated and stored into an Altera MIF format file located at: + * ./sw/ao68000_tool/microcode.mif. The microcode locations are + * save at:./rtl/verilog/ao68000/microcode/microcode_locations.v, + * - run and compare the results of ao68000 RTL simulation of + * ao68000/sim/rtl_sim/run/tb_ao68000/tb_ao68000 with the software MC68000 + * emulation of ao68000/sim/sw_emulators/winuae/ao (\ref page_verification), + * - extract the specification contents from Doxygen HTML output, to generate the specification ODT file. + * + * The tool is located at: ./sw/ao68000_tool/dist/ao68000_tool.jar. The makefile containing instructions to compile + * the tool is available at: ./sw/ao68000_tool/Makefile. To recompile the tool, ant (http://ant.apache.org) is required. + */ + +/*! \page page_mc68000 MC68000 notes + * \verbinclude ./doc/src/mc68000.txt + */ + +/*! \page page_old_notes Old ao68000 notes + * \verbinclude ./doc/src/old_notes.txt + */ + +/*! \page page_microcode_compilation Microcode compilation + * The ao68000 microcode is represented as an Java program. Execution of this program results in generating the binary + * microcode. + * + *Microcode operations
+ * All possible microcode operations are described in microcode_params.v. + * The locations of: + * - each operation in the microcode word, + * - every procedure in the microcode + * + * are defined in the auto-generated microcode_locations.v file. All the available operation are also represented as Java functions and + * saved in an auto-generated file, located at ./sw/ao68000_tool/src/ao68000_tool/Parser.java (\ref page_microcode_operations). + * These two auto-generated files are generated by the tool ao68000_tool.jar (\ref page_tool). + * + *Microcode compilation
+ * The source for the microcode is located at ./sw/ao68000_tool/src/ao68000_tool/Microcode.java (\ref page_microcode). + * + * The compiled microcode, in Altera MIF format, is located at ./rtl/verilog/ao68000/microcode/microcode.mif. + * + * The tool ao68000_tool.jar (\ref page_tool) is used to compile the microcode source and transform it into a MIF file. + * The makefile containing instructions for performing the compilation is located at ./sw/ao68000_tool/Makefile. + */ + + +/*! \page page_microcode_operations Microcode operations + * The listing below represents operations available in the \ref page_microcode. It is taken from: + * ./sw/ao68000_tool/src/ao68000_tool/Parser.java. More information about the microcode structure and compilation is available at + * \ref page_microcode_compilation. + * + * \include ./sw/ao68000_tool/src/ao68000_tool/Parser.java + */ + +/*! \page page_microcode Microcode + * The listing below represents the microcode. + * It is taken from ./sw/ao68000_tool/src/ao68000_tool/Microcode.java. More information about the microcode structure and + * compilation is available at \ref page_microcode_compilation. + * + * \include ./sw/ao68000_tool/src/ao68000_tool/Microcode.java + */ + +/*! \page page_spec_architecture Architecture + *
+ * \image html ./doc/img/architecture.png
+ * |
ao68000
+ * \copydoc ao68000 + * + *bus_control
+ * \copydoc bus_control + * + *registers
+ * \copydoc registers + * + *memory_registers
+ * \copydoc memory_registers + * + *decoder
+ * \copydoc decoder + * + *condition
+ * \copydoc condition + * + *alu
+ * \copydoc alu + * + *microcode_branch
+ * \copydoc microcode_branch + */ + +/*! \page page_spec_operation Operation + * The ao68000 IP Core is designed to operate in a similar way as the original MC68000. The most import differences are: + * - the core IO ports are compatible with the WISHBONE specification, + * - the execution of instructions in the ao68000 core is not cycle-exact with the original MC68000 and usually takes a few cycles longer. + * + *Setting up the core
+ * The ao68000 IP Core has an WISHBONE MASTER interface. All standard memory access bus cycles conform to the WISHBONE specification. + * These cycles include: + * - instruction fetch, + * - data read, + * - data write. + * + * The cycles are either Single, Block or Read-Modify-Write (for the TAS instruction). When waiting to finish a bus cycle + * the ao68000 reacts on the following input signals: + * - ACK_I: the cycle is completed successfully, + * - RTY_I: the cycle is immediately repeated, the processor does not continue its operation before the current bus cycle is finished. + * In case of the Read-Modify-Write cycle - only the current bus cycle is repeated: either the read or write. + * - ERR_I: the cycle is terminated and a bus error is processed. In case of double bus error the processor enters the blocked state. + * + * There is also a special bus cycle: the interrupt acknowledge cycle. This cycle is a reaction on receiving a external interrupt from + * the ipl_i inputs. The processor only samples the ipl_i lines after processing an instruction, so the interrupt lines have to be asserted + * for some time before the core reacts. The interrupt acknowledge cycle is performed in the following way: + * - ADR_O is set to { 27'b111_1111_1111_1111_1111_1111_1111, 3 bits indicating the interrupt priority level for this cycle }, + * - SEL_O is set to 4'b1111, + * - fc_o is set to 3'b111 to indicate a CPU Cycle as in the original MC68000. + * + * The ao68000 reacts on the following signals when waiting to finish a interrupt acknowledge bus cycle: + * - ACK_I: the cycle is completed successfully and the interrupt vector is read from DAT_I[7:0], + * - RTY_I: the cycle is completed successfully and the processor generates a auto-vector internally, + * - ERR_I: the cycle is terminated and the processor starts processing a spurious interrupt exception. + * + * Every bus cycle is supplemented with output tags: + * - WISHBONE standard tags: SGL_O, BLK_O, RMW_O, CTI_O, BTE_O, + * - ao68000 custom tag: fc_o that operates like the Function Code of the original MC68000. + * + * The ao68000 core has two additional outputs that are used to indicate the state of the processor: + * - reset_o is a external device reset signal. It is asserted when processing the RESET instruction. It is asserted for 124 bus cycles. + * After that the processor returns to normal instruction processing. + * - blocked_o is an output that indicates that the processor is blocked after a double bus error. When this output line is asserted + * the processor is blocked and does not process any instructions. The only way to continue processing instructions is to reset + * the core. + * + *Resetting the core
+ * The ao68000 core is reset with a standard synchronous WISHBONE RST_I input. One clock cycle with RST_I asserted is enough to reset + * the core. After deasserting the signal, the core starts its standard startup sequence, which is similar to the one performed + * by the original MC68000: + * - the value of the SSP register is read from address 0, + * - the value of the PC is read from address 1. + * + * An identical sequence is performed when powering up the core for the first time. + * + *Processor modes
+ * The ao68000 core has two modes of operation - exactly like the original MC68000: + * - Supervisor mode + * - User mode. + * + * Performing a privileged instruction when running in user mode results in a privilege exception, just like in MC68000. + * + *Processor states
+ * The ao68000 core can be in one of the following states: + * - instruction processing, which includes group 2 exception processing, + * - group 0 and group 1 exception processing, + * - external device reset state when processing the RESET instruction, + * - blocked state after a double bus error. + */ + +/*! \page page_spec_registers Registers + * The ao68000 IP Core is a WISHBONE Master and does not contain any registers available for reading or writing from outside of the core. + */ + +/*! \page page_spec_clocks Clocks + *Name | Source | Rates (MHz) | Remarks | Description | ||
Max | Min | Resolution | ||||
CLK_I | Input Port | 70 | - | - | - | System clock. |
WISHBONE IO Ports
+ *Port | Width | Direction | Description |
CLK_I | 1 | Input | \copydoc CLK_I |
RST_I | 1 | Input | \copydoc RST_I |
CYC_O | 1 | Output | \copydoc CYC_O |
ADR_O | 30 | Output | \copydoc ADR_O |
DAT_O | 32 | Output | \copydoc DAT_O |
DAT_I | 32 | Input | \copydoc DAT_I |
SEL_O | 4 | Output | \copydoc SEL_O |
STB_O | 1 | Output | \copydoc STB_O |
WE_O | 1 | Output | \copydoc WE_O |
ACK_I | 1 | Input | \copydoc ACK_I |
ERR_I | 1 | Input | \copydoc ERR_I |
RTY_I | 1 | Input | \copydoc RTY_I |
SGL_O | 1 | Output | \copydoc SGL_O |
BLK_O | 1 | Output | \copydoc BLK_O |
RMW_O | 1 | Output | \copydoc RMW_O |
CTI_O | 3 | Output | \copydoc CTI_O |
BTE_O | 2 | Output | \copydoc BTE_O |
fc_o | 3 | Output | \copydoc fc_o |
Other IO Ports
+ *Port | Width | Direction | Description |
ipl_i | 3 | Input | \copydoc ipl_i |
reset_o | 1 | Output | \copydoc reset_o |
blocked_o | 1 | Output | \copydoc blocked_o |
-
+ * Specification for the: WISHBONE System-on-Chip (SoC) Interconnection Architecture for Portable IP Cores.
+ * Revision: B.3.
+ * Released: September 7, 2002.
+ * Available from: http://www.opencores.org.
+ * -
+ * M68000 8-/16-/32-Bit Microprocessors User’s Manual.
+ * Ninth Edition.
+ * Freescale Semiconductor, Inc.
+ * Available from: http://www.freescale.com.
+ * -
+ * MOTOROLA M68000 FAMILY Programmer’s Reference Manual (Includes CPU32 Instructions).
+ * MOTOROLA INC., 1992. M68000PM/AD REV.1.
+ * Available form: http://www.freescale.com.
+ * -
+ * ao68000 Doxygen(Design) Documentation.
+ *
Requirements
+ * - Linux kernel sources (http://www.kernel.org), tested with version 2.6.33.1, + * - a MC68000 toolchain (http://www.gnu.org), tested with binutils-2.20 and gcc-core-4.4.3, + * - a development board to run the system, tested with Terasic DE2-70 board (http://www.terasic.com.tw), + * - a SDHC card, + * - a serial cable to view the output of kernel execution on a serial terminal program. + * + *System-on-Chip
+ * In order to test the ao68000 processor by booting the Linux kernel, a System-on-Chip is prepared and located at: + * ./rtl/verilog/full_system/. The system consists of: + * - an early boot state machine: early_boot.v, + * - a SDHC card controller: sd.v, + * - a serial line transmitter: serial_txd.v, + * - a SSRAM controller: ssram.v, + * - a simple timer: timer.v, + * - a top level module, that instantiates the above modules and the ao68000 processor: full_system.v. + * + *Step-by-step instruction to prepare the system
+ * - download the Linux kernel (linux-2.6.33.1.tar.bz2), + * - download the toolchain (binutils-2.20.tar.bz2, gcc-core-4.4.3.tar.bz2), + * - configure and make Binutils:+ *
./configure --prefix=(build prefix) --target=m68knommu-none-linux
+ *
make
+ *
make install
+ * - configure and make GCC: + *
./../gcc-4.4.3/configure --prefix=(build prefix) --target=m68knommu-none-linux
+ * --disable-threads --disable-shared --disable-libmudflap --disable-libssp --disable-libiberty --disable-zlib --disable-libgomp
+ * + *
make
+ *
make install
+ * - patch the Linux kernel sources by copying the contents of the directory ./sw/linux/linux-2.6.33.1-ao68000/ into the Linux kernel + * sources directory, + * - configure and make the Linux kernel:
+ *
make menuconfig ARCH=m68knommu CROSS_COMPILE=(build prefix)/bin/m68knommu-none-linux-
+ *
make ARCH=m68knommu CROSS_COMPILE=(build prefix)/bin/m68knommu-none-linux-
+ * - convert the Linux kernel binary in ELF format into a flat binary format: + *
(build prefix)//bin/m68knommu-none-linux-objcopy -O binary vmlinux vmlinux.bin
+ * - synthesise the full_system with the Altera Quartus II tool. The instructions to perform the synthesis are located in the makefile + * located at: ./syn/altera/bin/Makefile, + * - prepare a SDHC card with the software: + * - copy the first 8 bytes of memory form the file ./sw/linux/sector0.dat:
+ *
dd if=sector0.dat of=/dev/(SD card device)
+ * This file contains the SSP and PC values read by the ao68000 processor after booting.
+ * - copy the Linux kernel flat binary, at offset 1024: + *
dd if=vmlinux.bin of=/dev/(SD card device) bs=1024 seek=1
+ * - insert the SDHC card into the reader in the Terasic DE2-70 board, + * - load the synthesised SOF file into the FPGA + * - look at the output of the kernel console by opening a serial terminal application and reading the output of the board. + * + *
Notes
+ * - the SLOB allocator and not the default SLAB allocator had to be selected because of a problem in the kernel sources + * (in_interrupt() check in ./kernel/slab.c:2109 before enabling the interrupts), + * - the source file in the Linux kernel: ./init/initramfs.c compiled with the GCC option -m68000 contains illegal code + * to execute on a MC68000 (copy a long word from an unaligned address). Even after correcting this problem, the kernel did not want to boot + * reliably (sometimes it booted and found the init program, sometimes not). + * + *Linux console output
+ * The output of the running kernel is presented below: + * \verbinclude ./doc/src/linux_booting.txt + */ + Index: trunk/doc/src/linux_booting.txt =================================================================== --- trunk/doc/src/linux_booting.txt (nonexistent) +++ trunk/doc/src/linux_booting.txt (revision 2) @@ -0,0 +1,34 @@ +Linux version 2.6.33.1 (alek@gesserit) (gcc version 4.4.3 (GCC) ) #11 Sun Mar 21 + 13:47:14 CET 2010 + +AO68000 support Aleksander Osman
trunk/doc/specification.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/README.txt
===================================================================
--- trunk/doc/README.txt (nonexistent)
+++ trunk/doc/README.txt (revision 2)
@@ -0,0 +1,13 @@
+The ao68000 core documentation is generated by the Doxygen tool
+(www.doxygen.org) with the doxverilog patch
+(http://developer.berlios.de/projects/doxverilog/).
+
+A generated copy of the documentation is included. Because of its size, it is
+stored in an compressed archive: doxygen_generated.tar.gz.
+
+To decompress it type:
+make unpack
+
+To open the documentation, open the file:
+./doxygen/html/index.html
+in a browser.
Index: trunk/doc/doxygen.cfg
===================================================================
--- trunk/doc/doxygen.cfg (nonexistent)
+++ trunk/doc/doxygen.cfg (revision 2)
@@ -0,0 +1,258 @@
+# Doxyfile 1.5.8
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = ao68000
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = ./doxygen
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 4
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VERILOG= YES
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING =
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+TYPEDEF_HIDES_STRUCT = NO
+SYMBOL_CACHE_SIZE = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = YES
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_DIRECTORIES = NO
+SHOW_FILES = YES
+SHOW_NAMESPACES = YES
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = ./../rtl/verilog/ao68000 ./../doc/src
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.v
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH = ./..
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH = ./img
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = YES
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+HTML_DYNAMIC_SECTIONS = NO
+GENERATE_DOCSET = NO
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = NO
+QCH_FILE =
+QHP_NAMESPACE =
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 4
+GENERATE_TREEVIEW = NONE
+TREEVIEW_WIDTH = 250
+FORMULA_FONTSIZE = 10
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH = ./../rtl/verilog/ao68000
+INCLUDE_FILE_PATTERNS = *.v
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+MSCGEN_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+DOT_FONTNAME = FreeSans
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Options related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
Index: trunk/doc/img/wishbone_compatible.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/img/wishbone_compatible.png
===================================================================
--- trunk/doc/img/wishbone_compatible.png (nonexistent)
+++ trunk/doc/img/wishbone_compatible.png (revision 2)
trunk/doc/img/wishbone_compatible.png
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/img/structure.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/img/structure.png
===================================================================
--- trunk/doc/img/structure.png (nonexistent)
+++ trunk/doc/img/structure.png (revision 2)
trunk/doc/img/structure.png
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/img/architecture.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/img/architecture.png
===================================================================
--- trunk/doc/img/architecture.png (nonexistent)
+++ trunk/doc/img/architecture.png (revision 2)
trunk/doc/img/architecture.png
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/img/structure.graphml
===================================================================
--- trunk/doc/img/structure.graphml (nonexistent)
+++ trunk/doc/img/structure.graphml (revision 2)
@@ -0,0 +1,774 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dn Addr (3)
+
+
+
+
+
+
+
+
+
+
+ An Addr (3)
+
+
+
+
+
+
+
+
+
+
+ Dn RAM
+
+
+
+
+
+
+
+
+
+
+ An RAM
+
+
+
+
+
+
+
+
+
+
+ Dn output
+
+
+
+
+
+
+
+
+
+
+ An output
+
+
+
+
+
+
+
+
+
+
+ USP
+
+
+
+
+
+
+
+
+
+
+ SR
+
+
+
+
+
+
+
+
+
+
+ CCR
+
+
+
+
+
+
+
+
+
+
+ Operand1 (32)
+
+
+
+
+
+
+
+
+
+
+ Operand2 (32)
+
+
+
+
+
+
+
+
+
+
+ ALU
+
+AND,OR,EOR
+ADD,SUB
+MULU,MULS,DIVU,DIVS
+
+
+
+
+
+
+
+
+
+
+ Result register (32)
+
+
+
+
+
+
+
+
+
+
+ PC (32)
+
+
+
+
+
+
+
+
+
+
+ ir (16)
+
+
+
+
+
+
+
+
+
+
+ prefetch (80)
+
+
+
+
+
+
+
+
+
+
+ Shift
+
+
+
+
+
+
+
+
+
+
+ address (32)
+
+
+
+
+
+
+
+
+
+
+ size (2)
+
+
+
+
+
+
+
+
+
+
+ data (32)
+
+
+
+
+
+
+
+
+
+
+ Bus cycle
+unit
+
+
+
+
+
+
+
+
+
+
+ fc (3)
+
+
+
+
+
+
+
+
+
+
+ Prefetch unit
+
+
+
+
+
+
+
+
+
+
+ Decode unit
+
+
+
+
+
+
+
+
+
+
+ Efficient Address
+unit
+
+
+
+
+
+
+
+
+
+
+ ipl (3)
+
+
+
+
+
+
+
+
+
+
+ Reset
+Blocked
+(2)
+
+
+
+
+
+
+
+
+
+
+ Micrcode ROM
+
+45 kilobits
+
+
+
+
+
+
+
+
+
+
+ Micro PC (9)
+
+
+
+
+
+
+
+
+
+
+ Micro word (88)
+
+
+
+
+
+
+
+
+
+
+ Increment
+
+
+
+
+
+
+
+
+
+
+ Decrement
+
+
+
+
+
+
+
+
+
+
+ Index register (32)
+
+
+
+
+
+
+
+
+
+
+ select (4)
+
+
+
+
+
+
+
+
+
+
+ ea_reg (3)
+
+
+
+
+
+
+
+
+
+
+ ea_mod (3)
+
+
+
+
+
+
+
+
+
+
+ ea_type (4)
+
+
+
+
+
+
+
+
+
+
+ movem_modreg (6)
+
+
+
+
+
+
+
+
+
+
+ movem_loop (5)
+
+
+
+
+
+
+
+
+
+
+ trap (8)
+
+
+
+
+
+
+
+
+
+
+ Offset register (32)
+
+
+
+
+
+
+
+
+
+
+ movem_reg (16)
+
+
+
+
+
+
+
+
+
+
+ ALU unit
+
+
+
+
+
+
+
+
+
+
+ Microcode unit
+
+
+
+
+
+
+
+
+
+
+ Register file
+
+
+
+
+
+
+
+
+
+
+ stop_flag (1)
+
+
+
+
+
+
+
+
+
+
+ trace_flag (1)
+
+
+
+
+
+
+
+
+
+
+ group_0_flag (1)
+
+
+
+
+
+
+
+
+
+
+ instruction_flag (1)
+
+
+
+
+
+
+
+
+
+
+ read_modify_write_flag (1)
+
+
+
+
+
+
+
+
+
+
+ do_reset_flag (1)
+
+
+
+
+
+
+
+
+
+
+ do_interrupt_flag (1)
+
+
+
+
+
+
+
+
+
+
+ do_read_flag (1)
+
+
+
+
+
+
+
+
+
+
+ do_write_flag (1)
+
+
+
+
+
+
+
+
+
+
+ do_blocked_flag (1)
+
+
+
+
+
+
+
+
+
+
+ data_write (32)
+
+
+
+
+
+
+
+
+
+
+ An input (32)
+
+
+
+
+
+
+
+
+
+
+ Status unit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: trunk/doc/img/architecture.graphml
===================================================================
--- trunk/doc/img/architecture.graphml (nonexistent)
+++ trunk/doc/img/architecture.graphml (revision 2)
@@ -0,0 +1,363 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ao68000
+
+
+
+
+
+
+
+
+
+
+ bus_control
+
+
+
+
+
+
+
+
+
+
+ registers
+
+
+
+
+
+
+
+
+
+
+ memory_registers
+
+
+
+
+
+
+
+
+
+
+ decoder
+
+
+
+
+
+
+
+
+
+
+ condition
+
+
+
+
+
+
+
+
+
+
+ alu
+
+
+
+
+
+
+
+
+
+
+ microcode_branch
+
+
+
+
+
+
+
+
+
+
+ WISHBONE bus
+
+
+
+
+
+
+
+
+
+
+ Interrupt input
+
+Reset output
+
+Blocked output
+
+
+
+
+
+
+
+
+
+
+ microcode
+
+
+
+
+
+
+
+
+
+
+ Dn and An
+registers
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: trunk/doc/img/opencores.jpg
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/img/opencores.jpg
===================================================================
--- trunk/doc/img/opencores.jpg (nonexistent)
+++ trunk/doc/img/opencores.jpg (revision 2)
trunk/doc/img/opencores.jpg
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/Makefile
===================================================================
--- trunk/doc/Makefile (nonexistent)
+++ trunk/doc/Makefile (revision 2)
@@ -0,0 +1,57 @@
+ifndef BROWSER
+BROWSER := firefox
+endif
+
+ifndef AO68000_BASE
+AO68000_BASE := $(CURDIR)/..
+endif
+
+help:
+ @echo -e "Select operation to perform. Type 'make' followed by the name of the operation."
+ @echo
+ @echo -e "Available operations:"
+ @echo -e "unpack \t- unpack generated doxygen HTML documentation."
+ @echo -e "doxygen \t- run the doxygen tool on the ao68000 project."
+ @echo -e " \t- Doxverilog version required."
+ @echo -e "view \t- open generated doxygen HTML documentation in a browser."
+ @echo -e "spec_extract \t- generate the specification.odt file from the HTML docs."
+ @echo
+ @exit 0
+
+unpack:
+ tar -x -z -f doxygen_generated.tar.gz
+
+doxygen: doxygen.cfg ./doxygen
+ifndef DOXVERILOG
+ @echo "DOXVERILOG environment variable not set. Set it to a Doxverilog executable."
+ @exit 1
+endif
+ $(DOXVERILOG) doxygen.cfg
+
+view: doxygen
+ $(BROWSER) ./doxygen/html/index.html &
+
+spec_extract: ./doxygen
+ mkdir -p ./out/spec_extract
+ java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar spec_extract $(AO68000_BASE)/doc/doxygen/html/page_spec_references.html $(AO68000_BASE)/doc/out/spec_extract/references.html
+ java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar spec_extract $(AO68000_BASE)/doc/doxygen/html/page_spec_ports.html $(AO68000_BASE)/doc/out/spec_extract/ports.html
+ java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar spec_extract $(AO68000_BASE)/doc/doxygen/html/page_spec_clocks.html $(AO68000_BASE)/doc/out/spec_extract/clocks.html
+ java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar spec_extract $(AO68000_BASE)/doc/doxygen/html/page_spec_registers.html $(AO68000_BASE)/doc/out/spec_extract/registers.html
+ java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar spec_extract $(AO68000_BASE)/doc/doxygen/html/page_spec_operation.html $(AO68000_BASE)/doc/out/spec_extract/operation.html
+ java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar spec_extract $(AO68000_BASE)/doc/doxygen/html/page_spec_architecture.html $(AO68000_BASE)/doc/out/spec_extract/architecture.html
+ java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar spec_extract $(AO68000_BASE)/doc/doxygen/html/page_spec_introduction.html $(AO68000_BASE)/doc/out/spec_extract/introduction.html
+ java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar spec_extract $(AO68000_BASE)/doc/doxygen/html/page_spec_revisions.html $(AO68000_BASE)/doc/out/spec_extract/revisions.html
+
+ soffice "macro:///Standard.Module1.Main(file://$(AO68000_BASE)/doc/src/specification_template.odt,file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,,file://$(AO68000_BASE)/doc/out/spec_extract/references.html,True)"
+ soffice "macro:///Standard.Module1.Main(file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,,file://$(AO68000_BASE)/doc/out/spec_extract/ports.html,True)"
+ soffice "macro:///Standard.Module1.Main(file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,,file://$(AO68000_BASE)/doc/out/spec_extract/clocks.html,True)"
+ soffice "macro:///Standard.Module1.Main(file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,,file://$(AO68000_BASE)/doc/out/spec_extract/registers.html,True)"
+ soffice "macro:///Standard.Module1.Main(file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,,file://$(AO68000_BASE)/doc/out/spec_extract/operation.html,True)"
+ soffice "macro:///Standard.Module1.Main(file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,,file://$(AO68000_BASE)/doc/out/spec_extract/architecture.html,True)"
+ soffice "macro:///Standard.Module1.Main(file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,,file://$(AO68000_BASE)/doc/out/spec_extract/introduction.html,True)"
+ soffice "macro:///Standard.Module1.Main(file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,file://$(AO68000_BASE)/doc/out/spec_extract/specification.odt,,file://$(AO68000_BASE)/doc/out/spec_extract/revisions.html,False)"
+
+clean:
+ rm -R -f ./doxygen
+ rm -R -f ./out/spec_extract
+
Index: trunk/sim/rtl_sw_compare/bin/Makefile
===================================================================
--- trunk/sim/rtl_sw_compare/bin/Makefile (nonexistent)
+++ trunk/sim/rtl_sw_compare/bin/Makefile (revision 2)
@@ -0,0 +1,42 @@
+AO68000_BASE := $(CURDIR)/../../..
+export AO68000_BASE
+
+DEST_DIR := $(AO68000_BASE)/sim/rtl_sw_compare/run
+
+START_IR_DEC := 0
+END_IR_DEC := 65536
+TERM_PROGRAM := xterm
+COUNT := 2
+COUNT_LIST := $(wordlist 1,$(COUNT),0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
+
+STEP = `expr \( $(END_IR_DEC) - $(START_IR_DEC) \) / $(COUNT)`
+
+help:
+ @echo -e "Select RTL-SW comparison profile. Type 'make' followed by the name of the profile."
+ @echo
+ @echo -e "Available profiles:"
+ @echo -e "tb_ao68000_with_winuae \t- compare tb_ao68000 RTL project with winuae software project."
+ @echo
+ @exit 0
+
+tb_ao68000_with_winuae:
+ $(foreach i,$(COUNT_LIST), mkdir -p $(DEST_DIR)/tb_ao68000_$(i); )
+ $(foreach i,$(COUNT_LIST), mkdir -p $(DEST_DIR)/tb_ao68000_$(i)/microcode; )
+ $(foreach i,$(COUNT_LIST), mkdir -p $(DEST_DIR)/tb_ao68000_$(i)/bin; )
+ $(foreach i,$(COUNT_LIST), mkdir -p $(DEST_DIR)/tb_ao68000_$(i)/vcd; )
+ $(foreach i,$(COUNT_LIST), cp $(AO68000_BASE)/rtl/verilog/ao68000/microcode/microcode.mif $(DEST_DIR)/tb_ao68000_$(i)/microcode; )
+ $(foreach i,$(COUNT_LIST), echo -e "#!/bin/bash\n$(AO68000_BASE)/sim/rtl_sim/run/tb_ao68000/tb_ao68000 \$$@" \
+ > $(DEST_DIR)/tb_ao68000_$(i)/bin/run.sh; \
+ )
+ $(foreach i,$(COUNT_LIST), chmod +x $(DEST_DIR)/tb_ao68000_$(i)/bin/run.sh; )
+ $(foreach i,$(COUNT_LIST), $(TERM_PROGRAM) -e java -jar $(AO68000_BASE)/sw/ao68000_tool/dist/ao68000_tool.jar test \
+ $(AO68000_BASE)/sim/sw_emulators/run/winuae/ao \
+ $(DEST_DIR)/tb_ao68000_$(i)/bin/run.sh \
+ `expr $(i) \* \( \( $(END_IR_DEC) - $(START_IR_DEC) \) / $(COUNT) \)` \
+ `expr \( $(i) + 1 \) \* \( \( $(END_IR_DEC) - $(START_IR_DEC) \) / $(COUNT) \)` \
+ & \
+ )
+
+clean:
+ rm -f -R $(DEST_DIR)/tb_ao68000_*
+
Index: trunk/sim/sw_emulators/bin/Makefile
===================================================================
--- trunk/sim/sw_emulators/bin/Makefile (nonexistent)
+++ trunk/sim/sw_emulators/bin/Makefile (revision 2)
@@ -0,0 +1,22 @@
+AO68000_BASE := $(CURDIR)/../../..
+export AO68000_BASE
+
+SRC_DIR := $(AO68000_BASE)/bench/sw_emulators
+DEST_DIR := $(AO68000_BASE)/sim/sw_emulators/run
+
+help:
+ @echo -e "Select software MC68000 emulator to compile. Type 'make' followed by the name of the project."
+ @echo
+ @echo -e "Available projects:"
+ @echo -e "winuae \t- MC68000 emulator from the WinUAE project (www.winuae.net)."
+ @echo
+ @exit 0
+
+winuae:
+ mkdir -p $(DEST_DIR)/winuae
+ cp $(SRC_DIR)/winuae/Makefile $(DEST_DIR)/winuae
+ $(MAKE) -C $(DEST_DIR)/winuae VPATH=$(SRC_DIR)/winuae
+
+clean:
+ rm -f -R $(DEST_DIR)/winuae
+
Index: trunk/sim/rtl_sim/bin/Makefile
===================================================================
--- trunk/sim/rtl_sim/bin/Makefile (nonexistent)
+++ trunk/sim/rtl_sim/bin/Makefile (revision 2)
@@ -0,0 +1,21 @@
+AO68000_BASE := $(CURDIR)/../../..
+export AO68000_BASE
+
+SRC_DIR := $(AO68000_BASE)/bench/verilog
+DEST_DIR := $(AO68000_BASE)/sim/rtl_sim/run
+
+help:
+ @echo -e "Select RTL simulation to compile. Type 'make' followed by the name of the project."
+ @echo
+ @echo -e "Available projects:"
+ @echo -e "tb_ao68000 \t- testbench for ao68000."
+ @echo
+ @exit 0
+
+tb_ao68000:
+ mkdir -p $(DEST_DIR)/tb_ao68000
+ cp $(SRC_DIR)/tb_ao68000/Makefile $(DEST_DIR)/tb_ao68000
+ $(MAKE) -C $(DEST_DIR)/tb_ao68000 VPATH=$(SRC_DIR)/tb_ao68000
+
+clean:
+ rm -f -R $(DEST_DIR)/tb_ao68000
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/time.c
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/time.c (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/time.c (revision 2)
@@ -0,0 +1,93 @@
+/*
+ * linux/arch/m68knommu/kernel/time.c
+ *
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ *
+ * This file contains the m68k-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#define TICK_SIZE (tick_nsec / 1000)
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+ if (mach_set_clock_mmss)
+ return mach_set_clock_mmss (nowtime);
+ return -1;
+}
+
+#ifndef CONFIG_GENERIC_CLOCKEVENTS
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+irqreturn_t arch_timer_interrupt(int irq, void *dummy)
+{
+ unsigned long flags;
+
+
+ if (current->pid)
+ profile_tick(CPU_PROFILING);
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+ do_timer(1);
+
+
+#ifndef CONFIG_SMP
+ update_process_times(user_mode(get_irq_regs()));
+#endif
+
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+
+ return(IRQ_HANDLED);
+}
+#endif
+
+static unsigned long read_rtc_mmss(void)
+{
+ unsigned int year, mon, day, hour, min, sec;
+
+ if (mach_gettod)
+ mach_gettod(&year, &mon, &day, &hour, &min, &sec);
+ else
+ year = mon = day = hour = min = sec = 0;
+
+ if ((year += 1900) < 1970)
+ year += 100;
+
+ return mktime(year, mon, day, hour, min, sec);
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+ ts->tv_sec = read_rtc_mmss();
+ ts->tv_nsec = 0;
+}
+
+int update_persistent_clock(struct timespec now)
+{
+ return set_rtc_mmss(now.tv_sec);
+}
+
+void time_init(void)
+{
+ hw_timer_init();
+}
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/setup.c
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/setup.c (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/setup.c (revision 2)
@@ -0,0 +1,358 @@
+/*
+ * linux/arch/m68knommu/kernel/setup.c
+ *
+ * Copyright (C) 1999-2007 Greg Ungerer (gerg@snapgear.com)
+ * Copyright (C) 1998,1999 D. Jeff Dionne
+ * Copyleft ()) 2000 James D. Schettine {james@telos-systems.com}
+ * Copyright (C) 1998 Kenneth Albanowski
+ * Copyright (C) 1995 Hamish Macdonald
+ * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
+ * Copyright (C) 2001 Lineo, Inc.
+ *
+ * 68VZ328 Fixes/support Evan Stawnyczy
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+unsigned long memory_start;
+unsigned long memory_end;
+
+EXPORT_SYMBOL(memory_start);
+EXPORT_SYMBOL(memory_end);
+
+char __initdata command_line[COMMAND_LINE_SIZE];
+
+/* machine dependent timer functions */
+void (*mach_gettod)(int*, int*, int*, int*, int*, int*);
+int (*mach_set_clock_mmss)(unsigned long);
+
+/* machine dependent reboot functions */
+void (*mach_reset)(void);
+void (*mach_halt)(void);
+void (*mach_power_off)(void);
+
+#ifdef CONFIG_M68000
+ #define CPU "MC68000"
+#endif
+#ifdef CONFIG_M68328
+ #define CPU "MC68328"
+#endif
+#ifdef CONFIG_M68EZ328
+ #define CPU "MC68EZ328"
+#endif
+#ifdef CONFIG_M68VZ328
+ #define CPU "MC68VZ328"
+#endif
+#ifdef CONFIG_M68360
+ #define CPU "MC68360"
+#endif
+#if defined(CONFIG_M5206)
+ #define CPU "COLDFIRE(m5206)"
+#endif
+#if defined(CONFIG_M5206e)
+ #define CPU "COLDFIRE(m5206e)"
+#endif
+#if defined(CONFIG_M520x)
+ #define CPU "COLDFIRE(m520x)"
+#endif
+#if defined(CONFIG_M523x)
+ #define CPU "COLDFIRE(m523x)"
+#endif
+#if defined(CONFIG_M5249)
+ #define CPU "COLDFIRE(m5249)"
+#endif
+#if defined(CONFIG_M5271)
+ #define CPU "COLDFIRE(m5270/5271)"
+#endif
+#if defined(CONFIG_M5272)
+ #define CPU "COLDFIRE(m5272)"
+#endif
+#if defined(CONFIG_M5275)
+ #define CPU "COLDFIRE(m5274/5275)"
+#endif
+#if defined(CONFIG_M528x)
+ #define CPU "COLDFIRE(m5280/5282)"
+#endif
+#if defined(CONFIG_M5307)
+ #define CPU "COLDFIRE(m5307)"
+#endif
+#if defined(CONFIG_M532x)
+ #define CPU "COLDFIRE(m532x)"
+#endif
+#if defined(CONFIG_M5407)
+ #define CPU "COLDFIRE(m5407)"
+#endif
+#if defined(CONFIG_AO68000)
+ #define CPU "AO68000"
+#endif
+#ifndef CPU
+ #define CPU "UNKNOWN"
+#endif
+
+extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
+extern int _ramstart, _ramend;
+
+#if defined(CONFIG_UBOOT)
+/*
+ * parse_uboot_commandline
+ *
+ * Copies u-boot commandline arguments and store them in the proper linux
+ * variables.
+ *
+ * Assumes:
+ * _init_sp global contains the address in the stack pointer when the
+ * kernel starts (see head.S::_start)
+ *
+ * U-Boot calling convention:
+ * (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
+ *
+ * _init_sp can be parsed as such
+ *
+ * _init_sp+00 = u-boot cmd after jsr into kernel (skip)
+ * _init_sp+04 = &kernel board_info (residual data)
+ * _init_sp+08 = &initrd_start
+ * _init_sp+12 = &initrd_end
+ * _init_sp+16 = &cmd_start
+ * _init_sp+20 = &cmd_end
+ *
+ * This also assumes that the memory locations pointed to are still
+ * unmodified. U-boot places them near the end of external SDRAM.
+ *
+ * Argument(s):
+ * commandp = the linux commandline arg container to fill.
+ * size = the sizeof commandp.
+ *
+ * Returns:
+ */
+void parse_uboot_commandline(char *commandp, int size)
+{
+ extern unsigned long _init_sp;
+ unsigned long *sp;
+ unsigned long uboot_kbd;
+ unsigned long uboot_initrd_start, uboot_initrd_end;
+ unsigned long uboot_cmd_start, uboot_cmd_end;
+
+
+ sp = (unsigned long *)_init_sp;
+ uboot_kbd = sp[1];
+ uboot_initrd_start = sp[2];
+ uboot_initrd_end = sp[3];
+ uboot_cmd_start = sp[4];
+ uboot_cmd_end = sp[5];
+
+ if (uboot_cmd_start && uboot_cmd_end)
+ strncpy(commandp, (const char *)uboot_cmd_start, size);
+#if defined(CONFIG_BLK_DEV_INITRD)
+ if (uboot_initrd_start && uboot_initrd_end &&
+ (uboot_initrd_end > uboot_initrd_start)) {
+ initrd_start = uboot_initrd_start;
+ initrd_end = uboot_initrd_end;
+ ROOT_DEV = Root_RAM0;
+ printk(KERN_INFO "initrd at 0x%lx:0x%lx\n",
+ initrd_start, initrd_end);
+ }
+#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
+}
+#endif /* #if defined(CONFIG_UBOOT) */
+
+void __init setup_arch(char **cmdline_p)
+{
+ int bootmap_size;
+
+ memory_start = PAGE_ALIGN(_ramstart);
+ memory_end = _ramend;
+
+ init_mm.start_code = (unsigned long) &_stext;
+ init_mm.end_code = (unsigned long) &_etext;
+ init_mm.end_data = (unsigned long) &_edata;
+ init_mm.brk = (unsigned long) 0;
+
+ config_BSP(&command_line[0], sizeof(command_line));
+
+#if defined(CONFIG_BOOTPARAM)
+ strncpy(&command_line[0], CONFIG_BOOTPARAM_STRING, sizeof(command_line));
+ command_line[sizeof(command_line) - 1] = 0;
+#endif /* CONFIG_BOOTPARAM */
+
+#if defined(CONFIG_UBOOT)
+ /* CONFIG_UBOOT and CONFIG_BOOTPARAM defined, concatenate cmdline */
+ #if defined(CONFIG_BOOTPARAM)
+ /* Add the whitespace separator */
+ command_line[strlen(CONFIG_BOOTPARAM_STRING)] = ' ';
+ /* Parse uboot command line into the rest of the buffer */
+ parse_uboot_commandline(
+ &command_line[(strlen(CONFIG_BOOTPARAM_STRING)+1)],
+ (sizeof(command_line) -
+ (strlen(CONFIG_BOOTPARAM_STRING)+1)));
+ /* Only CONFIG_UBOOT defined, create cmdline */
+ #else
+ parse_uboot_commandline(&command_line[0], sizeof(command_line));
+ #endif /* CONFIG_BOOTPARAM */
+ command_line[sizeof(command_line) - 1] = 0;
+#endif /* CONFIG_UBOOT */
+ printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU "\n");
+
+#ifdef CONFIG_UCDIMM
+ printk(KERN_INFO "uCdimm by Lineo, Inc. \n");
+#endif
+#ifdef CONFIG_M68VZ328
+ printk(KERN_INFO "M68VZ328 support by Evan Stawnyczy \n");
+#endif
+#ifdef CONFIG_COLDFIRE
+ printk(KERN_INFO "COLDFIRE port done by Greg Ungerer, gerg@snapgear.com\n");
+#ifdef CONFIG_M5307
+ printk(KERN_INFO "Modified for M5307 by Dave Miller, dmiller@intellistor.com\n");
+#endif
+#ifdef CONFIG_ELITE
+ printk(KERN_INFO "Modified for M5206eLITE by Rob Scott, rscott@mtrob.fdns.net\n");
+#endif
+#endif
+ printk(KERN_INFO "Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
+
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )
+ printk(KERN_INFO "TRG SuperPilot FLASH card support \n");
+#endif
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
+ printk(KERN_INFO "PalmV support by Lineo Inc. \n");
+#endif
+#if defined (CONFIG_M68360)
+ printk(KERN_INFO "QUICC port done by SED Systems ,\n");
+ printk(KERN_INFO "based on 2.0.38 port by Lineo Inc. .\n");
+#endif
+#ifdef CONFIG_DRAGEN2
+ printk(KERN_INFO "DragonEngine II board support by Georges Menie\n");
+#endif
+#ifdef CONFIG_M5235EVB
+ printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n");
+#endif
+
+ pr_debug("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
+ "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
+ (int) &_sdata, (int) &_edata,
+ (int) &_sbss, (int) &_ebss);
+ pr_debug("MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ",
+ (int) &_ebss, (int) memory_start,
+ (int) memory_start, (int) memory_end);
+
+ /* Keep a copy of command line */
+ *cmdline_p = &command_line[0];
+ memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
+ boot_command_line[COMMAND_LINE_SIZE-1] = 0;
+
+#ifdef DEBUG
+ if (strlen(*cmdline_p))
+ printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
+#endif
+#if defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+
+ /*
+ * Give all the memory to the bootmap allocator, tell it to put the
+ * boot mem_map at the start of memory.
+ */
+ bootmap_size = init_bootmem_node(
+ NODE_DATA(0),
+ memory_start >> PAGE_SHIFT, /* map goes here */
+ PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */
+ memory_end >> PAGE_SHIFT);
+ /*
+ * Free the usable memory, we have to make sure we do not free
+ * the bootmem bitmap so we then reserve it after freeing it :-)
+ */
+
+ free_bootmem(memory_start, memory_end - memory_start);
+ reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
+
+#if defined(CONFIG_UBOOT) && defined(CONFIG_BLK_DEV_INITRD)
+ if ((initrd_start > 0) && (initrd_start < initrd_end) &&
+ (initrd_end < memory_end))
+ reserve_bootmem(initrd_start, initrd_end - initrd_start,
+ BOOTMEM_DEFAULT);
+#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
+
+ /*
+ * Get kmalloc into gear.
+ */
+ paging_init();
+}
+
+/*
+ * Get CPU information for use by the procfs.
+ */
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ char *cpu, *mmu, *fpu;
+ u_long clockfreq;
+
+ cpu = CPU;
+ mmu = "none";
+ fpu = "none";
+
+#ifdef CONFIG_COLDFIRE
+ clockfreq = (loops_per_jiffy * HZ) * 3;
+#else
+ clockfreq = (loops_per_jiffy * HZ) * 16;
+#endif
+
+ seq_printf(m, "CPU:\t\t%s\n"
+ "MMU:\t\t%s\n"
+ "FPU:\t\t%s\n"
+ "Clocking:\t%lu.%1luMHz\n"
+ "BogoMips:\t%lu.%02lu\n"
+ "Calibration:\t%lu loops\n",
+ cpu, mmu, fpu,
+ clockfreq / 1000000,
+ (clockfreq / 100000) % 10,
+ (loops_per_jiffy * HZ) / 500000,
+ ((loops_per_jiffy * HZ) / 5000) % 100,
+ (loops_per_jiffy * HZ));
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
+
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/vmlinux.lds.S
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/vmlinux.lds.S (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/kernel/vmlinux.lds.S (revision 2)
@@ -0,0 +1,182 @@
+/*
+ * vmlinux.lds.S -- master linker script for m68knommu arch
+ *
+ * (C) Copyright 2002-2006, Greg Ungerer
+ *
+ * This linker script is equiped to build either ROM loaded or RAM
+ * run kernels.
+ */
+
+#include
+#include
+#include
+
+#if defined(CONFIG_RAMKERNEL)
+#define RAM_START CONFIG_KERNELBASE
+#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
+#define TEXT ram
+#define DATA ram
+#define INIT ram
+#define BSSS ram
+#endif
+#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
+#define RAM_START CONFIG_RAMBASE
+#define RAM_LENGTH CONFIG_RAMSIZE
+#define ROMVEC_START CONFIG_ROMVEC
+#define ROMVEC_LENGTH CONFIG_ROMVECSIZE
+#define ROM_START CONFIG_ROMSTART
+#define ROM_LENGTH CONFIG_ROMSIZE
+#define TEXT rom
+#define DATA ram
+#define INIT ram
+#define BSSS ram
+#endif
+
+#ifndef DATA_ADDR
+#define DATA_ADDR
+#endif
+
+
+OUTPUT_ARCH(m68k)
+ENTRY(_start)
+
+MEMORY {
+ ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH
+#ifdef ROM_START
+ romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH
+ rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH
+#endif
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+#ifdef ROMVEC_START
+ . = ROMVEC_START ;
+ .romvec : {
+ __rom_start = . ;
+ _romvec = .;
+ *(.data.initvect)
+ } > romvec
+#endif
+
+ .text : {
+ _text = .;
+ _stext = . ;
+ HEAD_TEXT
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ *(.text.lock)
+
+ . = ALIGN(16); /* Exception table */
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+
+ *(.rodata) *(.rodata.*)
+ *(__vermagic) /* Kernel version magic */
+ *(__markers_strings)
+ *(.rodata1)
+ *(.rodata.str1.1)
+
+ /* Kernel symbol table: Normal symbols */
+ . = ALIGN(4);
+ __start___ksymtab = .;
+ *(__ksymtab)
+ __stop___ksymtab = .;
+
+ /* Kernel symbol table: GPL-only symbols */
+ __start___ksymtab_gpl = .;
+ *(__ksymtab_gpl)
+ __stop___ksymtab_gpl = .;
+
+ /* Kernel symbol table: Normal unused symbols */
+ __start___ksymtab_unused = .;
+ *(__ksymtab_unused)
+ __stop___ksymtab_unused = .;
+
+ /* Kernel symbol table: GPL-only unused symbols */
+ __start___ksymtab_unused_gpl = .;
+ *(__ksymtab_unused_gpl)
+ __stop___ksymtab_unused_gpl = .;
+
+ /* Kernel symbol table: GPL-future symbols */
+ __start___ksymtab_gpl_future = .;
+ *(__ksymtab_gpl_future)
+ __stop___ksymtab_gpl_future = .;
+
+ /* Kernel symbol table: Normal symbols */
+ __start___kcrctab = .;
+ *(__kcrctab)
+ __stop___kcrctab = .;
+
+ /* Kernel symbol table: GPL-only symbols */
+ __start___kcrctab_gpl = .;
+ *(__kcrctab_gpl)
+ __stop___kcrctab_gpl = .;
+
+ /* Kernel symbol table: Normal unused symbols */
+ __start___kcrctab_unused = .;
+ *(__kcrctab_unused)
+ __stop___kcrctab_unused = .;
+
+ /* Kernel symbol table: GPL-only unused symbols */
+ __start___kcrctab_unused_gpl = .;
+ *(__kcrctab_unused_gpl)
+ __stop___kcrctab_unused_gpl = .;
+
+ /* Kernel symbol table: GPL-future symbols */
+ __start___kcrctab_gpl_future = .;
+ *(__kcrctab_gpl_future)
+ __stop___kcrctab_gpl_future = .;
+
+ /* Kernel symbol table: strings */
+ *(__ksymtab_strings)
+
+ /* Built-in module parameters */
+ . = ALIGN(4) ;
+ __start___param = .;
+ *(__param)
+ __stop___param = .;
+
+ *(.note.gnu.build-id)
+
+ . = ALIGN(4) ;
+ _etext = . ;
+ } > TEXT
+
+ .data DATA_ADDR : {
+ . = ALIGN(4);
+ _sdata = . ;
+ DATA_DATA
+ CACHELINE_ALIGNED_DATA(32)
+ INIT_TASK_DATA(THREAD_SIZE)
+ _edata = . ;
+ } > DATA
+
+ .init.text : {
+ . = ALIGN(PAGE_SIZE);
+ __init_begin = .;
+ } > INIT
+ INIT_TEXT_SECTION(PAGE_SIZE) > INIT
+ INIT_DATA_SECTION(16) > INIT
+ .init.data : {
+ . = ALIGN(PAGE_SIZE);
+ __init_end = .;
+ } > INIT
+
+ .bss : {
+ . = ALIGN(4);
+ _sbss = . ;
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4) ;
+ _ebss = . ;
+ _end = . ;
+ } > BSSS
+
+ DISCARDS
+}
+
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/Kconfig
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/Kconfig (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/Kconfig (revision 2)
@@ -0,0 +1,752 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+mainmenu "uClinux/68k (w/o MMU) Kernel Configuration"
+
+config M68K
+ bool
+ default y
+ select HAVE_IDE
+
+config MMU
+ bool
+ default n
+
+config NO_DMA
+ bool
+ depends on !COLDFIRE
+ default y
+
+config FPU
+ bool
+ default n
+
+config ZONE_DMA
+ bool
+ default y
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+ default n
+
+config ARCH_HAS_ILOG2_U32
+ bool
+ default n
+
+config ARCH_HAS_ILOG2_U64
+ bool
+ default n
+
+config GENERIC_FIND_NEXT_BIT
+ bool
+ default y
+
+config GENERIC_GPIO
+ bool
+ default n
+
+config GENERIC_HWEIGHT
+ bool
+ default y
+
+config GENERIC_HARDIRQS
+ bool
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config GENERIC_TIME
+ bool
+ default y
+
+config GENERIC_CMOS_UPDATE
+ bool
+ default y
+
+config TIME_LOW_RES
+ bool
+ default y
+
+config GENERIC_CLOCKEVENTS
+ bool
+ default n
+
+config NO_IOPORT
+ def_bool y
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+menu "Processor type and features"
+
+choice
+ prompt "CPU"
+ default M68EZ328
+
+config M68328
+ bool "MC68328"
+ help
+ Motorola 68328 processor support.
+
+config AO68000
+ bool "AO68000"
+ help
+ AO68000 soft core support.
+
+config M68EZ328
+ bool "MC68EZ328"
+ help
+ Motorola 68EX328 processor support.
+
+config M68VZ328
+ bool "MC68VZ328"
+ help
+ Motorola 68VZ328 processor support.
+
+config M68360
+ bool "MC68360"
+ help
+ Motorola 68360 processor support.
+
+config M5206
+ bool "MCF5206"
+ help
+ Motorola ColdFire 5206 processor support.
+
+config M5206e
+ bool "MCF5206e"
+ help
+ Motorola ColdFire 5206e processor support.
+
+config M520x
+ bool "MCF520x"
+ select GENERIC_CLOCKEVENTS
+ help
+ Freescale Coldfire 5207/5208 processor support.
+
+config M523x
+ bool "MCF523x"
+ select GENERIC_CLOCKEVENTS
+ help
+ Freescale Coldfire 5230/1/2/4/5 processor support
+
+config M5249
+ bool "MCF5249"
+ help
+ Motorola ColdFire 5249 processor support.
+
+config M5271
+ bool "MCF5271"
+ help
+ Freescale (Motorola) ColdFire 5270/5271 processor support.
+
+config M5272
+ bool "MCF5272"
+ help
+ Motorola ColdFire 5272 processor support.
+
+config M5275
+ bool "MCF5275"
+ help
+ Freescale (Motorola) ColdFire 5274/5275 processor support.
+
+config M528x
+ bool "MCF528x"
+ select GENERIC_CLOCKEVENTS
+ help
+ Motorola ColdFire 5280/5282 processor support.
+
+config M5307
+ bool "MCF5307"
+ help
+ Motorola ColdFire 5307 processor support.
+
+config M532x
+ bool "MCF532x"
+ help
+ Freescale (Motorola) ColdFire 532x processor support.
+
+config M5407
+ bool "MCF5407"
+ help
+ Motorola ColdFire 5407 processor support.
+
+endchoice
+
+config M527x
+ bool
+ depends on (M5271 || M5275)
+ select GENERIC_CLOCKEVENTS
+ default y
+
+config COLDFIRE
+ bool
+ depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407)
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ default y
+
+config CLOCK_SET
+ bool "Enable setting the CPU clock frequency"
+ default n
+ help
+ On some CPU's you do not need to know what the core CPU clock
+ frequency is. On these you can disable clock setting. On some
+ traditional 68K parts, and on all ColdFire parts you need to set
+ the appropriate CPU clock frequency. On these devices many of the
+ onboard peripherals derive their timing from the master CPU clock
+ frequency.
+
+config CLOCK_FREQ
+ int "Set the core clock frequency"
+ default "66666666"
+ depends on CLOCK_SET
+ help
+ Define the CPU clock frequency in use. This is the core clock
+ frequency, it may or may not be the same as the external clock
+ crystal fitted to your board. Some processors have an internal
+ PLL and can have their frequency programmed at run time, others
+ use internal dividers. In general the kernel won't setup a PLL
+ if it is fitted (there are some exceptions). This value will be
+ specific to the exact CPU that you are using.
+
+config CLOCK_DIV
+ int "Set the core/bus clock divide ratio"
+ default "1"
+ depends on CLOCK_SET
+ help
+ On many SoC style CPUs the master CPU clock is also used to drive
+ on-chip peripherals. The clock that is distributed to these
+ peripherals is sometimes a fixed ratio of the master clock
+ frequency. If so then set this to the divider ratio of the
+ master clock to the peripheral clock. If not sure then select 1.
+
+config OLDMASK
+ bool "Old mask 5307 (1H55J) silicon"
+ depends on M5307
+ help
+ Build support for the older revision ColdFire 5307 silicon.
+ Specifically this is the 1H55J mask revision.
+
+comment "Platform"
+
+config TERASICDE2
+ bool "Terasic DE2-70 FPGA development board support"
+ depends on AO68000
+ help
+ Support for the Terasic DE2-70 FPGA development board.
+
+config PILOT3
+ bool "Pilot 1000/5000, PalmPilot Personal/Pro, or PalmIII support"
+ depends on M68328
+ help
+ Support for the Palm Pilot 1000/5000, Personal/Pro and PalmIII.
+
+config XCOPILOT_BUGS
+ bool "(X)Copilot support"
+ depends on PILOT3
+ help
+ Support the bugs of Xcopilot.
+
+config UC5272
+ bool 'Arcturus Networks uC5272 dimm board support'
+ depends on M5272
+ help
+ Support for the Arcturus Networks uC5272 dimm board.
+
+config UC5282
+ bool "Arcturus Networks uC5282 board support"
+ depends on M528x
+ help
+ Support for the Arcturus Networks uC5282 dimm board.
+
+config UCSIMM
+ bool "uCsimm module support"
+ depends on M68EZ328
+ help
+ Support for the Arcturus Networks uCsimm module.
+
+config UCDIMM
+ bool "uDsimm module support"
+ depends on M68VZ328
+ help
+ Support for the Arcturus Networks uDsimm module.
+
+config DRAGEN2
+ bool "DragenEngine II board support"
+ depends on M68VZ328
+ help
+ Support for the DragenEngine II board.
+
+config DIRECT_IO_ACCESS
+ bool "Allow user to access IO directly"
+ depends on (UCSIMM || UCDIMM || DRAGEN2)
+ help
+ Disable the CPU internal registers protection in user mode,
+ to allow a user application to read/write them.
+
+config INIT_LCD
+ bool "Initialize LCD"
+ depends on (UCSIMM || UCDIMM || DRAGEN2)
+ help
+ Initialize the LCD controller of the 68x328 processor.
+
+config MEMORY_RESERVE
+ int "Memory reservation (MiB)"
+ depends on (UCSIMM || UCDIMM)
+ help
+ Reserve certain memory regions on 68x328 based boards.
+
+config UCQUICC
+ bool "Lineo uCquicc board support"
+ depends on M68360
+ help
+ Support for the Lineo uCquicc board.
+
+config ARN5206
+ bool "Arnewsh 5206 board support"
+ depends on M5206
+ help
+ Support for the Arnewsh 5206 board.
+
+config M5206eC3
+ bool "Motorola M5206eC3 board support"
+ depends on M5206e
+ help
+ Support for the Motorola M5206eC3 board.
+
+config ELITE
+ bool "Motorola M5206eLITE board support"
+ depends on M5206e
+ help
+ Support for the Motorola M5206eLITE board.
+
+config M5208EVB
+ bool "Freescale M5208EVB board support"
+ depends on M520x
+ help
+ Support for the Freescale Coldfire M5208EVB.
+
+config M5235EVB
+ bool "Freescale M5235EVB support"
+ depends on M523x
+ help
+ Support for the Freescale M5235EVB board.
+
+config M5249C3
+ bool "Motorola M5249C3 board support"
+ depends on M5249
+ help
+ Support for the Motorola M5249C3 board.
+
+config M5271EVB
+ bool "Freescale (Motorola) M5271EVB board support"
+ depends on M5271
+ help
+ Support for the Freescale (Motorola) M5271EVB board.
+
+config M5275EVB
+ bool "Freescale (Motorola) M5275EVB board support"
+ depends on M5275
+ help
+ Support for the Freescale (Motorola) M5275EVB board.
+
+config M5272C3
+ bool "Motorola M5272C3 board support"
+ depends on M5272
+ help
+ Support for the Motorola M5272C3 board.
+
+config COBRA5272
+ bool "senTec COBRA5272 board support"
+ depends on M5272
+ help
+ Support for the senTec COBRA5272 board.
+
+config AVNET5282
+ bool "Avnet 5282 board support"
+ depends on M528x
+ help
+ Support for the Avnet 5282 board.
+
+config M5282EVB
+ bool "Motorola M5282EVB board support"
+ depends on M528x
+ help
+ Support for the Motorola M5282EVB board.
+
+config COBRA5282
+ bool "senTec COBRA5282 board support"
+ depends on M528x
+ help
+ Support for the senTec COBRA5282 board.
+
+config SOM5282EM
+ bool "EMAC.Inc SOM5282EM board support"
+ depends on M528x
+ help
+ Support for the EMAC.Inc SOM5282EM module.
+
+config WILDFIRE
+ bool "Intec Automation Inc. WildFire board support"
+ depends on M528x
+ help
+ Support for the Intec Automation Inc. WildFire.
+
+config WILDFIREMOD
+ bool "Intec Automation Inc. WildFire module support"
+ depends on M528x
+ help
+ Support for the Intec Automation Inc. WildFire module.
+
+config ARN5307
+ bool "Arnewsh 5307 board support"
+ depends on M5307
+ help
+ Support for the Arnewsh 5307 board.
+
+config M5307C3
+ bool "Motorola M5307C3 board support"
+ depends on M5307
+ help
+ Support for the Motorola M5307C3 board.
+
+config SECUREEDGEMP3
+ bool "SnapGear SecureEdge/MP3 platform support"
+ depends on M5307
+ help
+ Support for the SnapGear SecureEdge/MP3 platform.
+
+config M5329EVB
+ bool "Freescale (Motorola) M5329EVB board support"
+ depends on M532x
+ help
+ Support for the Freescale (Motorola) M5329EVB board.
+
+config COBRA5329
+ bool "senTec COBRA5329 board support"
+ depends on M532x
+ help
+ Support for the senTec COBRA5329 board.
+
+config M5407C3
+ bool "Motorola M5407C3 board support"
+ depends on M5407
+ help
+ Support for the Motorola M5407C3 board.
+
+config CLEOPATRA
+ bool "Feith CLEOPATRA board support"
+ depends on (M5307 || M5407)
+ help
+ Support for the Feith Cleopatra boards.
+
+config CANCam
+ bool "Feith CANCam board support"
+ depends on M5272
+ help
+ Support for the Feith CANCam board.
+
+config SCALES
+ bool "Feith SCALES board support"
+ depends on M5272
+ help
+ Support for the Feith SCALES board.
+
+config NETtel
+ bool "SecureEdge/NETtel board support"
+ depends on (M5206e || M5272 || M5307)
+ help
+ Support for the SnapGear NETtel/SecureEdge/SnapGear boards.
+
+config SNAPGEAR
+ bool "SnapGear router board support"
+ depends on NETtel
+ help
+ Special additional support for SnapGear router boards.
+
+config CPU16B
+ bool "Sneha Technologies S.L. Sarasvati board support"
+ depends on M5272
+ help
+ Support for the SNEHA CPU16B board.
+
+config MOD5272
+ bool "Netburner MOD-5272 board support"
+ depends on M5272
+ help
+ Support for the Netburner MOD-5272 board.
+
+config SAVANTrosie1
+ bool "Savant Rosie1 board support"
+ depends on M523x
+ help
+ Support for the Savant Rosie1 board.
+
+config ROMFS_FROM_ROM
+ bool "ROMFS image not RAM resident"
+ depends on (NETtel || SNAPGEAR)
+ help
+ The ROMfs filesystem will stay resident in the FLASH/ROM, not be
+ moved into RAM.
+
+config PILOT
+ bool
+ default y
+ depends on (PILOT3 || PILOT5)
+
+config ARNEWSH
+ bool
+ default y
+ depends on (ARN5206 || ARN5307)
+
+config FREESCALE
+ bool
+ default y
+ depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5329EVB || M5407C3)
+
+config HW_FEITH
+ bool
+ default y
+ depends on (CLEOPATRA || CANCam || SCALES)
+
+config senTec
+ bool
+ default y
+ depends on (COBRA5272 || COBRA5282)
+
+config EMAC_INC
+ bool
+ default y
+ depends on (SOM5282EM)
+
+config SNEHA
+ bool
+ default y
+ depends on CPU16B
+
+config SAVANT
+ bool
+ default y
+ depends on SAVANTrosie1
+
+config AVNET
+ bool
+ default y
+ depends on (AVNET5282)
+
+config UBOOT
+ bool "Support for U-Boot command line parameters"
+ help
+ If you say Y here kernel will try to collect command
+ line parameters from the initial u-boot stack.
+ default n
+
+config 4KSTACKS
+ bool "Use 4Kb for kernel stacks instead of 8Kb"
+ default y
+ help
+ If you say Y here the kernel will use a 4Kb stacksize for the
+ kernel stack attached to each process/thread. This facilitates
+ running more threads on a system and also reduces the pressure
+ on the VM subsystem for higher order allocations.
+
+config HZ
+ int
+ default 1000 if CLEOPATRA
+ default 100
+
+comment "RAM configuration"
+
+config RAMBASE
+ hex "Address of the base of RAM"
+ default "0"
+ help
+ Define the address that RAM starts at. On many platforms this is
+ 0, the base of the address space. And this is the default. Some
+ platforms choose to setup their RAM at other addresses within the
+ processor address space.
+
+config RAMSIZE
+ hex "Size of RAM (in bytes)"
+ default "0x400000"
+ help
+ Define the size of the system RAM. If you select 0 then the
+ kernel will try to probe the RAM size at runtime. This is not
+ supported on all CPU types.
+
+config VECTORBASE
+ hex "Address of the base of system vectors"
+ default "0"
+ help
+ Define the address of the system vectors. Commonly this is
+ put at the start of RAM, but it doesn't have to be. On ColdFire
+ platforms this address is programmed into the VBR register, thus
+ actually setting the address to use.
+
+config KERNELBASE
+ hex "Address of the base of kernel code"
+ default "0x400"
+ help
+ Typically on m68k systems the kernel will not start at the base
+ of RAM, but usually some small offset from it. Define the start
+ address of the kernel here. The most common setup will have the
+ processor vectors at the base of RAM and then the start of the
+ kernel. On some platforms some RAM is reserved for boot loaders
+ and the kernel starts after that. The 0x400 default was based on
+ a system with the RAM based at address 0, and leaving enough room
+ for the theoretical maximum number of 256 vectors.
+
+choice
+ prompt "RAM bus width"
+ default RAMAUTOBIT
+
+config RAMAUTOBIT
+ bool "AUTO"
+ help
+ Select the physical RAM data bus size. Not needed on most platforms,
+ so you can generally choose AUTO.
+
+config RAM8BIT
+ bool "8bit"
+ help
+ Configure RAM bus to be 8 bits wide.
+
+config RAM16BIT
+ bool "16bit"
+ help
+ Configure RAM bus to be 16 bits wide.
+
+config RAM32BIT
+ bool "32bit"
+ help
+ Configure RAM bus to be 32 bits wide.
+
+endchoice
+
+comment "ROM configuration"
+
+config ROM
+ bool "Specify ROM linker regions"
+ default n
+ help
+ Define a ROM region for the linker script. This creates a kernel
+ that can be stored in flash, with possibly the text, and data
+ regions being copied out to RAM at startup.
+
+config ROMBASE
+ hex "Address of the base of ROM device"
+ default "0"
+ depends on ROM
+ help
+ Define the address that the ROM region starts at. Some platforms
+ use this to set their chip select region accordingly for the boot
+ device.
+
+config ROMVEC
+ hex "Address of the base of the ROM vectors"
+ default "0"
+ depends on ROM
+ help
+ This is almost always the same as the base of the ROM. Since on all
+ 68000 type variants the vectors are at the base of the boot device
+ on system startup.
+
+config ROMVECSIZE
+ hex "Size of ROM vector region (in bytes)"
+ default "0x400"
+ depends on ROM
+ help
+ Define the size of the vector region in ROM. For most 68000
+ variants this would be 0x400 bytes in size. Set to 0 if you do
+ not want a vector region at the start of the ROM.
+
+config ROMSTART
+ hex "Address of the base of system image in ROM"
+ default "0x400"
+ depends on ROM
+ help
+ Define the start address of the system image in ROM. Commonly this
+ is strait after the ROM vectors.
+
+config ROMSIZE
+ hex "Size of the ROM device"
+ default "0x100000"
+ depends on ROM
+ help
+ Size of the ROM device. On some platforms this is used to setup
+ the chip select that controls the boot ROM device.
+
+choice
+ prompt "Kernel executes from"
+ ---help---
+ Choose the memory type that the kernel will be running in.
+
+config RAMKERNEL
+ bool "RAM"
+ help
+ The kernel will be resident in RAM when running.
+
+config ROMKERNEL
+ bool "ROM"
+ help
+ The kernel will be resident in FLASH/ROM when running. This is
+ often referred to as Execute-in-Place (XIP), since the kernel
+ code executes from the position it is stored in the FLASH/ROM.
+
+endchoice
+
+if COLDFIRE
+source "kernel/Kconfig.preempt"
+endif
+
+source "kernel/time/Kconfig"
+
+source "mm/Kconfig"
+
+endmenu
+
+config ISA_DMA_API
+ bool
+ depends on !M5272
+ default y
+
+source "drivers/pcmcia/Kconfig"
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+menu "Power management options"
+
+config PM
+ bool "Power Management support"
+ help
+ Support processor power management modes
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/m68knommu/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/head-ram.S
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/head-ram.S (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/head-ram.S (revision 2)
@@ -0,0 +1,61 @@
+#include
+
+ .global __main
+ .global __rom_start
+
+ .global _rambase
+ .global _ramvec
+ .global _ramstart
+ .global _ramend
+
+ .global splash_bits
+ .global _start
+ .global _stext
+ .global _edata
+
+ .text
+
+_start:
+_stext:
+ movew #0x2700, %sr /* Exceptions off! */
+
+ moveal #(CONFIG_RAMBASE + CONFIG_RAMSIZE), %ssp
+ moveal #_sbss, %a0
+ moveal #_ebss, %a1
+
+ /* Copy 0 to %a0 until %a0 >= %a1 */
+L1:
+ movel #0, %a0@+
+ cmpal %a0, %a1
+ bhi L1
+
+ /* Thread */
+ lea init_thread_union, %a0
+ lea PAGE_SIZE(%a0), %sp
+
+lp:
+ jsr start_kernel
+ jmp lp
+_exit:
+
+ jmp _exit
+
+__main:
+ /* nothing */
+ rts
+
+ .data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+.align 4
+_ramvec:
+.long 0
+_rambase:
+.long 0
+_ramstart:
+.long _ebss
+_ramend:
+.long (CONFIG_RAMBASE + CONFIG_RAMSIZE)
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/entry.S
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/entry.S (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/entry.S (revision 2)
@@ -0,0 +1,302 @@
+/*
+ * linux/arch/m68knommu/platform/68328/entry.S
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+.text
+
+.globl system_call
+.globl resume
+.globl ret_from_exception
+.globl ret_from_signal
+.globl sys_call_table
+.globl ret_from_interrupt
+.globl bad_interrupt
+.globl inthandler1
+.globl inthandler2
+.globl inthandler3
+.globl inthandler4
+.globl inthandler5
+.globl inthandler6
+.globl inthandler7
+
+.globl trap3
+.globl trap4
+.globl trap5
+.globl trap6
+.globl trap7
+.globl trap8
+.globl trap9
+.globl trap10
+
+trap3:
+ move.b #0x33, (0xE0000000)
+ jmp trap
+trap4:
+ move.b #0x34, (0xE0000000)
+ jmp trap
+trap5:
+ move.b #0x35, (0xE0000000)
+ jmp trap
+trap6:
+ move.b #0x36, (0xE0000000)
+ jmp trap
+trap7:
+ move.b #0x37, (0xE0000000)
+ jmp trap
+trap8:
+ move.b #0x38, (0xE0000000)
+ jmp trap
+trap9:
+ move.b #0x39, (0xE0000000)
+ jmp trap
+trap10:
+ move.b #0x3A, (0xE0000000)
+ jmp trap
+
+badsys:
+ movel #-ENOSYS,%sp@(PT_OFF_D0)
+ jra ret_from_exception
+
+do_trace:
+ movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
+ subql #4,%sp
+ SAVE_SWITCH_STACK
+ jbsr syscall_trace
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
+ movel %sp@(PT_OFF_ORIG_D0),%d1
+ movel #-ENOSYS,%d0
+ cmpl #NR_syscalls,%d1
+ jcc 1f
+ lsl #2,%d1
+ lea sys_call_table, %a0
+ jbsr %a0@(%d1)
+
+1: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
+ subql #4,%sp /* dummy return address */
+ SAVE_SWITCH_STACK
+ jbsr syscall_trace
+
+ret_from_signal:
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
+ jra ret_from_exception
+
+ENTRY(system_call)
+ SAVE_ALL
+
+ /* save top of frame*/
+ pea %sp@
+ jbsr set_esp0
+ addql #4,%sp
+
+ movel %sp@(PT_OFF_ORIG_D0),%d0
+
+ movel %sp,%d1 /* get thread_info pointer */
+ andl #-THREAD_SIZE,%d1
+ movel %d1,%a2
+ btst #TIF_SYSCALL_TRACE,%a2@(TI_FLAGS)
+ jne do_trace
+ cmpl #NR_syscalls,%d0
+ jcc badsys
+ lsl #2,%d0
+ lea sys_call_table,%a0
+ movel %a0@(%d0), %a0
+ jbsr %a0@
+ movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
+
+ret_from_exception:
+ btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
+ jeq Luser_return /* if so, skip resched, signals*/
+
+Lkernel_return:
+ RESTORE_ALL
+
+Luser_return:
+ /* only allow interrupts when we are really the last one on the*/
+ /* kernel stack, otherwise stack overflow can occur during*/
+ /* heavy interrupt load*/
+ andw #ALLOWINT,%sr
+
+ movel %sp,%d1 /* get thread_info pointer */
+ andl #-THREAD_SIZE,%d1
+ movel %d1,%a2
+ move %a2@(TI_FLAGS),%d1 /* thread_info->flags */
+ andl #_TIF_WORK_MASK,%d1
+ jne Lwork_to_do
+ RESTORE_ALL
+
+Lwork_to_do:
+ movel %a2@(TI_FLAGS),%d1 /* thread_info->flags */
+ btst #TIF_NEED_RESCHED,%d1
+ jne reschedule
+
+Lsignal_return:
+ subql #4,%sp /* dummy return address*/
+ SAVE_SWITCH_STACK
+ pea %sp@(SWITCH_STACK_SIZE)
+ clrl %sp@-
+ bsrw do_signal
+ addql #8,%sp
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
+Lreturn:
+ RESTORE_ALL
+
+/*
+ * This is the main interrupt handler, responsible for calling process_int()
+ */
+inthandler1:
+ SAVE_ALL
+ movew %sp@(PT_OFF_VECTOR), %d0
+ and #0x3ff, %d0
+
+ movel %sp,%sp@-
+ movel #1,%sp@- /* put vector # on stack*/
+ jbsr process_int /* process the IRQ*/
+3: addql #8,%sp /* pop parameters off stack*/
+ bra ret_from_interrupt
+
+inthandler2:
+ SAVE_ALL
+ movew %sp@(PT_OFF_VECTOR), %d0
+ and #0x3ff, %d0
+
+ movel %sp,%sp@-
+ movel #2,%sp@- /* put vector # on stack*/
+ jbsr process_int /* process the IRQ*/
+3: addql #8,%sp /* pop parameters off stack*/
+ bra ret_from_interrupt
+
+inthandler3:
+ SAVE_ALL
+ movew %sp@(PT_OFF_VECTOR), %d0
+ and #0x3ff, %d0
+
+ movel %sp,%sp@-
+ movel #3,%sp@- /* put vector # on stack*/
+ jbsr process_int /* process the IRQ*/
+3: addql #8,%sp /* pop parameters off stack*/
+ bra ret_from_interrupt
+
+inthandler4:
+ SAVE_ALL
+ movew %sp@(PT_OFF_VECTOR), %d0
+ and #0x3ff, %d0
+
+ movel %sp,%sp@-
+ movel #4,%sp@- /* put vector # on stack*/
+ jbsr process_int /* process the IRQ*/
+3: addql #8,%sp /* pop parameters off stack*/
+ bra ret_from_interrupt
+
+inthandler5:
+ SAVE_ALL
+ movew %sp@(PT_OFF_VECTOR), %d0
+ and #0x3ff, %d0
+
+ movel %sp,%sp@-
+ movel #5,%sp@- /* put vector # on stack*/
+ jbsr process_int /* process the IRQ*/
+3: addql #8,%sp /* pop parameters off stack*/
+ bra ret_from_interrupt
+
+inthandler6:
+ SAVE_ALL
+ movew %sp@(PT_OFF_VECTOR), %d0
+ and #0x3ff, %d0
+
+ movel %sp,%sp@-
+ movel #6,%sp@- /* put vector # on stack*/
+ jbsr process_int /* process the IRQ*/
+3: addql #8,%sp /* pop parameters off stack*/
+ bra ret_from_interrupt
+
+inthandler7:
+ SAVE_ALL
+ movew %sp@(PT_OFF_VECTOR), %d0
+ and #0x3ff, %d0
+
+ movel %sp,%sp@-
+ movel #7,%sp@- /* put vector # on stack*/
+ jbsr process_int /* process the IRQ*/
+3: addql #8,%sp /* pop parameters off stack*/
+ bra ret_from_interrupt
+
+inthandler:
+ SAVE_ALL
+ movew %sp@(PT_OFF_VECTOR), %d0
+ and #0x3ff, %d0
+
+ movel %sp,%sp@-
+ movel %d0,%sp@- /* put vector # on stack*/
+ jbsr process_int /* process the IRQ*/
+3: addql #8,%sp /* pop parameters off stack*/
+ bra ret_from_interrupt
+
+ret_from_interrupt:
+ /*jeq 1f*/
+2:
+ RESTORE_ALL
+
+ /*ALIGN*/
+1:
+ moveb %sp@(PT_OFF_SR), %d0
+ and #7, %d0
+ jhi 2b
+
+ /* check if we need to do software interrupts */
+ /*tst.l irq_stat+CPUSTAT_SOFTIRQ_PENDING*/
+ jeq ret_from_exception
+
+ pea ret_from_exception
+ jra do_softirq
+
+
+/*
+ * Handler for uninitialized and spurious interrupts.
+ */
+ENTRY(bad_interrupt)
+ addql #1,num_spurious
+ rte
+
+/*
+ * Beware - when entering resume, prev (the current task) is
+ * in a0, next (the new task) is in a1,so don't change these
+ * registers until their contents are no longer needed.
+ */
+ENTRY(resume)
+ movel %a0,%d1 /* save prev thread in d1 */
+ movew %sr,%a0@(TASK_THREAD+THREAD_SR) /* save sr */
+ movel %usp,%a2 /* save usp */
+ movel %a2,%a0@(TASK_THREAD+THREAD_USP)
+
+ SAVE_SWITCH_STACK
+ movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
+ movel %a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
+ RESTORE_SWITCH_STACK
+
+ movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore user stack */
+ movel %a0,%usp
+ movew %a1@(TASK_THREAD+THREAD_SR),%sr /* restore thread status reg */
+ rts
+
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/config.c
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/config.c (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/config.c (revision 2)
@@ -0,0 +1,127 @@
+/***************************************************************************/
+
+/*
+ * linux/arch/m68knommu/platform/ao68000/config.c
+ *
+ * Copyright (C) 1993 Hamish Macdonald
+ * Copyright (C) 1999 D. Jeff Dionne
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * VZ Support/Fixes Evan Stawnyczy
+ */
+
+/***************************************************************************/
+
+#include
+#include
+#include
+#include
+
+
+// EARLY PRINTK from arch/arm/kernel/early_printk.c ---------------------------------
+#include
+#include
+
+//extern void printch(int);
+
+static void early_write(const char *s, unsigned n)
+{
+ volatile char *uart = (char *)0xE0000000;
+
+ while(n-- > 0) {
+ uart[0] = s[0];
+ s++;
+ }
+}
+
+static void early_console_write(struct console *con, const char *s, unsigned n)
+{
+ early_write(s, n);
+}
+
+static struct console early_console = {
+ .name = "earlycon",
+ .write = early_console_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1,
+};
+
+asmlinkage void early_printk(const char *fmt, ...)
+{
+ char buf[512];
+ int n;
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = vscnprintf(buf, sizeof(buf), fmt, ap);
+ early_write(buf, n);
+ va_end(ap);
+}
+
+static int __init setup_early_printk(char *buf)
+{
+ // blockes if called in (in_interrupt()) in kernel/printk.c
+ register_console(&early_console);
+ return 0;
+}
+//------------------------------------------------------------------------------------------
+
+
+/***************************************************************************/
+
+void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
+{
+ *year = *mon = *day = 1;
+ *hour = 2;
+ *min = 3;
+ *sec = 4;
+}
+
+/***************************************************************************/
+
+void m68328_reset (void)
+{
+ local_irq_disable();
+ while(1) { ; }
+}
+
+/***************************************************************************/
+
+void config_BSP(char *command, int len)
+{
+// setup_early_printk(command);
+
+ printk(KERN_INFO "\nAO68000 support Aleksander Osman \n");
+
+ mach_gettod = m68328_timer_gettod;
+ mach_reset = m68328_reset;
+}
+
+/***************************************************************************/
+
+static irqreturn_t hw_tick(int irq, void *dummy)
+{
+ return arch_timer_interrupt(irq, dummy);
+}
+
+/***************************************************************************/
+
+static struct irqaction ao68000_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = hw_tick,
+};
+
+/***************************************************************************/
+
+
+void hw_timer_init(void)
+{
+ /* set ISR */
+ setup_irq(0x01, &ao68000_timer_irq);
+}
+
+/***************************************************************************/
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/Makefile
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/Makefile (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/Makefile (revision 2)
@@ -0,0 +1,16 @@
+#
+# Makefile for arch/m68knommu/platform/ao68000.
+#
+
+head-y = head-$(MODEL).o
+
+obj-y += entry.o ints.o
+#timers.o
+obj-$(CONFIG_AO68000) += config.o
+
+extra-y := head.o
+
+$(obj)/head.o: $(obj)/$(head-y)
+ ln -sf $(head-y) $(obj)/head.o
+
+clean-files := $(obj)/head.o $(head-y)
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/ints.c
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/ints.c (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/platform/ao68000/ints.c (revision 2)
@@ -0,0 +1,142 @@
+/*
+ * linux/arch/m68knommu/platform/ao68000/ints.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if defined(CONFIG_M68328)
+#include
+#elif defined(CONFIG_M68EZ328)
+#include
+#elif defined(CONFIG_M68VZ328)
+#include
+#endif
+
+/* assembler routines */
+asmlinkage void system_call(void);
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void trap3(void);
+asmlinkage void trap4(void);
+asmlinkage void trap5(void);
+asmlinkage void trap6(void);
+asmlinkage void trap7(void);
+asmlinkage void trap8(void);
+asmlinkage void trap9(void);
+asmlinkage void trap10(void);
+asmlinkage void trap11(void);
+asmlinkage void trap12(void);
+asmlinkage void trap13(void);
+asmlinkage void trap14(void);
+asmlinkage void trap15(void);
+asmlinkage void trap33(void);
+asmlinkage void trap34(void);
+asmlinkage void trap35(void);
+asmlinkage void trap36(void);
+asmlinkage void trap37(void);
+asmlinkage void trap38(void);
+asmlinkage void trap39(void);
+asmlinkage void trap40(void);
+asmlinkage void trap41(void);
+asmlinkage void trap42(void);
+asmlinkage void trap43(void);
+asmlinkage void trap44(void);
+asmlinkage void trap45(void);
+asmlinkage void trap46(void);
+asmlinkage void trap47(void);
+asmlinkage irqreturn_t bad_interrupt(int, void *);
+asmlinkage irqreturn_t inthandler(void);
+asmlinkage irqreturn_t inthandler1(void);
+asmlinkage irqreturn_t inthandler2(void);
+asmlinkage irqreturn_t inthandler3(void);
+asmlinkage irqreturn_t inthandler4(void);
+asmlinkage irqreturn_t inthandler5(void);
+asmlinkage irqreturn_t inthandler6(void);
+asmlinkage irqreturn_t inthandler7(void);
+
+extern e_vector *_ramvec;
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+/* The 68k family did not have a good way to determine the source
+ * of interrupts until later in the family. The EC000 core does
+ * not provide the vector number on the stack, we vector everything
+ * into one vector and look in the blasted mask register...
+ * This code is designed to be fast, almost constant time, not clean!
+ */
+asmlinkage void process_int(int vec, struct pt_regs *fp)
+{
+ do_IRQ(vec, fp);
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+}
+
+static struct irq_chip intc_irq_chip = {
+ .name = "M68K-INTC",
+ .mask = intc_irq_mask,
+ .unmask = intc_irq_unmask,
+};
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the machine vector table.
+ */
+void __init init_IRQ(void)
+{
+ int i;
+
+ _ramvec[2] = (e_vector) buserr;
+
+ /* set up the vectors */
+ _ramvec[3] = (e_vector) trap3;
+ _ramvec[4] = (e_vector) trap4;
+ _ramvec[5] = (e_vector) trap5;
+ _ramvec[6] = (e_vector) trap6;
+ _ramvec[7] = (e_vector) trap7;
+ _ramvec[8] = (e_vector) trap8;
+ _ramvec[9] = (e_vector) trap9;
+ _ramvec[10] = (e_vector) trap10;
+
+ for (i = 11; i < 24; ++i) _ramvec[i] = (e_vector) trap;
+
+ _ramvec[25] = (e_vector) inthandler1;
+ _ramvec[26] = (e_vector) inthandler2;
+ _ramvec[27] = (e_vector) inthandler3;
+ _ramvec[28] = (e_vector) inthandler4;
+ _ramvec[29] = (e_vector) inthandler5;
+ _ramvec[30] = (e_vector) inthandler6;
+ _ramvec[31] = (e_vector) inthandler7;
+
+ _ramvec[32] = (e_vector) system_call;
+
+ for(i=33; i<256; i++) _ramvec[i] = (e_vector) trap; //bad_interrupt
+
+ for (i = 0; (i < NR_IRQS); i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = NULL;
+ irq_desc[i].depth = 1;
+ irq_desc[i].chip = &intc_irq_chip;
+ }
+}
+
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/defconfig
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/defconfig (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/defconfig (revision 2)
@@ -0,0 +1,378 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33.1
+# Sun Mar 21 13:19:24 2010
+#
+CONFIG_M68K=y
+# CONFIG_MMU is not set
+CONFIG_NO_DMA=y
+# CONFIG_FPU is not set
+CONFIG_ZONE_DMA=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_TIME_LOW_RES=y
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_NO_IOPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+# CONFIG_SLUB is not set
+CONFIG_SLOB=y
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+# CONFIG_BLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# Processor type and features
+#
+# CONFIG_M68328 is not set
+CONFIG_AO68000=y
+# CONFIG_M68EZ328 is not set
+# CONFIG_M68VZ328 is not set
+# CONFIG_M68360 is not set
+# CONFIG_M5206 is not set
+# CONFIG_M5206e is not set
+# CONFIG_M520x is not set
+# CONFIG_M523x is not set
+# CONFIG_M5249 is not set
+# CONFIG_M5271 is not set
+# CONFIG_M5272 is not set
+# CONFIG_M5275 is not set
+# CONFIG_M528x is not set
+# CONFIG_M5307 is not set
+# CONFIG_M532x is not set
+# CONFIG_M5407 is not set
+# CONFIG_CLOCK_SET is not set
+
+#
+# Platform
+#
+CONFIG_TERASICDE2=y
+# CONFIG_UBOOT is not set
+CONFIG_4KSTACKS=y
+CONFIG_HZ=100
+
+#
+# RAM configuration
+#
+CONFIG_RAMBASE=0x0
+CONFIG_RAMSIZE=0x100000
+CONFIG_VECTORBASE=0x0
+CONFIG_KERNELBASE=0x400
+CONFIG_RAMAUTOBIT=y
+# CONFIG_RAM8BIT is not set
+# CONFIG_RAM16BIT is not set
+# CONFIG_RAM32BIT is not set
+
+#
+# ROM configuration
+#
+# CONFIG_ROM is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+CONFIG_ISA_DMA_API=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+CONFIG_DE2_70_CONSOLE=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# Pseudo filesystems
+#
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_SAMPLES is not set
+# CONFIG_FULLDEBUG is not set
+CONFIG_BOOTPARAM=y
+CONFIG_BOOTPARAM_STRING=""
+# CONFIG_NO_KERNEL_MSG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/configs/ao68000_defconfig
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/configs/ao68000_defconfig (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/configs/ao68000_defconfig (revision 2)
@@ -0,0 +1,378 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33.1
+# Sun Mar 21 13:19:24 2010
+#
+CONFIG_M68K=y
+# CONFIG_MMU is not set
+CONFIG_NO_DMA=y
+# CONFIG_FPU is not set
+CONFIG_ZONE_DMA=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_TIME_LOW_RES=y
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_NO_IOPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+# CONFIG_SLUB is not set
+CONFIG_SLOB=y
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+# CONFIG_BLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# Processor type and features
+#
+# CONFIG_M68328 is not set
+CONFIG_AO68000=y
+# CONFIG_M68EZ328 is not set
+# CONFIG_M68VZ328 is not set
+# CONFIG_M68360 is not set
+# CONFIG_M5206 is not set
+# CONFIG_M5206e is not set
+# CONFIG_M520x is not set
+# CONFIG_M523x is not set
+# CONFIG_M5249 is not set
+# CONFIG_M5271 is not set
+# CONFIG_M5272 is not set
+# CONFIG_M5275 is not set
+# CONFIG_M528x is not set
+# CONFIG_M5307 is not set
+# CONFIG_M532x is not set
+# CONFIG_M5407 is not set
+# CONFIG_CLOCK_SET is not set
+
+#
+# Platform
+#
+CONFIG_TERASICDE2=y
+# CONFIG_UBOOT is not set
+CONFIG_4KSTACKS=y
+CONFIG_HZ=100
+
+#
+# RAM configuration
+#
+CONFIG_RAMBASE=0x0
+CONFIG_RAMSIZE=0x100000
+CONFIG_VECTORBASE=0x0
+CONFIG_KERNELBASE=0x400
+CONFIG_RAMAUTOBIT=y
+# CONFIG_RAM8BIT is not set
+# CONFIG_RAM16BIT is not set
+# CONFIG_RAM32BIT is not set
+
+#
+# ROM configuration
+#
+# CONFIG_ROM is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+CONFIG_ISA_DMA_API=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+CONFIG_DE2_70_CONSOLE=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# Pseudo filesystems
+#
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_SAMPLES is not set
+# CONFIG_FULLDEBUG is not set
+CONFIG_BOOTPARAM=y
+CONFIG_BOOTPARAM_STRING=""
+# CONFIG_NO_KERNEL_MSG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/Makefile
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/Makefile (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68knommu/Makefile (revision 2)
@@ -0,0 +1,129 @@
+#
+# arch/m68knommu/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# (C) Copyright 2002, Greg Ungerer
+#
+
+KBUILD_DEFCONFIG := ao68000_defconfig
+
+platform-$(CONFIG_M68328) := 68328
+platform-$(CONFIG_M68EZ328) := 68EZ328
+platform-$(CONFIG_M68VZ328) := 68VZ328
+platform-$(CONFIG_M68360) := 68360
+platform-$(CONFIG_M5206) := 5206
+platform-$(CONFIG_M5206e) := 5206e
+platform-$(CONFIG_M520x) := 520x
+platform-$(CONFIG_M523x) := 523x
+platform-$(CONFIG_M5249) := 5249
+platform-$(CONFIG_M527x) := 527x
+platform-$(CONFIG_M5272) := 5272
+platform-$(CONFIG_M528x) := 528x
+platform-$(CONFIG_M5307) := 5307
+platform-$(CONFIG_M532x) := 532x
+platform-$(CONFIG_M5407) := 5407
+platform-$(CONFIG_AO68000) := ao68000
+PLATFORM := $(platform-y)
+
+board-$(CONFIG_PILOT) := pilot
+board-$(CONFIG_UC5272) := UC5272
+board-$(CONFIG_UC5282) := UC5282
+board-$(CONFIG_UCSIMM) := ucsimm
+board-$(CONFIG_UCDIMM) := ucdimm
+board-$(CONFIG_UCQUICC) := uCquicc
+board-$(CONFIG_DRAGEN2) := de2
+board-$(CONFIG_ARNEWSH) := ARNEWSH
+board-$(CONFIG_FREESCALE) := FREESCALE
+board-$(CONFIG_M5235EVB) := M5235EVB
+board-$(CONFIG_M5271EVB) := M5271EVB
+board-$(CONFIG_M5275EVB) := M5275EVB
+board-$(CONFIG_M5282EVB) := M5282EVB
+board-$(CONFIG_ELITE) := eLITE
+board-$(CONFIG_NETtel) := NETtel
+board-$(CONFIG_SECUREEDGEMP3) := MP3
+board-$(CONFIG_CLEOPATRA) := CLEOPATRA
+board-$(CONFIG_senTec) := senTec
+board-$(CONFIG_SNEHA) := SNEHA
+board-$(CONFIG_M5208EVB) := M5208EVB
+board-$(CONFIG_MOD5272) := MOD5272
+board-$(CONFIG_AVNET) := AVNET
+board-$(CONFIG_SAVANT) := SAVANT
+board-$(CONFIG_TERASICDE2) := TERASICDE2
+
+BOARD := $(board-y)
+
+model-$(CONFIG_RAMKERNEL) := ram
+model-$(CONFIG_ROMKERNEL) := rom
+MODEL := $(model-y)
+
+#
+# Some code support is grouped together for a common cpu-subclass (for
+# example all ColdFire cpu's are very similar). Determine the sub-class
+# for the selected cpu. ONLY need to define this for the non-base member
+# of the family.
+#
+cpuclass-$(CONFIG_M5206) := coldfire
+cpuclass-$(CONFIG_M5206e) := coldfire
+cpuclass-$(CONFIG_M520x) := coldfire
+cpuclass-$(CONFIG_M523x) := coldfire
+cpuclass-$(CONFIG_M5249) := coldfire
+cpuclass-$(CONFIG_M527x) := coldfire
+cpuclass-$(CONFIG_M5272) := coldfire
+cpuclass-$(CONFIG_M528x) := coldfire
+cpuclass-$(CONFIG_M5307) := coldfire
+cpuclass-$(CONFIG_M532x) := coldfire
+cpuclass-$(CONFIG_M5407) := coldfire
+cpuclass-$(CONFIG_M68328) := 68328
+cpuclass-$(CONFIG_M68EZ328) := 68328
+cpuclass-$(CONFIG_M68VZ328) := 68328
+cpuclass-$(CONFIG_M68360) := 68360
+cpuclass-$(CONFIG_AO68000) := ao68000
+CPUCLASS := $(cpuclass-y)
+
+ifneq ($(CPUCLASS),$(PLATFORM))
+CLASSDIR := arch/m68knommu/platform/$(cpuclass-y)/
+endif
+
+export PLATFORM BOARD MODEL CPUCLASS
+
+#
+# Some CFLAG additions based on specific CPU type.
+#
+cflags-$(CONFIG_M5206) := $(call cc-option,-mcpu=5206,-m5200)
+cflags-$(CONFIG_M5206e) := $(call cc-option,-m5206e,-m5200)
+cflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200)
+cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307)
+cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200)
+cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307)
+cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5271,-m5200)
+cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307)
+cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307)
+cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200)
+cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
+cflags-$(CONFIG_M5407) := $(call cc-option,-m5407,-m5200)
+cflags-$(CONFIG_M68328) := -m68000
+cflags-$(CONFIG_M68EZ328) := -m68000
+cflags-$(CONFIG_M68VZ328) := -m68000
+cflags-$(CONFIG_M68360) := -m68332
+cflags-$(CONFIG_AO68000) := -m68000
+
+KBUILD_AFLAGS += $(cflags-y)
+KBUILD_AFLAGS += -D__uClinux__
+
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -D__uClinux__
+KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
+
+head-y := arch/m68knommu/platform/$(cpuclass-y)/head.o
+
+core-y += arch/m68knommu/kernel/ \
+ arch/m68knommu/mm/ \
+ $(CLASSDIR) \
+ arch/m68knommu/platform/$(PLATFORM)/
+libs-y += arch/m68knommu/lib/
+
+archclean:
+
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68k/include/asm/delay_no.h
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68k/include/asm/delay_no.h (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/arch/m68k/include/asm/delay_no.h (revision 2)
@@ -0,0 +1,76 @@
+#ifndef _M68KNOMMU_DELAY_H
+#define _M68KNOMMU_DELAY_H
+
+/*
+ * Copyright (C) 1994 Hamish Macdonald
+ * Copyright (C) 2004 Greg Ungerer
+ */
+
+#include
+
+static inline void __delay(unsigned long loops)
+{
+#if defined(CONFIG_COLDFIRE)
+ /* The coldfire runs this loop at significantly different speeds
+ * depending upon long word alignment or not. We'll pad it to
+ * long word alignment which is the faster version.
+ * The 0x4a8e is of course a 'tstl %fp' instruction. This is better
+ * than using a NOP (0x4e71) instruction because it executes in one
+ * cycle not three and doesn't allow for an arbitary delay waiting
+ * for bus cycles to finish. Also fp/a6 isn't likely to cause a
+ * stall waiting for the register to become valid if such is added
+ * to the coldfire at some stage.
+ */
+ __asm__ __volatile__ ( ".balignw 4, 0x4a8e\n\t"
+ "1: subql #1, %0\n\t"
+ "jcc 1b"
+ : "=d" (loops) : "0" (loops));
+#else
+ __asm__ __volatile__ ( "1: subql #1, %0\n\t"
+ "jcc 1b"
+ : "=d" (loops) : "0" (loops));
+#endif
+}
+
+/*
+ * Ideally we use a 32*32->64 multiply to calculate the number of
+ * loop iterations, but the older standard 68k and ColdFire do not
+ * have this instruction. So for them we have a clsoe approximation
+ * loop using 32*32->32 multiplies only. This calculation based on
+ * the ARM version of delay.
+ *
+ * We want to implement:
+ *
+ * loops = (usecs * 0x10c6 * HZ * loops_per_jiffy) / 2^32
+ */
+
+#define HZSCALE (268435456 / (1000000/HZ))
+
+extern unsigned long loops_per_jiffy;
+
+static inline void _udelay(unsigned long usecs)
+{
+#if defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \
+ defined(CONFIG_M68VZ328) || defined(CONFIG_M68360) || \
+ defined(CONFIG_COLDFIRE) || defined(CONFIG_AO68000)
+ __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6);
+#else
+ unsigned long tmp;
+
+ usecs *= 4295; /* 2**32 / 1000000 */
+ __asm__ ("mulul %2,%0:%1"
+ : "=d" (usecs), "=d" (tmp)
+ : "d" (usecs), "1" (loops_per_jiffy*HZ));
+ __delay(usecs);
+#endif
+}
+
+/*
+ * Moved the udelay() function into library code, no longer inlined.
+ * I had to change the algorithm because we are overflowing now on
+ * the faster ColdFire parts. The code is a little bigger, so it makes
+ * sense to library it.
+ */
+extern void udelay(unsigned long usecs);
+
+#endif /* defined(_M68KNOMMU_DELAY_H) */
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/Kconfig
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/Kconfig (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/Kconfig (revision 2)
@@ -0,0 +1,1499 @@
+#
+# Serial device configuration
+#
+
+menu "Serial drivers"
+ depends on HAS_IOMEM
+
+#
+# The new 8250/16550 serial drivers
+config SERIAL_8250
+ tristate "8250/16550 and compatible serial support"
+ select SERIAL_CORE
+ ---help---
+ This selects whether you want to include the driver for the standard
+ serial ports. The standard answer is Y. People who might say N
+ here are those that are setting up dedicated Ethernet WWW/FTP
+ servers, or users that have one of the various bus mice instead of a
+ serial mouse and don't intend to use their machine's standard serial
+ port for anything. (Note that the Cyclades and Stallion multi
+ serial port drivers do not need this driver built in for them to
+ work.)
+
+ To compile this driver as a module, choose M here: the
+ module will be called 8250.
+ [WARNING: Do not compile this driver as a module if you are using
+ non-standard serial ports, since the configuration information will
+ be lost when the driver is unloaded. This limitation may be lifted
+ in the future.]
+
+ BTW1: If you have a mouseman serial mouse which is not recognized by
+ the X window system, try running gpm first.
+
+ BTW2: If you intend to use a software modem (also called Winmodem)
+ under Linux, forget it. These modems are crippled and require
+ proprietary drivers which are only available under Windows.
+
+ Most people will say Y or M here, so that they can use serial mice,
+ modems and similar devices connecting to the standard serial ports.
+
+config DE2_70_CONSOLE
+ bool "Console on Terasic DE2-70 board"
+ select SERIAL_CORE_CONSOLE
+ help
+ Select console.
+
+config SERIAL_8250_CONSOLE
+ bool "Console on 8250/16550 and compatible serial port"
+ depends on SERIAL_8250=y
+ select SERIAL_CORE_CONSOLE
+ ---help---
+ If you say Y here, it will be possible to use a serial port as the
+ system console (the system console is the device which receives all
+ kernel messages and warnings and which allows logins in single user
+ mode). This could be useful if some terminal or printer is connected
+ to that serial port.
+
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttyS1". (Try "man bootparam" or see the documentation of
+ your boot loader (grub or lilo or loadlin) about how to pass options
+ to the kernel at boot time.)
+
+ If you don't have a VGA card installed and you say Y here, the
+ kernel will automatically use the first serial line, /dev/ttyS0, as
+ system console.
+
+ You can set that using a kernel command line option such as
+ "console=uart8250,io,0x3f8,9600n8"
+ "console=uart8250,mmio,0xff5e0000,115200n8".
+ and it will switch to normal serial console when the corresponding
+ port is ready.
+ "earlycon=uart8250,io,0x3f8,9600n8"
+ "earlycon=uart8250,mmio,0xff5e0000,115200n8".
+ it will not only setup early console.
+
+ If unsure, say N.
+
+config FIX_EARLYCON_MEM
+ bool
+ depends on X86
+ default y
+
+config SERIAL_8250_GSC
+ tristate
+ depends on SERIAL_8250 && GSC
+ default SERIAL_8250
+
+config SERIAL_8250_PCI
+ tristate "8250/16550 PCI device support" if EMBEDDED
+ depends on SERIAL_8250 && PCI
+ default SERIAL_8250
+ help
+ This builds standard PCI serial support. You may be able to
+ disable this feature if you only need legacy serial support.
+ Saves about 9K.
+
+config SERIAL_8250_PNP
+ tristate "8250/16550 PNP device support" if EMBEDDED
+ depends on SERIAL_8250 && PNP
+ default SERIAL_8250
+ help
+ This builds standard PNP serial support. You may be able to
+ disable this feature if you only need legacy serial support.
+
+config SERIAL_8250_HP300
+ tristate
+ depends on SERIAL_8250 && HP300
+ default SERIAL_8250
+
+config SERIAL_8250_CS
+ tristate "8250/16550 PCMCIA device support"
+ depends on PCMCIA && SERIAL_8250
+ ---help---
+ Say Y here to enable support for 16-bit PCMCIA serial devices,
+ including serial port cards, modems, and the modem functions of
+ multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are
+ credit-card size devices often used with laptops.)
+
+ To compile this driver as a module, choose M here: the
+ module will be called serial_cs.
+
+ If unsure, say N.
+
+config SERIAL_8250_NR_UARTS
+ int "Maximum number of 8250/16550 serial ports"
+ depends on SERIAL_8250
+ default "4"
+ help
+ Set this to the number of serial ports you want the driver
+ to support. This includes any ports discovered via ACPI or
+ PCI enumeration and any ports that may be added at run-time
+ via hot-plug, or any ISA multi-port serial cards.
+
+config SERIAL_8250_RUNTIME_UARTS
+ int "Number of 8250/16550 serial ports to register at runtime"
+ depends on SERIAL_8250
+ range 0 SERIAL_8250_NR_UARTS
+ default "4"
+ help
+ Set this to the maximum number of serial ports you want
+ the kernel to register at boot time. This can be overridden
+ with the module parameter "nr_uarts", or boot-time parameter
+ 8250.nr_uarts
+
+config SERIAL_8250_EXTENDED
+ bool "Extended 8250/16550 serial driver options"
+ depends on SERIAL_8250
+ help
+ If you wish to use any non-standard features of the standard "dumb"
+ driver, say Y here. This includes HUB6 support, shared serial
+ interrupts, special multiport support, support for more than the
+ four COM 1/2/3/4 boards, etc.
+
+ Note that the answer to this question won't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about serial driver options. If unsure, say N.
+
+config SERIAL_8250_MANY_PORTS
+ bool "Support more than 4 legacy serial ports"
+ depends on SERIAL_8250_EXTENDED && !IA64
+ help
+ Say Y here if you have dumb serial boards other than the four
+ standard COM 1/2/3/4 ports. This may happen if you have an AST
+ FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
+ from ), or other custom
+ serial port hardware which acts similar to standard serial port
+ hardware. If you only use the standard COM 1/2/3/4 ports, you can
+ say N here to save some memory. You can also say Y if you have an
+ "intelligent" multiport card such as Cyclades, Digiboards, etc.
+
+#
+# Multi-port serial cards
+#
+
+config SERIAL_8250_FOURPORT
+ tristate "Support Fourport cards"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ Say Y here if you have an AST FourPort serial board.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_fourport.
+
+config SERIAL_8250_ACCENT
+ tristate "Support Accent cards"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ Say Y here if you have an Accent Async serial board.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_accent.
+
+config SERIAL_8250_BOCA
+ tristate "Support Boca cards"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ Say Y here if you have a Boca serial board. Please read the Boca
+ mini-HOWTO, available from
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_boca.
+
+config SERIAL_8250_EXAR_ST16C554
+ tristate "Support Exar ST16C554/554D Quad UART"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ The Uplogix Envoy TU301 uses this Exar Quad UART. If you are
+ tinkering with your Envoy TU301, or have a machine with this UART,
+ say Y here.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_exar_st16c554.
+
+config SERIAL_8250_HUB6
+ tristate "Support Hub6 cards"
+ depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+ help
+ Say Y here if you have a HUB6 serial board.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_hub6.
+
+config SERIAL_8250_SHARE_IRQ
+ bool "Support for sharing serial interrupts"
+ depends on SERIAL_8250_EXTENDED
+ help
+ Some serial boards have hardware support which allows multiple dumb
+ serial ports on the same board to share a single IRQ. To enable
+ support for this in the serial driver, say Y here.
+
+config SERIAL_8250_DETECT_IRQ
+ bool "Autodetect IRQ on standard ports (unsafe)"
+ depends on SERIAL_8250_EXTENDED
+ help
+ Say Y here if you want the kernel to try to guess which IRQ
+ to use for your serial port.
+
+ This is considered unsafe; it is far better to configure the IRQ in
+ a boot script using the setserial command.
+
+ If unsure, say N.
+
+config SERIAL_8250_RSA
+ bool "Support RSA serial ports"
+ depends on SERIAL_8250_EXTENDED
+ help
+ ::: To be written :::
+
+config SERIAL_8250_MCA
+ tristate "Support 8250-type ports on MCA buses"
+ depends on SERIAL_8250 != n && MCA
+ help
+ Say Y here if you have a MCA serial ports.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_mca.
+
+config SERIAL_8250_ACORN
+ tristate "Acorn expansion card serial port support"
+ depends on ARCH_ACORN && SERIAL_8250
+ help
+ If you have an Atomwide Serial card or Serial Port card for an Acorn
+ system, say Y to this option. The driver can handle 1, 2, or 3 port
+ cards. If unsure, say N.
+
+config SERIAL_8250_AU1X00
+ bool "Au1x00 serial port support"
+ depends on SERIAL_8250 != n && SOC_AU1X00
+ help
+ If you have an Au1x00 SOC based board and want to use the serial port,
+ say Y to this option. The driver can handle up to 4 serial ports,
+ depending on the SOC. If unsure, say N.
+
+config SERIAL_8250_RM9K
+ bool "Support for MIPS RM9xxx integrated serial port"
+ depends on SERIAL_8250 != n && SERIAL_RM9000
+ select SERIAL_8250_SHARE_IRQ
+ help
+ Selecting this option will add support for the integrated serial
+ port hardware found on MIPS RM9122 and similar processors.
+ If unsure, say N.
+
+comment "Non-8250 serial port support"
+
+config SERIAL_AMBA_PL010
+ tristate "ARM AMBA PL010 serial port support"
+ depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
+ select SERIAL_CORE
+ help
+ This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have
+ an Integrator/AP or Integrator/PP2 platform, or if you have a
+ Cirrus Logic EP93xx CPU, say Y or M here.
+
+ If unsure, say N.
+
+config SERIAL_AMBA_PL010_CONSOLE
+ bool "Support for console on AMBA serial port"
+ depends on SERIAL_AMBA_PL010=y
+ select SERIAL_CORE_CONSOLE
+ ---help---
+ Say Y here if you wish to use an AMBA PrimeCell UART as the system
+ console (the system console is the device which receives all kernel
+ messages and warnings and which allows logins in single user mode).
+
+ Even if you say Y here, the currently visible framebuffer console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttyAM0". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
+config SERIAL_AMBA_PL011
+ tristate "ARM AMBA PL011 serial port support"
+ depends on ARM_AMBA
+ select SERIAL_CORE
+ help
+ This selects the ARM(R) AMBA(R) PrimeCell PL011 UART. If you have
+ an Integrator/PP2, Integrator/CP or Versatile platform, say Y or M
+ here.
+
+ If unsure, say N.
+
+config SERIAL_AMBA_PL011_CONSOLE
+ bool "Support for console on AMBA serial port"
+ depends on SERIAL_AMBA_PL011=y
+ select SERIAL_CORE_CONSOLE
+ ---help---
+ Say Y here if you wish to use an AMBA PrimeCell UART as the system
+ console (the system console is the device which receives all kernel
+ messages and warnings and which allows logins in single user mode).
+
+ Even if you say Y here, the currently visible framebuffer console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttyAMA0". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
+config SERIAL_SB1250_DUART
+ tristate "BCM1xxx on-chip DUART serial support"
+ depends on SIBYTE_SB1xxx_SOC=y
+ select SERIAL_CORE
+ default y
+ ---help---
+ Support for the asynchronous serial interface (DUART) included in
+ the BCM1250 and derived System-On-a-Chip (SOC) devices. Note that
+ the letter D in DUART stands for "dual", which is how the device
+ is implemented. Depending on the SOC configuration there may be
+ one or more DUARTs available of which all are handled.
+
+ If unsure, say Y. To compile this driver as a module, choose M here:
+ the module will be called sb1250-duart.
+
+config SERIAL_SB1250_DUART_CONSOLE
+ bool "Support for console on a BCM1xxx DUART serial port"
+ depends on SERIAL_SB1250_DUART=y
+ select SERIAL_CORE_CONSOLE
+ default y
+ ---help---
+ If you say Y here, it will be possible to use a serial port as the
+ system console (the system console is the device which receives all
+ kernel messages and warnings and which allows logins in single user
+ mode).
+
+ If unsure, say Y.
+
+config SERIAL_ATMEL
+ bool "AT91 / AT32 on-chip serial port support"
+ depends on (ARM && ARCH_AT91) || AVR32
+ select SERIAL_CORE
+ help
+ This enables the driver for the on-chip UARTs of the Atmel
+ AT91 and AT32 processors.
+
+config SERIAL_ATMEL_CONSOLE
+ bool "Support for console on AT91 / AT32 serial port"
+ depends on SERIAL_ATMEL=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you wish to use an on-chip UART on a Atmel
+ AT91 or AT32 processor as the system console (the system
+ console is the device which receives all kernel messages and
+ warnings and which allows logins in single user mode).
+
+config SERIAL_ATMEL_PDC
+ bool "Support DMA transfers on AT91 / AT32 serial port"
+ depends on SERIAL_ATMEL
+ default y
+ help
+ Say Y here if you wish to use the PDC to do DMA transfers to
+ and from the Atmel AT91 / AT32 serial port. In order to
+ actually use DMA transfers, make sure that the use_dma_tx
+ and use_dma_rx members in the atmel_uart_data struct is set
+ appropriately for each port.
+
+ Note that break and error handling currently doesn't work
+ properly when DMA is enabled. Make sure that ports where
+ this matters don't use DMA.
+
+config SERIAL_ATMEL_TTYAT
+ bool "Install as device ttyATn instead of ttySn"
+ depends on SERIAL_ATMEL=y
+ help
+ Say Y here if you wish to have the internal AT91 / AT32 UARTs
+ appear as /dev/ttyATn (major 204, minor starting at 154)
+ instead of the normal /dev/ttySn (major 4, minor starting at
+ 64). This is necessary if you also want other UARTs, such as
+ external 8250/16C550 compatible UARTs.
+ The ttySn nodes are legally reserved for the 8250 serial driver
+ but are often misused by other serial drivers.
+
+ To use this, you should create suitable ttyATn device nodes in
+ /dev/, and pass "console=ttyATn" to the kernel.
+
+ Say Y if you have an external 8250/16C550 UART. If unsure, say N.
+
+config SERIAL_KS8695
+ bool "Micrel KS8695 (Centaur) serial port support"
+ depends on ARCH_KS8695
+ select SERIAL_CORE
+ help
+ This selects the Micrel Centaur KS8695 UART. Say Y here.
+
+config SERIAL_KS8695_CONSOLE
+ bool "Support for console on KS8695 (Centaur) serial port"
+ depends on SERIAL_KS8695=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you wish to use a KS8695 (Centaur) UART as the
+ system console (the system console is the device which
+ receives all kernel messages and warnings and which allows
+ logins in single user mode).
+
+config SERIAL_CLPS711X
+ tristate "CLPS711X serial port support"
+ depends on ARM && ARCH_CLPS711X
+ select SERIAL_CORE
+ help
+ ::: To be written :::
+
+config SERIAL_CLPS711X_CONSOLE
+ bool "Support for console on CLPS711X serial port"
+ depends on SERIAL_CLPS711X=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttyCL1". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
+config SERIAL_SAMSUNG
+ tristate "Samsung SoC serial support"
+ depends on ARM && PLAT_S3C
+ select SERIAL_CORE
+ help
+ Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
+ providing /dev/ttySAC0, 1 and 2 (note, some machines may not
+ provide all of these ports, depending on how the serial port
+ pins are configured.
+
+config SERIAL_SAMSUNG_UARTS
+ int
+ depends on ARM && PLAT_S3C
+ default 2 if ARCH_S3C2400
+ default 4 if ARCH_S5PC1XX || ARCH_S3C64XX || CPU_S3C2443
+ default 3
+ help
+ Select the number of available UART ports for the Samsung S3C
+ serial driver
+
+config SERIAL_SAMSUNG_DEBUG
+ bool "Samsung SoC serial debug"
+ depends on SERIAL_SAMSUNG && DEBUG_LL
+ help
+ Add support for debugging the serial driver. Since this is
+ generally being used as a console, we use our own output
+ routines that go via the low-level debug printascii()
+ function.
+
+config SERIAL_SAMSUNG_CONSOLE
+ bool "Support for console on Samsung SoC serial port"
+ depends on SERIAL_SAMSUNG=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Allow selection of the S3C24XX on-board serial ports for use as
+ an virtual console.
+
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttySACx". (Try "man bootparam" or see the documentation of
+ your boot loader about how to pass options to the kernel at
+ boot time.)
+
+config SERIAL_S3C2400
+ tristate "Samsung S3C2410 Serial port support"
+ depends on ARM && SERIAL_SAMSUNG && CPU_S3C2400
+ default y if CPU_S3C2400
+ help
+ Serial port support for the Samsung S3C2400 SoC
+
+config SERIAL_S3C2410
+ tristate "Samsung S3C2410 Serial port support"
+ depends on SERIAL_SAMSUNG && CPU_S3C2410
+ default y if CPU_S3C2410
+ help
+ Serial port support for the Samsung S3C2410 SoC
+
+config SERIAL_S3C2412
+ tristate "Samsung S3C2412/S3C2413 Serial port support"
+ depends on SERIAL_SAMSUNG && CPU_S3C2412
+ default y if CPU_S3C2412
+ help
+ Serial port support for the Samsung S3C2412 and S3C2413 SoC
+
+config SERIAL_S3C2440
+ tristate "Samsung S3C2440/S3C2442 Serial port support"
+ depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442)
+ default y if CPU_S3C2440
+ default y if CPU_S3C2442
+ help
+ Serial port support for the Samsung S3C2440 and S3C2442 SoC
+
+config SERIAL_S3C24A0
+ tristate "Samsung S3C24A0 Serial port support"
+ depends on SERIAL_SAMSUNG && CPU_S3C24A0
+ default y if CPU_S3C24A0
+ help
+ Serial port support for the Samsung S3C24A0 SoC
+
+config SERIAL_S3C6400
+ tristate "Samsung S3C6400/S3C6410 Serial port support"
+ depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410)
+ default y
+ help
+ Serial port support for the Samsung S3C6400 and S3C6410
+ SoCs
+
+config SERIAL_S5PC100
+ tristate "Samsung S5PC100 Serial port support"
+ depends on SERIAL_SAMSUNG && CPU_S5PC100
+ default y
+ help
+ Serial port support for the Samsung S5PC100 SoCs
+
+config SERIAL_MAX3100
+ tristate "MAX3100 support"
+ depends on SPI
+ select SERIAL_CORE
+ help
+ MAX3100 chip support
+
+config SERIAL_DZ
+ bool "DECstation DZ serial driver"
+ depends on MACH_DECSTATION && 32BIT
+ select SERIAL_CORE
+ default y
+ ---help---
+ DZ11-family serial controllers for DECstations and VAXstations,
+ including the DC7085, M7814, and M7819.
+
+config SERIAL_DZ_CONSOLE
+ bool "Support console on DECstation DZ serial driver"
+ depends on SERIAL_DZ=y
+ select SERIAL_CORE_CONSOLE
+ default y
+ ---help---
+ If you say Y here, it will be possible to use a serial port as the
+ system console (the system console is the device which receives all
+ kernel messages and warnings and which allows logins in single user
+ mode).
+
+ Note that the firmware uses ttyS3 as the serial console on
+ DECstations that use this driver.
+
+ If unsure, say Y.
+
+config SERIAL_ZS
+ tristate "DECstation Z85C30 serial support"
+ depends on MACH_DECSTATION
+ select SERIAL_CORE
+ default y
+ ---help---
+ Support for the Zilog 85C350 serial communications controller used
+ for serial ports in newer DECstation systems. These include the
+ DECsystem 5900 and all models of the DECstation and DECsystem 5000
+ systems except from model 200.
+
+ If unsure, say Y. To compile this driver as a module, choose M here:
+ the module will be called zs.
+
+config SERIAL_ZS_CONSOLE
+ bool "Support for console on a DECstation Z85C30 serial port"
+ depends on SERIAL_ZS=y
+ select SERIAL_CORE_CONSOLE
+ default y
+ ---help---
+ If you say Y here, it will be possible to use a serial port as the
+ system console (the system console is the device which receives all
+ kernel messages and warnings and which allows logins in single user
+ mode).
+
+ Note that the firmware uses ttyS1 as the serial console on the
+ Maxine and ttyS3 on the others using this driver.
+
+ If unsure, say Y.
+
+config SERIAL_21285
+ tristate "DC21285 serial port support"
+ depends on ARM && FOOTBRIDGE
+ select SERIAL_CORE
+ help
+ If you have a machine based on a 21285 (Footbridge) StrongARM(R)/
+ PCI bridge you can enable its onboard serial port by enabling this
+ option.
+
+config SERIAL_21285_CONSOLE
+ bool "Console on DC21285 serial port"
+ depends on SERIAL_21285=y
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the 21285 footbridge you can
+ make it the console by answering Y to this option.
+
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttyFB". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
+config SERIAL_MPSC
+ bool "Marvell MPSC serial port support"
+ depends on PPC32 && MV64X60
+ select SERIAL_CORE
+ help
+ Say Y here if you want to use the Marvell MPSC serial controller.
+
+config SERIAL_MPSC_CONSOLE
+ bool "Support for console on Marvell MPSC serial port"
+ depends on SERIAL_MPSC
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you want to support a serial console on a Marvell MPSC.
+
+config SERIAL_PXA
+ bool "PXA serial port support"
+ depends on ARCH_PXA || ARCH_MMP
+ select SERIAL_CORE
+ help
+ If you have a machine based on an Intel XScale PXA2xx CPU you
+ can enable its onboard serial ports by enabling this option.
+
+config SERIAL_PXA_CONSOLE
+ bool "Console on PXA serial port"
+ depends on SERIAL_PXA
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the Intel XScale PXA
+ CPU you can make it the console by answering Y to this option.
+
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttySA0". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
+config SERIAL_SA1100
+ bool "SA1100 serial port support"
+ depends on ARM && ARCH_SA1100
+ select SERIAL_CORE
+ help
+ If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
+ can enable its onboard serial port by enabling this option.
+ Please read for further
+ info.
+
+config SERIAL_SA1100_CONSOLE
+ bool "Console on SA1100 serial port"
+ depends on SERIAL_SA1100
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the SA1100/SA1110 StrongARM
+ CPU you can make it the console by answering Y to this option.
+
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttySA0". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
+config SERIAL_BFIN
+ tristate "Blackfin serial port support"
+ depends on BLACKFIN
+ select SERIAL_CORE
+ select SERIAL_BFIN_UART0 if (BF531 || BF532 || BF533 || BF561)
+ help
+ Add support for the built-in UARTs on the Blackfin.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin_5xx.
+
+config SERIAL_BFIN_CONSOLE
+ bool "Console on Blackfin serial port"
+ depends on SERIAL_BFIN=y
+ select SERIAL_CORE_CONSOLE
+
+choice
+ prompt "UART Mode"
+ depends on SERIAL_BFIN
+ default SERIAL_BFIN_DMA
+ help
+ This driver supports the built-in serial ports of the Blackfin family
+ of CPUs
+
+config SERIAL_BFIN_DMA
+ bool "DMA mode"
+ depends on !DMA_UNCACHED_NONE && KGDB_SERIAL_CONSOLE=n
+ help
+ This driver works under DMA mode. If this option is selected, the
+ blackfin simple dma driver is also enabled.
+
+config SERIAL_BFIN_PIO
+ bool "PIO mode"
+ help
+ This driver works under PIO mode.
+
+endchoice
+
+config SERIAL_BFIN_UART0
+ bool "Enable UART0"
+ depends on SERIAL_BFIN
+ help
+ Enable UART0
+
+config BFIN_UART0_CTSRTS
+ bool "Enable UART0 hardware flow control"
+ depends on SERIAL_BFIN_UART0
+ help
+ Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+ signal.
+
+config UART0_CTS_PIN
+ int "UART0 CTS pin"
+ depends on BFIN_UART0_CTSRTS && !BF548
+ default 23
+ help
+ The default pin is GPIO_GP7.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config UART0_RTS_PIN
+ int "UART0 RTS pin"
+ depends on BFIN_UART0_CTSRTS && !BF548
+ default 22
+ help
+ The default pin is GPIO_GP6.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config SERIAL_BFIN_UART1
+ bool "Enable UART1"
+ depends on SERIAL_BFIN && (!BF531 && !BF532 && !BF533 && !BF561)
+ help
+ Enable UART1
+
+config BFIN_UART1_CTSRTS
+ bool "Enable UART1 hardware flow control"
+ depends on SERIAL_BFIN_UART1
+ help
+ Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+ signal.
+
+config UART1_CTS_PIN
+ int "UART1 CTS pin"
+ depends on BFIN_UART1_CTSRTS && !BF548
+ default -1
+ help
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config UART1_RTS_PIN
+ int "UART1 RTS pin"
+ depends on BFIN_UART1_CTSRTS && !BF548
+ default -1
+ help
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config SERIAL_BFIN_UART2
+ bool "Enable UART2"
+ depends on SERIAL_BFIN && (BF54x || BF538 || BF539)
+ help
+ Enable UART2
+
+config BFIN_UART2_CTSRTS
+ bool "Enable UART2 hardware flow control"
+ depends on SERIAL_BFIN_UART2
+ help
+ Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+ signal.
+
+config UART2_CTS_PIN
+ int "UART2 CTS pin"
+ depends on BFIN_UART2_CTSRTS && !BF548
+ default -1
+ help
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config UART2_RTS_PIN
+ int "UART2 RTS pin"
+ depends on BFIN_UART2_CTSRTS && !BF548
+ default -1
+ help
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config SERIAL_BFIN_UART3
+ bool "Enable UART3"
+ depends on SERIAL_BFIN && (BF54x)
+ help
+ Enable UART3
+
+config BFIN_UART3_CTSRTS
+ bool "Enable UART3 hardware flow control"
+ depends on SERIAL_BFIN_UART3
+ help
+ Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+ signal.
+
+config UART3_CTS_PIN
+ int "UART3 CTS pin"
+ depends on BFIN_UART3_CTSRTS && !BF548
+ default -1
+ help
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config UART3_RTS_PIN
+ int "UART3 RTS pin"
+ depends on BFIN_UART3_CTSRTS && !BF548
+ default -1
+ help
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.
+
+config SERIAL_IMX
+ bool "IMX serial port support"
+ depends on ARM && (ARCH_IMX || ARCH_MXC)
+ select SERIAL_CORE
+ select RATIONAL
+ help
+ If you have a machine based on a Motorola IMX CPU you
+ can enable its onboard serial port by enabling this option.
+
+config SERIAL_IMX_CONSOLE
+ bool "Console on IMX serial port"
+ depends on SERIAL_IMX
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the Motorola IMX
+ CPU you can make it the console by answering Y to this option.
+
+ Even if you say Y here, the currently visible virtual console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttySA0". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
+config SERIAL_UARTLITE
+ tristate "Xilinx uartlite serial port support"
+ depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE
+ select SERIAL_CORE
+ help
+ Say Y here if you want to use the Xilinx uartlite serial controller.
+
+ To compile this driver as a module, choose M here: the
+ module will be called uartlite.
+
+config SERIAL_UARTLITE_CONSOLE
+ bool "Support for console on Xilinx uartlite serial port"
+ depends on SERIAL_UARTLITE=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you wish to use a Xilinx uartlite as the system
+ console (the system console is the device which receives all kernel
+ messages and warnings and which allows logins in single user mode).
+
+config SERIAL_SUNCORE
+ bool
+ depends on SPARC
+ select SERIAL_CORE
+ select SERIAL_CORE_CONSOLE
+ default y
+
+config SERIAL_SUNZILOG
+ tristate "Sun Zilog8530 serial support"
+ depends on SPARC
+ help
+ This driver supports the Zilog8530 serial ports found on many Sparc
+ systems. Say Y or M if you want to be able to these serial ports.
+
+config SERIAL_SUNZILOG_CONSOLE
+ bool "Console on Sun Zilog8530 serial port"
+ depends on SERIAL_SUNZILOG=y
+ help
+ If you would like to be able to use the Zilog8530 serial port
+ on your Sparc system as the console, you can do so by answering
+ Y to this option.
+
+config SERIAL_SUNSU
+ tristate "Sun SU serial support"
+ depends on SPARC && PCI
+ help
+ This driver supports the 8250 serial ports that run the keyboard and
+ mouse on (PCI) UltraSPARC systems. Say Y or M if you want to be able
+ to these serial ports.
+
+config SERIAL_SUNSU_CONSOLE
+ bool "Console on Sun SU serial port"
+ depends on SERIAL_SUNSU=y
+ help
+ If you would like to be able to use the SU serial port
+ on your Sparc system as the console, you can do so by answering
+ Y to this option.
+
+config SERIAL_MUX
+ tristate "Serial MUX support"
+ depends on GSC
+ select SERIAL_CORE
+ default y
+ ---help---
+ Saying Y here will enable the hardware MUX serial driver for
+ the Nova, K class systems and D class with a 'remote control card'.
+ The hardware MUX is not 8250/16550 compatible therefore the
+ /dev/ttyB0 device is shared between the Serial MUX and the PDC
+ software console. The following steps need to be completed to use
+ the Serial MUX:
+
+ 1. create the device entry (mknod /dev/ttyB0 c 11 0)
+ 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
+ 3. Add device ttyB0 to /etc/securetty (if you want to log on as
+ root on this console.)
+ 4. Change the kernel command console parameter to: console=ttyB0
+
+config SERIAL_MUX_CONSOLE
+ bool "Support for console on serial MUX"
+ depends on SERIAL_MUX=y
+ select SERIAL_CORE_CONSOLE
+ default y
+
+config PDC_CONSOLE
+ bool "PDC software console support"
+ depends on PARISC && !SERIAL_MUX && VT
+ default n
+ help
+ Saying Y here will enable the software based PDC console to be
+ used as the system console. This is useful for machines in
+ which the hardware based console has not been written yet. The
+ following steps must be competed to use the PDC console:
+
+ 1. create the device entry (mknod /dev/ttyB0 c 11 0)
+ 2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
+ 3. Add device ttyB0 to /etc/securetty (if you want to log on as
+ root on this console.)
+ 4. Change the kernel command console parameter to: console=ttyB0
+
+config SERIAL_SUNSAB
+ tristate "Sun Siemens SAB82532 serial support"
+ depends on SPARC && PCI
+ help
+ This driver supports the Siemens SAB82532 DUSCC serial ports on newer
+ (PCI) UltraSPARC systems. Say Y or M if you want to be able to these
+ serial ports.
+
+config SERIAL_SUNSAB_CONSOLE
+ bool "Console on Sun Siemens SAB82532 serial port"
+ depends on SERIAL_SUNSAB=y
+ help
+ If you would like to be able to use the SAB82532 serial port
+ on your Sparc system as the console, you can do so by answering
+ Y to this option.
+
+config SERIAL_SUNHV
+ bool "Sun4v Hypervisor Console support"
+ depends on SPARC64
+ help
+ This driver supports the console device found on SUN4V Sparc
+ systems. Say Y if you want to be able to use this device.
+
+config SERIAL_IP22_ZILOG
+ tristate "SGI Zilog8530 serial support"
+ depends on SGI_HAS_ZILOG
+ select SERIAL_CORE
+ help
+ This driver supports the Zilog8530 serial ports found on SGI
+ systems. Say Y or M if you want to be able to these serial ports.
+
+config SERIAL_IP22_ZILOG_CONSOLE
+ bool "Console on SGI Zilog8530 serial port"
+ depends on SERIAL_IP22_ZILOG=y
+ select SERIAL_CORE_CONSOLE
+
+config SERIAL_SH_SCI
+ tristate "SuperH SCI(F) serial port support"
+ depends on HAVE_CLK && (SUPERH || H8300)
+ select SERIAL_CORE
+
+config SERIAL_SH_SCI_NR_UARTS
+ int "Maximum number of SCI(F) serial ports"
+ depends on SERIAL_SH_SCI
+ default "2"
+
+config SERIAL_SH_SCI_CONSOLE
+ bool "Support for console on SuperH SCI(F)"
+ depends on SERIAL_SH_SCI=y
+ select SERIAL_CORE_CONSOLE
+
+config SERIAL_PNX8XXX
+ bool "Enable PNX8XXX SoCs' UART Support"
+ depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
+ select SERIAL_CORE
+ help
+ If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
+ and you want to use serial ports, say Y. Otherwise, say N.
+
+config SERIAL_PNX8XXX_CONSOLE
+ bool "Enable PNX8XX0 serial console"
+ depends on SERIAL_PNX8XXX
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
+ and you want to use serial console, say Y. Otherwise, say N.
+
+config SERIAL_CORE
+ tristate
+
+config SERIAL_CORE_CONSOLE
+ bool
+
+config CONSOLE_POLL
+ bool
+
+config SERIAL_68328
+ bool "68328 serial support"
+ depends on M68328 || M68EZ328 || M68VZ328
+ help
+ This driver supports the built-in serial port of the Motorola 68328
+ (standard, EZ and VZ varieties).
+
+config SERIAL_68328_RTS_CTS
+ bool "Support RTS/CTS on 68328 serial port"
+ depends on SERIAL_68328
+
+config SERIAL_MCF
+ bool "Coldfire serial support"
+ depends on COLDFIRE
+ select SERIAL_CORE
+ help
+ This serial driver supports the Freescale Coldfire serial ports.
+
+config SERIAL_MCF_BAUDRATE
+ int "Default baudrate for Coldfire serial ports"
+ depends on SERIAL_MCF
+ default 19200
+ help
+ This setting lets you define what the default baudrate is for the
+ ColdFire serial ports. The usual default varies from board to board,
+ and this setting is a way of catering for that.
+
+config SERIAL_MCF_CONSOLE
+ bool "Coldfire serial console support"
+ depends on SERIAL_MCF
+ select SERIAL_CORE_CONSOLE
+ help
+ Enable a ColdFire internal serial port to be the system console.
+
+config SERIAL_68360_SMC
+ bool "68360 SMC uart support"
+ depends on M68360
+ help
+ This driver supports the SMC serial ports of the Motorola 68360 CPU.
+
+config SERIAL_68360_SCC
+ bool "68360 SCC uart support"
+ depends on M68360
+ help
+ This driver supports the SCC serial ports of the Motorola 68360 CPU.
+
+config SERIAL_68360
+ bool
+ depends on SERIAL_68360_SMC || SERIAL_68360_SCC
+ default y
+
+config SERIAL_PMACZILOG
+ tristate "PowerMac z85c30 ESCC support"
+ depends on PPC_OF && PPC_PMAC
+ select SERIAL_CORE
+ help
+ This driver supports the Zilog z85C30 serial ports found on
+ PowerMac machines.
+ Say Y or M if you want to be able to these serial ports.
+
+config SERIAL_PMACZILOG_TTYS
+ bool "Use ttySn device nodes for Zilog z85c30"
+ depends on SERIAL_PMACZILOG
+ help
+ The pmac_zilog driver for the z85C30 chip on many powermacs
+ historically used the device numbers for /dev/ttySn. The
+ 8250 serial port driver also uses these numbers, which means
+ the two drivers being unable to coexist; you could not use
+ both z85C30 and 8250 type ports at the same time.
+
+ If this option is not selected, the pmac_zilog driver will
+ use the device numbers allocated for /dev/ttyPZn. This allows
+ the pmac_zilog and 8250 drivers to co-exist, but may cause
+ existing userspace setups to break. Programs that need to
+ access the built-in serial ports on powermacs will need to
+ be reconfigured to use /dev/ttyPZn instead of /dev/ttySn.
+
+ If you enable this option, any z85c30 ports in the system will
+ be registered as ttyS0 onwards as in the past, and you will be
+ unable to use the 8250 module for PCMCIA or other 16C550-style
+ UARTs.
+
+ Say N unless you need the z85c30 ports on your powermac
+ to appear as /dev/ttySn.
+
+config SERIAL_PMACZILOG_CONSOLE
+ bool "Console on PowerMac z85c30 serial port"
+ depends on SERIAL_PMACZILOG=y
+ select SERIAL_CORE_CONSOLE
+ help
+ If you would like to be able to use the z85c30 serial port
+ on your PowerMac as the console, you can do so by answering
+ Y to this option.
+
+config SERIAL_LH7A40X
+ tristate "Sharp LH7A40X embedded UART support"
+ depends on ARM && ARCH_LH7A40X
+ select SERIAL_CORE
+ help
+ This enables support for the three on-board UARTs of the
+ Sharp LH7A40X series CPUs. Choose Y or M.
+
+config SERIAL_LH7A40X_CONSOLE
+ bool "Support for console on Sharp LH7A40X serial port"
+ depends on SERIAL_LH7A40X=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you wish to use one of the serial ports as the
+ system console--the system console is the device which
+ receives all kernel messages and warnings and which allows
+ logins in single user mode.
+
+ Even if you say Y here, the currently visible framebuffer console
+ (/dev/tty0) will still be used as the default system console, but
+ you can alter that using a kernel command line, for example
+ "console=ttyAM1".
+
+config SERIAL_CPM
+ tristate "CPM SCC/SMC serial port support"
+ depends on CPM2 || 8xx
+ select SERIAL_CORE
+ help
+ This driver supports the SCC and SMC serial ports on Motorola
+ embedded PowerPC that contain a CPM1 (8xx) or CPM2 (8xxx)
+
+config SERIAL_CPM_CONSOLE
+ bool "Support for console on CPM SCC/SMC serial port"
+ depends on SERIAL_CPM=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you wish to use a SCC or SMC CPM UART as the system
+ console (the system console is the device which receives all kernel
+ messages and warnings and which allows logins in single user mode).
+
+ Even if you say Y here, the currently visible framebuffer console
+ (/dev/tty0) will still be used as the system console by default, but
+ you can alter that using a kernel command line option such as
+ "console=ttyCPM0". (Try "man bootparam" or see the documentation of
+ your boot loader (lilo or loadlin) about how to pass options to the
+ kernel at boot time.)
+
+config SERIAL_SGI_L1_CONSOLE
+ bool "SGI Altix L1 serial console support"
+ depends on IA64_GENERIC || IA64_SGI_SN2
+ select SERIAL_CORE
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have an SGI Altix and you would like to use the system
+ controller serial port as your console (you want this!),
+ say Y. Otherwise, say N.
+
+config SERIAL_MPC52xx
+ tristate "Freescale MPC52xx/MPC512x family PSC serial support"
+ depends on PPC_MPC52xx || PPC_MPC512x
+ select SERIAL_CORE
+ help
+ This driver supports MPC52xx and MPC512x PSC serial ports. If you would
+ like to use them, you must answer Y or M to this option. Note that
+ for use as console, it must be included in kernel and not as a
+ module.
+
+config SERIAL_MPC52xx_CONSOLE
+ bool "Console on a Freescale MPC52xx/MPC512x family PSC serial port"
+ depends on SERIAL_MPC52xx=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Select this options if you'd like to use one of the PSC serial port
+ of the Freescale MPC52xx family as a console.
+
+config SERIAL_MPC52xx_CONSOLE_BAUD
+ int "Freescale MPC52xx/MPC512x family PSC serial port baud"
+ depends on SERIAL_MPC52xx_CONSOLE=y
+ default "9600"
+ help
+ Select the MPC52xx console baud rate.
+ This value is only used if the bootloader doesn't pass in the
+ console baudrate
+
+config SERIAL_ICOM
+ tristate "IBM Multiport Serial Adapter"
+ depends on PCI && (PPC_ISERIES || PPC_PSERIES)
+ select SERIAL_CORE
+ select FW_LOADER
+ help
+ This driver is for a family of multiport serial adapters
+ including 2 port RVX, 2 port internal modem, 4 port internal
+ modem and a split 1 port RVX and 1 port internal modem.
+
+ This driver can also be built as a module. If so, the module
+ will be called icom.
+
+config SERIAL_M32R_SIO
+ bool "M32R SIO I/F"
+ depends on M32R
+ default y
+ select SERIAL_CORE
+ help
+ Say Y here if you want to use the M32R serial controller.
+
+config SERIAL_M32R_SIO_CONSOLE
+ bool "use SIO console"
+ depends on SERIAL_M32R_SIO=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you want to support a serial console.
+
+ If you use an M3T-M32700UT or an OPSPUT platform,
+ please say also y for SERIAL_M32R_PLDSIO.
+
+config SERIAL_M32R_PLDSIO
+ bool "M32R SIO I/F on a PLD"
+ depends on SERIAL_M32R_SIO=y && (PLAT_OPSPUT || PLAT_USRV || PLAT_M32700UT)
+ default n
+ help
+ Say Y here if you want to use the M32R serial controller
+ on a PLD (Programmable Logic Device).
+
+ If you use an M3T-M32700UT or an OPSPUT platform,
+ please say Y.
+
+config SERIAL_TXX9
+ bool "TMPTX39XX/49XX SIO support"
+ depends on HAS_TXX9_SERIAL
+ select SERIAL_CORE
+ default y
+
+config HAS_TXX9_SERIAL
+ bool
+
+config SERIAL_TXX9_NR_UARTS
+ int "Maximum number of TMPTX39XX/49XX SIO ports"
+ depends on SERIAL_TXX9
+ default "6"
+
+config SERIAL_TXX9_CONSOLE
+ bool "TMPTX39XX/49XX SIO Console support"
+ depends on SERIAL_TXX9=y
+ select SERIAL_CORE_CONSOLE
+
+config SERIAL_TXX9_STDSERIAL
+ bool "TX39XX/49XX SIO act as standard serial"
+ depends on !SERIAL_8250 && SERIAL_TXX9
+
+config SERIAL_VR41XX
+ tristate "NEC VR4100 series Serial Interface Unit support"
+ depends on CPU_VR41XX
+ select SERIAL_CORE
+ help
+ If you have a NEC VR4100 series processor and you want to use
+ Serial Interface Unit(SIU) or Debug Serial Interface Unit(DSIU)
+ (not include VR4111/VR4121 DSIU), say Y. Otherwise, say N.
+
+config SERIAL_VR41XX_CONSOLE
+ bool "Enable NEC VR4100 series Serial Interface Unit console"
+ depends on SERIAL_VR41XX=y
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have a NEC VR4100 series processor and you want to use
+ a console on a serial port, say Y. Otherwise, say N.
+
+config SERIAL_JSM
+ tristate "Digi International NEO PCI Support"
+ depends on PCI
+ select SERIAL_CORE
+ help
+ This is a driver for Digi International's Neo series
+ of cards which provide multiple serial ports. You would need
+ something like this to connect more than two modems to your Linux
+ box, for instance in order to become a dial-in server. This driver
+ supports PCI boards only.
+
+ If you have a card like this, say Y here, otherwise say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jsm.
+
+config SERIAL_SGI_IOC4
+ tristate "SGI IOC4 controller serial support"
+ depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC4
+ select SERIAL_CORE
+ help
+ If you have an SGI Altix with an IOC4 based Base IO card
+ and wish to use the serial ports on this card, say Y.
+ Otherwise, say N.
+
+config SERIAL_SGI_IOC3
+ tristate "SGI Altix IOC3 serial support"
+ depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC3
+ select SERIAL_CORE
+ help
+ If you have an SGI Altix with an IOC3 serial card,
+ say Y or M. Otherwise, say N.
+
+config SERIAL_MSM
+ bool "MSM on-chip serial port support"
+ depends on ARM && ARCH_MSM
+ select SERIAL_CORE
+
+config SERIAL_MSM_CONSOLE
+ bool "MSM serial console support"
+ depends on SERIAL_MSM=y
+ select SERIAL_CORE_CONSOLE
+
+config SERIAL_NETX
+ tristate "NetX serial port support"
+ depends on ARM && ARCH_NETX
+ select SERIAL_CORE
+ help
+ If you have a machine based on a Hilscher NetX SoC you
+ can enable its onboard serial port by enabling this option.
+
+ To compile this driver as a module, choose M here: the
+ module will be called netx-serial.
+
+config SERIAL_NETX_CONSOLE
+ bool "Console on NetX serial port"
+ depends on SERIAL_NETX=y
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the Hilscher NetX SoC
+ you can make it the console by answering Y to this option.
+
+config SERIAL_OF_PLATFORM
+ tristate "Serial port on Open Firmware platform bus"
+ depends on PPC_OF || MICROBLAZE
+ depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL
+ help
+ If you have a PowerPC based system that has serial ports
+ on a platform specific bus, you should enable this option.
+ Currently, only 8250 compatible ports are supported, but
+ others can easily be added.
+
+config SERIAL_OF_PLATFORM_NWPSERIAL
+ tristate "NWP serial port driver"
+ depends on PPC_OF && PPC_DCR
+ select SERIAL_OF_PLATFORM
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_CORE
+ help
+ This driver supports the cell network processor nwp serial
+ device.
+
+config SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE
+ bool "Console on NWP serial port"
+ depends on SERIAL_OF_PLATFORM_NWPSERIAL=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Support for Console on the NWP serial ports.
+
+config SERIAL_QE
+ tristate "Freescale QUICC Engine serial port support"
+ depends on QUICC_ENGINE
+ select SERIAL_CORE
+ select FW_LOADER
+ default n
+ help
+ This driver supports the QE serial ports on Freescale embedded
+ PowerPC that contain a QUICC Engine.
+
+config SERIAL_SC26XX
+ tristate "SC2681/SC2692 serial port support"
+ depends on SNI_RM
+ select SERIAL_CORE
+ help
+ This is a driver for the onboard serial ports of
+ older RM400 machines.
+
+config SERIAL_SC26XX_CONSOLE
+ bool "Console on SC2681/SC2692 serial port"
+ depends on SERIAL_SC26XX
+ select SERIAL_CORE_CONSOLE
+ help
+ Support for Console on SC2681/SC2692 serial ports.
+
+config SERIAL_BFIN_SPORT
+ tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)"
+ depends on BLACKFIN && EXPERIMENTAL
+ select SERIAL_CORE
+ help
+ Enable SPORT emulate UART on Blackfin series.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin_sport_uart.
+
+choice
+ prompt "Baud rate for Blackfin SPORT UART"
+ depends on SERIAL_BFIN_SPORT
+ default SERIAL_SPORT_BAUD_RATE_57600
+ help
+ Choose a baud rate for the SPORT UART, other uart settings are
+ 8 bit, 1 stop bit, no parity, no flow control.
+
+config SERIAL_SPORT_BAUD_RATE_115200
+ bool "115200"
+
+config SERIAL_SPORT_BAUD_RATE_57600
+ bool "57600"
+
+config SERIAL_SPORT_BAUD_RATE_38400
+ bool "38400"
+
+config SERIAL_SPORT_BAUD_RATE_19200
+ bool "19200"
+
+config SERIAL_SPORT_BAUD_RATE_9600
+ bool "9600"
+endchoice
+
+config SPORT_BAUD_RATE
+ int
+ depends on SERIAL_BFIN_SPORT
+ default 115200 if (SERIAL_SPORT_BAUD_RATE_115200)
+ default 57600 if (SERIAL_SPORT_BAUD_RATE_57600)
+ default 38400 if (SERIAL_SPORT_BAUD_RATE_38400)
+ default 19200 if (SERIAL_SPORT_BAUD_RATE_19200)
+ default 9600 if (SERIAL_SPORT_BAUD_RATE_9600)
+
+config SERIAL_TIMBERDALE
+ tristate "Support for timberdale UART"
+ depends on MFD_TIMBERDALE
+ select SERIAL_CORE
+ ---help---
+ Add support for UART controller on timberdale.
+
+config SERIAL_BCM63XX
+ tristate "bcm63xx serial port support"
+ select SERIAL_CORE
+ depends on BCM63XX
+ help
+ If you have a bcm63xx CPU, you can enable its onboard
+ serial port by enabling this options.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bcm963xx_uart.
+
+config SERIAL_BCM63XX_CONSOLE
+ bool "Console on bcm63xx serial port"
+ depends on SERIAL_BCM63XX=y
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the serial port on the bcm63xx CPU
+ you can make it the console by answering Y to this option.
+
+config SERIAL_GRLIB_GAISLER_APBUART
+ tristate "GRLIB APBUART serial support"
+ depends on OF
+ ---help---
+ Add support for the GRLIB APBUART serial port.
+
+config SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
+ bool "Console on GRLIB APBUART serial port"
+ depends on SERIAL_GRLIB_GAISLER_APBUART=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Support for running a console on the GRLIB APBUART
+
+endmenu
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/de2_70_console.c
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/de2_70_console.c (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/de2_70_console.c (revision 2)
@@ -0,0 +1,79 @@
+/*
+ * de2_70_console: simple console driver for Terasic DE2-70 board. Based on uartlite.c
+ *
+ * Copyright (C) 2010 Aleksander Osman
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#define DE2_70_NAME "ttyDE2"
+
+/* ---------------------------------------------------------------------
+ * Console driver operations
+ */
+
+static void de2_70_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ volatile char *tst = (char *)0xE0000000;
+
+ while(count-- > 0) {
+ tst[0] = s[0];
+ s++;
+ }
+}
+
+static int __devinit de2_70_console_setup(struct console *co, char *options)
+{
+ return 0;
+}
+
+static struct console de2_70_console = {
+ .name = DE2_70_NAME,
+ .write = de2_70_console_write,
+ .setup = de2_70_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1, /* Specified on the cmdline (e.g. console=ttyUL0 ) */
+};
+
+static int __init de2_70_console_init(void)
+{
+ register_console(&de2_70_console);
+ return 0;
+}
+
+console_initcall(de2_70_console_init);
+
+/* ---------------------------------------------------------------------
+ * Module setup/teardown
+ */
+
+int __init de2_70_init(void)
+{
+ return 0;
+}
+
+void __exit de2_70_exit(void)
+{
+}
+
+module_init(de2_70_init);
+module_exit(de2_70_exit);
+
+MODULE_AUTHOR("Aleksander Osman <>");
+MODULE_DESCRIPTION("DE2-70 console");
+MODULE_LICENSE("GPL");
Index: trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/Makefile
===================================================================
--- trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/Makefile (nonexistent)
+++ trunk/sw/linux/linux-2.6.33.1-ao68000/drivers/serial/Makefile (revision 2)
@@ -0,0 +1,85 @@
+#
+# Makefile for the kernel serial device drivers.
+#
+
+obj-$(CONFIG_SERIAL_CORE) += serial_core.o
+obj-$(CONFIG_SERIAL_21285) += 21285.o
+obj-$(CONFIG_DE2_70_CONSOLE) += de2_70_console.o
+
+# These Sparc drivers have to appear before others such as 8250
+# which share ttySx minor node space. Otherwise console device
+# names change and other unplesantries.
+obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
+obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o
+obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
+obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o
+obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
+
+obj-$(CONFIG_SERIAL_8250) += 8250.o
+obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
+obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
+obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
+obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
+obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
+obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
+obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
+obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
+obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
+obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
+obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
+obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
+obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
+obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
+obj-$(CONFIG_SERIAL_PXA) += pxa.o
+obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
+obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
+obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
+obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
+obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
+obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
+obj-$(CONFIG_SERIAL_S3C2400) += s3c2400.o
+obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
+obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
+obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
+obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
+obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
+obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o
+obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
+obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
+obj-$(CONFIG_SERIAL_MUX) += mux.o
+obj-$(CONFIG_SERIAL_68328) += 68328serial.o
+obj-$(CONFIG_SERIAL_68360) += 68360serial.o
+obj-$(CONFIG_SERIAL_MCF) += mcf.o
+obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
+obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
+obj-$(CONFIG_SERIAL_DZ) += dz.o
+obj-$(CONFIG_SERIAL_ZS) += zs.o
+obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
+obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += sn_console.o
+obj-$(CONFIG_SERIAL_CPM) += cpm_uart/
+obj-$(CONFIG_SERIAL_IMX) += imx.o
+obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o
+obj-$(CONFIG_SERIAL_ICOM) += icom.o
+obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o
+obj-$(CONFIG_SERIAL_MPSC) += mpsc.o
+obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o
+obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
+obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o
+obj-$(CONFIG_SERIAL_JSM) += jsm/
+obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
+obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
+obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
+obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
+obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
+obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
+obj-$(CONFIG_SERIAL_MSM) += msm_serial.o
+obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
+obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
+obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o
+obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
+obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
+obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
+obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
+obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
Index: trunk/sw/linux/sector0.dat
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/linux/sector0.dat
===================================================================
--- trunk/sw/linux/sector0.dat (nonexistent)
+++ trunk/sw/linux/sector0.dat (revision 2)
trunk/sw/linux/sector0.dat
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/build/built-jar.properties
===================================================================
--- trunk/sw/ao68000_tool/build/built-jar.properties (nonexistent)
+++ trunk/sw/ao68000_tool/build/built-jar.properties (revision 2)
@@ -0,0 +1,2 @@
+#Sun Mar 28 03:18:46 CEST 2010
+/home/alek/aktualne/ao68000/sw/ao68000_tool=
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/Parser.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/Parser.class
===================================================================
--- trunk/sw/ao68000_tool/build/classes/ao68000_tool/Parser.class (nonexistent)
+++ trunk/sw/ao68000_tool/build/classes/ao68000_tool/Parser.class (revision 2)
trunk/sw/ao68000_tool/build/classes/ao68000_tool/Parser.class
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/ParseParams.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/ParseParams.class
===================================================================
--- trunk/sw/ao68000_tool/build/classes/ao68000_tool/ParseParams.class (nonexistent)
+++ trunk/sw/ao68000_tool/build/classes/ao68000_tool/ParseParams.class (revision 2)
trunk/sw/ao68000_tool/build/classes/ao68000_tool/ParseParams.class
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/GenerateMicrocode.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/GenerateMicrocode.class
===================================================================
--- trunk/sw/ao68000_tool/build/classes/ao68000_tool/GenerateMicrocode.class (nonexistent)
+++ trunk/sw/ao68000_tool/build/classes/ao68000_tool/GenerateMicrocode.class (revision 2)
trunk/sw/ao68000_tool/build/classes/ao68000_tool/GenerateMicrocode.class
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/Microcode.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/Microcode.class
===================================================================
--- trunk/sw/ao68000_tool/build/classes/ao68000_tool/Microcode.class (nonexistent)
+++ trunk/sw/ao68000_tool/build/classes/ao68000_tool/Microcode.class (revision 2)
trunk/sw/ao68000_tool/build/classes/ao68000_tool/Microcode.class
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/Main.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/Main.class
===================================================================
--- trunk/sw/ao68000_tool/build/classes/ao68000_tool/Main.class (nonexistent)
+++ trunk/sw/ao68000_tool/build/classes/ao68000_tool/Main.class (revision 2)
trunk/sw/ao68000_tool/build/classes/ao68000_tool/Main.class
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/Tester.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/Tester.class
===================================================================
--- trunk/sw/ao68000_tool/build/classes/ao68000_tool/Tester.class (nonexistent)
+++ trunk/sw/ao68000_tool/build/classes/ao68000_tool/Tester.class (revision 2)
trunk/sw/ao68000_tool/build/classes/ao68000_tool/Tester.class
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/DocumentationTool.class
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/ao68000_tool/build/classes/ao68000_tool/DocumentationTool.class
===================================================================
--- trunk/sw/ao68000_tool/build/classes/ao68000_tool/DocumentationTool.class (nonexistent)
+++ trunk/sw/ao68000_tool/build/classes/ao68000_tool/DocumentationTool.class (revision 2)
trunk/sw/ao68000_tool/build/classes/ao68000_tool/DocumentationTool.class
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/dist/ao68000_tool.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sw/ao68000_tool/dist/ao68000_tool.jar
===================================================================
--- trunk/sw/ao68000_tool/dist/ao68000_tool.jar (nonexistent)
+++ trunk/sw/ao68000_tool/dist/ao68000_tool.jar (revision 2)
trunk/sw/ao68000_tool/dist/ao68000_tool.jar
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/sw/ao68000_tool/dist/README.TXT
===================================================================
--- trunk/sw/ao68000_tool/dist/README.TXT (nonexistent)
+++ trunk/sw/ao68000_tool/dist/README.TXT (revision 2)
@@ -0,0 +1,33 @@
+========================
+BUILD OUTPUT DESCRIPTION
+========================
+
+When you build an Java application project that has a main class, the IDE
+automatically copies all of the JAR
+files on the projects classpath to your projects dist/lib folder. The IDE
+also adds each of the JAR files to the Class-Path element in the application
+JAR files manifest file (MANIFEST.MF).
+
+To run the project from the command line, go to the dist folder and
+type the following:
+
+java -jar "ao68000_tool.jar"
+
+To distribute this project, zip up the dist folder (including the lib folder)
+and distribute the ZIP file.
+
+Notes:
+
+* If two JAR files on the project classpath have the same name, only the first
+JAR file is copied to the lib folder.
+* Only JAR files are copied to the lib folder.
+If the classpath contains other types of files or folders, none of the
+classpath elements are copied to the lib folder. In such a case,
+you need to copy the classpath elements to the lib folder manually after the build.
+* If a library on the projects classpath also has a Class-Path element
+specified in the manifest,the content of the Class-Path element has to be on
+the projects runtime path.
+* To set a main class in a standard Java project, right-click the project node
+in the Projects window and choose Properties. Then click Run and enter the
+class name in the Main Class field. Alternatively, you can manually type the
+class name in the manifest Main-Class element.
Index: trunk/sw/ao68000_tool/nbproject/project.properties
===================================================================
--- trunk/sw/ao68000_tool/nbproject/project.properties (nonexistent)
+++ trunk/sw/ao68000_tool/nbproject/project.properties (revision 2)
@@ -0,0 +1,63 @@
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/ao68000_tool.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+excludes=
+includes=**
+jar.compress=false
+javac.classpath=
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.source=1.5
+javac.target=1.5
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}:\
+ ${libs.junit.classpath}:\
+ ${libs.junit_4.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
+main.class=ao68000_tool.Main
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+platform.active=default_platform
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+source.encoding=UTF-8
+src.dir=src
+test.src.dir=test
Index: trunk/sw/ao68000_tool/nbproject/project.xml
===================================================================
--- trunk/sw/ao68000_tool/nbproject/project.xml (nonexistent)
+++ trunk/sw/ao68000_tool/nbproject/project.xml (revision 2)
@@ -0,0 +1,15 @@
+
+
+ org.netbeans.modules.java.j2seproject
+
+
+ ao68000_tool
+
+
+
+
+
+
+
+
+
Index: trunk/sw/ao68000_tool/nbproject/genfiles.properties
===================================================================
--- trunk/sw/ao68000_tool/nbproject/genfiles.properties (nonexistent)
+++ trunk/sw/ao68000_tool/nbproject/genfiles.properties (revision 2)
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=2c4f0216
+build.xml.script.CRC32=9d8ae462
+build.xml.stylesheet.CRC32=958a1d3e@1.32.1.45
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=2c4f0216
+nbproject/build-impl.xml.script.CRC32=2127d4d7
+nbproject/build-impl.xml.stylesheet.CRC32=576378a2@1.32.1.45
Index: trunk/sw/ao68000_tool/nbproject/private/private.properties
===================================================================
--- trunk/sw/ao68000_tool/nbproject/private/private.properties (nonexistent)
+++ trunk/sw/ao68000_tool/nbproject/private/private.properties (revision 2)
@@ -0,0 +1,3 @@
+compile.on.save=true
+jaxbwiz.endorsed.dirs=/home/alek/programy/netbeans-6.8/ide12/modules/ext/jaxb/api
+user.properties.file=/home/alek/.netbeans/6.8/build.properties
Index: trunk/sw/ao68000_tool/nbproject/private/private.xml
===================================================================
--- trunk/sw/ao68000_tool/nbproject/private/private.xml (nonexistent)
+++ trunk/sw/ao68000_tool/nbproject/private/private.xml (revision 2)
@@ -0,0 +1,4 @@
+
+
+
+
Index: trunk/sw/ao68000_tool/nbproject/build-impl.xml
===================================================================
--- trunk/sw/ao68000_tool/nbproject/build-impl.xml (nonexistent)
+++ trunk/sw/ao68000_tool/nbproject/build-impl.xml (revision 2)
@@ -0,0 +1,805 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set src.dir
+ Must set test.src.dir
+ Must set build.dir
+ Must set dist.dir
+ Must set build.classes.dir
+ Must set dist.javadoc.dir
+ Must set build.test.classes.dir
+ Must set build.test.results.dir
+ Must set build.classes.excludes
+ Must set dist.jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+
+
+
+
+
+ java -cp "${run.classpath.with.dist.jar}" ${main.class}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To run this application from the command line without Ant, try:
+
+ java -jar "${dist.jar.resolved}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+ Must select one file in the IDE or set run.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must select one file in the IDE or set debug.class
+
+
+
+
+ Must set fix.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set javac.includes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+
+
+
+
+ Must select some files in the IDE or set test.includes
+
+
+
+ Some tests failed; see details above.
+
+
+
+
+ Must select one file in the IDE or set test.class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+ Must select one file in the IDE or set applet.url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: trunk/sw/ao68000_tool/src/ao68000_tool/GenerateMicrocode.java
===================================================================
--- trunk/sw/ao68000_tool/src/ao68000_tool/GenerateMicrocode.java (nonexistent)
+++ trunk/sw/ao68000_tool/src/ao68000_tool/GenerateMicrocode.java (revision 2)
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package ao68000_tool;
+
+import java.io.OutputStream;
+import java.util.Vector;
+import java.util.HashMap;
+import java.util.HashSet;
+
+class GenerateMicrocode {
+ static void entry(boolean newline, String name) throws Exception {
+ /*
+ * if newline is true: end of last line
+ * if name is "offset_" + label: branch label
+ * if name is "label_" + label: label declaration
+ */
+
+ if(ParseParams.prefixes == null || labels == null || lines == null) throw new Exception("Entry validator not initialized.");
+
+ // save last line
+ if(newline == true && current_line != null && current_line.size() > 0) lines.add(current_line);
+ // prepare a new line
+ if(newline == true) current_line = new HashMap();
+
+ // save label location
+ if(name.startsWith("label_")) {
+ String label = name.substring(6);
+ if(labels.containsKey(label)) throw new Exception("Double label declaration: " + label);
+ labels.put(label, lines.size());
+ return;
+ }
+
+ // get prefix
+ String prefix = "PROCEDURE_";
+ if(name.startsWith("offset_")) {
+ String label = name.substring(7);
+ name = "label_" + label;
+ }
+ else {
+ prefix = null;
+ for(String p : ParseParams.prefixes) {
+ if(name.startsWith(p)) {
+ prefix = p;
+ break;
+ }
+ }
+ }
+
+ if(prefix == null) throw new Exception("Unknown prefix for name: " + name);
+
+ // check for double prefix
+ if(current_line.containsKey(prefix)) throw new Exception("Double prefix call: " + prefix);
+
+ // extend current line
+ current_line.put(prefix, name);
+ }
+
+ static void fill_bit_part(int array[], int start, int end, int value) throws Exception {
+ while(start <= end) {
+ int bit = value & 0x1;
+
+ array[start] = bit;
+
+ value >>= 1;
+ start++;
+ }
+ }
+ static void final_process(OutputStream out) throws Exception {
+ if(ParseParams.prefixes == null || labels == null || lines == null) throw new Exception("Final validator not initialized.");
+ // add last line
+ if(current_line != null && current_line.size() > 0) lines.add(current_line);
+
+
+ int i=0;
+ // resolve labels
+ for(HashMap line : lines) {
+ if(line.containsKey("PROCEDURE_")) {
+ String value = line.get("PROCEDURE_");
+
+ if(value.startsWith("label_")) {
+ String label = value.substring(6);
+
+ if(labels.containsKey(label) == false) throw new Exception("Unresolved label: " + label);
+ int label_value = labels.get(label);
+
+ int delta = label_value - i;
+
+ if(delta < 0 || delta > 15) throw new Exception("Label: " + label + " out of bounds: " + delta);
+ line.put("PROCEDURE_", "value_" + delta);
+ }
+ }
+ i++;
+ }
+
+ // prepare output header
+ int depth = 1;
+ while(depth < lines.size()) depth *= 2;
+
+ out.write(new String("DEPTH = " + depth + ";\n").getBytes());
+ out.write(new String("WIDTH = " + bit_line.length + ";\n").getBytes());
+ out.write(new String("ADDRESS_RADIX = DEC;\n").getBytes());
+ out.write(new String("DATA_RADIX = BIN;\n").getBytes());
+ out.write(new String("CONTENT\n").getBytes());
+ out.write(new String("BEGIN\n").getBytes());
+
+ i=0;
+ HashSet set = new HashSet();
+ Vector bit_lines = new Vector();
+ // prepare final bit array
+ for(HashMap line : lines) {
+ for(int j=0; j=0; j--) {
+ bits += bit_line[j];
+ }
+ set.add(bits);
+ bit_lines.add(bits);
+ out.write(new String(bits + ";\n").getBytes());
+
+ i++;
+ }
+ out.write(new String("END;\n").getBytes());
+
+
+ // prepare a compact microcode with a microcode decoder
+ // microcode reduced to 500x8 bits = 4000 bits, but microcode decoder takes about 1000 LE
+ // so currently unused
+/*
+ i = set.size();
+ int bit_size = 0;
+ while(i > 0) {
+ bit_size++;
+ i /= 2;
+ }
+ System.out.println("Set size: " + set.size() + ", bit size: " + bit_size + ", bit_line.length: " + bit_line.length);
+
+ String empty_line = "";
+ i = 0;
+ while(i < bit_line.length) {
+ empty_line += "0";
+ i++;
+ }
+
+
+ String verilog = "assign micro_data =" + "\n";
+
+ verilog += "(encoded == " + bit_size + "'d" + 0 + ") ? " + bit_line.length + "'b" + empty_line + " :" + "\n";
+ HashMap bit_line_numbers = new HashMap();
+ i = 1;
+ for(String line : set) {
+ verilog += "(encoded == " + bit_size + "'d" + i + ") ? " + bit_line.length + "'b" + line + " :" + "\n";
+
+ bit_line_numbers.put(line, i);
+ i++;
+ }
+ verilog += bit_line.length + "'b" + empty_line + ";" + "\n";
+
+ i=0;
+ for(String line : bit_lines) {
+ String addr = "" + i + ": ";
+ while(addr.length() < 8) addr = " " + addr;
+ System.out.print(addr);
+
+ String content = "" + bit_line_numbers.get(line) + ";";
+ System.out.println(content);
+
+ i++;
+ }
+ System.out.println("Verilog:\n" + verilog);
+*/
+ }
+ static void print_microcode_defines(OutputStream out) throws Exception {
+ if(ParseParams.prefix_locations == null || ParseParams.prefixes == null) throw new Exception("No prefix_locations or prefixes set.");
+
+ out.write(new String("/*! \\file microcode_locations.v\n * \\brief Definitions of microcode locations.\n */\n").getBytes());
+
+ for(String s : ParseParams.prefixes) {
+ int start = ParseParams.prefix_locations.get(s + "start");
+ int end = ParseParams.prefix_locations.get(s + "end");
+
+ String short_name = s.substring(0, s.length()-1);
+ short_name = short_name.toLowerCase();
+
+ out.write(new String("`define MICRO_DATA_" + short_name + " " + "micro_data[" + end + ":" + start + "]\n").getBytes());
+ }
+ out.write(new String("\n").getBytes());
+
+ for(String label : labels.keySet()) {
+ if(label.startsWith("MICROPC_")) {
+ out.write(new String("`define " + label + " 9'd" + labels.get(label) + "\n").getBytes());
+ }
+ }
+ }
+ static void generate(OutputStream microcode_os, OutputStream locations_os) throws Exception {
+ bit_line = new int[ParseParams.control_bit_offset];
+ lines = new Vector>();
+ labels = new HashMap();
+
+ Microcode.microcode(new Parser());
+
+ final_process(microcode_os);
+ print_microcode_defines(locations_os);
+ }
+ static HashMap current_line;
+ static Vector> lines;
+ static HashMap labels;
+ static int bit_line[];
+}
Index: trunk/sw/ao68000_tool/src/ao68000_tool/Microcode.java
===================================================================
--- trunk/sw/ao68000_tool/src/ao68000_tool/Microcode.java (nonexistent)
+++ trunk/sw/ao68000_tool/src/ao68000_tool/Microcode.java (revision 2)
@@ -0,0 +1,1537 @@
+/*
+ * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package ao68000_tool;
+
+public class Microcode {
+ static void microcode(Parser p) throws Exception {
+
+ p.label("reset");
+
+ p .GROUP_0_FLAG_SET();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ // move SSP and PC from prefetch
+ p .AN_INPUT_FROM_PREFETCH_IR().AN_ADDRESS_SSP().AN_WRITE_ENABLE_SET()
+ .PC_FROM_PREFETCH_IR()
+ // jump to main loop
+ .BRANCH_procedure().PROCEDURE_jump_to_main_loop();
+
+
+ p.label("MICROPC_ADDRESS_BUS_TRAP");
+
+ // save trap number and bus cycle extended information
+ p .TRAP_FROM_INTERRUPT()
+ .OP2_MOVE_ADDRESS_BUS_INFO()
+ // clear internal flags
+ .READ_MODIFY_WRITE_FLAG_CLEAR()
+ .INSTRUCTION_FLAG_SET()
+ .DO_READ_FLAG_CLEAR()
+ .DO_WRITE_FLAG_CLEAR()
+ .DO_INTERRUPT_FLAG_CLEAR()
+
+ // check if group_0_flag already active
+ .BRANCH_group_0_flag().offset("address_bus_trap_group_0_flag_cleared");
+
+ // if group_0_flag active: block processor
+ p .DO_BLOCKED_FLAG_SET()
+ .BRANCH_procedure()
+ .PROCEDURE_wait_finished();
+
+ // continue processing trap
+ p .label("address_bus_trap_group_0_flag_cleared");
+ p .GROUP_0_FLAG_SET();
+
+ //--
+ // move PC to OP1
+ p .OP1_FROM_PC();
+ // move OP1 to result
+ p .ALU_SIMPLE_MOVE()
+ // move SR to OP1
+ .OP1_FROM_SR();
+
+ // set supervisor, clear trace
+ p .ALU_SR_SET_TRAP();
+
+ //--
+ // stack PC
+ p .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea()
+ // move SR to result
+ .ALU_SIMPLE_MOVE()
+ // move IR to OP1
+ .OP1_FROM_IR();
+
+ // stack SR
+ p .SIZE_WORD().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea()
+ // move IR to result
+ .ALU_SIMPLE_MOVE()
+ // move fault address to OP1
+ .OP1_FROM_FAULT_ADDRESS();
+
+ //--
+ // stack IR
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea()
+ // move fault address to result
+ .ALU_SIMPLE_MOVE()
+ // move bus cycle info stored in OP2 to OP1
+ .OP1_FROM_OP2();
+
+ // stack fault address
+ p .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea()
+ // move bus cycle info from OP1 to result
+ .ALU_SIMPLE_MOVE();
+
+ // stack bus cycle info
+ p .SIZE_WORD().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ //--
+ // load PC from exception vector table
+ p .ADDRESS_FROM_TRAP()
+ .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+ p .ALU_SIMPLE_MOVE();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .PC_FROM_RESULT();
+
+ // wait one cycle to check loaded PC: is it even ?
+ p .OP1_FROM_OP2();
+ //--
+ // jump to main loop
+ p .BRANCH_procedure().PROCEDURE_jump_to_main_loop();
+
+ p.label("MICROPC_TRAP_ENTRY");
+
+ //--
+ // move PC to OP1
+ p .OP1_FROM_PC();
+ // move OP1 to result
+ p .ALU_SIMPLE_MOVE()
+ // move SR to OP1
+ .OP1_FROM_SR();
+
+ // set supervisor, clear trace
+ p .ALU_SR_SET_TRAP();
+
+ //--
+ // stack PC
+ p .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea()
+ // move SR to result
+ .ALU_SIMPLE_MOVE();
+
+ // stack SR
+ p .SIZE_WORD().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ //--
+ // load PC from exception vector table
+ p .ADDRESS_FROM_TRAP()
+ .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+ p .ALU_SIMPLE_MOVE();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .PC_FROM_RESULT();
+
+ // wait one cycle to check loaded PC: is it even ?
+ p .OP1_FROM_OP2();
+
+ //--
+ // return
+ p .BRANCH_procedure().PROCEDURE_return();
+
+
+ p.label("MICROPC_MAIN_LOOP");
+
+ // check if stop flag set and wait for valid prefetch and decode instruction
+ // execute instruction, instruction generated trap possible
+ p .BRANCH_stop_flag_wait_ir_decode().offset("main_loop_after_execution")
+ // clear read-modify-write flag always
+ .READ_MODIFY_WRITE_FLAG_CLEAR()
+
+ // save trace flag, only when valid prefetch and valid instruction and stop flag cleared
+ .TRACE_FLAG_COPY_WHEN_NO_STOP()
+
+ // save first instruction word, only when prefetch valid and stop flag cleared
+ .IR_LOAD_WHEN_PREFETCH_VALID()
+ // clear group 0 flag, only when valid prefetch and stop flag cleared
+ .GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH()
+
+ // increment PC by 2, only when valid prefetch and valid instruction and stop flag cleared
+ .PC_INCR_BY_2_IN_MAIN_LOOP()
+ // clear instruction flag, only when valid prefetch and valid instruction and stop flag cleared
+ .INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP();
+
+ // call trap
+ p .TRAP_FROM_DECODER()
+ .INSTRUCTION_FLAG_SET()
+ .BRANCH_procedure().PROCEDURE_call_trap();
+ // after trap jump to main loop
+ p .BRANCH_procedure().PROCEDURE_jump_to_main_loop();
+
+ // jump here after execution
+ p .label("main_loop_after_execution");
+
+ // check if trace flag set and check external interrupt
+ p .BRANCH_trace_flag_and_interrupt().offset("main_loop_interrupt")
+ // set instruction flag, always
+ .INSTRUCTION_FLAG_SET();
+
+ // call trap
+ p .TRAP_TRACE()
+ .STOP_FLAG_CLEAR()
+ .BRANCH_procedure().PROCEDURE_call_trap();
+ // after trap continue
+
+ // jump here if trace flag not set and interupt pending
+ p .label("main_loop_interrupt");
+
+ // check external interrupt
+ p .DO_INTERRUPT_FLAG_SET_IF_ACTIVE()
+ .BRANCH_procedure().PROCEDURE_interrupt_mask();
+
+ p .BRANCH_procedure().PROCEDURE_wait_finished()
+ .ALU_SR_SET_INTERRUPT();
+
+ p .DO_INTERRUPT_FLAG_CLEAR()
+ .TRAP_FROM_INTERRUPT()
+ .STOP_FLAG_CLEAR()
+ .BRANCH_procedure().PROCEDURE_call_trap();
+
+ // after trap jump to main loop
+ p .BRANCH_procedure().PROCEDURE_jump_to_main_loop();
+
+ // **************************************************************** EA
+
+ // load ea: to address register
+
+ // (An), (An)+:
+ p.label("MICROPC_LOAD_EA_An");
+ p.label("MICROPC_LOAD_EA_An_plus");
+
+ p .ADDRESS_FROM_AN_OUTPUT()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // -(An):
+ p.label("MICROPC_LOAD_EA_minus_An");
+
+ p .ADDRESS_FROM_AN_OUTPUT();
+ p .ADDRESS_DECR_BY_SIZE()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // (d16, An):
+ p.label("MICROPC_LOAD_EA_d16_An");
+
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .INDEX_0()
+ .OFFSET_IMM_16()
+ .PC_INCR_BY_2()
+ .ADDRESS_FROM_AN_OUTPUT();
+
+ p .ADDRESS_FROM_BASE_INDEX_OFFSET()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // (d8, An, Xn):
+ p.label("MICROPC_LOAD_EA_d8_An_Xn");
+
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid()
+ .ADDRESS_FROM_AN_OUTPUT();
+
+ p .AN_ADDRESS_FROM_EXTENDED()
+ .DN_ADDRESS_FROM_EXTENDED()
+ .OFFSET_IMM_8();
+
+ p .AN_ADDRESS_FROM_EXTENDED()
+ .INDEX_LOAD_EXTENDED()
+ .PC_INCR_BY_2();
+
+ p .ADDRESS_FROM_BASE_INDEX_OFFSET()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // (xxx).W:
+ p.label("MICROPC_LOAD_EA_xxx_W");
+
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .ADDRESS_FROM_IMM_16()
+ .PC_INCR_BY_2()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // (xxx).L:
+ p.label("MICROPC_LOAD_EA_xxx_L");
+
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .ADDRESS_FROM_IMM_32()
+ .PC_INCR_BY_4()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // (d16, PC):
+ p.label("MICROPC_LOAD_EA_d16_PC");
+
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .INDEX_0()
+ .OFFSET_IMM_16();
+
+ p .ADDRESS_FROM_PC_INDEX_OFFSET()
+ .PC_INCR_BY_2()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // (d8, PC, Xn):
+ p.label("MICROPC_LOAD_EA_d8_PC_Xn");
+
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .AN_ADDRESS_FROM_EXTENDED()
+ .DN_ADDRESS_FROM_EXTENDED()
+ .OFFSET_IMM_8();
+
+ p .AN_ADDRESS_FROM_EXTENDED()
+ .INDEX_LOAD_EXTENDED();
+
+ p .ADDRESS_FROM_PC_INDEX_OFFSET()
+ .PC_INCR_BY_2()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_LOAD_EA_illegal_command");
+
+ // call trap
+ p .TRAP_ILLEGAL_INSTR()
+ .BRANCH_procedure().PROCEDURE_call_trap();
+ // after trap jump to main loop
+ p .BRANCH_procedure().PROCEDURE_jump_to_main_loop();
+
+
+ // perform_ea_read: memory, Dn,An,immediate
+
+ // Dn:
+ p.label("MICROPC_PERFORM_EA_READ_Dn");
+
+ p .OP1_FROM_DN()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // An:
+ p.label("MICROPC_PERFORM_EA_READ_An");
+
+ p .OP1_FROM_AN()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // immediate
+ p.label("MICROPC_PERFORM_EA_READ_imm");
+
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // memory
+ p.label("MICROPC_PERFORM_EA_READ_memory");
+
+ p .DO_READ_FLAG_SET()
+ .BRANCH_procedure().PROCEDURE_wait_finished();
+
+ p .DO_READ_FLAG_CLEAR()
+ .OP1_FROM_DATA()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // perform ea write: memory, Dn,An
+ // size of operand matters: select in memory write
+
+ // Dn:
+ p.label("MICROPC_PERFORM_EA_WRITE_Dn");
+
+ p .DN_WRITE_ENABLE_SET()
+ .BRANCH_procedure().PROCEDURE_return();
+
+
+ // An:
+ p.label("MICROPC_PERFORM_EA_WRITE_An");
+
+ p .AN_WRITE_ENABLE_SET()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // memory:
+ p.label("MICROPC_PERFORM_EA_WRITE_memory");
+
+ p .DATA_WRITE_FROM_RESULT()
+ .DO_WRITE_FLAG_SET()
+ .BRANCH_procedure().PROCEDURE_wait_finished();
+
+ p .DO_WRITE_FLAG_CLEAR()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // save ea: (An)+,-(An)
+
+ // (An)+:
+ p.label("MICROPC_SAVE_EA_An_plus");
+
+ p .ADDRESS_INCR_BY_SIZE();
+
+ p .AN_INPUT_FROM_ADDRESS()
+ .AN_WRITE_ENABLE_SET()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // -(An)
+ p.label("MICROPC_SAVE_EA_minus_An");
+
+ p .AN_INPUT_FROM_ADDRESS()
+ .AN_WRITE_ENABLE_SET()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // **************************************************************** Instructions
+
+ p.label("MICROPC_MOVEP_memory_to_register");
+
+ p .SIZE_BYTE().EA_REG_IR_2_0().EA_MOD_INDIRECTOFFSET().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_MOVEP_M2R_1()
+ .ADDRESS_INCR_BY_2()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_MOVEP_M2R_2()
+ .ADDRESS_INCR_BY_2()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_MOVEP_M2R_3()
+ .ADDRESS_INCR_BY_2()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_MOVEP_M2R_4()
+ .SIZE_1().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MOVEP_register_to_memory");
+
+ p .SIZE_1_PLUS().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .SIZE_BYTE().EA_REG_IR_2_0().EA_MOD_INDIRECTOFFSET().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .ALU_MOVEP_R2M_1()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .ADDRESS_INCR_BY_2()
+ .ALU_MOVEP_R2M_2()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_movep_16().offset("movep_16");
+
+ p .ADDRESS_INCR_BY_2()
+ .ALU_MOVEP_R2M_3()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .ADDRESS_INCR_BY_2()
+ .ALU_MOVEP_R2M_4()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ // jump here if word operation
+ p .label("movep_16");
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MOVEM_memory_to_register");
+
+ p .SIZE_WORD().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ p .MOVEM_REG_FROM_OP1()
+ .MOVEM_MODREG_LOAD_0()
+ .MOVEM_LOOP_LOAD_0()
+ .SIZE_2().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROL_POSTINC();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ // push current micro pc on stack
+ p .BRANCH_procedure().PROCEDURE_push_micropc();
+
+ // check if loop finished
+ p .BRANCH_movem_loop().offset("movem_memory_to_register_loop");
+
+ // check if operation on register required
+ p .BRANCH_movem_reg().offset("movem_memory_to_register_reg");
+
+ p .SIZE_2().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROL_POSTINC();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_SIGN_EXTEND()
+ .ADDRESS_INCR_BY_SIZE()
+ .SIZE_LONG().EA_REG_MOVEM_REG_2_0().EA_MOD_MOVEM_MOD_5_3().EA_TYPE_DN_AN();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ // jump here if operation on register not required
+ p .label("movem_memory_to_register_reg");
+
+ p .MOVEM_MODREG_INCR_BY_1()
+ .MOVEM_REG_SHIFT_RIGHT()
+ .MOVEM_LOOP_INCR_BY_1()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // jump here if loop finished
+ p .label("movem_memory_to_register_loop");
+
+ p .BRANCH_procedure().PROCEDURE_pop_micropc()
+ .SIZE_2().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROL_POSTINC();
+
+ p .BRANCH_procedure().PROCEDURE_call_save_ea()
+ .ADDRESS_DECR_BY_SIZE();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MOVEM_register_to_memory_predecrement");
+
+ p .SIZE_WORD().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ p .MOVEM_REG_FROM_OP1()
+ .MOVEM_MODREG_LOAD_6b001111()
+ .MOVEM_LOOP_LOAD_0()
+ .SIZE_2().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROLALTER_PREDEC();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ // push current micro pc on stack
+ p .BRANCH_procedure().PROCEDURE_push_micropc();
+
+ // check if loop finished
+ p .BRANCH_movem_loop().offset("movem_register_to_memory_predecrement_loop");
+
+ // check if operation on register required
+ p .BRANCH_movem_reg().offset("movem_register_to_memory_predecrement_reg");
+
+ p .SIZE_2().EA_REG_MOVEM_REG_2_0().EA_MOD_MOVEM_MOD_5_3().EA_TYPE_DN_AN();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_SIGN_EXTEND()
+ .SIZE_2().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROLALTER_PREDEC();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .ADDRESS_DECR_BY_SIZE();
+
+ // jump here if operation on register not required
+ p .label("movem_register_to_memory_predecrement_reg");
+
+ p .MOVEM_MODREG_DECR_BY_1()
+ .MOVEM_REG_SHIFT_RIGHT()
+ .MOVEM_LOOP_INCR_BY_1()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // jump here if loop finished
+ p .label("movem_register_to_memory_predecrement_loop");
+
+ p .BRANCH_procedure().PROCEDURE_pop_micropc()
+ .ADDRESS_INCR_BY_SIZE();
+
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MOVEM_register_to_memory_control");
+
+ p .SIZE_WORD().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ p .MOVEM_REG_FROM_OP1()
+ .MOVEM_MODREG_LOAD_0()
+ .MOVEM_LOOP_LOAD_0()
+ .SIZE_2().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROLALTER_PREDEC();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ // push current micro pc on stack
+ p .BRANCH_procedure().PROCEDURE_push_micropc();
+
+ // check if loop finished
+ p .BRANCH_movem_loop().offset("movem_register_to_memory_control_loop");
+
+ // check if operation on register required
+ p .BRANCH_movem_reg().offset("movem_register_to_memory_control_reg");
+
+ p .SIZE_2().EA_REG_MOVEM_REG_2_0().EA_MOD_MOVEM_MOD_5_3().EA_TYPE_DN_AN();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_SIGN_EXTEND()
+ .SIZE_2().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROLALTER_PREDEC();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .ADDRESS_INCR_BY_SIZE();
+
+ // jump here if operation on register not required
+ p .label("movem_register_to_memory_control_reg");
+
+ p .MOVEM_MODREG_INCR_BY_1()
+ .MOVEM_REG_SHIFT_RIGHT()
+ .MOVEM_LOOP_INCR_BY_1()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // jump here if loop finished
+ p .label("movem_register_to_memory_control_loop");
+
+ p .BRANCH_procedure().PROCEDURE_pop_micropc();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_LEA");
+
+ p .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .OP1_FROM_ADDRESS();
+
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_LONG().EA_REG_IR_11_9().EA_MOD_AN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_PEA");
+
+ p .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .OP1_FROM_ADDRESS();
+
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_ANDI_EORI_ORI_ADDI_SUBI");
+//+++
+ p .SIZE_3().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE()
+
+ .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .OP2_FROM_OP1()
+ .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_ARITHMETIC_LOGIC()
+ .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_ORI_to_CCR_ORI_to_SR_ANDI_to_CCR_ANDI_to_SR_EORI_to_CCR_EORI_to_SR");
+//+
+ p .SIZE_3().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ p .OP2_FROM_OP1()
+ .OP1_FROM_SR();
+
+ p .ALU_ARITHMETIC_LOGIC();
+
+ p .OP1_FROM_RESULT();
+
+ p .ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_CMPI");
+//+
+ p .SIZE_3().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE()
+
+ .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .OP2_FROM_OP1()
+ .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_ARITHMETIC_LOGIC()
+ .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_ABCD_SBCD_ADDX_SUBX");
+
+ p .SIZE_3().EA_REG_IR_2_0().EA_MOD_DN_PREDEC().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .OP2_FROM_OP1()
+ .SIZE_3().EA_REG_IR_11_9().EA_MOD_DN_PREDEC().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_ABCD_SBCD_ADDX_SUBX()
+ .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_EXG");
+
+ p .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DN_AN();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_LONG().EA_REG_IR_11_9().EA_MOD_DN_AN_EXG().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DN_AN();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+
+ p.label("MICROPC_CMPM");
+
+ p .SIZE_3().EA_REG_IR_2_0().EA_MOD_POSTINC().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .OP2_FROM_OP1()
+ .SIZE_3().EA_REG_IR_11_9().EA_MOD_POSTINC().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_ARITHMETIC_LOGIC()
+ .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_immediate_register");
+
+ p .SIZE_3().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .OP2_FROM_OP1()
+ .SIZE_3().EA_REG_IR_2_0().EA_MOD_DN().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .OP2_LOAD_COUNT();
+
+ p .ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare();
+
+ p .BRANCH_procedure().PROCEDURE_push_micropc();
+
+ p .BRANCH_operand2().offset("shift_rotate_immediate_loop");
+
+ p .ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR();
+ p .OP1_FROM_RESULT()
+ .OP2_DECR_BY_1()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // jump here if loop finished
+ p .label("shift_rotate_immediate_loop");
+
+ p .BRANCH_procedure().PROCEDURE_pop_micropc();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_all_memory");
+
+ p .SIZE_WORD().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_MEMORYALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .OP2_LOAD_1();
+
+ p .ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare();
+ p .ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR();
+
+ p .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_MOVE");
+
+ p .SIZE_4().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_4().EA_REG_IR_11_9().EA_MOD_IR_8_6().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+ p .ALU_MOVE()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MOVEA");
+
+ p .SIZE_4().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_SIGN_EXTEND()
+ .SIZE_4().EA_REG_IR_11_9().EA_MOD_AN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_EOR");
+
+ p .SIZE_3().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .OP2_FROM_OP1()
+ .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_ARITHMETIC_LOGIC()
+ .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_ADD_to_mem_SUB_to_mem_AND_to_mem_OR_to_mem");
+
+ p .SIZE_3().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .OP2_FROM_OP1()
+ .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_MEMORYALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_ARITHMETIC_LOGIC()
+ .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_ADD_to_Dn_SUB_to_Dn_AND_to_Dn_OR_to_Dn");
+
+ p .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .OP2_FROM_OP1()
+ .SIZE_3().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_ARITHMETIC_LOGIC()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_CMP");
+
+ p .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .OP2_FROM_OP1()
+ .SIZE_3().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_ARITHMETIC_LOGIC()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_ADDA_SUBA");
+
+ p .SIZE_5().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .OP2_FROM_OP1()
+ .SIZE_LONG().EA_REG_IR_11_9().EA_MOD_AN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_CMPA");
+
+ p .SIZE_5().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .OP2_FROM_OP1()
+ .SIZE_LONG().EA_REG_IR_11_9().EA_MOD_AN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_CHK");
+
+ p .SIZE_WORD().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATA();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .OP2_FROM_OP1()
+ .SIZE_WORD().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_CHK();
+
+ p .BRANCH_special_01().offset("chk_no_trap");
+ p .TRAP_CHK()
+ .BRANCH_procedure().PROCEDURE_call_trap();
+ // after return continue
+
+ // jump here if no trap
+ p .label("chk_no_trap");
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MULS_MULU_DIVS_DIVU");
+
+ p .SIZE_WORD().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATA();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .OP2_FROM_OP1()
+ .SIZE_LONG().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_MULS_MULU_DIVS_DIVU()
+ .MOVEM_LOOP_LOAD_0();
+
+ p .BRANCH_special_01().offset("div_no_div_by_zero_trap");
+ p .TRAP_DIV_BY_ZERO()
+ .BRANCH_procedure().PROCEDURE_call_trap();
+ // return after return
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ // jump here if no trap
+ p .label("div_no_div_by_zero_trap");
+
+ // push current micro pc on stack
+ p .BRANCH_procedure().PROCEDURE_push_micropc();
+
+ // check if loop finished
+ p .BRANCH_movem_loop().offset("mult_div_loop_0");
+ p .MOVEM_LOOP_INCR_BY_1()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // jump here after first loop finished
+ p .label("mult_div_loop_0");
+
+ p .BRANCH_procedure().PROCEDURE_pop_micropc()
+ .MOVEM_LOOP_LOAD_0();
+
+ // push current micro pc on stack
+ p .BRANCH_procedure().PROCEDURE_push_micropc();
+
+ // check if loop finished
+ p .BRANCH_movem_loop().offset("mult_div_loop_1");
+ p .MOVEM_LOOP_INCR_BY_1()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ // jump here after second loop finished
+ p .label("mult_div_loop_1");
+
+ p .ALU_MULS_MULU_DIVS_DIVU()
+ .BRANCH_procedure().PROCEDURE_pop_micropc();
+
+ p .BRANCH_special_10().offset("mult_div_overflow");
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ // jump here if overflow
+ p .label("mult_div_overflow");
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MOVEQ");
+
+ p .OP1_MOVEQ()
+ .SIZE_LONG().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .ALU_MOVE()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_BCHG_BCLR_BSET_immediate");
+
+ p .SIZE_BYTE().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ p .OP2_FROM_OP1()
+ .SIZE_6().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_BCHG_BCLR_BSET_BTST()
+ .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_BTST_immediate");
+
+ p .SIZE_BYTE().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ p .OP2_FROM_OP1()
+ .SIZE_6().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATA();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_BCHG_BCLR_BSET_BTST()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_BCHG_BCLR_BSET_register");
+
+ p .SIZE_6().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .OP2_FROM_OP1()
+ .SIZE_6().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_BCHG_BCLR_BSET_BTST()
+ .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_BTST_register");
+
+ p .SIZE_6().EA_REG_IR_11_9().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .OP2_FROM_OP1()
+ .SIZE_6().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATA();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_BCHG_BCLR_BSET_BTST()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_TAS");
+
+ p .READ_MODIFY_WRITE_FLAG_SET()
+ .SIZE_BYTE().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_TAS()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .READ_MODIFY_WRITE_FLAG_CLEAR()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_NEGX_CLR_NEG_NOT_NBCD");
+
+ p .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT()
+ .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_SWAP_EXT");
+
+ p .SIZE_2().EA_REG_IR_2_0().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_TST");
+
+ p .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_MOVE()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_ADDQ_SUBQ_not_An");
+
+ p .OP2_ADDQ_SUBQ()
+ .SIZE_3().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+
+ p .ALU_ARITHMETIC_LOGIC()
+ .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_ADDQ_SUBQ_An");
+
+ p .OP2_ADDQ_SUBQ()
+ .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_AN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_Scc");
+
+ p .BRANCH_condition_0().offset("scc_condition_0");
+ p .OP1_LOAD_ONES();
+
+ // jump here if condition is false
+ p .label("scc_condition_0");
+
+ p .BRANCH_condition_1().offset("scc_condition_1");
+ p .OP1_LOAD_ZEROS();
+
+ // jump here if condition is true
+ p .label("scc_condition_1");
+
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_BYTE().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_Bcc_BRA");
+
+ p .OP1_FROM_PC();
+
+ p .ALU_SIMPLE_MOVE()
+ .BRANCH_ir().offset("bcc_bra_no_word");
+
+ p .SIZE_WORD().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ // jump here if no need to load extra immediate word
+ p .label("bcc_bra_no_word");
+
+ p .BRANCH_condition_0().offset("bcc_bra_no_branch");
+
+ p .OP2_FROM_OP1();
+ p .OP2_MOVE_OFFSET()
+ .OP1_FROM_RESULT();
+
+ p .ALU_SIMPLE_LONG_ADD();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .PC_FROM_RESULT();
+
+ // wait for PC check
+ p .ALU_SIMPLE_MOVE();
+
+ // jump here if no branch
+ p .label("bcc_bra_no_branch");
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_DBcc");
+
+ p .BRANCH_condition_1().offset("dbcc_condition_true");
+
+ p .OP2_LOAD_1()
+ .SIZE_WORD().EA_REG_IR_2_0().EA_MOD_DN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_SIMPLE_LONG_SUB();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .OP1_FROM_PC()
+ .SIZE_WORD().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .ALU_SIMPLE_MOVE();
+
+ p .BRANCH_result().offset("dbcc_condition_true");
+
+ p .OP2_FROM_OP1()
+ .OP1_FROM_RESULT();
+
+ p .ALU_SIMPLE_LONG_ADD()
+ // wait for instruction prefetch
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .PC_FROM_RESULT();
+
+ // wait for PC check
+ p .ALU_SIMPLE_MOVE();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ // jump here if condition is true
+ p .label("dbcc_condition_true");
+
+ p .PC_INCR_BY_2()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MOVE_FROM_SR");
+
+ p .OP1_FROM_SR()
+ .SIZE_WORD().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATAALTER();
+
+ p .ALU_SIMPLE_MOVE()
+ .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_MOVE_TO_CCR_MOVE_TO_SR");
+
+ p .SIZE_WORD().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_DATA();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_MOVE_USP_to_USP");
+
+ p .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_AN().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ p .ALU_SIMPLE_MOVE();
+
+ p .AN_ADDRESS_USP()
+ .AN_WRITE_ENABLE_SET();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+
+ p.label("MICROPC_MOVE_USP_to_An");
+
+ p .OP1_FROM_USP()
+ .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_AN().EA_TYPE_ALL();
+
+ p .ALU_SIMPLE_MOVE()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_LINK");
+
+ // load An to OP1
+ p .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_AN().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ // move OP1 to result
+ p .ALU_LINK_MOVE()
+ .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+
+ // write result to (SP)
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ // load SP to OP1
+ p .SIZE_LONG().EA_REG_3b111().EA_MOD_AN().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ // move OP1 to result
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_AN().EA_TYPE_ALL();
+
+ // save result to An
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ // load offset word to OP1
+ p .SIZE_WORD().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ // move OP1 to OP2
+ p .OP2_FROM_OP1()
+ .SIZE_LONG().EA_REG_3b111().EA_MOD_AN().EA_TYPE_ALL();
+
+ // load SP to OP1
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ // add offset and SP to SP
+ p .ALU_SIMPLE_LONG_ADD()
+ .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_ULNK");
+ // load An to OP1
+ p .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_AN().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+
+ // move OP1 to result
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_LONG().EA_REG_3b111().EA_MOD_AN().EA_TYPE_ALL();
+
+ // save result to SP
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ // load (SP) to OP1
+ p .SIZE_LONG().EA_REG_3b111().EA_MOD_POSTINC().EA_TYPE_ALL();
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ // move OP1 to result
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_AN().EA_TYPE_ALL();
+
+ // save result to An
+ p .BRANCH_procedure().PROCEDURE_call_perform_ea_write();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_BSR");
+
+ p .OP1_FROM_PC();
+
+ p .ALU_SIMPLE_MOVE()
+ .BRANCH_ir().offset("bsr_no_word");
+ p .SIZE_WORD().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ // jump here if no need to load extra immediate word
+ p .label("bsr_no_word");
+
+ p .OP2_FROM_OP1();
+ p .OP2_MOVE_OFFSET()
+ .OP1_FROM_RESULT();
+
+ p .ALU_SIMPLE_LONG_ADD();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .OP1_FROM_PC()
+ .PC_FROM_RESULT();
+
+ p .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+
+ p .ALU_SIMPLE_MOVE()
+ .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_JMP");
+
+ p .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROL();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .OP1_FROM_ADDRESS();
+ p .ALU_SIMPLE_MOVE();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .PC_FROM_RESULT();
+
+ // wait for PC check
+ p .ALU_SIMPLE_MOVE();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_JSR");
+
+ p .SIZE_LONG().EA_REG_IR_2_0().EA_MOD_IR_5_3().EA_TYPE_CONTROL();
+
+ p .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .OP1_FROM_ADDRESS();
+ p .ALU_SIMPLE_MOVE();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .OP1_FROM_PC()
+ .PC_FROM_RESULT();
+
+ p .SIZE_LONG().EA_REG_3b111().EA_MOD_PREDEC().EA_TYPE_ALL();
+
+ p .ALU_SIMPLE_MOVE()
+ .BRANCH_procedure().PROCEDURE_call_load_ea();
+
+ p .BRANCH_procedure().PROCEDURE_call_write();
+
+ p.label("MICROPC_RTE_RTR");
+
+ p .SIZE_WORD().EA_REG_3b111().EA_MOD_POSTINC().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_SIMPLE_MOVE()
+ .SIZE_LONG().EA_REG_3b111().EA_MOD_POSTINC().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_SIMPLE_MOVE()
+ .OP1_FROM_RESULT();
+ p .ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .PC_FROM_RESULT();
+
+ // wait for PC check
+ p .ALU_SIMPLE_MOVE();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_RTS");
+
+ p .SIZE_LONG().EA_REG_3b111().EA_MOD_POSTINC().EA_TYPE_ALL();
+
+ p .BRANCH_procedure().PROCEDURE_call_read();
+ p .BRANCH_procedure().PROCEDURE_call_save_ea();
+
+ p .ALU_SIMPLE_MOVE();
+
+ // wait for instruction prefetch
+ p .BRANCH_procedure().PROCEDURE_wait_prefetch_valid();
+
+ p .PC_FROM_RESULT();
+
+ // wait for PC check
+ p .ALU_SIMPLE_MOVE();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_NOP");
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_TRAP");
+
+ p .TRAP_TRAP()
+ .BRANCH_procedure().PROCEDURE_call_trap();
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_TRAPV");
+
+ p .BRANCH_V().offset("trapv_no_trap");
+
+ p .TRAP_TRAPV()
+ .BRANCH_procedure().PROCEDURE_call_trap();
+
+ // jump here if overflow == 0
+ p .label("trapv_no_trap");
+
+ p .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_RESET");
+
+ p .DO_RESET_FLAG_SET();
+ p .BRANCH_procedure().PROCEDURE_wait_finished();
+
+ p .DO_RESET_FLAG_CLEAR()
+ .BRANCH_procedure().PROCEDURE_return();
+
+ p.label("MICROPC_STOP");
+
+ p .SIZE_WORD().EA_REG_3b100().EA_MOD_3b111().EA_TYPE_ALL()
+ .BRANCH_procedure().PROCEDURE_wait_prefetch_valid_32();
+
+ p .OP1_FROM_IMMEDIATE()
+ .PC_INCR_BY_SIZE();
+
+ p .ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR()
+ .STOP_FLAG_SET()
+ .BRANCH_procedure().PROCEDURE_return();
+ }
+}
Index: trunk/sw/ao68000_tool/src/ao68000_tool/Main.java
===================================================================
--- trunk/sw/ao68000_tool/src/ao68000_tool/Main.java (nonexistent)
+++ trunk/sw/ao68000_tool/src/ao68000_tool/Main.java (revision 2)
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package ao68000_tool;
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+public class Main {
+ /**
+ * Print program call arguments description and exit.
+ */
+ static void print_call_arguments() {
+ System.out.println("Can not parse program arguments.");
+ System.out.println("");
+ System.out.println("ao68000_tool accepts the following syntax:");
+ System.out.println(" [operation arguments]");
+ System.out.println("");
+ System.out.println("The following are available:");
+ System.out.println("\t parser