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

Subversion Repositories aoocs

[/] [aoocs/] [trunk/] [rtl/] [ocs_input.v] - Rev 2

Compare with Previous | Blame | View Log

/*
 * 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
 * \brief OCS user input implementation with WISHBONE slave interface.
 */
 
/*! \brief \copybrief ocs_input.v
 
List of user input registers:
\verbatim
Implemented:
     [DSKDATR & *008  ER  P       Disk data early read (dummy address)          not implemented]
    JOY0DAT     *00A  R   D       Joystick-mouse 0 data (vert,horiz)            read implemented here
 
    JOY1DAT     *00C  R   D       Joystick-mouse 1 data (vert,horiz)            read implemented here
     [CLXDAT    *00E  R   D       Collision data register (read and clear)      read implemented here]
 
    JOYTEST     *036  W   D       Write to all four joystick-mouse counters at once
 
Not implemented:
     [ADKCONR   *010  R   P       Audio, disk control register read             read not implemented here]
    POT0DAT     *012  R   P( E )  Pot counter pair 0 data (vert,horiz)          read not implemented here
 
    POT1DAT     *014  R   P( E )  Pot counter pair 1 data (vert,horiz)          
    POTGOR      *016  R   P       Pot port data read (formerly POTINP)
    POTGO       *034  W   P       Pot port data write and start
\endverbatim
*/
module ocs_input(
    //% \name Clock and reset
    //% @{
    input               CLK_I,
    input               reset_n,
    //% @}
 
    //% \name On-Screen-Display management interface
    //% @{
    input               on_screen_display,
    input               enable_joystick_1,
    //% @}
 
    //% \name WISHBONE slave
    //% @{
    input               CYC_I,
    input               STB_I,
    input               WE_I,
    input [8:2]         ADR_I,
    input [3:0]         SEL_I,
    input [31:0]        DAT_I,
    output reg [31:0]   DAT_O,
    output reg          ACK_O,
    //% @}
 
    //% \name Not aligned register access on a 32-bit WISHBONE bus
    //% @{
        // CLXDAT read implemented here
    output              na_clx_dat_read,
    input [15:0]        na_clx_dat,
        // POT0DAT read not implemented here
    input               na_pot0dat_read,
    output [15:0]       na_pot0dat,
    //% @}
 
    //% \name User input CIA interface
    //% @{
    // keyboard output
    input               sp_from_cia,
    output              sp_to_cia,
    output reg          cnt_to_cia,
 
    // CIA-A fire buttons
    output reg          ciaa_fire_0_n,
    output              ciaa_fire_1_n,
    //% @}
 
    //% \name drv_keyboard interface
    //% @{
    output              keyboard_ready,
    input               keyboard_event,
    input [7:0]         keyboard_scancode,
 
    // joystick on port 1
    input               joystick_1_up,
    input               joystick_1_down,
    input               joystick_1_left,
    input               joystick_1_right,
    input               joystick_1_fire,
    //% @}
 
    //% \name drv_mouse interface
    //% @{
    input               mouse_moved,
    input [8:0]         mouse_y_move,
    input [8:0]         mouse_x_move,
    input               mouse_left_button,
    input               mouse_right_button,
    input               mouse_middle_button
    //% @}
);
 
//-------------------- keyboard start
assign sp_to_cia = ~sp_shift[7];
 
