OpenCores
URL https://opencores.org/ocsvn/cpu8080/cpu8080/trunk

Subversion Repositories cpu8080

[/] [cpu8080/] [tags/] [initial/] [project/] [cpu8080.v] - Blame information for rev 33

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 samiam9512
`timescale 1ns / 1ps
2
////////////////////////////////////////////////////////////////////////////////
3
// Company:                                                                   //  
4
// Engineer:       Scott Moore                                                //
5
//                                                                            //
6
// Create Date:    11:45:32 09/04/2006                                        // 
7
// Design Name:                                                               // 
8
// Module Name:    cpu8080                                                    //
9
// Project Name:   cpu8080                                                    //
10
// Target Devices: xc3c200, xc3s1000                                          //
11
// Tool versions:                                                             //
12
// Description:                                                               //
13
//                                                                            //
14
//     Executes the 8080 instruction set. It is designed to be an internal    //
15
//     cell. Each of the I/Os are positive logic, and all signals are         //
16
//     constant with the exception of the data bus. The control signals are   //
17
//     fully decoded (unlike the orignal 8080), and features read and write   //
18
//     signals for both memory and I/O space. The I/O space is an 8 bit       //
19
//     address as in the original 8080.                                       //
20
//                                                                            //
21
//     Like the original 8080, the interrupt vectoring is fully external. The //
22
//     the external controller forces a full instruction onto the data bus.   //
23
//     The sequence begins with the assertion of interrupt request. The CPU   //
24
//     will then assert interrupt acknowledge, then it will run a special     //
25
//     read cycle with readint asserted for each cycle of a possibly          //
26
//     multibyte instruction. This matches the original 8080, which typically //
27
//     used single byte restart instructions to form a simple interrupt       //
28
//     controller, but was capable of full vectoring via insertion of a jump, //
29
//     call or similar instruction.                                           //
30
//                                                                            //
31
//     The memory, I/O and interrupt fetches all obey a simple clocking       //
32
//     sequence as follows. The CPU uses the positive clock edge to assert    //
33
//     and sample signals and data. The external logic theoretically uses the //
34
//     positive edge to check signal assertions and sample data, but it can   //
35
//     either use the negative edge, or actually be asynronous logic.         //
36
//                                                                            //
37
//     A standard read sequence is as follows:                                //
38
//                                                                            //
39
//     1. At the positive clock edge, readmem, readio or readint is asserted. //
40
//     2. At the positive clock edge (or immediately), the external memory    //
41
//        places data onto the data bus.                                      //
42
//     3. At the next positive clock edge, the data is sampled, and the read  //
43
//        Signal is deasserted.                                               //
44
//                                                                            //
45
//     A standard write sequence is as follows:                               //
46
//                                                                            //
47
//     1. At the positive edge, data is asserted on the data bus.             //
48
//     2. At the postive clock edge, writemem or writeio is asserted.         //
49
//     3. At the next positive clock edge, writemem or writeio is deasserted. //
50
//     4. At the positive edge, the data is deasserted.                       //
51
//                                                                            //
52
// Dependencies:                                                              //
53
//                                                                            //
54
// Revision:                                                                  //
55
// Revision 0.01 - File Created                                               //
56
// Additional Comments:                                                       //
57
//                                                                            //
58
// Notes:                                                                     //
59
//                                                                            //
60
// 1. Auxiliary carry is not complete.                                        //
61
//                                                                            //
62
// 2. inta should take place instead of readmem for each interrupt vector     //
63
//    instruction that is fetched. This behavior matches the original Intel   //
64
//    interrupt controller, and it should not be required to gate readmem OFF //
65
//    during interrupt cycles.                                                //
66
//                                                                            //
67
////////////////////////////////////////////////////////////////////////////////
68
 
69
//
70
// CPU states
71
//
72
 
73
`define cpus_idle     5'h00 // Idle
74
`define cpus_fetchi   5'h01 // Instruction fetch
75
`define cpus_fetchi2  5'h02 // Instruction fetch 2
76
`define cpus_halt     5'h03 // Halt (wait for interrupt)
77
`define cpus_alucb    5'h04 // alu cycleback
78
`define cpus_indcb    5'h05 // inr/dcr cycleback
79
`define cpus_movmtbc  5'h06 // Move memory to bc
80
`define cpus_movmtde  5'h07 // Move memory to de
81
`define cpus_movmthl  5'h08 // Move memory to hl
82
`define cpus_movmtsp  5'h09 // Move memory to sp
83
`define cpus_lhld     5'h0a // LHLD
84
`define cpus_jmp      5'h0b // JMP
85
`define cpus_write    5'h0c // write byte
86
`define cpus_write2   5'h0d // write byte #2
87
`define cpus_write3   5'h0e // write byte #3
88
`define cpus_write4   5'h0f // write byte #4
89
`define cpus_read     5'h10 // read byte
90
`define cpus_read2    5'h11 // read byte #2
91
`define cpus_pop      5'h12 // POP completion
92
`define cpus_in       5'h13 // IN
93
`define cpus_in2      5'h14 // IN #2
94
`define cpus_out      5'h15 // OUT
95
`define cpus_out2     5'h16 // OUT #2
96
`define cpus_out3     5'h17 // OUT #3
97
`define cpus_out4     5'h18 // OUT #4
98
`define cpus_movtr    5'h19 // move to register
99
`define cpus_movrtw   5'h1a // move read to write
100
`define cpus_movrtwa  5'h1b // move read to write address
101
`define cpus_movrtra  5'h1c // move read to read address
102
`define cpus_accimm   5'h1d // accumulator immediate operations
103
`define cpus_daa      5'h1e // DAA completion
104
 
105
//
106
// Register numbers
107
//
108
 
109
`define reg_b 3'b000 // B
110
`define reg_c 3'b001 // C
111
`define reg_d 3'b010 // D
112
`define reg_e 3'b011 // E
113
`define reg_h 3'b100 // H
114
`define reg_l 3'b101 // L
115
`define reg_m 3'b110 // M
116
`define reg_a 3'b111 // A
117
 
118
//
119
// ALU operations
120
//
121
 
122
`define aluop_add 3'b000 // add
123
`define aluop_adc 3'b001 // add with carry in
124
`define aluop_sub 3'b010 // subtract
125
`define aluop_sbb 3'b011 // subtract with borrow in
126
`define aluop_and 3'b100 // and
127
`define aluop_xor 3'b101 // xor
128
`define aluop_or  3'b110 // or
129
`define aluop_cmp 3'b111 // compare
130
 
