6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Tue Jun 04, 2024 1:35 pm

All times are UTC




Post new topic Reply to topic  [ 17 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Mon Oct 05, 2020 2:43 pm 
Offline
User avatar

Joined: Sun Nov 27, 2011 12:03 pm
Posts: 229
Location: Amsterdam, Netherlands
Since no core I tried is consistent with the real 65C02 when it comes to 'decimal mode' results for non-BCD operands, here is a piece of Verilog that I created for my own 65C02 core, that actually is consistent with the real thing.

Note that C is valid as well, and N and Z are 'result[7]' and 'result == 8'h00' as usual. Make up your very own V flag (personally, I find the notion that BCD numbers can be negative and specifically, then, 0x80 and up, ludicrous and completely arbitrary).

Enjoy (if this is useful to you).

Code:

module BCD_ADD
(
   a_in,
   data_in,
   carry_in,
   fixup_in,
   sbc_else_adc,
   data_out,
   carry_out,
   fixup_out
);

   input  [3:0] a_in;
   input  [3:0] data_in;
   input        carry_in;
   input        fixup_in;
   input        sbc_else_adc;
   output [3:0] data_out;
   output       carry_out;
   output       fixup_out;

   wire [3:0] adder_data;
   wire [4:0] adder_result;
   wire       adder_carry;
   wire       digit_not_bcd;
   reg  [3:0] digit_add_data;
   reg        digit_add_carry;
   wire [4:0] digit_result;

   assign adder_data = sbc_else_adc ? ~data_in : data_in;

   assign adder_result = a_in + adder_data + carry_in;

   assign adder_carry = adder_result[4];

   assign digit_not_bcd = (adder_result[3:0] > 4'd9);

   always @(*)
     casex ({ sbc_else_adc, adder_carry, digit_not_bcd })
       3'b000 : { digit_add_data, digit_add_carry } = { 4'h0, 1'b0     };
       3'b0xx : { digit_add_data, digit_add_carry } = { 4'h6, 1'b0     };
       3'b10x : { digit_add_data, digit_add_carry } = { 4'h9, fixup_in };
       3'b11x : { digit_add_data, digit_add_carry } = { 4'hF, fixup_in };
     endcase

   assign digit_result = adder_result[3:0] + digit_add_data + digit_add_carry;

   assign data_out = digit_result[3:0];

   assign carry_out = adder_carry | (~sbc_else_adc & digit_not_bcd);

   assign fixup_out = digit_result[4];

endmodule

BCD_ADD nibble_0
(
  .a_in(a_in[3:0]),
  .data_in(data_in[3:0]),
  .carry_in(carry_in),
  .fixup_in(1'b1),
  .sbc_else_adc(operation[2]),
  .data_out(d_adder_result[3:0]),
  .carry_out(d_nibble_carry),
  .fixup_out(d_nibble_fixup)
);

BCD_ADD nibble_1
(
  .a_in(a_in[7:4]),
  .data_in(data_in[7:4]),
  .carry_in(d_nibble_carry),
  .fixup_in(d_nibble_fixup),
  .sbc_else_adc(operation[2]),
  .data_out(d_adder_result[7:4]),
  .carry_out(d_adder_result[8]),
  .fixup_out()
);



Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 05, 2020 6:51 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
I think I would take the convention that V represents an overflow from bit 6 to bit 7. It's not very useful, but it's consistent with the binary operation.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: No registered users and 27 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: