OpenCores
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 (&regs, 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 (&regs, 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 + *
+ * OpenCores ao68000 IP Core. + * \author Aleksander Osman, + * \date 28.03.2010 + * \version 1.0 + * + * \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 + *
+ * + * Structure Diagram: + * \image html structure.png + */ + + +/*! \page page_spec_introduction Introduction + * + * The OpenCores ao68000 IP Core is a Motorola MC68000 compatible processor. + * + *

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
+ */ + +/*! \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. + * + *

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 + *
+ * Figure 1: Simplified block diagram of ao68000 top module. + *
+ *

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 + * + * + * + * + * + * + * + * + *
Table 1: List of clocks.
NameSourceRates (MHz)RemarksDescription
MaxMinResolution
CLK_IInput Port70---System clock.
+ */ + +/*! \page page_spec_ports IO Ports + *

WISHBONE IO Ports

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Table 1: List of 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

+ * + * + * + * + * + * + * + *
Table 2: List of Other IO ports.
Port Width Direction Description
ipl_i 3 Input \copydoc ipl_i
reset_o 1 Output \copydoc reset_o
blocked_o1 Output \copydoc blocked_o
+ */ + +/*! \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 + *
  1. + * 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.
      + *
  2. + * M68000 8-/16-/32-Bit Microprocessors User’s Manual.
    + * Ninth Edition.
    + * Freescale Semiconductor, Inc.
    + * Available from: http://www.freescale.com.
      + *
  3. + * MOTOROLA M68000 FAMILY Programmer’s Reference Manual (Includes CPU32 Instructions).
    + * MOTOROLA INC., 1992. M68000PM/AD REV.1.
    + * Available form: http://www.freescale.com.
      + *
  4. + * ao68000 Doxygen(Design) Documentation.
      + *
+ */ + +/*! \page page_soc_linux System-on-Chip example with ao68000 running Linux + * The ao68000 IP Core is capable of booting the Linux kernel (http://www.kernel.org) up to the init program search. + * + *

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 + +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)
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 "); + System.out.println("\t microcode "); + System.out.println("\t "); + System.out.println("\t test "); + System.out.println("\t spec_extract "); + System.out.println(""); + System.out.println("For more information please read the ao68000 IP core documentation."); + + System.exit(1); + } + + /** + * @param args - program arguments described in method + * print_call_arguments(). + */ + public static void main(String[] args) { + try { + // check program call arguments + if(args[0].equals("parser") == true && args.length != 3) print_call_arguments(); + else if(args[0].equals("microcode") == true && args.length != 4) print_call_arguments(); + else if(args[0].equals("test") == true && args.length != 5) print_call_arguments(); + else if(args[0].equals("spec_extract") == true && args.length != 3) print_call_arguments(); + + if(args[0].equals("parser")) { + String java = ParseParams.parse(args[1]); + + FileOutputStream output = new FileOutputStream(args[2]); + output.write(java.getBytes()); + output.close(); + } + else if(args[0].equals("microcode")) { + ParseParams.parse(args[1]); + + FileOutputStream microcode_os = new FileOutputStream(args[2]); + FileOutputStream locations_os = new FileOutputStream(args[3]); + + GenerateMicrocode.generate(microcode_os, locations_os); + + microcode_os.close(); + locations_os.close(); + } + else if(args[0].equals("test")) { + File exe1 = new File(args[1]); + File exe2 = new File(args[2]); + + int start = Integer.parseInt(args[3]); + int end = Integer.parseInt(args[4]); + + Tester.start_test(exe1, exe2, start, end); + } + else if(args[0].equals("spec_extract")) { + DocumentationTool.extract(args[1], args[2]); + } + + System.exit(0); + } + catch(Exception e) { + e.printStackTrace(); + + try { + while(true) { + Thread.sleep(1000); + } + } + catch(Exception e2) { + e2.printStackTrace(); + } + } + } +} Index: trunk/sw/ao68000_tool/src/ao68000_tool/Tester.java =================================================================== --- trunk/sw/ao68000_tool/src/ao68000_tool/Tester.java (nonexistent) +++ trunk/sw/ao68000_tool/src/ao68000_tool/Tester.java (revision 2) @@ -0,0 +1,365 @@ +/* + * 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.util.HashMap; +import java.util.Random; +import java.util.Vector; + +/* + * 0000 0000 ss ddd DDD : ORI + * + * 0000 rrr1 00 ddd DDD : BTST + * 0000 ddd1 ss 001 sss : MOVEP from memory + * + * 0000 rrr1 01 ddd DDD : BCHG + * 0000 rrr1 10 ddd DDD : BCLR + * 0000 rrr1 11 ddd DDD : BSET + * + * 0000 0010 ss ddd DDD : ANDI + * + * 0000 0100 ss ddd DDD : SUBI + * + * 0000 0110 ss ddd DDD : ADDI + * + * 0000 1000 00 ddd DDD : BTST imm + * 0000 1000 01 ddd DDD : BCHG imm + * 0000 1000 10 ddd DDD : BCLR imm + * 0000 1000 11 ddd DDD : BSET imm + * + * 0000 1010 ss ddd DDD : EORI + * 0000 1100 ss ddd DDD : CMPI + * + * 0000 1110 xx xxx xxx : illegal instruction + * + * 00ss DDDd dd sss SSS : MOVE + * 00ss DDD0 01 sss SSS : MOVEA + * + * 0100 0000 ss ddd DDD : NEGX + * 0100 0000 11 ddd DDD : MOVE FROM SR + * + * 0100 0001 00 xxx xxx : illegal instruction + * + * 0100 rrrs s0 ddd DDD : CHK + * 0100 rrr1 11 ddd DDD : LEA + * + * 0100 0010 ss ddd DDD : CLR + * + * 0100 0100 ss ddd DDD : NEG + * 0100 0100 11 sss SSS : MOVE TO CCR + * 0100 0110 ss ddd DDD : NOT + * 0100 0110 11 sss SSS : MOVE TO SR + * + * 0100 1000 00 ddd DDD : NBCD + * 0100 1000 01 000 rrr : SWAP + * + * 0100 1000 01 001 xxx : illegal instruction + * 0100 1000 01 ddd DDD : PEA + * + * 0100 1000 ss ddd DDD : EXT + * 0100 1000 ss 001 rrr : MOVEM register to memory + * + * 0100 1010 ss ddd DDD : TST + * 0100 1010 11 ddd DDD : TAS + * + * 0100 1010 11 111 100 : ILLEGAL + * + * 0100 1100 ss ddd DDD : MOVEM memory to register + * + * 0100 1110 01 00i iii : TRAP + * + * 0100 1110 01 010 rrr : LNK + * 0100 1110 01 011 rrr : ULNK + * + * 0100 1110 01 10d rrr : MOVE USP + * + * 0100 1110 01 110 000 : RESET + * 0100 1110 01 110 001 : NOP + * 0100 1110 01 110 010 : STOP + * 0100 1110 01 110 011 : RTE + * 0100 1110 01 110 100 : illegal instruction + * 0100 1110 01 110 101 : RTS + * 0100 1110 01 110 110 : TRAPV + * 0100 1110 01 110 111 : RTR + * + * 0100 1110 01 111 xxx : illegal instruction + * 0100 1110 10 sss SSS : JSR + * 0100 1110 11 sss SSS : JMP + * + * 0101 cccc 11 001 rrr : DBcc + * 0101 cccc 11 ddd DDD : Scc + * 0101 qqq1 ss ddd DDD : SUBQ + * 0101 qqq0 ss ddd DDD : ADDQ + * + * 0110 0001 dd ddd ddd : BSR + * 0110 0000 dd ddd ddd : BRA + * 0110 cccc dd ddd ddd : Bcc + * + * 0111 rrr0 dd ddd ddd : MOVEQ + * + * 1011 rrro oo sss SSS : CMP + * 1011 rrro oo sss SSS : CMPA + * 1011 ddd1 ss 001 sss : CMPM + * 1011 ssso oo ddd DDD : EOR + * + * 1101 rrro oo eee EEE : ADD + * 1100 rrro oo eee EEE : AND + * 1000 rrro oo eee EEE : OR + * 1001 rrro oo eee EEE : SUB + * + * 1001 rrro oo sss SSS : SUBA + * 1101 rrro oo sss SSS : ADDA + * + * 1101 ddd1 oo 00m sss : ADDX + * 1001 ddd1 oo 00m sss : SUBX + * + * 1100 ddd1 00 00m sss : ABCD + * 1000 ddd1 00 00m sss : SBCD + * + * 1100 ddd1 oo ooo aaa : EXG + * + * 1100 ddd0 11 sss SSS : MULU + * 1100 ddd1 11 sss SSS : MULS + * 1000 ddd0 11 sss SSS : DIVU + * 1000 ddd1 11 sss SSS : DIVS + * + * 1110 000d 11 sss SSS : ASL,ASR memory + * 1110 cccd ss i00 rrr : ASL,ASR register/immediate + * 1110 001d 11 sss SSS : LSL,LSR memory + * 1110 cccd ss i01 rrr : LSL,LSR register/immediate + * 1110 011d 11 sss SSS : ROL,ROR memory + * 1110 cccd ss i11 rrr : ROL,ROR register/immediate + * 1110 010d 11 sss SSS : ROXL,ROXR memory + * 1110 cccd ss i10 rrr : ROXL,ROXR register/immediate + */ + +public class Tester { + static int get_random(Random random, boolean must_be_even) { + if(global_zero) return 0; + while(true) { + int rand = random.nextInt(); + if(must_be_even == false) return rand; + else if(must_be_even == true && (rand % 2) == 0) return rand; + } + } + static int get_random_bit(Random random) { + if(global_zero) return 0; + return (random.nextInt() % 2 == 0) ? 0 : 1; + } + static int get_random_ipm(Random random) { + if(global_zero) return 0; + int rand = random.nextInt(); + rand = rand % 8; + return (rand < 0) ? -rand : rand; + } + static String get_8_char_hex_string(int val) throws Exception { + String s = Integer.toHexString(val>>>2); + while(s.length() < 8) s = "0" + s; + return s.substring(s.length()-8); + } + static String get_4_char_hex_string(int val) throws Exception { + String s = Integer.toHexString(val); + while(s.length() < 4) s = "0" + s; + return s.substring(s.length()-4); + } + + static void start_test(File exe1, File exe2, int start, int end) throws Exception { + random = new Random(); + for(int i=start; i map_exe1 = start_test_process(common, exe1); + if(map_exe1 == null) throw new Exception("Exe1 odd address read/write."); + + + program_output += "\nRunning exe2: " + exe2.getName() + "\n"; + common.remove(0); + common.add(0, exe2.getCanonicalPath()); + HashMap map_exe2 = start_test_process(common, exe2); + if(map_exe2 == null) throw new Exception("Exe2 odd address read/write."); + + boolean failed = false; + boolean is_blocked = (map_exe1.containsKey("processor blocked") && map_exe2.containsKey("processor blocked")) ? true : false; + for(String key : map_exe1.keySet()) { + String value_emu = map_exe1.get(key); + String value_verilog = map_exe2.get(key); + map_exe2.remove(key); + + // if processor blocked, do not compare PC and SSP registers + if(is_blocked && key.equals("PC")) continue; + if(is_blocked && key.equals("SSP")) continue; + + if(value_emu.equals(value_verilog) == false) { + if(failed == false) System.out.println(""); + System.out.println("Key mismatch: " + key + ": Exe1=" + value_emu + " / Exe2=" + value_verilog); + failed = true; + } + } + for(String key : map_exe2.keySet()) { + if(failed == false) System.out.println(""); + System.out.println("Key mismatch: " + key + ": EXE1=" + null + " / EXE2=" + map_exe2.get(key)); + failed = true; + } + + if(failed) { + System.out.println(""); + throw new Exception("Mismatch detected. Program output:\n" + program_output); + } + } + catch(Exception e) { + String result = ""; + for(String s : common) { + result += s + "\n"; + } + throw new Exception(e.getMessage() + "\nCommon dump:\n" + result + "\nInstruction:\n" + instruction); + } + } + static HashMap start_test_process(Vector common, File file) throws Exception { + + Runtime runtime = Runtime.getRuntime(); + String result = ""; + String addresses = "\n"; + int count=0; + while(true) { + result = ""; + if(file.isDirectory() == false) file = new File(file.getParent()); + Process p = runtime.exec(common.toArray(new String[0]), null, file); + + int read = p.getInputStream().read(); + while(read != -1) { + result += (char)read; + read = p.getInputStream().read(); + } + p.waitFor(); + p.getErrorStream().close(); + p.getInputStream().close(); + p.getOutputStream().close(); + + if(p.exitValue() == 0) break; + else { + int index = result.indexOf("Missing argument: MEM"); + int index2 = result.indexOf("on odd address"); + if(index != -1) { + index += new String("Missing argument: MEM").length(); + result = result.substring(index, index+8); + addresses += result + "\n"; + + String to_add = "+MEM" + result + "=" + Integer.toHexString(get_random(random, false)); + if(to_add.length() > 4+8+1+8) throw new Exception("Illegal memory value length: " + to_add); + common.add(to_add); + } + else if(index2 != -1) { + throw new Exception("Odd address:" + result); + } + else throw new Exception("Error running process:\n" + result); + } + + count++; + if(count == 100) throw new Exception("Number of memory reads exceeded: " + common.firstElement() + " " + addresses); + } + + program_output += result; + + result = result.substring(result.indexOf("START TEST") + new String("START TEST").length()); + String split[] = result.split("\n"); + + HashMap map = new HashMap(); + for(int i=0; i= next_end) { + deep--; + start = next_end + 5; + } + else if(next_start == -1 && next_end != -1) { + deep--; + start = next_end + 5; + } + else throw new Exception("Error parsing file."); + } + String result = all.substring(start_saved, start) + ">"; + + //System.out.println("s: " + start_saved + ", e: " + start); + //System.out.println(result); + + result = result.replaceAll("

", " "); + result = result.replaceAll("

", " "); + + int max=0; + while(result.indexOf("href=\"", max) != -1) { + int i = result.indexOf("href=\"", max); + max = i+6; + + if(result.substring(i).startsWith("href=\"http:")) continue; + + result = result.substring(0, i) + "href=\"file://./doxygen/html/" + result.substring(i+6); + } + + // save output + FileOutputStream out = new FileOutputStream(dest); + out.write(result.getBytes()); + out.close(); + } +} Index: trunk/sw/ao68000_tool/src/ao68000_tool/Parser.java =================================================================== --- trunk/sw/ao68000_tool/src/ao68000_tool/Parser.java (nonexistent) +++ trunk/sw/ao68000_tool/src/ao68000_tool/Parser.java (revision 2) @@ -0,0 +1,719 @@ +package ao68000_tool; +class Parser { + boolean newline; + Parser() { this(true); } + Parser(boolean newline) { this.newline = newline; } + Parser EA_REG_IR_2_0() throws Exception { + GenerateMicrocode.entry(newline, "EA_REG_IR_2_0"); + return new Parser(false); + } + Parser EA_REG_IR_11_9() throws Exception { + GenerateMicrocode.entry(newline, "EA_REG_IR_11_9"); + return new Parser(false); + } + Parser EA_REG_MOVEM_REG_2_0() throws Exception { + GenerateMicrocode.entry(newline, "EA_REG_MOVEM_REG_2_0"); + return new Parser(false); + } + Parser EA_REG_3b111() throws Exception { + GenerateMicrocode.entry(newline, "EA_REG_3b111"); + return new Parser(false); + } + Parser EA_REG_3b100() throws Exception { + GenerateMicrocode.entry(newline, "EA_REG_3b100"); + return new Parser(false); + } + Parser EA_MOD_IR_5_3() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_IR_5_3"); + return new Parser(false); + } + Parser EA_MOD_MOVEM_MOD_5_3() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_MOVEM_MOD_5_3"); + return new Parser(false); + } + Parser EA_MOD_IR_8_6() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_IR_8_6"); + return new Parser(false); + } + Parser EA_MOD_PREDEC() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_PREDEC"); + return new Parser(false); + } + Parser EA_MOD_3b111() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_3b111"); + return new Parser(false); + } + Parser EA_MOD_DN_PREDEC() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_DN_PREDEC"); + return new Parser(false); + } + Parser EA_MOD_DN_AN_EXG() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_DN_AN_EXG"); + return new Parser(false); + } + Parser EA_MOD_POSTINC() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_POSTINC"); + return new Parser(false); + } + Parser EA_MOD_AN() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_AN"); + return new Parser(false); + } + Parser EA_MOD_DN() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_DN"); + return new Parser(false); + } + Parser EA_MOD_INDIRECTOFFSET() throws Exception { + GenerateMicrocode.entry(newline, "EA_MOD_INDIRECTOFFSET"); + return new Parser(false); + } + Parser EA_TYPE_ALL() throws Exception { + GenerateMicrocode.entry(newline, "EA_TYPE_ALL"); + return new Parser(false); + } + Parser EA_TYPE_CONTROL_POSTINC() throws Exception { + GenerateMicrocode.entry(newline, "EA_TYPE_CONTROL_POSTINC"); + return new Parser(false); + } + Parser EA_TYPE_CONTROLALTER_PREDEC() throws Exception { + GenerateMicrocode.entry(newline, "EA_TYPE_CONTROLALTER_PREDEC"); + return new Parser(false); + } + Parser EA_TYPE_CONTROL() throws Exception { + GenerateMicrocode.entry(newline, "EA_TYPE_CONTROL"); + return new Parser(false); + } + Parser EA_TYPE_DATAALTER() throws Exception { + GenerateMicrocode.entry(newline, "EA_TYPE_DATAALTER"); + return new Parser(false); + } + Parser EA_TYPE_DN_AN() throws Exception { + GenerateMicrocode.entry(newline, "EA_TYPE_DN_AN"); + return new Parser(false); + } + Parser EA_TYPE_MEMORYALTER() throws Exception { + GenerateMicrocode.entry(newline, "EA_TYPE_MEMORYALTER"); + return new Parser(false); + } + Parser EA_TYPE_DATA() throws Exception { + GenerateMicrocode.entry(newline, "EA_TYPE_DATA"); + return new Parser(false); + } + Parser OP1_FROM_OP2() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_OP2"); + return new Parser(false); + } + Parser OP1_FROM_ADDRESS() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_ADDRESS"); + return new Parser(false); + } + Parser OP1_FROM_DATA() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_DATA"); + return new Parser(false); + } + Parser OP1_FROM_IMMEDIATE() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_IMMEDIATE"); + return new Parser(false); + } + Parser OP1_FROM_RESULT() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_RESULT"); + return new Parser(false); + } + Parser OP1_MOVEQ() throws Exception { + GenerateMicrocode.entry(newline, "OP1_MOVEQ"); + return new Parser(false); + } + Parser OP1_FROM_PC() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_PC"); + return new Parser(false); + } + Parser OP1_LOAD_ZEROS() throws Exception { + GenerateMicrocode.entry(newline, "OP1_LOAD_ZEROS"); + return new Parser(false); + } + Parser OP1_LOAD_ONES() throws Exception { + GenerateMicrocode.entry(newline, "OP1_LOAD_ONES"); + return new Parser(false); + } + Parser OP1_FROM_SR() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_SR"); + return new Parser(false); + } + Parser OP1_FROM_USP() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_USP"); + return new Parser(false); + } + Parser OP1_FROM_AN() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_AN"); + return new Parser(false); + } + Parser OP1_FROM_DN() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_DN"); + return new Parser(false); + } + Parser OP1_FROM_IR() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_IR"); + return new Parser(false); + } + Parser OP1_FROM_FAULT_ADDRESS() throws Exception { + GenerateMicrocode.entry(newline, "OP1_FROM_FAULT_ADDRESS"); + return new Parser(false); + } + Parser OP2_FROM_OP1() throws Exception { + GenerateMicrocode.entry(newline, "OP2_FROM_OP1"); + return new Parser(false); + } + Parser OP2_LOAD_1() throws Exception { + GenerateMicrocode.entry(newline, "OP2_LOAD_1"); + return new Parser(false); + } + Parser OP2_LOAD_COUNT() throws Exception { + GenerateMicrocode.entry(newline, "OP2_LOAD_COUNT"); + return new Parser(false); + } + Parser OP2_ADDQ_SUBQ() throws Exception { + GenerateMicrocode.entry(newline, "OP2_ADDQ_SUBQ"); + return new Parser(false); + } + Parser OP2_MOVE_OFFSET() throws Exception { + GenerateMicrocode.entry(newline, "OP2_MOVE_OFFSET"); + return new Parser(false); + } + Parser OP2_MOVE_ADDRESS_BUS_INFO() throws Exception { + GenerateMicrocode.entry(newline, "OP2_MOVE_ADDRESS_BUS_INFO"); + return new Parser(false); + } + Parser OP2_DECR_BY_1() throws Exception { + GenerateMicrocode.entry(newline, "OP2_DECR_BY_1"); + return new Parser(false); + } + Parser ADDRESS_INCR_BY_SIZE() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_INCR_BY_SIZE"); + return new Parser(false); + } + Parser ADDRESS_DECR_BY_SIZE() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_DECR_BY_SIZE"); + return new Parser(false); + } + Parser ADDRESS_INCR_BY_2() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_INCR_BY_2"); + return new Parser(false); + } + Parser ADDRESS_FROM_AN_OUTPUT() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_FROM_AN_OUTPUT"); + return new Parser(false); + } + Parser ADDRESS_FROM_BASE_INDEX_OFFSET() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_FROM_BASE_INDEX_OFFSET"); + return new Parser(false); + } + Parser ADDRESS_FROM_IMM_16() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_FROM_IMM_16"); + return new Parser(false); + } + Parser ADDRESS_FROM_IMM_32() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_FROM_IMM_32"); + return new Parser(false); + } + Parser ADDRESS_FROM_PC_INDEX_OFFSET() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_FROM_PC_INDEX_OFFSET"); + return new Parser(false); + } + Parser ADDRESS_FROM_TRAP() throws Exception { + GenerateMicrocode.entry(newline, "ADDRESS_FROM_TRAP"); + return new Parser(false); + } + Parser SIZE_BYTE() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_BYTE"); + return new Parser(false); + } + Parser SIZE_WORD() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_WORD"); + return new Parser(false); + } + Parser SIZE_LONG() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_LONG"); + return new Parser(false); + } + Parser SIZE_1() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_1"); + return new Parser(false); + } + Parser SIZE_1_PLUS() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_1_PLUS"); + return new Parser(false); + } + Parser SIZE_2() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_2"); + return new Parser(false); + } + Parser SIZE_3() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_3"); + return new Parser(false); + } + Parser SIZE_4() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_4"); + return new Parser(false); + } + Parser SIZE_5() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_5"); + return new Parser(false); + } + Parser SIZE_6() throws Exception { + GenerateMicrocode.entry(newline, "SIZE_6"); + return new Parser(false); + } + Parser MOVEM_MODREG_LOAD_0() throws Exception { + GenerateMicrocode.entry(newline, "MOVEM_MODREG_LOAD_0"); + return new Parser(false); + } + Parser MOVEM_MODREG_LOAD_6b001111() throws Exception { + GenerateMicrocode.entry(newline, "MOVEM_MODREG_LOAD_6b001111"); + return new Parser(false); + } + Parser MOVEM_MODREG_INCR_BY_1() throws Exception { + GenerateMicrocode.entry(newline, "MOVEM_MODREG_INCR_BY_1"); + return new Parser(false); + } + Parser MOVEM_MODREG_DECR_BY_1() throws Exception { + GenerateMicrocode.entry(newline, "MOVEM_MODREG_DECR_BY_1"); + return new Parser(false); + } + Parser MOVEM_LOOP_LOAD_0() throws Exception { + GenerateMicrocode.entry(newline, "MOVEM_LOOP_LOAD_0"); + return new Parser(false); + } + Parser MOVEM_LOOP_INCR_BY_1() throws Exception { + GenerateMicrocode.entry(newline, "MOVEM_LOOP_INCR_BY_1"); + return new Parser(false); + } + Parser MOVEM_REG_FROM_OP1() throws Exception { + GenerateMicrocode.entry(newline, "MOVEM_REG_FROM_OP1"); + return new Parser(false); + } + Parser MOVEM_REG_SHIFT_RIGHT() throws Exception { + GenerateMicrocode.entry(newline, "MOVEM_REG_SHIFT_RIGHT"); + return new Parser(false); + } + Parser IR_LOAD_WHEN_PREFETCH_VALID() throws Exception { + GenerateMicrocode.entry(newline, "IR_LOAD_WHEN_PREFETCH_VALID"); + return new Parser(false); + } + Parser PC_FROM_RESULT() throws Exception { + GenerateMicrocode.entry(newline, "PC_FROM_RESULT"); + return new Parser(false); + } + Parser PC_INCR_BY_2() throws Exception { + GenerateMicrocode.entry(newline, "PC_INCR_BY_2"); + return new Parser(false); + } + Parser PC_INCR_BY_4() throws Exception { + GenerateMicrocode.entry(newline, "PC_INCR_BY_4"); + return new Parser(false); + } + Parser PC_INCR_BY_SIZE() throws Exception { + GenerateMicrocode.entry(newline, "PC_INCR_BY_SIZE"); + return new Parser(false); + } + Parser PC_FROM_PREFETCH_IR() throws Exception { + GenerateMicrocode.entry(newline, "PC_FROM_PREFETCH_IR"); + return new Parser(false); + } + Parser PC_INCR_BY_2_IN_MAIN_LOOP() throws Exception { + GenerateMicrocode.entry(newline, "PC_INCR_BY_2_IN_MAIN_LOOP"); + return new Parser(false); + } + Parser TRAP_ILLEGAL_INSTR() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_ILLEGAL_INSTR"); + return new Parser(false); + } + Parser TRAP_DIV_BY_ZERO() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_DIV_BY_ZERO"); + return new Parser(false); + } + Parser TRAP_CHK() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_CHK"); + return new Parser(false); + } + Parser TRAP_TRAPV() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_TRAPV"); + return new Parser(false); + } + Parser TRAP_PRIVIL_VIOLAT() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_PRIVIL_VIOLAT"); + return new Parser(false); + } + Parser TRAP_TRACE() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_TRACE"); + return new Parser(false); + } + Parser TRAP_TRAP() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_TRAP"); + return new Parser(false); + } + Parser TRAP_FROM_DECODER() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_FROM_DECODER"); + return new Parser(false); + } + Parser TRAP_FROM_INTERRUPT() throws Exception { + GenerateMicrocode.entry(newline, "TRAP_FROM_INTERRUPT"); + return new Parser(false); + } + Parser OFFSET_IMM_8() throws Exception { + GenerateMicrocode.entry(newline, "OFFSET_IMM_8"); + return new Parser(false); + } + Parser OFFSET_IMM_16() throws Exception { + GenerateMicrocode.entry(newline, "OFFSET_IMM_16"); + return new Parser(false); + } + Parser INDEX_0() throws Exception { + GenerateMicrocode.entry(newline, "INDEX_0"); + return new Parser(false); + } + Parser INDEX_LOAD_EXTENDED() throws Exception { + GenerateMicrocode.entry(newline, "INDEX_LOAD_EXTENDED"); + return new Parser(false); + } + Parser STOP_FLAG_SET() throws Exception { + GenerateMicrocode.entry(newline, "STOP_FLAG_SET"); + return new Parser(false); + } + Parser STOP_FLAG_CLEAR() throws Exception { + GenerateMicrocode.entry(newline, "STOP_FLAG_CLEAR"); + return new Parser(false); + } + Parser TRACE_FLAG_COPY_WHEN_NO_STOP() throws Exception { + GenerateMicrocode.entry(newline, "TRACE_FLAG_COPY_WHEN_NO_STOP"); + return new Parser(false); + } + Parser GROUP_0_FLAG_SET() throws Exception { + GenerateMicrocode.entry(newline, "GROUP_0_FLAG_SET"); + return new Parser(false); + } + Parser GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH() throws Exception { + GenerateMicrocode.entry(newline, "GROUP_0_FLAG_CLEAR_WHEN_VALID_PREFETCH"); + return new Parser(false); + } + Parser INSTRUCTION_FLAG_SET() throws Exception { + GenerateMicrocode.entry(newline, "INSTRUCTION_FLAG_SET"); + return new Parser(false); + } + Parser INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP() throws Exception { + GenerateMicrocode.entry(newline, "INSTRUCTION_FLAG_CLEAR_IN_MAIN_LOOP"); + return new Parser(false); + } + Parser READ_MODIFY_WRITE_FLAG_SET() throws Exception { + GenerateMicrocode.entry(newline, "READ_MODIFY_WRITE_FLAG_SET"); + return new Parser(false); + } + Parser READ_MODIFY_WRITE_FLAG_CLEAR() throws Exception { + GenerateMicrocode.entry(newline, "READ_MODIFY_WRITE_FLAG_CLEAR"); + return new Parser(false); + } + Parser DO_RESET_FLAG_SET() throws Exception { + GenerateMicrocode.entry(newline, "DO_RESET_FLAG_SET"); + return new Parser(false); + } + Parser DO_RESET_FLAG_CLEAR() throws Exception { + GenerateMicrocode.entry(newline, "DO_RESET_FLAG_CLEAR"); + return new Parser(false); + } + Parser DO_INTERRUPT_FLAG_SET_IF_ACTIVE() throws Exception { + GenerateMicrocode.entry(newline, "DO_INTERRUPT_FLAG_SET_IF_ACTIVE"); + return new Parser(false); + } + Parser DO_INTERRUPT_FLAG_CLEAR() throws Exception { + GenerateMicrocode.entry(newline, "DO_INTERRUPT_FLAG_CLEAR"); + return new Parser(false); + } + Parser DO_READ_FLAG_SET() throws Exception { + GenerateMicrocode.entry(newline, "DO_READ_FLAG_SET"); + return new Parser(false); + } + Parser DO_READ_FLAG_CLEAR() throws Exception { + GenerateMicrocode.entry(newline, "DO_READ_FLAG_CLEAR"); + return new Parser(false); + } + Parser DO_WRITE_FLAG_SET() throws Exception { + GenerateMicrocode.entry(newline, "DO_WRITE_FLAG_SET"); + return new Parser(false); + } + Parser DO_WRITE_FLAG_CLEAR() throws Exception { + GenerateMicrocode.entry(newline, "DO_WRITE_FLAG_CLEAR"); + return new Parser(false); + } + Parser DO_BLOCKED_FLAG_SET() throws Exception { + GenerateMicrocode.entry(newline, "DO_BLOCKED_FLAG_SET"); + return new Parser(false); + } + Parser DATA_WRITE_FROM_RESULT() throws Exception { + GenerateMicrocode.entry(newline, "DATA_WRITE_FROM_RESULT"); + return new Parser(false); + } + Parser AN_ADDRESS_FROM_EXTENDED() throws Exception { + GenerateMicrocode.entry(newline, "AN_ADDRESS_FROM_EXTENDED"); + return new Parser(false); + } + Parser AN_ADDRESS_USP() throws Exception { + GenerateMicrocode.entry(newline, "AN_ADDRESS_USP"); + return new Parser(false); + } + Parser AN_ADDRESS_SSP() throws Exception { + GenerateMicrocode.entry(newline, "AN_ADDRESS_SSP"); + return new Parser(false); + } + Parser AN_WRITE_ENABLE_SET() throws Exception { + GenerateMicrocode.entry(newline, "AN_WRITE_ENABLE_SET"); + return new Parser(false); + } + Parser AN_INPUT_FROM_ADDRESS() throws Exception { + GenerateMicrocode.entry(newline, "AN_INPUT_FROM_ADDRESS"); + return new Parser(false); + } + Parser AN_INPUT_FROM_PREFETCH_IR() throws Exception { + GenerateMicrocode.entry(newline, "AN_INPUT_FROM_PREFETCH_IR"); + return new Parser(false); + } + Parser DN_ADDRESS_FROM_EXTENDED() throws Exception { + GenerateMicrocode.entry(newline, "DN_ADDRESS_FROM_EXTENDED"); + return new Parser(false); + } + Parser DN_WRITE_ENABLE_SET() throws Exception { + GenerateMicrocode.entry(newline, "DN_WRITE_ENABLE_SET"); + return new Parser(false); + } + Parser ALU_SR_SET_INTERRUPT() throws Exception { + GenerateMicrocode.entry(newline, "ALU_SR_SET_INTERRUPT"); + return new Parser(false); + } + Parser ALU_SR_SET_TRAP() throws Exception { + GenerateMicrocode.entry(newline, "ALU_SR_SET_TRAP"); + return new Parser(false); + } + Parser ALU_MOVEP_M2R_1() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVEP_M2R_1"); + return new Parser(false); + } + Parser ALU_MOVEP_M2R_2() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVEP_M2R_2"); + return new Parser(false); + } + Parser ALU_MOVEP_M2R_3() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVEP_M2R_3"); + return new Parser(false); + } + Parser ALU_MOVEP_M2R_4() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVEP_M2R_4"); + return new Parser(false); + } + Parser ALU_MOVEP_R2M_1() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVEP_R2M_1"); + return new Parser(false); + } + Parser ALU_MOVEP_R2M_2() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVEP_R2M_2"); + return new Parser(false); + } + Parser ALU_MOVEP_R2M_3() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVEP_R2M_3"); + return new Parser(false); + } + Parser ALU_MOVEP_R2M_4() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVEP_R2M_4"); + return new Parser(false); + } + Parser ALU_SIGN_EXTEND() throws Exception { + GenerateMicrocode.entry(newline, "ALU_SIGN_EXTEND"); + return new Parser(false); + } + Parser ALU_ARITHMETIC_LOGIC() throws Exception { + GenerateMicrocode.entry(newline, "ALU_ARITHMETIC_LOGIC"); + return new Parser(false); + } + Parser ALU_ABCD_SBCD_ADDX_SUBX() throws Exception { + GenerateMicrocode.entry(newline, "ALU_ABCD_SBCD_ADDX_SUBX"); + return new Parser(false); + } + Parser ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare() throws Exception { + GenerateMicrocode.entry(newline, "ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR_prepare"); + return new Parser(false); + } + Parser ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR() throws Exception { + GenerateMicrocode.entry(newline, "ALU_ASL_LSL_ROL_ROXL_ASR_LSR_ROR_ROXR"); + return new Parser(false); + } + Parser ALU_MOVE() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVE"); + return new Parser(false); + } + Parser ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ() throws Exception { + GenerateMicrocode.entry(newline, "ALU_ADDA_SUBA_CMPA_ADDQ_SUBQ"); + return new Parser(false); + } + Parser ALU_CHK() throws Exception { + GenerateMicrocode.entry(newline, "ALU_CHK"); + return new Parser(false); + } + Parser ALU_MULS_MULU_DIVS_DIVU() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MULS_MULU_DIVS_DIVU"); + return new Parser(false); + } + Parser ALU_BCHG_BCLR_BSET_BTST() throws Exception { + GenerateMicrocode.entry(newline, "ALU_BCHG_BCLR_BSET_BTST"); + return new Parser(false); + } + Parser ALU_TAS() throws Exception { + GenerateMicrocode.entry(newline, "ALU_TAS"); + return new Parser(false); + } + Parser ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT() throws Exception { + GenerateMicrocode.entry(newline, "ALU_NEGX_CLR_NEG_NOT_NBCD_SWAP_EXT"); + return new Parser(false); + } + Parser ALU_SIMPLE_LONG_ADD() throws Exception { + GenerateMicrocode.entry(newline, "ALU_SIMPLE_LONG_ADD"); + return new Parser(false); + } + Parser ALU_SIMPLE_LONG_SUB() throws Exception { + GenerateMicrocode.entry(newline, "ALU_SIMPLE_LONG_SUB"); + return new Parser(false); + } + Parser ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR() throws Exception { + GenerateMicrocode.entry(newline, "ALU_MOVE_TO_CCR_SR_RTE_RTR_STOP_LOGIC_TO_CCR_SR"); + return new Parser(false); + } + Parser ALU_SIMPLE_MOVE() throws Exception { + GenerateMicrocode.entry(newline, "ALU_SIMPLE_MOVE"); + return new Parser(false); + } + Parser ALU_LINK_MOVE() throws Exception { + GenerateMicrocode.entry(newline, "ALU_LINK_MOVE"); + return new Parser(false); + } + Parser BRANCH_movem_loop() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_movem_loop"); + return new Parser(false); + } + Parser BRANCH_movem_reg() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_movem_reg"); + return new Parser(false); + } + Parser BRANCH_operand2() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_operand2"); + return new Parser(false); + } + Parser BRANCH_special_01() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_special_01"); + return new Parser(false); + } + Parser BRANCH_special_10() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_special_10"); + return new Parser(false); + } + Parser BRANCH_condition_0() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_condition_0"); + return new Parser(false); + } + Parser BRANCH_condition_1() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_condition_1"); + return new Parser(false); + } + Parser BRANCH_result() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_result"); + return new Parser(false); + } + Parser BRANCH_V() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_V"); + return new Parser(false); + } + Parser BRANCH_movep_16() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_movep_16"); + return new Parser(false); + } + Parser BRANCH_stop_flag_wait_ir_decode() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_stop_flag_wait_ir_decode"); + return new Parser(false); + } + Parser BRANCH_ir() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_ir"); + return new Parser(false); + } + Parser BRANCH_trace_flag_and_interrupt() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_trace_flag_and_interrupt"); + return new Parser(false); + } + Parser BRANCH_group_0_flag() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_group_0_flag"); + return new Parser(false); + } + Parser BRANCH_procedure() throws Exception { + GenerateMicrocode.entry(newline, "BRANCH_procedure"); + return new Parser(false); + } + Parser PROCEDURE_call_load_ea() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_call_load_ea"); + return new Parser(false); + } + Parser PROCEDURE_call_perform_ea_read() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_call_perform_ea_read"); + return new Parser(false); + } + Parser PROCEDURE_call_perform_ea_write() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_call_perform_ea_write"); + return new Parser(false); + } + Parser PROCEDURE_call_save_ea() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_call_save_ea"); + return new Parser(false); + } + Parser PROCEDURE_return() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_return"); + return new Parser(false); + } + Parser PROCEDURE_wait_finished() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_wait_finished"); + return new Parser(false); + } + Parser PROCEDURE_wait_prefetch_valid() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_wait_prefetch_valid"); + return new Parser(false); + } + Parser PROCEDURE_wait_prefetch_valid_32() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_wait_prefetch_valid_32"); + return new Parser(false); + } + Parser PROCEDURE_jump_to_main_loop() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_jump_to_main_loop"); + return new Parser(false); + } + Parser PROCEDURE_push_micropc() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_push_micropc"); + return new Parser(false); + } + Parser PROCEDURE_call_trap() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_call_trap"); + return new Parser(false); + } + Parser PROCEDURE_pop_micropc() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_pop_micropc"); + return new Parser(false); + } + Parser PROCEDURE_interrupt_mask() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_interrupt_mask"); + return new Parser(false); + } + Parser PROCEDURE_call_read() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_call_read"); + return new Parser(false); + } + Parser PROCEDURE_call_write() throws Exception { + GenerateMicrocode.entry(newline, "PROCEDURE_call_write"); + return new Parser(false); + } + void label(String label) throws Exception { GenerateMicrocode.entry(newline, "label_" + label); } + Parser offset(String label) throws Exception { + GenerateMicrocode.entry(newline, "offset_" + label); + return new Parser(false); + } +} Index: trunk/sw/ao68000_tool/src/ao68000_tool/ParseParams.java =================================================================== --- trunk/sw/ao68000_tool/src/ao68000_tool/ParseParams.java (nonexistent) +++ trunk/sw/ao68000_tool/src/ao68000_tool/ParseParams.java (revision 2) @@ -0,0 +1,121 @@ +/* + * 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.FileInputStream; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.HashMap; + +class ParseParams { + /** + * Parse microcode_params.v to get information about what to control with the microcode, + * that is, about the microcode parameters. + * + * @param file_name - path to microcode_params.v, + * @return - the contents of Parser.java, + * @throws Exception - in case of file read error. + */ + static String parse(String file_name) throws Exception { + // load file + File file = new File(file_name); + byte bytes[] = new byte[(int)file.length()]; + FileInputStream in = new FileInputStream(file); + if( in.read(bytes) != bytes.length ) throw new Exception("Can not read from file: " + file.getCanonicalPath()); + in.close(); + + // prepare Parser.java header and constructors + String java = ""; + java += "package ao68000_tool;" + "\n"; + java += "class Parser {" + "\n"; + java += "\t" + "boolean newline;" + "\n"; + java += "\t" + "Parser() { this(true); }" + "\n"; + java += "\t" + "Parser(boolean newline) { this.newline = newline; }" + "\n"; + + // prepare data structures to keep information about the microcode parameters + prefixes = new Vector(); + prefix_locations = new HashMap(); + name_values = new HashMap(); + + // split read file into lines + String string = new String(bytes); + String tokens[] = string.split("\\n"); + + // prepare patterns, initialize counters + Pattern pat = Pattern.compile("`define\\s*(\\S+)\\s*(\\d+)'d(\\d+).*"); + int last_parameter_size = 0; + control_bit_offset = 0; + + // parse each line + for(String s : tokens) { + Matcher m0 = pat.matcher(s); + + // match parameter names and values + if( m0.matches() ) { + String name = m0.group(1); + int size = Integer.parseInt(m0.group(2)); + int value = Integer.parseInt(m0.group(3)); + + // check if parameter name ends with _IDLE + if(name.endsWith("_IDLE")) { + last_parameter_size = size; + + String prefix = name.substring(0, name.length()-5); + + prefixes.add(prefix + "_"); + prefix_locations.put(prefix + "_start", control_bit_offset); + prefix_locations.put(prefix + "_end", control_bit_offset+last_parameter_size-1); + control_bit_offset += last_parameter_size; + } + else { + java += "\t" + "Parser " + name + "() throws Exception {" + "\n"; + java += "\t\t" + "GenerateMicrocode.entry(newline, \"" + name + "\");" + "\n"; + java += "\t\t" + "return new Parser(false);" + "\n"; + java += "\t" + "}" + "\n"; + + name_values.put(name, value); + } + } + } + + // prepare Parser.java ending + java += "\t" + "void label(String label) throws Exception { GenerateMicrocode.entry(newline, \"label_\" + label); }" + "\n"; + java += "\t" + "Parser offset(String label) throws Exception {" + "\n"; + java += "\t\t" + "GenerateMicrocode.entry(newline, \"offset_\" + label);" + "\n"; + java += "\t\t" + "return new Parser(false);" + "\n"; + java += "\t" + "}" + "\n"; + + java += "}" + "\n"; + + return java; + } + + static Vector prefixes; + static HashMap name_values; + static HashMap prefix_locations; + static int control_bit_offset; +} Index: trunk/sw/ao68000_tool/manifest.mf =================================================================== --- trunk/sw/ao68000_tool/manifest.mf (nonexistent) +++ trunk/sw/ao68000_tool/manifest.mf (revision 2) @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + Index: trunk/sw/ao68000_tool/Makefile =================================================================== --- trunk/sw/ao68000_tool/Makefile (nonexistent) +++ trunk/sw/ao68000_tool/Makefile (revision 2) @@ -0,0 +1,21 @@ +ifndef AO68000_BASE +AO68000_BASE := $(CURDIR)/../.. +endif + +AO68000_RTL := $(AO68000_BASE)/rtl/verilog/ao68000 + +help: + @echo -e "Select operation to perform. Type 'make' followed by the name of the operation." + @echo + @echo -e "Available operations:" + @echo -e "microcode \t- compile microcode for the ao68000." + @echo -e "compile_tool \t- compile the ao68000_tool. Ant tool required." + @echo + @exit 0 + +./dist/ao68000_tool.jar: + ant jar + +microcode: ./dist/ao68000_tool.jar + java -jar ./dist/ao68000_tool.jar parser $(AO68000_RTL)/microcode_params.v ./src/ao68000_tool/Parser.java + java -jar ./dist/ao68000_tool.jar microcode $(AO68000_RTL)/microcode_params.v $(AO68000_RTL)/microcode/microcode.mif $(AO68000_RTL)/microcode/microcode_locations.v Index: trunk/sw/ao68000_tool/build.xml =================================================================== --- trunk/sw/ao68000_tool/build.xml (nonexistent) +++ trunk/sw/ao68000_tool/build.xml (revision 2) @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project ao68000_tool. + + + Index: trunk/sw/nbcd_abcd_sbcd/nbcd_abcd_sbcd.c =================================================================== --- trunk/sw/nbcd_abcd_sbcd/nbcd_abcd_sbcd.c (nonexistent) +++ trunk/sw/nbcd_abcd_sbcd/nbcd_abcd_sbcd.c (revision 2) @@ -0,0 +1,300 @@ +/* + * 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 + +/* +struct from_68knotes_t { + unsigned char operand; + unsigned int x; + unsigned char unadjusted; + unsigned char adjusted; + unsigned int v; +}; +struct from_68knotes_t from_68knotes[] = { + { 0x00, 0, 0x00, 0x00, 0 }, + { 0x00, 1, 0xFF, 0x99, 0 }, + { 0xFF, 0, 0x01, 0x9B, 0 }, + { 0xFF, 1, 0x00, 0x9A, 0 }, + { 0x01, 0, 0xFF, 0x99, 0 }, + { 0x01, 1, 0xFE, 0x98, 0 }, + { 0x0F, 0, 0xF1, 0x8B, 0 }, + { 0x0F, 1, 0xF0, 0x8A, 0 }, + { 0xF0, 0, 0x10, 0xB0, 0 }, + { 0xF0, 1, 0x0F, 0xA9, 0 }, + { 0x9A, 0, 0x66, 0x00, 0 }, + { 0x9A, 1, 0x65, 0xFF, 0 }, + { 0x99, 0, 0x67, 0x01, 0 }, + { 0x99, 1, 0x66, 0x00, 0 }, + { 0x10, 0, 0xF0, 0x90, 0 }, + { 0x10, 1, 0xEF, 0x89, 0 }, + { 0x7F, 0, 0x81, 0x1B, 1 }, + { 0x7F, 1, 0x80, 0x1A, 1 }, + { 0x80, 0, 0x80, 0x20, 1 }, + { 0x80, 1, 0x7F, 0x19, 0 }, + { 0x81, 0, 0x7F, 0x19, 0 }, + { 0x81, 1, 0x7E, 0x18, 0 } +}; +*/ + +struct input_t { + unsigned char src; + unsigned char dst; + + unsigned int x; + unsigned int z; + unsigned int v; +}; + +struct output_t { + unsigned char result; + + unsigned int c; + unsigned int v; + unsigned int z; + unsigned int n; + unsigned int x; +}; + +struct output_t uae_nbcd(struct input_t in) { + signed char src = in.dst; + + unsigned short newv_lo = - (src & 0xF) - in.x; + unsigned short newv_hi = - (src & 0xF0); + unsigned short newv; + int cflg; + if (newv_lo > 9) { newv_lo -= 6; } + newv = newv_hi + newv_lo; cflg = (newv & 0x1F0) > 0x90; + if (cflg) newv -= 0x60; + + struct output_t out; + out.c = cflg ? 1 : 0; + out.x = out.c; + out.z = in.z & ((((signed char)(newv)) == 0) ? 1 : 0); + out.n = (((signed char)(newv)) < 0) ? 1 : 0; + out.v = in.v; + + out.result = (newv) & 0xff; + return out; +} +struct output_t verilog_nbcd(struct input_t in) { + struct output_t out; + + unsigned char l = 25 - ((in.dst) & 0x0F); + unsigned char h = 25 - (((in.dst) & 0xF0) >> 4); + + if( ((in.dst) & 0x0F) > 9 ) h -= 1; + + l &= 0x0F; + h &= 0x0F; + + if(in.x == 0) { + if(l == 9) { + l = 0; + h = (h==9) ? 0 : h+1; + } + else if(l == 0xF) { + l = 0; + h += 1; + } + else { + l += 1; + } + } + + l &= 0x0F; + h &= 0x0F; + + out.result = (h << 4) + l; + + out.v = in.v; + out.z = in.z & ((out.result == 0) ? 1 : 0); + out.c = out.x = (in.dst == 0 && in.x == 0) ? 0 : 1; + out.n = (((out.result) & 0x80) == 0) ? 0 : 1; + + return out; +} + +struct output_t uae_abcd(struct input_t in) { + signed char src = in.src; + signed char dst = in.dst; + + unsigned short newv_lo = (src & 0xF) + (dst & 0xF) + (in.x ? 1 : 0); + unsigned short newv_hi = (src & 0xF0) + (dst & 0xF0); + unsigned short newv, tmp_newv; + int cflg; + newv = tmp_newv = newv_hi + newv_lo; if (newv_lo > 9) { newv += 6; } + cflg = (newv & 0x3F0) > 0x90; + if (cflg) newv += 0x60; + + struct output_t out; + out.c = cflg; + out.x = out.c; + out.z = in.z & (((signed char)(newv)) == 0); + out.n = ((signed char)(newv)) < 0; + out.v = (tmp_newv & 0x80) == 0 && (newv & 0x80) != 0; + out.result = (newv) & 0xff; + + return out; +} +struct output_t verilog_abcd(struct input_t in) { + + unsigned char l = (in.src & 0x0F) + (in.dst & 0x0F) + in.x; + unsigned char h = ((in.src & 0xF0) >> 4) + ((in.dst & 0xF0) >> 4); + + int tmp = (in.src + in.dst + in.x) & 0x80; + + l = (l > 0x09) ? (l+6) : l; + h = (l > 0x1F) ? (h+2) : + (l > 0x0F) ? (h+1) : h; + h = (h > 0x09) ? (h+6) : h; + + struct output_t out; + out.c = (h > 0x09) ? 1 : 0; + out.x = out.c; + + l &= 0x0F; + h &= 0x0F; + + out.result = (h << 4) + l; + + out.z = in.z & (out.result == 0); + out.n = ((out.result & 0x80) == 0x80) ? 1 : 0; + out.v = (tmp == 0) && ((out.result & 0x80) != 0); + + return out; +} + +struct output_t uae_sbcd(struct input_t in) { + signed char src = in.src; + signed char dst = in.dst; + + unsigned short newv_lo = (dst & 0xF) - (src & 0xF) - (in.x ? 1 : 0); + unsigned short newv_hi = (dst & 0xF0) - (src & 0xF0); + unsigned short newv, tmp_newv; + int bcd = 0; + newv = tmp_newv = newv_hi + newv_lo; + if (newv_lo & 0xF0) { newv -= 6; bcd = 6; }; + if ((((dst & 0xFF) - (src & 0xFF) - (in.x ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; } + + struct output_t out; + out.c = (((dst & 0xFF) - (src & 0xFF) - bcd - (in.x ? 1 : 0)) & 0x300) > 0xFF; + out.x = out.c; + out.z = in.z & (((signed char)(newv)) == 0); + out.n = ((signed char)(newv)) < 0; + out.v = (tmp_newv & 0x80) != 0 && (newv & 0x80) == 0; + out.result = (newv) & 0xff; + + return out; +} + +struct output_t verilog_sbcd(struct input_t in) { + + unsigned char l = 32 + (in.dst & 0x0F) - (in.src & 0x0F) - in.x; + unsigned char h = 32 + ((in.dst & 0xF0) >> 4) - ((in.src & 0xF0) >> 4); + + int tmp = in.dst - in.src - in.x; + + l = (l < 32) ? (l-6) : l; + h = (l < 16) ? (h-2) : + (l < 32) ? (h-1) : h; + h = (h < 32 && (tmp & 0x100) > 0xFF) ? (h-6) : h; + + struct output_t out; + out.c = (h < 32) ? 1 : 0; + out.x = out.c; + + l &= 0x0F; + h &= 0x0F; + + out.result = (h << 4) + l; + + out.z = in.z & (out.result == 0); + out.n = ((out.result & 0x80) == 0x80) ? 1 : 0; + out.v = ((tmp & 0x80) != 0) && ((out.result & 0x80) == 0); + + return out; +} + +void compare(struct input_t in, struct output_t uae, struct output_t verilog) { + if( uae.result == verilog.result && + uae.c == verilog.c && + uae.v == verilog.v && + uae.z == verilog.z && + uae.n == verilog.n && + uae.x == verilog.x + ) return; + + //printf("%hhx + %hhx + %x: | ", in.dst, in.src, in.x); + //printf("%hhx - %hhx - %x: | ", in.dst, in.src, in.x); + + printf("[Mismatch: in.dst: %hhx, in.src: %hhx, in.x: %x] ", in.dst, in.src, in.x); + + if( uae.result != verilog.result ) printf("result: %hhx != %hhx | ", uae.result, verilog.result); + if( uae.c != verilog.c ) printf("c: %x != %x | ", uae.c, verilog.c); + if( uae.v != verilog.v ) printf("v: %x != %x | ", uae.v, verilog.v); + if( uae.z != verilog.z ) printf("z: %x != %x | ", uae.z, verilog.z); + if( uae.n != verilog.n ) printf("n: %x != %x | ", uae.n, verilog.n); + if( uae.x != verilog.x ) printf("x: %x != %x | ", uae.x, verilog.x); + printf("\n"); +} + +int main(int argc, char **argv) { + struct input_t in; + + int i,j,k,l,m; + for(i=0; i<256; i++) { + for(j=0; j<256; j++) { + for(k=0; k<2; k++) { + for(l=0; l<2; l++) { + for(m=0; m<2; m++) { + in.src = i; + in.dst = j; + in.x = k; + in.z = l; + in.v = m; + + struct output_t uae0 = uae_nbcd(in); + struct output_t verilog0 = verilog_nbcd(in); + + compare(in, uae0, verilog0); + + struct output_t uae1 = uae_abcd(in); + struct output_t verilog1 = verilog_abcd(in); + + compare(in, uae1, verilog1); + + struct output_t uae2 = uae_sbcd(in); + struct output_t verilog2 = verilog_sbcd(in); + + compare(in, uae2, verilog2); + } + } + } + } + } + + return 0; +} + Index: trunk/syn/altera/run/full_system/full_system.qpf =================================================================== --- trunk/syn/altera/run/full_system/full_system.qpf (nonexistent) +++ trunk/syn/altera/run/full_system/full_system.qpf (revision 2) @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.1 Build 222 10/21/2009 SJ Web Edition +# Date created = 21:50:15 March 02, 2010 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "9.1" +DATE = "21:50:15 March 02, 2010" + +# Revisions + +PROJECT_REVISION = "full_system" Index: trunk/syn/altera/run/full_system/full_system.qsf =================================================================== --- trunk/syn/altera/run/full_system/full_system.qsf (nonexistent) +++ trunk/syn/altera/run/full_system/full_system.qsf (revision 2) @@ -0,0 +1,167 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.1 Build 222 10/21/2009 SJ Web Edition +# Date created = 21:50:15 March 02, 2010 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# full_system_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + +set_global_assignment -name FAMILY "Cyclone II" +set_global_assignment -name DEVICE EP2C70F896C6 +set_global_assignment -name TOP_LEVEL_ENTITY full_system +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 9.1 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:50:15 MARCH 02, 2010" +set_global_assignment -name LAST_QUARTUS_VERSION 9.1 +set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga +set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 896 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 6 +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED" +set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED" +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region" +set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region" +set_global_assignment -name VERILOG_FILE ao68000.v +set_global_assignment -name VERILOG_FILE altera_specific/alu_mult_div.v +set_global_assignment -name VERILOG_FILE altera_specific/register_ram.v +set_global_assignment -name VERILOG_FILE altera_specific/microcode_rom.v +set_global_assignment -name VERILOG_FILE ssram.v +set_global_assignment -name VERILOG_FILE early_boot.v +set_global_assignment -name VERILOG_FILE full_system.v +set_global_assignment -name VERILOG_FILE sd.v +set_global_assignment -name VERILOG_FILE serial_txd.v +set_global_assignment -name VERILOG_FILE timer.v +set_location_assignment PIN_R3 -to clk_i +set_location_assignment PIN_AA23 -to rst_i +set_location_assignment PIN_T26 -to sd_clk_o +set_location_assignment PIN_W29 -to sd_dat_io +set_location_assignment PIN_W28 -to sd_cmd_io +set_location_assignment PIN_AJ6 -to sd_debug[0] +set_location_assignment PIN_AK5 -to sd_debug[1] +set_location_assignment PIN_AJ5 -to sd_debug[2] +set_location_assignment PIN_AJ4 -to sd_debug[3] +set_location_assignment PIN_AK3 -to sd_debug[4] +set_location_assignment PIN_AH4 -to sd_debug[5] +set_location_assignment PIN_D21 -to uart_rxd +set_location_assignment PIN_E21 -to uart_txd +set_location_assignment PIN_G22 -to uart_cts +set_location_assignment PIN_F23 -to uart_rts +set_location_assignment PIN_AG8 -to ssram_address[0] +set_location_assignment PIN_AF8 -to ssram_address[1] +set_location_assignment PIN_AF14 -to ssram_address[10] +set_location_assignment PIN_AG14 -to ssram_address[11] +set_location_assignment PIN_AE15 -to ssram_address[12] +set_location_assignment PIN_AF15 -to ssram_address[13] +set_location_assignment PIN_AC16 -to ssram_address[14] +set_location_assignment PIN_AF20 -to ssram_address[15] +set_location_assignment PIN_AG20 -to ssram_address[16] +set_location_assignment PIN_AE11 -to ssram_address[17] +set_location_assignment PIN_AF11 -to ssram_address[18] +#set_location_assignment PIN_AG10 -to ssram_address[19] +set_location_assignment PIN_AH7 -to ssram_address[2] +#set_location_assignment PIN_AG9 -to ssram_address[20] +set_location_assignment PIN_AG7 -to ssram_address[3] +set_location_assignment PIN_AG6 -to ssram_address[4] +set_location_assignment PIN_AG5 -to ssram_address[5] +set_location_assignment PIN_AE12 -to ssram_address[6] +set_location_assignment PIN_AG12 -to ssram_address[7] +set_location_assignment PIN_AD13 -to ssram_address[8] +set_location_assignment PIN_AE13 -to ssram_address[9] +set_location_assignment PIN_AG17 -to ssram_adsc_n +set_location_assignment PIN_AC18 -to ssram_adsp_n +set_location_assignment PIN_AD16 -to ssram_advance_n +set_location_assignment PIN_AC21 -to ssram_byteen0_n +set_location_assignment PIN_AC20 -to ssram_byteen1_n +set_location_assignment PIN_AD20 -to ssram_byteen2_n +set_location_assignment PIN_AH20 -to ssram_byteen3_n +set_location_assignment PIN_AH19 -to ssram_ce1_n +set_location_assignment PIN_AG19 -to ssram_ce2 +set_location_assignment PIN_AD22 -to ssram_ce3_n +set_location_assignment PIN_AD7 -to ssram_clk +#set_location_assignment PIN_AK9 -to SRAM_DPA[0] +#set_location_assignment PIN_AJ23 -to SRAM_DPA[1] +#set_location_assignment PIN_AK20 -to SRAM_DPA[2] +#set_location_assignment PIN_AJ9 -to SRAM_DPA[3] +set_location_assignment PIN_AH10 -to ssram_data[0] +set_location_assignment PIN_AJ10 -to ssram_data[1] +set_location_assignment PIN_AH17 -to ssram_data[10] +set_location_assignment PIN_AJ18 -to ssram_data[11] +set_location_assignment PIN_AH18 -to ssram_data[12] +set_location_assignment PIN_AK19 -to ssram_data[13] +set_location_assignment PIN_AJ19 -to ssram_data[14] +set_location_assignment PIN_AK23 -to ssram_data[15] +set_location_assignment PIN_AJ20 -to ssram_data[16] +set_location_assignment PIN_AK21 -to ssram_data[17] +set_location_assignment PIN_AJ21 -to ssram_data[18] +set_location_assignment PIN_AK22 -to ssram_data[19] +set_location_assignment PIN_AK10 -to ssram_data[2] +set_location_assignment PIN_AJ22 -to ssram_data[20] +set_location_assignment PIN_AH15 -to ssram_data[21] +set_location_assignment PIN_AJ15 -to ssram_data[22] +set_location_assignment PIN_AJ16 -to ssram_data[23] +set_location_assignment PIN_AK14 -to ssram_data[24] +set_location_assignment PIN_AJ14 -to ssram_data[25] +set_location_assignment PIN_AJ13 -to ssram_data[26] +set_location_assignment PIN_AH13 -to ssram_data[27] +set_location_assignment PIN_AK12 -to ssram_data[28] +set_location_assignment PIN_AK7 -to ssram_data[29] +set_location_assignment PIN_AJ11 -to ssram_data[3] +set_location_assignment PIN_AJ8 -to ssram_data[30] +set_location_assignment PIN_AK8 -to ssram_data[31] +set_location_assignment PIN_AK11 -to ssram_data[4] +set_location_assignment PIN_AH12 -to ssram_data[5] +set_location_assignment PIN_AJ12 -to ssram_data[6] +set_location_assignment PIN_AH16 -to ssram_data[7] +set_location_assignment PIN_AK17 -to ssram_data[8] +set_location_assignment PIN_AJ17 -to ssram_data[9] +set_location_assignment PIN_AG18 -to ssram_globalw_n +set_location_assignment PIN_AD18 -to ssram_oe_n +set_location_assignment PIN_AF18 -to ssram_writeen_n + +set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "AS INPUT TRI-STATED" +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_location_assignment PIN_AC13 -to pc_debug[0] +set_location_assignment PIN_AB13 -to pc_debug[1] +set_location_assignment PIN_AC12 -to pc_debug[2] +set_location_assignment PIN_AB12 -to pc_debug[3] +set_location_assignment PIN_AC11 -to pc_debug[4] +set_location_assignment PIN_AD9 -to pc_debug[5] +set_location_assignment PIN_AD8 -to pc_debug[6] +set_location_assignment PIN_AJ7 -to pc_debug[7] +set_global_assignment -name OPTIMIZE_HOLD_TIMING "IO PATHS AND MINIMUM TPD PATHS" +set_global_assignment -name FITTER_EFFORT "AUTO FIT" +set_global_assignment -name SMART_RECOMPILE ON +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file Index: trunk/syn/altera/bin/Makefile =================================================================== --- trunk/syn/altera/bin/Makefile (nonexistent) +++ trunk/syn/altera/bin/Makefile (revision 2) @@ -0,0 +1,22 @@ +help: + @echo -e "Select project to synthesise. Type 'make' followed by the name of the project." + @echo + @echo -e "Available projects:" + @echo -e "full_system \t- system for Terasic DE2-70 board, consists of:" + @echo -e "\t\t ao68000 processor core," + @echo -e "\t\t SSRAM controller," + @echo -e "\t\t SDHC controller," + @echo -e "\t\t serial output," + @echo -e "\t\t boot controller." + @echo + @exit 0 + +full_system: + mkdir -p ./../out/full_system + cp ./../run/full_system/* ./../out/full_system/ + cp ./../../../rtl/verilog/full_system/* ./../out/full_system/ + cp -R ./../../../rtl/verilog/ao68000/* ./../out/full_system/ + cd ./../out/full_system && quartus_sh --flow compile full_system + +clean: + rm -f -R ./../out/full_system Index: trunk/Makefile =================================================================== --- trunk/Makefile (nonexistent) +++ trunk/Makefile (revision 2) @@ -0,0 +1,38 @@ +AO68000_BASE := $(CURDIR) +export AO68000_BASE + +help: + @echo -e "Select operation to perform. Type 'make' followed by the name of the operation." + @echo + @echo -e "Available operations:" + @echo -e "synthesise \t- synthesise full_system SoC with ao68000 processor." + @echo -e "compare \t- run RTL-Software comparison." + @echo -e "docs \t- unpack Doxygen documentation." + @echo -e "clean \t- clean all." + @echo -e "commit \t- commit project to SVN repository." + @echo + @exit 0 + +synthesise: + $(MAKE) -C $(AO68000_BASE)/syn/altera/bin full_system + +docs: + $(MAKE) -C $(AO68000_BASE)/doc unpack + +compare: + $(MAKE) -C $(AO68000_BASE)/sw/ao68000_tool microcode + $(MAKE) -C $(AO68000_BASE)/sim/rtl_sim/bin tb_ao68000 + $(MAKE) -C $(AO68000_BASE)/sim/sw_emulators/bin winuae + $(MAKE) -C $(AO68000_BASE)/sim/rtl_sw_compare/bin tb_ao68000_with_winuae + +clean: + $(MAKE) -C $(AO68000_BASE)/bench/sw_emulators/winuae clean + $(MAKE) -C $(AO68000_BASE)/bench/verilog/tb_ao68000 clean + $(MAKE) -C $(AO68000_BASE)/doc clean + $(MAKE) -C $(AO68000_BASE)/sim/rtl_sim/bin clean + $(MAKE) -C $(AO68000_BASE)/sim/rtl_sw_compare/bin clean + $(MAKE) -C $(AO68000_BASE)/sim/sw_emulators/bin clean + $(MAKE) -C $(AO68000_BASE)/syn/altera/bin clean + +commit: clean + svn commit

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.