131
//
132
// State macros
133
//
134
`define mac_writebyte  1  // write a byte
135
`define mac_readbtoreg 2  // read a byte, place in register
136
`define mac_readdtobc  4  // read double byte to BC
137
`define mac_readdtode  6  // read double byte to DE
138
`define mac_readdtohl  8 // read double byte to HL
139
`define mac_readdtosp  10 // read double byte to SP
140
`define mac_readbmtw   12 // read byte and move to write
141
`define mac_readbmtr   14 // read byte and move to register
142
`define mac_sta        16 // STA
143
`define mac_lda        20 // LDA
144
`define mac_shld       25 // SHLD
145
`define mac_lhld       30 // LHLD
146
`define mac_writedbyte 36 // write double byte
147
`define mac_pop        38 // POP
148
`define mac_xthl       40 // XTHL
149
`define mac_accimm     44 // accumulator immediate
150
`define mac_jmp        45 // JMP
151
`define mac_call       47 // CALL
152
`define mac_in         51 // IN
153
`define mac_out        52 // OUT
154
`define mac_rst        53 // RST
155
 
156
module cpu8080(addr,     // Address out
157
               data,     // Data bus
158
               readmem,  // Memory read   
159
               writemem, // Memory write
160
               readio,   // Read I/O space
161
               writeio,  // Write I/O space
162
               intr,     // Interrupt request 
163
               inta,     // Interrupt request 
164
               waitr,    // Wait request
165
               reset,    // Reset
166
               clock);   // System clock
167
 
168
   output [15:0] addr;
169
   inout  [7:0] data;
170
   output readmem;
171
   output writemem;
172
   output readio;
173
   output writeio;
174
   input  intr;
175
   output inta;
176
   input  waitr;
177
   input  reset;
178
   input  clock;
179
 
180
   // Output or input lines that need to be registered
181
 
182
   reg           readmem;
183
   reg           writemem;
184
   reg    [15:0] pc;
185
   reg    [15:0] addr;
186
   reg           readio;
187
   reg           writeio;
188
   reg           inta;
189
   reg    [15:0] sp;
190
 
191
   // Local registers
192
 
193
   reg    [4:0]  state;       // CPU state machine
194
   reg    [2:0]  regd;        // Destination register
195
   reg    [7:0]  datao;       // Data output register
196
   reg           dataeno;     // Enable output data
197
   reg    [15:0] waddrhold;   // address holding for write
198
   reg    [15:0] raddrhold;   // address holding for read
199
   reg    [7:0]  wdatahold;   // single byte write data holding
200
   reg    [7:0]  wdatahold2;  // single byte write data holding
201
   reg    [7:0]  rdatahold;   // single byte read data holding
202
   reg    [7:0]  rdatahold2;  // single byte read data holding
203
   reg    [1:0]  popdes;      // POP destination code
204
   reg    [5:0]  statesel;    // state map selector
205
   reg    [4:0]  nextstate;   // next state output
206
 
207
   // Register file. Note that 3'b110 (6) is not used, and is the code for a
208
   // memory reference.
209
 
210
   reg    [7:0]  regfil[0:7];
211
 
212
   // The flags are represented individually
213
 
214
   reg           carry; // carry bit
215
   reg           auxcar; // auxiliary carry bit
216
   reg           sign; // sign bit
217
   reg           zero; // zero bit
218
   reg           parity; // parity bit
219
   reg           ei; // interrupt enable
220
 
221
   // ALU communication
222
 
223
   wire   [7:0]  alures;  // result
224
   reg    [7:0]  aluopra; // left side operand
225
   reg    [7:0]  aluoprb; // right side operand
226
   reg           alucin;  // carry in
227
   wire          alucout; // carry out
228
   wire          alupar;  // parity out
229
   wire          aluaxc;  // auxiliary carry
230
   reg    [2:0]  alusel;  // alu operational select
231
 
232
   // Instantiate the ALU
233
 
234
   alu alu(alures, aluopra, aluoprb, alucin, alucout, aluzout, alusout, alupar,
235
           aluaxc, alusel);
236
 
237
   always @(posedge clock)
238
      if (reset) begin // syncronous reset actions
239
 
240
      state <= `cpus_fetchi; // Clear CPU state to initial fetch
241
      pc <= 0; // reset program counter to 1st location
242
      dataeno <= 0; // get off the data bus
243
      readmem <= 0; // all signals out false
244
      writemem <= 0;
245
      readio <= 0;
246
      writeio <= 0;
247
      inta <= 0;
248
      ei <= 1; // interrupts on on reset, check this
249
 
250
   end else case (state)
251
 
252
      `cpus_fetchi: begin // start of instruction fetch
253
 
254
         // interrupt is like a normal instruction cycle, except we set the 
255
         // acknowledge for the entire instruction fetch.
256
         if (intr && ei) inta <= 1; // interrupt request, set interrupt acknowledge
257
         else inta <= 0; // clear interrupt acknowledge
258
         addr <= pc; // place current program count on output
259
         readmem <= 1; // activate instruction memory read
260
         state <= `cpus_fetchi2; // next state
261
 
262
      end
263
 
264
      `cpus_fetchi2: begin // complete instruction memory read
265
 
266
         readmem <= 0; // Deactivate instruction memory read
267
 
268
         // We split off the instructions into 4 groups. Most of the 8080
269
         // instructions are in the MOV and ACC operations class.
270
 
271
         case (data[7:6]) // Decode top level
272
 
273
            2'b00: begin // 00: Data transfers and others
274
 
275
               case (data[5:0]) // decode these instructions
276
 
277
                  6'b000000: begin // NOP
278
 
279
                     // yes, do nothing
280
 
281
                     state <= `cpus_fetchi; // Fetch next instruction
282
                     pc <= pc+1; // Next instruction byte
283
 
284
                  end
285
 
286
                  6'b110111: begin // STC
287
 
288
                     carry <= 1; // set carry flag
289
                     state <= `cpus_fetchi; // Fetch next instruction
290
                     pc <= pc+1; // Next instruction byte
291
 
292
                  end
293
 
294
                  6'b111111: begin // CMC
295
 
296
                     carry <= ~carry; // complement carry flag
297
                     state <= `cpus_fetchi; // Fetch next instruction
298
                     pc <= pc+1; // Next instruction byte
299
 
300
                  end
301
 
302
                  6'b101111: begin // CMA
303
 
304
                     regfil[`reg_a] <= ~regfil[`reg_a]; // complement accumulator
305
                     state <= `cpus_fetchi; // Fetch next instruction
306
                     pc <= pc+1; // Next instruction byte
307
 
308
                  end
309
 
310
                  6'b100111: begin // DAA
311
 
312
                     // decimal adjust accumulator, or remove by carry any 
313
                     // results in nybbles greater than 9
314
 
315
                     if (regfil[`reg_a][3:0] > 9 || auxcar) begin
316
 
317
                        { carry, regfil[`reg_a] } <= regfil[`reg_a]+6;
318
                        auxcar <= (regfil[`reg_a][3:0]+6 >> 4) & 1;
319
 
320
                     end
321
                     state <= `cpus_daa; // finish DAA
322
                     pc <= pc+1; // Next instruction byte
323
 
324
                  end
325
 
326
                  6'b000100, 6'b001100, 6'b010100, 6'b011100, 6'b100100,
327
                  6'b101100, 6'b110100, 6'b111100, 6'b000101, 6'b001101,
328
                  6'b010101, 6'b011101, 6'b100101, 6'b101101, 6'b110101,
329
                  6'b111101: begin // INR/DCR
330
 
331
                     regd <= data[5:3]; // get source/destination reg
332
                     aluopra <= regfil[data[5:3]]; // load as alu a
333
                     aluoprb <= 1; // load 1 as alu b
334
                     if (data[0]) alusel <= `aluop_sub; // set subtract
335
                     else alusel <= `aluop_add; // set add
336
                     state <= `cpus_indcb; // go inr/dcr cycleback
337
                     pc <= pc+1; // Next instruction byte
338
 
339
                  end
340
 
341
                  6'b000010, 6'b010010: begin // STAX
342
 
343
                     wdatahold <= regfil[`reg_a]; // place A as source
344
                     if (data[4]) // use DE pair
345
                        waddrhold <= regfil[`reg_d]<<8|regfil[`reg_d];
346
                     else // use BC pair
347
                        waddrhold <= regfil[`reg_b] << 8|regfil[`reg_c];
348
                     statesel <= `mac_writebyte; // write byte
349
                     state <= `cpus_write;
350
                     pc <= pc+1; // Next instruction byte
351
 
352
                  end
353
 
354
                  6'b001010, 6'b011010: begin // LDAX
355
 
356
                     regd <= `reg_a; // set A as destination
357
                     if (data[4]) // use DE pair
358
                        raddrhold <= regfil[`reg_d]<<8|regfil[`reg_d];
359
                     else // use BC pair
360
                        raddrhold <= regfil[`reg_b]<<8|regfil[`reg_c];
361
                     statesel <= `mac_readbtoreg; // read byte to register
362
                     state <= `cpus_read;
363
                     pc <= pc+1; // Next instruction byte
364
 
365
                  end
366
 
367
                  6'b000111: begin // RLC
368
 
369
                     // rotate left circular
370
                     { carry, regfil[`reg_a] } <=