assign keyboard_ready = (cnt_counter == 16'd0);
 
 
reg [15:0] cnt_counter;
reg [7:0] sp_shift;
always @(posedge CLK_I or negedge reset_n) begin
    if(reset_n == 1'b0) begin
        cnt_to_cia  <= 1'b1;
        cnt_counter <= 16'd0;
        sp_shift    <= 8'hFF;
    end
    else if(keyboard_event == 1'b1 && on_screen_display == 1'b0) begin
        sp_shift <= keyboard_scancode;
        cnt_counter <= cnt_counter + 16'd1;
        cnt_to_cia <= 1'b0;
    end
    else if(cnt_counter >= 16'd1 && cnt_counter <= 16'd15) begin
        cnt_counter <= cnt_counter + 16'd1;
        cnt_to_cia <= ~cnt_to_cia;
        if(cnt_to_cia == 1'b1) sp_shift <= { sp_shift[6:0], 1'b0 };
    end
    else if(cnt_counter == 16'd16 && sp_from_cia == 1'b0) begin
        cnt_counter <= cnt_counter + 16'd1;
    end
    else if(cnt_counter == 16'd17 && sp_from_cia == 1'b1) begin
        cnt_counter <= 16'd0;
    end
/*  synchronization
    else if(cnt_counter == 16'd65535 && sp_from_cia == 1'b1) begin
        cnt_to_cia <= ~cnt_to_cia;
        cnt_counter <= 16'd16;
    end
    else if(cnt_counter >= 16'd16 && sp_from_cia == 1'b1) begin
        cnt_counter <= cnt_counter + 16'd1;
    end
    else sp_from_cia == 1'b0 -> sp_from_cia == 1'b0 begin
        cnt_counter <= 16'd0;
    end
*/
end
//-------------------- keyboard end
 
 
assign na_pot0dat = 16'd0;
 
assign na_clx_dat_read =
    (CYC_I == 1'b1 && STB_I == 1'b1 && ACK_O == 1'b0 && WE_I == 1'b0 && { ADR_I, 2'b0 } == 9'h018 && SEL_I[1:0] != 2'b00);
 
reg [15:0] potgo;
reg [15:0] joy0dat;
reg [15:0] joy1dat;
reg right_button_n;
reg middle_button_n;
 
wire [15:0] joy1dat_final;
assign joy1dat_final =
    (enable_joystick_1 == 1'b1)?
    {   6'b0,                               //15-10
        joystick_1_left,                    //9
        joystick_1_up ^ joystick_1_left,    //8
        6'b0,                               //7-2
        joystick_1_right,                   //1
        joystick_1_down ^ joystick_1_right  //0
    } :
    joy1dat;
 
assign ciaa_fire_1_n = (enable_joystick_1 == 1'b1 && joystick_1_fire == 1'b1)? 1'b0 : 1'b1;
 
wire [15:0] potgo_final;
assign potgo_final = { 1'b0, potgo[14], 1'b0, potgo[12], 1'b0, right_button_n, 1'b0, middle_button_n, 7'b0, 1'b0 };
 
wire [8:0] joy0dat_y;
assign joy0dat_y = { joy0dat[15], joy0dat[15:8] } - mouse_y_move;
 
wire [8:0] joy0dat_x;
assign joy0dat_x = { joy0dat[7], joy0dat[7:0] } + mouse_x_move;
 
always @(posedge CLK_I or negedge reset_n) begin
    if(reset_n == 1'b0) begin
        DAT_O           <= 32'd0;
        ACK_O           <= 1'b0;
 
        ciaa_fire_0_n   <= 1'b1;
 
        potgo           <= 16'd0;
        joy0dat         <= 16'd0;
        joy1dat         <= 16'd0;
 
        right_button_n  <= 1'b1;
        middle_button_n <= 1'b1;
    end
    else begin
        if(CYC_I == 1'b1 && STB_I == 1'b1 && ACK_O == 1'b0) ACK_O <= 1'b1;
        else                                                ACK_O <= 1'b0;
 
        if(mouse_moved == 1'b1) begin
            joy0dat[15:8] <= joy0dat_y[7:0];
            joy0dat[7:0] <= joy0dat_x[7:0];
 
            ciaa_fire_0_n   <= ~mouse_left_button;
            right_button_n  <= ~mouse_right_button;
            middle_button_n <= ~mouse_middle_button;
        end
 
        if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b0) begin
            if({ ADR_I, 2'b0 } == 9'h008)                       DAT_O[31:0]     <= { 16'd0 /*DSKDATR*/, joy0dat };
            if({ ADR_I, 2'b0 } == 9'h00C)                       DAT_O[31:0]     <= { joy1dat_final, na_clx_dat };
            if({ ADR_I, 2'b0 } == 9'h014)                       DAT_O[31:0]     <= { 16'd0 /*POT1DAT*/, potgo_final };
        end
        else if(CYC_I == 1'b1 && STB_I == 1'b1 && WE_I == 1'b1) begin
            if({ ADR_I, 2'b0 } == 9'h034 && SEL_I[3] == 1'b1)   potgo[15:8] <= DAT_I[31:24];
            if({ ADR_I, 2'b0 } == 9'h034 && SEL_I[2] == 1'b1)   potgo[7:0]  <= DAT_I[23:16];
            if({ ADR_I, 2'b0 } == 9'h034 && SEL_I[1] == 1'b1)   { joy0dat[15:8], joy1dat[15:8] } <= { DAT_I[15:8], DAT_I[15:8] };
            if({ ADR_I, 2'b0 } == 9'h034 && SEL_I[0] == 1'b1)   { joy0dat[7:0], joy1dat[7:0] } <= { DAT_I[7:0], DAT_I[7:0] };
        end
    end
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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