module timer
(
    input clk,
    input reset,
    input [7:0] i_data,
    output logic [7:0] o_data,
    input cs,
    input rwb,
    input [1:0] addr,
    output logic irqb
);

//new idea for timer:
//it can either be oneshot or repeating
//it can either cause an interrupt or not.
//if you want it to do both, add another timer.

/*
Addr	Read	        Write
0	    Counter Low	    Latch Low
1	    Counter High	Latch High
2	    Divisor	        Divisor
3	    Status	        Control
*/

logic [15:0] timer_latch, timer_counter;

//control register
// bit 0: Enable interrupts
// bit 1: Enable 1 shot mode

//writing to latch low starts the timer

logic [7:0] divisor, status, control;

logic count_en;

assign status[0] = count_en;

logic [15:0] pulsecount;

//I think this should be negedge so that writes go through
always @(negedge clk) begin
    if (reset) begin
        count_en = '0;
        timer_counter <= '0;
        pulsecount <= '0;
        timer_latch <= '1;
        divisor <= '0;
        control <= '0;
        irqb <= '1;
    end else begin

        if (count_en) begin
            if (pulsecount[15:8] == divisor) begin
                timer_counter <= timer_counter + 16'b1;
                pulsecount <= '0;
            end else begin
                pulsecount <= pulsecount + 16'b1;
            end
        end

        if (timer_counter == timer_latch) begin
            // if interrupts are enabled
            if (control[0]) begin
                irqb <= '0;
            end

            // if oneshot mode is enabled
            if (control[1]) begin
                count_en <= '0;
            end else begin
                timer_counter <= '0;
            end

        end

        if (cs & rwb) begin
            irqb <= '1;
        end

        if (cs & ~rwb) begin
            case (addr)
                2'h0: begin
                    count_en <= '1;
                    timer_latch[7:0] <= i_data;
                end

                2'h1: begin
                    timer_latch[15:8] <= i_data;
                end

                2'h2: begin
                    divisor <= i_data;
                end

                2'h3: begin
                    control <= i_data;
                end
            endcase
        end

    end
end

always_comb begin
    o_data = '0;

    unique case (addr)
        2'h0: begin
            o_data = timer_counter[7:0];
        end

        2'h1: begin
            o_data = timer_counter[15:8];
        end

        2'h2: begin
            o_data = divisor;
        end

        2'h3: begin
            o_data = status;
        end

        default: o_data = 'x;

    endcase
end



endmodule