371
                        (regfil[`reg_a] << 1)+regfil[`reg_a][7];
372
                     state <= `cpus_fetchi; // Fetch next instruction
373
                     pc <= pc+1; // Next instruction byte
374
 
375
                  end
376
 
377
                  6'b010111: begin // RAL
378
 
379
                     // rotate left through carry
380
                     { carry, regfil[`reg_a] } <= (regfil[`reg_a] << 1)+carry;
381
                     state <= `cpus_fetchi; // Fetch next instruction
382
                     pc <= pc+1; // Next instruction byte
383
 
384
                  end
385
 
386
                  6'b001111: begin // RRC
387
 
388
                     // rotate right circular
389
                     regfil[`reg_a] <=
390
                        (regfil[`reg_a] >> 1)+(regfil[`reg_a][0] << 7);
391
                     carry <= regfil[`reg_a][0];
392
                     state <= `cpus_fetchi; // Fetch next instruction
393
                     pc <= pc+1; // Next instruction byte
394
 
395
                  end
396
 
397
                  6'b011111: begin // RAR
398
 
399
                     // rotate right through carry
400
                     regfil[`reg_a] <= (regfil[`reg_a] >> 1)+(carry << 7);
401
                     carry <= regfil[`reg_a][0];
402
                     state <= `cpus_fetchi; // Fetch next instruction
403
                     pc <= pc+1; // Next instruction byte
404
 
405
                  end
406
 
407
                  6'b001001: begin // DAD B
408
 
409
                     // add BC to HL
410
                     { carry, regfil[`reg_h], regfil[`reg_l] } <=
411
                        (regfil[`reg_h] << 8)+regfil[`reg_l]+
412
                        (regfil[`reg_b] << 8)+regfil[`reg_c];
413
                     state <= `cpus_fetchi; // Fetch next instruction
414
                     pc <= pc+1; // Next instruction byte
415
 
416
                  end
417
 
418
                  6'b011001: begin // DAD D
419
 
420
                     // add DE to HL
421
                     { carry, regfil[`reg_h], regfil[`reg_l] } <=
422
                        (regfil[`reg_h] << 8)+regfil[`reg_l]+
423
                        (regfil[`reg_d] << 8)+regfil[`reg_e];
424
                     state <= `cpus_fetchi; // Fetch next instruction
425
                     pc <= pc+1; // Next instruction byte
426
 
427
                  end
428
 
429
                  6'b101001: begin // DAD H
430
 
431
                     // add HL to HL
432
                     { carry, regfil[`reg_h], regfil[`reg_l] } <=
433
                        (regfil[`reg_h] << 8)+regfil[`reg_l]+
434
                        (regfil[`reg_h] << 8)+regfil[`reg_l];
435
                     state <= `cpus_fetchi; // Fetch next instruction
436
                     pc <= pc+1; // Next instruction byte
437
 
438
                  end
439
 
440
                  6'b111001: begin // DAD SP
441
 
442
                     // add SP to HL
443
                     { carry, regfil[`reg_h], regfil[`reg_l] } <=
444
                        (regfil[`reg_h] << 8)+regfil[`reg_l]+sp;
445
                     state <= `cpus_fetchi; // Fetch next instruction
446
                     pc <= pc+1; // Next instruction byte
447
 
448
                  end
449
 
450
                  6'b000011: begin // INX B
451
 
452
                     // increment BC, no flags set
453
                     regfil[`reg_b] <=
454
                        (((regfil[`reg_b] << 8)+regfil[`reg_c])+1)>>8;
455
                     regfil[`reg_c] <=
456
                        ((regfil[`reg_b] << 8)+regfil[`reg_c])+1;
457
                     state <= `cpus_fetchi; // Fetch next instruction
458
                     pc <= pc+1; // Next instruction byte
459
 
460
                  end
461
 
462
                  6'b010011: begin // INX D
463
 
464
                     // increment DE, no flags set
465
                     regfil[`reg_d] <=
466
                        (((regfil[`reg_d] << 8)+regfil[`reg_e])+1)>>8;
467
                     regfil[`reg_e] <=
468
                        ((regfil[`reg_d] << 8)+regfil[`reg_e])+1;
469
                     state <= `cpus_fetchi; // Fetch next instruction
470
                     pc <= pc+1; // Next instruction byte
471
 
472
                  end
473
 
474
                  6'b100011: begin // INX H
475
 
476
                     // increment HL, no flags set
477
                     regfil[`reg_h] <=
478
                        (((regfil[`reg_h] << 8)+regfil[`reg_l])+1)>>8;
479
                     regfil[`reg_l] <=
480
                        ((regfil[`reg_h] << 8)+regfil[`reg_l])+1;
481
                     state <= `cpus_fetchi; // Fetch next instruction
482
                     pc <= pc+1; // Next instruction byte
483
 
484
                  end
485
 
486
                  6'b110011: begin // INX SP
487
 
488
                     // increment SP, no flags set
489
                     sp <= sp+1;
490
                     state <= `cpus_fetchi; // Fetch next instruction
491
                     pc <= pc+1; // Next instruction byte
492
 
493
                  end
494
 
495
                  6'b001011: begin // DCX B
496
 
497
                     // decrement BC, no flags set
498
                     regfil[`reg_b] <=
499
                        (((regfil[`reg_b] << 8)+regfil[`reg_c])-1)>>8;
500
                     regfil[`reg_c] <=
501
                        ((regfil[`reg_b] << 8)+regfil[`reg_c])-1;
502
                     state <= `cpus_fetchi; // Fetch next instruction
503
                     pc <= pc+1; // Next instruction byte
504
 
505
                  end
506
 
507
                  6'b011011: begin // DCX D
508
 
509
                     // decrement DE, no flags set
510
                     regfil[`reg_d] <=
511
                        (((regfil[`reg_d] << 8)+regfil[`reg_e])-1)>>8;
512
                     regfil[`reg_e] <=
513
                        ((regfil[`reg_d] << 8)+regfil[`reg_e])-11;
514
                     state <= `cpus_fetchi; // Fetch next instruction
515
                     pc <= pc+1; // Next instruction byte
516
 
517
                  end
518
 
519
                  6'b101011: begin // DCX H
520
 
521
                     // decrement HL, no flags set
522
                     regfil[`reg_h] <=
523
                        (((regfil[`reg_h] << 8)+regfil[`reg_l])-1)>>8;
524
                     regfil[`reg_l] <=
525
                        ((regfil[`reg_h] << 8)+regfil[`reg_l])-1;
526
                     state <= `cpus_fetchi; // Fetch next instruction
527
                     pc <= pc+1; // Next instruction byte
528
 
529
                  end
530
 
531
                  6'b111011: begin // DCX SP
532
 
533
                     // decrement SP, no flags set
534
                     sp <= sp-1;
535
                     state <= `cpus_fetchi; // Fetch next instruction
536
                     pc <= pc+1; // Next instruction byte
537
 
538
                  end
539
 
540
                  6'b000001: begin // LXI B
541
 
542
                     raddrhold <= pc+1; // pick up after instruction
543
                     statesel <= `mac_readdtobc; // read double to BC
544
                     state <= `cpus_read;
545
                     pc <= pc+3; // skip
546
 
547
                  end
548
 
549
                  6'b010001: begin // LXI D
550
 
551
                     raddrhold <= pc+1; // pick up after instruction
552
                     statesel <= `mac_readdtode; // read double to DE
553
                     state <= `cpus_read;
554
                     pc <= pc+3; // skip
555
 
556
                  end
557
 
558
                  6'b100001: begin // LXI H
559
 
560
                     raddrhold <= pc+1; // pick up after instruction
561
                     statesel <= `mac_readdtohl; // read double to HL
562
                     state <= `cpus_read;
563
                     pc <= pc+3; // skip
564
 
565
                  end
566
 
567
                  6'b110001: begin // LXI SP
568
 
569
                     raddrhold <= pc+1; // pick up after instruction
570
                     pc <= pc+3; // skip
571
                     statesel <= `mac_readdtosp; // read double to SP
572
                     state <= `cpus_read;
573
                     pc <= pc+3; // skip
574
 
575
                  end
576
 
577
                  6'b000110, 6'b001110, 6'b010110, 6'b011110, 6'b100110,
578
                  6'b101110, 6'b110110, 6'b111110: begin // MVI
579
 
580
                     // move immediate to register
581
                     regd <= data[5:3]; // set destination register
582
                     raddrhold <= pc+1; // set pickup address
583
                     if (data[5:3] == `reg_m) begin // it's mvi m,imm
584
 
585
                        regd <= data[5:3]; // set destination register
586
                        // set destination address
587
                        waddrhold <= { regfil[`reg_h], regfil[`reg_l] };
588
                        statesel <= `mac_readbmtw; // read byte and move to write
589
 
590
                     end else
591
                        statesel <= `mac_readbmtr; // read byte and move to register
592
                     state <= `cpus_read;
593
                     pc <= pc+2; // advance over byte
594
 
595
                  end
596
 
597
                  6'b110010: begin // STA
598
 
599
                     wdatahold <= regfil[`reg_a]; // set write data
600
                     raddrhold <= pc+1; // set read address
601
                     statesel <= `mac_sta; // perform sta
602
                     state <= `cpus_read;
603
                     pc <= pc+3; // next
604
 
605
                  end
606
 
607
                  6'b111010: begin // LDA
608
 
609
                     raddrhold <= pc+1; // set read address
610
                     regd <= `reg_a; // set destination
611
                     statesel <= `mac_lda; // perform lda
612
                     state <= `cpus_read;
613
                     pc <= pc+3; // next
614
 
615
                  end
616
 
617
                  6'b100010: begin // SHLD
618
 
619
                     wdatahold <= regfil[`reg_l]; // set write data
620
                     wdatahold2 <= regfil[`reg_h];
621
                     raddrhold <= pc+1; // set read address
622
                     statesel <= `mac_shld; // perform SHLD
623
                     state <= `cpus_read;
624
                     pc <= pc+3; // next
625
 
626
                  end
627
 
628
                  6'b101010: begin // LHLD
629
 
630
                     raddrhold <= pc+1; // set read address
631
                     statesel <= `mac_lhld; // perform LHLD
632
                     state <= `cpus_read;
633
                     pc <= pc+3; // next
634
 
635
                  end
636
 
637
                  // the illegal opcodes behave as NOPs
638
 
639
                  6'b001000, 6'b010000, 6'b011000, 6'b100000, 6'b101000,
640
                  6'b110000, 6'b110000: begin
641
 
642
                     state <= `cpus_fetchi; // fetch next instruction
643
                     pc <= pc+1; // Next instruction byte
644
 
645
                  end
646
 
647
               endcase
648
 
649
            end
650
 
651
            2'b01: begin // 01: MOV instruction
652
 
653
               // Check its the halt instruction, which occupies the invalid
654
               // "MOV M,M" instruction.
655
               if (data == 8'b01110110) state <= `cpus_halt;
656
               // Otherwise, the 01 prefix is single instruction format.
657
               else begin
658
 
659
                  // Format 01DDDSSS
660
 
661
                  // Check memory source, use state if so
662
                  if (data[2:0] == `reg_m) begin
663
 
664
                     // place hl as address
665
                     raddrhold <= regfil[`reg_h]<<8|regfil[`reg_l];
666
                     regd <= data[5:3]; // set destination
667
                     statesel <= `mac_readbtoreg; // read byte to register
668
                     state <= `cpus_read;
669
 
670
                  // Check memory destination, use state if so
671
                  end else if (regd == `reg_m) begin
672
 
673
                     // place hl as address
674
                     waddrhold <= regfil[`reg_h]<<8|regfil[`reg_l];
675
                     wdatahold <= regfil[data[2:0]]; // place data to write
676
                     statesel <= `mac_writebyte; // write byte
677
                     state <= `cpus_write;
678
 
679
                  // otherwise simple register to register
680
                  end else begin
681
 
682
                     regfil[data[5:3]] <= regfil[data[2:0]];
683
                     state <= `cpus_fetchi; // Fetch next instruction
684
 
685
                  end
686
 
687
               end
688
               pc <= pc+1; // Next instruction byte
689
 
690
            end
691
 
692
            2'b10: begin // 10: Reg or mem to accumulator ops
693
 
694
               // 10 prefix is single instruction format
695
               aluopra <= regfil[`reg_a]; // load as alu a
696
               aluoprb <= regfil[data[2:0]]; // load as alu b
697
               alusel <= data[5:3]; // set alu operation from instruction
698
               alucin <= carry; // input carry
699
               if (data[2:0] == `reg_m) begin
700
 
701
                  // set read address
702
                  raddrhold <= regfil[`reg_h]<<8|regfil[`reg_l];
703
                  regd <= `reg_a; // set destination always a
704
                  statesel <= `mac_readbtoreg; // read byte to register
705
                  state <= `cpus_read;
706
 
707
               end else
708
                  state <= `cpus_alucb; // go to alu cycleback
709
               pc <= pc+1; // Next instruction byte
710
 
711
            end
712
 
713
            2'b11: begin // 11: jmp/call and others
714
 
715
               case (data[5:0]) // decode these instructions
716
 
717
                  6'b000101, 6'b010101, 6'b100101, 6'b110101: begin // PUSH
718
 
719
                     waddrhold <= sp-2; // write to stack
720
                     sp <= sp-2; // pushdown stack
721
                     case (data[5:4]) // register set
722
 
723
                        2'b00: { wdatahold2, wdatahold } <=
724
                                  { regfil[`reg_b], regfil[`reg_c] };
725
                        2'b01: { wdatahold2, wdatahold } <=
726
                                  { regfil[`reg_d], regfil[`reg_e] };
727
                        2'b10: { wdatahold2, wdatahold } <=
728
                                  { regfil[`reg_h], regfil[`reg_l] };
729
                        2'b11: { wdatahold2, wdatahold } <=
730
                                  { regfil[`reg_a], sign, zero, 1'b0, auxcar,
731
                                    1'b0, parity, carry };
732
 
733
                     endcase
734
                     statesel <= `mac_writedbyte; // write double byte
735
                     state <= `cpus_write;
736
                     pc <= pc+1; // Next instruction byte
737
 
738
                  end
739
 
740
                  6'b000001, 6'b010001, 6'b100001, 6'b110001: begin // POP
741
 
742
                     popdes <= data[5:4]; // set destination
743
                     raddrhold <= sp; // read from stack
744
                     sp <= sp+2; // pushup stack
745
                     statesel <= `mac_pop; // perform POP
746
                     state <= `cpus_read;
747
                     pc <= pc+1; // Next instruction byte
748
 
749
                  end
750
 
751
                  6'b101011: begin // XCHG
752
 
753
                     regfil[`reg_d] <= regfil[`reg_h];
754
                     regfil[`reg_e] <= regfil[`reg_l];
755
                     regfil[`reg_h] <= regfil[`reg_d];
756
                     regfil[`reg_l] <= regfil[`reg_e];
757
                     state <= `cpus_fetchi; // Fetch next instruction
758
                     pc <= pc+1; // Next instruction byte
759
 
760
                  end
761
 
762
                  6'b100011: begin // XTHL
763
 
764
                     raddrhold <= sp; // address SP for read
765
                     waddrhold <= sp; // address SP for write
766
                     wdatahold <= regfil[`reg_l]; // set data is HL
767
                     wdatahold2 <= regfil[`reg_h];
768
                     statesel <= `mac_xthl; // perform XTHL
769
                     state <= `cpus_read;
770
                     pc <= pc+1; // Next instruction byte
771
 
772
                  end
773
 
774
                  6'b111001: begin // SPHL
775
 
776
                     sp <= { regfil[`reg_h], regfil[`reg_l] };
777
                     state <= `cpus_fetchi; // Fetch next instruction
778
                     pc <= pc+1; // Next instruction byte
779
 
780
                  end
781
 
782
                  6'b000110, 6'b001110, 6'b010110, 6'b011110, 6'b100110,
783
                  6'b101110, 6'b110110,
784
                  6'b111110: begin // immediate arithmetic to accumulator
785
 
786
                     aluopra <= regfil[`reg_a]; // load as alu a
787
                     alusel <= data[5:3]; // set alu operation from instruction
788
                     alucin <= carry; // input carry
789
                     raddrhold <= pc+1; // read at PC
790
                     statesel <= `mac_accimm; // finish accumulator immediate
791
                     state <= `cpus_read;
792
                     pc <= pc+2; // skip immediate byte
793
 
794
                  end
795
 
796
                  6'b101001: begin // PCHL
797
 
798
                     state <= `cpus_fetchi; // Fetch next instruction
799
                     pc <= { regfil[`reg_h], regfil[`reg_l] };
800
 
801
                  end
802
 
803
                  6'b000011: begin // JMP
804
 
805
                     raddrhold <= pc+1; // pick up jump address
806
                     statesel <= `mac_jmp; // finish JMP
807
                     state <= `cpus_read;
808
 
809
                  end
810
 
811
                  6'b000010, 6'b001010, 6'b010010, 6'b011010, 6'b100010,
812
                  6'b101010, 6'b110010, 6'b111010: begin // Jcc
813
 
814
                     raddrhold <= pc+1; // pick up jump address
815
                     statesel <= `mac_jmp; // finish JMP
816
                     // choose continue or read according to condition
817
                     case (data[5:3]) // decode flag cases
818
 
819
                        3'b000: if (zero) state <= `cpus_fetchi;
820
                                else state <= `cpus_read;
821
                        3'b001: if (!zero) state <= `cpus_fetchi;
822
                                else state <= `cpus_read;
823
                        3'b010: if (carry) state <= `cpus_fetchi;
824
                                else state <= `cpus_read;
825
                        3'b011: if (!carry) state <= `cpus_fetchi;
826
                                else state <= `cpus_read;
827
                        3'b100: if (parity) state <= `cpus_fetchi;
828
                                else state <= `cpus_read;
829
                        3'b101: if (!parity) state <= `cpus_fetchi;
830
                                else state <= `cpus_read;
831
                        3'b110: if (sign) state <= `cpus_fetchi;
832
                                else state <= `cpus_read;
833
                        3'b111: if (!sign) state <= `cpus_fetchi;
834
                                else state <= `cpus_read;
835
 
836
                     endcase
837
                     pc <= pc+3; // advance after jump for false
838
 
839
                  end
840
 
841
                  6'b001101: begin // CALL
842
 
843
                     raddrhold <= pc+1; // pick up call address
844
                     waddrhold <= sp-2; // place address on stack
845
                     { wdatahold2, wdatahold } <= pc+3; // of address after call
846
                     sp <= sp-2; // pushdown stack
847
                     statesel <= `mac_call; // finish CALL
848
                     state <= `cpus_read;
849
 
850
                  end
851
 
852
                  6'b000100, 6'b001100, 6'b010100, 6'b011100, 6'b100100,
853
                  6'b101100, 6'b110100, 6'b111100: begin // Ccc
854
 
855
                     raddrhold <= pc+1; // pick up call address
856
                     waddrhold <= sp-2; // place address on stack
857
                     { wdatahold2, wdatahold } <= pc+3; // of address after call
858
                     sp <= sp-2; // pushdown stack
859
                     statesel <= `mac_call; // finish CALL
860
                     // choose continue or read according to condition
861
                     case (data[5:3]) // decode flag cases
862
 
863
                        3'b000: if (zero) state <= `cpus_fetchi;
864
                                else state <= `cpus_read;
865
                        3'b001: if (!zero) state <= `cpus_fetchi;
866
                                else state <= `cpus_read;
867
                        3'b010: if (carry) state <= `cpus_fetchi;
868
                                else state <= `cpus_read;
869
                        3'b011: if (!carry) state <= `cpus_fetchi;
870
                                else state <= `cpus_read;
871
                        3'b100: if (parity) state <= `cpus_fetchi;
872
                                else state <= `cpus_read;
873
                        3'b101: if (!parity) state <= `cpus_fetchi;
874
                                else state <= `cpus_read;
875
                        3'b110: if (sign) state <= `cpus_fetchi;
876
                                else state <= `cpus_read;
877
                        3'b111: if (!sign) state <= `cpus_fetchi;
878
                                else state <= `cpus_read;
879
 
880
                     endcase
881
                     pc <= pc+3; // advance after jump for false
882
 
883
                  end
884
 
885
                  6'b001001: begin // RET
886
 
887
                     raddrhold <= sp; // read from stack
888
                     sp <= sp+2; // pushup stack
889
                     statesel <= `mac_jmp; // finish JMP
890
                     state <= `cpus_read;
891
 
892
                  end
893
 
894
                  6'b000000, 6'b001000, 6'b010000, 6'b011000, 6'b100000,
895
                  6'b101000, 6'b110000, 6'b111000: begin // Rcc
896
 
897
                     raddrhold <= sp; // read from stack
898
                     sp <= sp+2; // pushup stack
899
                     statesel <= `mac_jmp; // finish JMP
900
                     // choose read or continue according to condition
901
                     case (data[5:3]) // decode flag cases
902
 
903
                        3'b000: if (zero) state <= `cpus_fetchi;
904
                                else state <= `cpus_read;
905
                        3'b001: if (!zero) state <= `cpus_fetchi;
906
                                else state <= `cpus_read;
907
                        3'b010: if (carry) state <= `cpus_fetchi;
908
                                else state <= `cpus_read;
909
                        3'b011: if (!carry) state <= `cpus_fetchi;
910
                                else state <= `cpus_read;
911
                        3'b100: if (parity) state <= `cpus_fetchi;
912
                                else state <= `cpus_read;
913
                        3'b101: if (!parity) state <= `cpus_fetchi;
914
                                else state <= `cpus_read;
915
                        3'b110: if (sign) state <= `cpus_fetchi;
916
                                else state <= `cpus_read;
917
                        3'b111: if (!sign) state <= `cpus_fetchi;
918
                                else state <= `cpus_read;
919
 
920
                     endcase
921
                     pc <= pc+1; // Next instruction byte
922
 
923
                  end
924
 
925
                  6'b000111, 6'b001111, 6'b010111, 6'b011111, 6'b100111,
926
                  6'b101111, 6'b110111, 6'b111111: begin // RST
927
 
928
                     pc <= data & 8'b00111000; // place restart value in PC
929
                     waddrhold <= sp-2; // place address on stack
930
                     { wdatahold2, wdatahold } <= pc+1; // of address after call
931
                     sp <= sp-2; // pushdown stack
932
                     statesel <= `mac_writedbyte; // finish RST
933
                     state <= `cpus_write; // write to stack
934
 
935
                  end
936
 
937
                  6'b111011: begin // EI
938
 
939
                     ei <= 1'b1;
940
                     state <= `cpus_fetchi; // Fetch next instruction
941
                     pc <= pc+1; // Next instruction byte
942
 
943
                  end
944
 
945
                  6'b110011: begin // DI
946
 
947
                     ei <= 1'b0;
948
                     state <= `cpus_fetchi; // Fetch next instruction
949
                     pc <= pc+1; // Next instruction byte
950
 
951
                  end
952
 
953
                  6'b011011: begin // IN p
954
 
955
                     raddrhold <= pc+1; // pick up byte I/O address
956
                     pc <= pc+2; // next
957
                     statesel <= `mac_in; // finish IN
958
                     state <= `cpus_read;
959
                     pc <= pc+2; // Next instruction byte
960
 
961
                  end
962
 
963
                  6'b010011: begin // OUT p
964
 
965
                     raddrhold <= pc+1; // pick up byte I/O address
966
                     pc <= pc+2; // next
967
                     statesel <= `mac_out; // finish OUT
968
                     state <= `cpus_read;
969
                     pc <= pc+2; // Next instruction byte
970
 
971
                  end
972
 
973
                  // the illegal opcodes behave as NOPs
974
 
975
                  6'b001011, 6'b011001, 6'b011101, 6'b101101,
976
                  6'b111101: begin
977
 
978
                     state <= `cpus_fetchi; // fetch next instruction
979
                     pc <= pc+2; // Next instruction byte
980
 
981
                  end
982
 
983
               endcase
984
 
985
            end
986
 
987
         endcase
988
 
989
      end
990
 
991
      // Follow states. These state handlers implement the following cycles past
992
      // M1, or primary fetch state.
993
 
994
      //
995
      // single byte write, writes wdatahold to the waddrhold address
996
      //
997
 
998
      `cpus_write: begin
999
 
1000
         addr <= waddrhold; // place address on output
1001
         waddrhold <= waddrhold+1; // next address
1002
         datao <= wdatahold; // set data to output
1003
         wdatahold <= wdatahold2; // next data
1004
         dataeno <= 1; // enable output data
1005
         state <= `cpus_write2; // next state
1006
 
1007
      end
1008
 
1009
      `cpus_write2: begin // continue write #2
1010
 
1011
         writemem <= 1; // enable write memory data
1012
         state <= `cpus_write3; // idle one cycle for write
1013
 
1014
      end
1015
 
1016
      `cpus_write3: begin // continue write #3
1017
 
1018
         if (!waitr) begin // no wait selected, otherwise cycle
1019
 
1020
            writemem <= 0; // disable write memory data
1021
            state <= `cpus_write4; // idle hold time
1022
 
1023
         end
1024
 
1025
      end
1026
 
1027
      `cpus_write4: begin // continue write #4
1028
 
1029
         dataeno <= 0; // disable output data
1030
         state <= nextstate; // get next macro state
1031
         statesel <= statesel+1; // and index next in macro 
1032
 
1033
      end
1034
 
1035
      //
1036
      // single byte read, reads rdatahold from the raddrhold address
1037
      //
1038
 
1039
      `cpus_read: begin
1040
 
1041
         addr <= raddrhold; // place address on output
1042
         raddrhold <= raddrhold+1; // next address
1043
         readmem <= 1; // activate instruction memory read
1044
         state <= `cpus_read2; // next state
1045
 
1046
      end
1047
 
1048
      `cpus_read2: begin // continue read #2
1049
 
1050
         if (!waitr) begin // no wait selected, otherwise cycle
1051
 
1052
            rdatahold2 <= rdatahold; // shift data
1053
            rdatahold <= data; // read new data
1054
            readmem <= 0; // deactivate instruction memory read
1055
            state <= nextstate; // get next macro state
1056
            statesel <= statesel+1; // and index next in macro 
1057
 
1058
         end
1059
 
1060
      end
1061
 
1062
      `cpus_pop: begin // finish POP instruction
1063
 
1064
         case (popdes) // register set
1065
 
1066
            2'b00: { regfil[`reg_b], regfil[`reg_c] } <=
1067
                      { rdatahold, rdatahold2 };
1068
            2'b01: { regfil[`reg_d], regfil[`reg_e] } <=
1069
                      { rdatahold, rdatahold2 };
1070
            2'b10: { regfil[`reg_h], regfil[`reg_l] } <=
1071
                      { rdatahold, rdatahold2 };
1072
            2'b11: begin
1073
 
1074
               regfil[`reg_a] <= rdatahold;
1075
               sign <= rdatahold2 >> 7&1;
1076
               zero <= rdatahold2 >> 6&1;
1077
               auxcar <= rdatahold2 >> 4&1;
1078
               parity <= rdatahold2 >> 2&1;
1079
               carry <= rdatahold2 >> 1&1;
1080
 
1081
            end
1082
 
1083
         endcase
1084
         state <= `cpus_fetchi; // Fetch next instruction
1085
 
1086
      end
1087
 
1088
      `cpus_jmp: begin // jump address
1089
 
1090
         state <= `cpus_fetchi; // and return to instruction fetch
1091
         pc <= { rdatahold, rdatahold2 };
1092
 
1093
      end
1094
 
1095
      `cpus_in: begin // input single byte to A
1096
 
1097
         addr <= rdatahold; // place I/O address on address lines
1098
         readio <= 1; // set read I/O
1099
         state <= `cpus_in2; // continue
1100
 
1101
      end
1102
 
1103
      `cpus_in2: begin // input single byte to A #2
1104
 
1105
         regfil[`reg_a] <= data; // place input data
1106
         readio <= 0; // clear read I/O
1107
         state <= `cpus_fetchi; // Fetch next instruction
1108
 
1109
      end
1110
 
1111
      `cpus_out: begin // output single byte from A
1112
 
1113
         addr <= rdatahold; // place address on output
1114
         datao <= regfil[`reg_a]; // set data to output
1115
         dataeno <= 1; // enable output data
1116
         state <= `cpus_out2; // next state
1117
 
1118
      end
1119
 
1120
      `cpus_out2: begin // continue out #2
1121
 
1122
         writeio <= 1; // enable write I/O data
1123
         state <= `cpus_out3; // idle one cycle for write
1124
 
1125
      end
1126
 
1127
      `cpus_out3: begin // continue out #3
1128
 
1129
         writeio <= 0; // disable write I/O data
1130
         state <= `cpus_out4; // idle hold time
1131
 
1132
      end
1133
 
1134
      `cpus_out4: begin // continue write #4
1135
 
1136
         dataeno <= 0; // disable output data
1137
         state <= `cpus_fetchi; // Fetch next instruction
1138
 
1139
      end
1140
 
1141
      `cpus_halt: begin // Halt waiting for interrupt
1142
 
1143
         // nothing to do, we leave the state at halt, which will cause it to
1144
         // be executed continually until we exit.
1145
 
1146
      end
1147
 
1148
      `cpus_movtr: begin // move to register
1149
 
1150
         regfil[regd] <= rdatahold; // place data
1151
         state <= nextstate; // get next macro state
1152
         statesel <= statesel+1; // and index next in macro 
1153
 
1154
      end
1155
 
1156
      `cpus_alucb: begin // alu cycleback
1157
 
1158
         regfil[`reg_a] <= alures; // place alu result back to A
1159
         carry <= alucout; // place carry
1160
         sign <= alusout; // place sign
1161
         zero <= aluzout; // place zero
1162
         parity <= alupar; // place parity
1163
         auxcar <= aluaxc; // place auxiliary carry
1164
         state <= `cpus_fetchi; // and return to instruction fetch
1165
 
1166
      end
1167
 
1168
      `cpus_indcb: begin // inr/dcr cycleback
1169
 
1170
         regfil[regd] <= alures; // place alu result back to source/dest
1171
         sign <= alures[7]; // place sign
1172
         zero <= aluzout; // place zero
1173
         parity <= alupar; // place parity
1174
         auxcar <= aluaxc; // place auxiliary carry
1175
         state <= `cpus_fetchi; // and return to instruction fetch
1176
 
1177
      end
1178
 
1179
      `cpus_movmtbc: begin // finish LXI B
1180
 
1181
         regfil[`reg_b] <= rdatahold; // place upper
1182
         regfil[`reg_c] <= rdatahold2; // place lower
1183
         state <= `cpus_fetchi; // and return to instruction fetch
1184
 
1185
      end
1186
 
1187
      `cpus_movmtde: begin // finish LXI D
1188
 
1189
         regfil[`reg_d] <= rdatahold; // place upper
1190
         regfil[`reg_e] <= rdatahold2; // place lower
1191
         state <= `cpus_fetchi; // and return to instruction fetch
1192
 
1193
      end
1194
 
1195
      `cpus_movmthl: begin // finish LXI H
1196
 
1197
         regfil[`reg_h] <= rdatahold; // place upper
1198
         regfil[`reg_l] <= rdatahold2; // place lower
1199
         state <= `cpus_fetchi; // and return to instruction fetch
1200
 
1201
      end
1202
 
1203
      `cpus_movmtsp: begin // finish LXI SP
1204
 
1205
         sp <= { rdatahold, rdatahold2 }; // place
1206
         state <= `cpus_fetchi; // and return to instruction fetch
1207
 
1208
      end
1209
 
1210
      `cpus_movrtw: begin // move read to write
1211
 
1212
         wdatahold <= rdatahold; // move read to write data
1213
         state <= nextstate; // get next macro state
1214
         statesel <= statesel+1; // and index next in macro 
1215
 
1216
      end
1217
 
1218
      `cpus_movrtwa: begin // move read data to write address
1219
 
1220
         waddrhold <= { rdatahold, rdatahold2 };
1221
         state <= nextstate; // get next macro state
1222
         statesel <= statesel+1; // and index next in macro 
1223
 
1224
      end
1225
 
1226
      `cpus_movrtra: begin // move read data to read address
1227
 
1228
         raddrhold <= { rdatahold, rdatahold2 };
1229
         state <= nextstate; // get next macro state
1230
         statesel <= statesel+1; // and index next in macro 
1231
 
1232
      end
1233
 
1234
      `cpus_lhld: begin // load HL from read data
1235
 
1236
         regfil[`reg_l] <= rdatahold2; // low
1237
         regfil[`reg_h] <= rdatahold; // high
1238
         state <= nextstate; // get next macro state
1239
         statesel <= statesel+1; // and index next in macro 
1240
 
1241
      end
1242
 
1243
      `cpus_accimm: begin
1244
 
1245
         aluoprb <= rdatahold; // load as alu b
1246
         state <= `cpus_alucb; // go to alu cycleback
1247
 
1248
      end
1249
 
1250
      `cpus_daa: begin
1251
 
1252
         if (regfil[`reg_a][7:4] > 9 || carry) begin
1253
 
1254
            { carry, regfil[`reg_a] } <= regfil[`reg_a]+8'h60;
1255
 
1256
         end
1257
         state <= `cpus_fetchi; // and return to instruction fetch
1258
 
1259
      end
1260
 
1261
      default: state <= 5'bx;
1262
 
1263
   endcase
1264
 
1265
   // Enable drive for data output
1266
   assign data = dataeno ? datao: 8'bz;
1267
 
1268
   //
1269
   // State macro generator
1270
   //
1271
   // This ROM contains series of state execution lists that perform various
1272
   // tasks, usually involving reads or writes.
1273
   //
1274
 
1275
   always @(statesel) case (statesel)
1276
 
1277
      // mac_writebyte: write a byte
1278
 
1279
       1: nextstate = `cpus_fetchi; // fetch next instruction
1280
 
1281
      // mac_readbtoreg: read a byte, place in register
1282
 
1283
       2: nextstate = `cpus_movtr; // move to register
1284
       3: nextstate = `cpus_fetchi; // Fetch next instruction
1285
 
1286
      // mac_readdtobc: read double byte to BC
1287
 
1288
       4: nextstate = `cpus_read; // get high byte
1289
       5: nextstate = `cpus_movmtbc; // place in BC
1290
 
1291
      // mac_readdtode: read double byte to DE
1292
 
1293
       6: nextstate = `cpus_read; // get high byte
1294
       7: nextstate = `cpus_movmtde; // place in DE
1295
 
1296
      // mac_readdtohl: read double byte to HL
1297
 
1298
       8: nextstate = `cpus_read; // get high byte
1299
       9: nextstate = `cpus_movmthl; // place in HL
1300
 
1301
      // mac_readdtosp: read double byte to SP
1302
 
1303
      10: nextstate = `cpus_read; // get high byte
1304
      11: nextstate = `cpus_movmtsp; // place in SP
1305
 
1306
      // mac_readbmtw: read byte and move to write
1307
 
1308
      12: nextstate = `cpus_movrtw; // move read to write 
1309
      13: nextstate = `cpus_fetchi; // Fetch next instruction
1310
 
1311
      // mac_readbmtr: read byte and move to register
1312
 
1313
      14: nextstate = `cpus_movtr; // place in register
1314
      15: nextstate = `cpus_fetchi; // Fetch next instruction
1315
 
1316
      // mac_sta: STA
1317
 
1318
      16: nextstate = `cpus_read; // read high byte
1319
      17: nextstate = `cpus_movrtwa; // move read to write address
1320
      18: nextstate = `cpus_write; // write to destination
1321
      19: nextstate = `cpus_fetchi; // Fetch next instruction
1322
 
1323
      // mac_lda: LDA
1324
 
1325
      20: nextstate = `cpus_read; // read high byte
1326
      21: nextstate = `cpus_movrtra; // move read to write address
1327
      22: nextstate = `cpus_read; // read byte
1328
      23: nextstate = `cpus_movtr; // move to register
1329
      24: nextstate = `cpus_fetchi; // Fetch next instruction
1330
 
1331
      // mac_shld: SHLD
1332
 
1333
      25: nextstate = `cpus_read; // read high byte
1334
      26: nextstate = `cpus_movrtwa; // move read to write address
1335
      27: nextstate = `cpus_write; // write to destination low
1336
      28: nextstate = `cpus_write; // write to destination high
1337
      29: nextstate = `cpus_fetchi; // Fetch next instruction
1338
 
1339
      // mac_lhld: LHLD
1340
 
1341
      30: nextstate = `cpus_read; // read high byte
1342
      31: nextstate = `cpus_movrtra; // move read to write address
1343
      32: nextstate = `cpus_read; // read byte low
1344
      33: nextstate = `cpus_read; // read byte high
1345
      34: nextstate = `cpus_lhld; // move to register
1346
      35: nextstate = `cpus_fetchi; // Fetch next instruction
1347
 
1348
      // mac_writedbyte: write double byte
1349
 
1350
      36: nextstate = `cpus_write; // double write
1351
      37: nextstate = `cpus_fetchi; // then fetch
1352
 
1353
      // mac_pop: POP
1354
 
1355
      38: nextstate = `cpus_read; // double it
1356
      39: nextstate = `cpus_pop; // then finish
1357
 
1358
      // mac_xthl: XTHL
1359
 
1360
      40: nextstate = `cpus_read; // double it
1361
      41: nextstate = `cpus_write; // then write
1362
      42: nextstate = `cpus_write; // double it
1363
      43: nextstate = `cpus_movmthl; // place word in hl
1364
 
1365
      // mac_accimm: accumulator immediate
1366
 
1367
      44: nextstate = `cpus_accimm; // finish
1368
 
1369
      // mac_jmp: JMP
1370
 
1371
      45: nextstate = `cpus_read; // double read
1372
      46: nextstate = `cpus_jmp; // then go pc
1373
 
1374
      // mac_call: CALL
1375
 
1376
      47: nextstate = `cpus_read; // double read
1377
      48: nextstate = `cpus_write; // then write
1378
      49: nextstate = `cpus_write; // double write
1379
      50: nextstate = `cpus_jmp; // then go to that
1380
 
1381
      // mac_in: IN
1382
 
1383
      51: nextstate = `cpus_in; // go to IN after getting that
1384
 
1385
      // mac_out: OUT
1386
 
1387
      52: nextstate = `cpus_out; // go to OUT after getting that
1388
 
1389
      // mac_rst: RST
1390
 
1391
      53: nextstate = `cpus_write; // double write
1392
      54: nextstate = `cpus_jmp; // then go to that
1393
 
1394
      default nextstate = 6'bx; // other states never reached
1395
 
1396
   endcase
1397
 
1398
endmodule
1399
 
1400
//
1401
// Alu module
1402
//
1403
// Finds arithmetic operations needed. Latches on the positive edge of the
1404
// clock. There are 8 different types of operations, which come from bits
1405
// 3-5 of the instruction.
1406
//
1407
 
1408
module alu(res, opra, oprb, cin, cout, zout, sout, parity, auxcar, sel);
1409
 
1410
   input  [7:0] opra;   // Input A
1411
   input  [7:0] oprb;   // Input B
1412
   input        cin;    // Carry in
1413
   output       cout;   // Carry out
1414
   output       zout;   // Zero out
1415
   output       sout;   // Sign out
1416
   output       parity; // parity
1417
   output       auxcar; // auxiliary carry
1418
   input  [2:0] sel;    // Operation select
1419
   output [7:0] res;    // Result of alu operation
1420
 
1421
   reg       cout;   // Carry out
1422
   reg       zout;   // Zero out
1423
   reg       sout;   // sign out
1424
   reg       parity; // parity
1425
   reg       auxcar; // auxiliary carry
1426
   reg [7:0] resi;   // Result of alu operation intermediate
1427
   reg [7:0] res;    // Result of alu operation
1428
 
1429
   always @(opra, oprb, cin, sel, res, resi) begin
1430
 
1431
      case (sel)
1432
 
1433
         `aluop_add: begin // add
1434
 
1435
            { cout, resi } = opra+oprb; // find result and carry
1436
            auxcar = (opra[3:0]+oprb[3:0]) >> 4 & 1; // find auxiliary carry
1437
 
1438
         end
1439
         `aluop_adc: begin // adc
1440
 
1441
            { cout, resi } = opra+oprb+cin; // find result and carry
1442
            auxcar = (opra[3:0]+oprb[3:0]+cin) >> 4 & 1; // find auxiliary carry
1443
 
1444
         end
1445
         `aluop_sub, `aluop_cmp: begin // sub/cmp
1446
 
1447
            { cout, resi } = opra-oprb; // find result and carry
1448
            auxcar = (opra[3:0]-oprb[3:0]) >> 4 & 1; // find auxiliary borrow
1449
 
1450
         end
1451
         `aluop_sbb: begin // sbb
1452
 
1453
            { cout, resi } = opra-oprb-cin; // find result and carry
1454
            auxcar = (opra[3:0]-oprb[3:0]-cin >> 4) & 1; // find auxiliary borrow
1455
 
1456
         end
1457
         `aluop_and: begin // ana
1458
 
1459
            { cout, resi } = {1'b0, opra&oprb}; // find result and carry
1460
            auxcar = 0; // clear auxillary carry
1461
 
1462
          end
1463
         `aluop_xor: begin // xra
1464
 
1465
            { cout, resi } = {1'b0, opra^oprb}; // find result and carry
1466
            auxcar = 0; // clear auxillary carry
1467
 
1468
         end
1469
         `aluop_or:  begin // ora
1470
 
1471
            { cout, resi } = {1'b0, opra|oprb}; // find result and carry
1472
            auxcar = 0; // clear auxillary carry
1473
 
1474
         end
1475
 
1476
      endcase
1477
 
1478
      if (sel != `aluop_cmp) res = resi; else res = opra;
1479
      zout <= ~|resi; // set zero flag from result
1480
      sout <= resi[7]; // set sign flag from result
1481
      parity <= ~^resi; // set parity flag from result
1482
 
1483
   end
1484
 
1485
endmodule

powered by: WebSVN 2.1.0

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