Spectrum test16

This commit is contained in:
antoniovillena 2016-04-28 14:25:04 +02:00
parent e2c0e4c711
commit 27832d8152
24 changed files with 18535 additions and 94 deletions

70
cores/Spectrum/coreid.v Normal file
View File

@ -0,0 +1,70 @@
`timescale 1ns / 1ps
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 18:22:21 06/07/2015
// Design Name:
// Module Name: coreid
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module coreid (
input wire clk,
input wire rst_n,
input wire [7:0] zxuno_addr,
input wire zxuno_regrd,
input wire regaddr_changed,
output wire [7:0] dout,
output wire oe_n
);
reg [7:0] text[0:15];
integer i;
initial begin
for (i=0;i<16;i=i+1)
text[i] = 8'h00;
text[ 0] = "T";
text[ 1] = "1";
text[ 2] = "6";
text[ 3] = "-";
text[ 4] = "1";
text[ 5] = "4";
text[ 6] = "0";
text[ 7] = "6";
text[ 8] = "2";
text[ 9] = "0";
text[10] = "1";
text[11] = "5";
end
reg [3:0] textindx = 4'h0;
reg reading = 1'b0;
assign oe_n = !(zxuno_addr == 8'hFF && zxuno_regrd==1'b1);
assign dout = (oe_n==1'b0)? text[textindx] : 8'hZZ;
always @(posedge clk) begin
if (rst_n == 1'b0 || (regaddr_changed==1'b1 && zxuno_addr==8'hFF)) begin
textindx <= 4'h0;
reading <= 1'b0;
end
else if (oe_n==1'b0) begin
reading <= 1'b1;
end
else if (reading == 1'b1 && oe_n==1'b1) begin
reading <= 1'b0;
textindx <= textindx + 1;
end
end
endmodule

View File

@ -0,0 +1,488 @@
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char BYTE;
/*
8 8 3 5 3 5
AAADDDDD AAADDDDD MRN JJJJJ MMM XXXXX
AAA = semifila del teclado a modificar | esta información está
DDDDD = dato (AND negado con lo que haya) de esa semifila | repetida para dos teclas
MRN = Master reset, Reset de usuario, NMI
JJJJJ = estado del joystick al pulsar tecla. Posiciones UDLRX
MMM = la tecla es un modificador
XXXXX = Reservado para uso futuro
Ej: en la dirección de memoria correspondiente al código de la tecla ESC,
que correspondería a la pulsación simultánea de CAPS SHIFT+SPACE, pondríamos:
00000001 11100001 000 00000 000 00000
Esto es: se activan las semifilas 0 y 7, y en cada una, se activa el bit 0
256 codigos + E0 = 512 codigos
SHIFT, CTRL, ALT = 8 combinaciones
512*8=4096 direcciones x 32 bits = 16384 bytes
En el core se dispondrá como una memoria de 16384x8 bits
Cada tecla ocupará cuatro direcciones consecutivas.
D+0 : tecla1 (o 0 si no la hay)
D+1 : tecla2 (o 0 si no la hay)
D+2 : señales de reset y joystick, 0 si no hay
D+3 : modificadores y señales de usuario, 0 si no hay
*/
// You shouldn't have to touch these defs unless your Spectrum has a different keyboard
// layout (because, for example, you are using a different ROM
#define SP_1 0x61
#define SP_2 0x62
#define SP_3 0x64
#define SP_4 0x68
#define SP_5 0x70
#define SP_0 0x81
#define SP_9 0x82
#define SP_8 0x84
#define SP_7 0x88
#define SP_6 0x90
#define SP_Q 0x41
#define SP_W 0x42
#define SP_E 0x44
#define SP_R 0x48
#define SP_T 0x50
#define SP_P 0xA1
#define SP_O 0xA2
#define SP_I 0xA4
#define SP_U 0xA8
#define SP_Y 0xB0
#define SP_A 0x21
#define SP_S 0x22
#define SP_D 0x24
#define SP_F 0x28
#define SP_G 0x30
#define SP_ENTER 0xC1
#define SP_L 0xC2
#define SP_K 0xC4
#define SP_J 0xC8
#define SP_H 0xD0
#define SP_CAPS 0x01
#define SP_Z 0x02
#define SP_X 0x04
#define SP_C 0x08
#define SP_V 0x10
#define SP_SPACE 0xE1
#define SP_SYMBOL 0xE2
#define SP_M 0xE4
#define SP_N 0xE8
#define SP_B 0xF0
#define SP_BANG (SP_SYMBOL<<8) | SP_1
#define SP_AT (SP_SYMBOL<<8) | SP_2
#define SP_HASH (SP_SYMBOL<<8) | SP_3
#define SP_DOLLAR (SP_SYMBOL<<8) | SP_4
#define SP_PERCEN (SP_SYMBOL<<8) | SP_5
#define SP_AMP (SP_SYMBOL<<8) | SP_6
#define SP_APOSTRO (SP_SYMBOL<<8) | SP_7
#define SP_PAROPEN (SP_SYMBOL<<8) | SP_8
#define SP_PARCLOS (SP_SYMBOL<<8) | SP_9
#define SP_UNDERSC (SP_SYMBOL<<8) | SP_0
#define SP_LESS (SP_SYMBOL<<8) | SP_R
#define SP_LESSEQ (SP_SYMBOL<<8) | SP_Q
#define SP_GREATER (SP_SYMBOL<<8) | SP_T
#define SP_GREATEQ (SP_SYMBOL<<8) | SP_E
#define SP_NOTEQ (SP_SYMBOL<<8) | SP_W
#define SP_BRAOPEN (SP_SYMBOL<<8) | SP_Y
#define SP_BRACLOS (SP_SYMBOL<<8) | SP_U
#define SP_SEMICOL (SP_SYMBOL<<8) | SP_O
#define SP_QUOTE (SP_SYMBOL<<8) | SP_P
#define SP_TILDE (SP_SYMBOL<<8) | SP_A
#define SP_PIPE (SP_SYMBOL<<8) | SP_S
#define SP_BACKSLA (SP_SYMBOL<<8) | SP_D
#define SP_CUROPEN (SP_SYMBOL<<8) | SP_F
#define SP_CURCLOS (SP_SYMBOL<<8) | SP_G
#define SP_CARET (SP_SYMBOL<<8) | SP_H
#define SP_MINUS (SP_SYMBOL<<8) | SP_J
#define SP_PLUS (SP_SYMBOL<<8) | SP_K
#define SP_EQUAL (SP_SYMBOL<<8) | SP_L
#define SP_COLON (SP_SYMBOL<<8) | SP_Z
#define SP_POUND (SP_SYMBOL<<8) | SP_X
#define SP_QUEST (SP_SYMBOL<<8) | SP_C
#define SP_SLASH (SP_SYMBOL<<8) | SP_V
#define SP_STAR (SP_SYMBOL<<8) | SP_B
#define SP_COMMA (SP_SYMBOL<<8) | SP_N
#define SP_DOT (SP_SYMBOL<<8) | SP_M
#define SP_EXTEND (SP_CAPS<<8) | SP_SYMBOL
#define SP_EDIT (SP_CAPS<<8) | SP_1
#define SP_CPSLOCK (SP_CAPS<<8) | SP_2
#define SP_TRUE (SP_CAPS<<8) | SP_3
#define SP_INVERSE (SP_CAPS<<8) | SP_4
#define SP_LEFT (SP_CAPS<<8) | SP_5
#define SP_DOWN (SP_CAPS<<8) | SP_6
#define SP_UP (SP_CAPS<<8) | SP_7
#define SP_RIGHT (SP_CAPS<<8) | SP_8
#define SP_GRAPH (SP_CAPS<<8) | SP_9
#define SP_DELETE (SP_CAPS<<8) | SP_0
#define SP_BREAK (SP_CAPS<<8) | SP_SPACE
// END of Spectrum keys definitions
// Definitions for additional signals generated by the keyboard core
// AAADDDDD AAADDDDD MRN JJJJJ MMM XXXXX
#define MODIFIER1 0x20
#define MODIFIER2 0x40
#define MODIFIER3 0x80
#define MRESET 0x80
#define URESET 0x40
#define NMI 0x20
#define JOYUP 0x10
#define JOYDOWN 0x08
#define JOYLEFT 0x04
#define JOYRIGHT 0x02
#define JOYFIRE 0x01
#define USER1 0x10
#define USER2 0x08
#define USER3 0x04
#define USER4 0x02
#define USER5 0x01
// End of additional signals
// A key can be pressed with up to three key modifiers
// which generates 8 combinations for each key
#define EXT 0x100
#define MD1 0x200
#define MD2 0x400
#define MD3 0x800
// Scan code 2 list. First, non localized keys
#define PC_A 0x1C
#define PC_B 0x32
#define PC_C 0x21
#define PC_D 0x23
#define PC_E 0x24
#define PC_F 0x2B
#define PC_G 0x34
#define PC_H 0x33
#define PC_I 0x43
#define PC_J 0x3B
#define PC_K 0x42
#define PC_L 0x4B
#define PC_M 0x3A
#define PC_N 0x31
#define PC_O 0x44
#define PC_P 0x4D
#define PC_Q 0x15
#define PC_R 0x2D
#define PC_S 0x1B
#define PC_T 0x2C
#define PC_U 0x3C
#define PC_V 0x2A
#define PC_W 0x1D
#define PC_X 0x22
#define PC_Y 0x35
#define PC_Z 0x1A
#define PC_0 0x45
#define PC_1 0x16
#define PC_2 0x1E
#define PC_3 0x26
#define PC_4 0x25
#define PC_5 0x2E
#define PC_6 0x36
#define PC_7 0x3D
#define PC_8 0x3E
#define PC_9 0x46
#define PC_F1 0x05
#define PC_F2 0x06
#define PC_F3 0x04
#define PC_F4 0x0C
#define PC_F5 0x03
#define PC_F6 0x0B
#define PC_F7 0x83
#define PC_F8 0x0A
#define PC_F9 0x01
#define PC_F10 0x09
#define PC_F11 0x78
#define PC_F12 0x07
#define PC_ESC 0x76
#define PC_SPACE 0x29
#define PC_LCTRL 0x14
#define PC_RCTRL 0x14 | EXT
#define PC_LSHIFT 0x12
#define PC_RSHIFT 0x59
#define PC_LALT 0x11
#define PC_RALT 0x11 | EXT
#define PC_LWIN 0x1F | EXT
#define PC_RWIN 0x27 | EXT
#define PC_APPS 0x2F | EXT
#define PC_TAB 0x0D
#define PC_CPSLOCK 0x58
#define PC_SCRLOCK 0x7E
#define PC_INSERT 0x70 | EXT
#define PC_DELETE 0x71 | EXT
#define PC_HOME 0x6C | EXT
#define PC_END 0x69 | EXT
#define PC_PGUP 0x7D | EXT
#define PC_PGDOWN 0x7A | EXT
#define PC_BKSPACE 0x66
#define PC_ENTER 0x5A
#define PC_UP 0x75 | EXT
#define PC_DOWN 0x72 | EXT
#define PC_LEFT 0x6B | EXT
#define PC_RIGHT 0x74 | EXT
#define PC_NUMLOCK 0x77
#define PC_KP_DIVIS 0x4A | EXT
#define PC_KP_MULT 0x7C
#define PC_KP_MINUS 0x7B
#define PC_KP_PLUS 0x79
#define PC_KP_ENTER 0x5A | EXT
#define PC_KP_DOT 0x71
#define PC_KP_0 0x70
#define PC_KP_1 0x69
#define PC_KP_2 0x72
#define PC_KP_3 0x7A
#define PC_KP_4 0x6B
#define PC_KP_5 0x73
#define PC_KP_6 0x74
#define PC_KP_7 0x6C
#define PC_KP_8 0x75
#define PC_KP_9 0x7D
// Localized keyboards start to differenciate from here
// Localized keyboard ES (Spain)
#define PC_BACKSLA 0x0E
#define PC_APOSTRO 0x4E
#define PC_OPNBANG 0x55
#define PC_GRAVEAC 0x54
#define PC_PLUS 0x5B
#define PC_EGNE 0x4C
#define PC_ACUTEAC 0x52
#define PC_CEDILLA 0x5D
#define PC_LESS 0x61
#define PC_COMMA 0x41
#define PC_DOT 0x49
#define PC_MINUS 0x4A
#define MAP(pc,sp,rj,mu) { \
rom[(pc)*4] = (((sp)>>8)&0xFF); \
rom[(pc)*4+1] = (((sp))&0xFF); \
rom[(pc)*4+2] = (rj); \
rom[(pc)*4+3] = (mu); \
}
#define MAPANY(pc,sp,rj,mu) { \
MAP(pc,sp,rj,mu); \
MAP(MD1|pc,sp,rj,mu); \
MAP(MD2|pc,sp,rj,mu); \
MAP(MD3|pc,sp,rj,mu); \
MAP(MD1|MD2|pc,sp,rj,mu); \
MAP(MD1|MD3|pc,sp,rj,mu); \
MAP(MD2|MD3|pc,sp,rj,mu); \
MAP(MD1|MD2|MD3|pc,sp,rj,mu); \
}
#define CLEANMAP { \
int i; \
for (i=0;i<(sizeof(rom)/sizeof(rom[0]));i++) \
rom[i] = 0; \
}
#define SAVEMAPHEX(name) { \
FILE *f; \
int i; \
f=fopen(name,"w"); \
for(i=0;i<(sizeof(rom)/sizeof(rom[0]));i++) \
fprintf(f,"%.2X\n",rom[i]); \
fclose(f); \
}
#define SAVEMAPBIN(name) { \
FILE *f; \
int i; \
f=fopen(name,"wb"); \
fwrite (rom, 1, sizeof(rom), f); \
fclose(f); \
}
int main()
{
BYTE rom[16384];
CLEANMAP;
MAPANY(PC_LSHIFT,0,0,MODIFIER1); // MD1 is SHIFT
MAPANY(PC_RSHIFT,0,0,MODIFIER1); // MD1 is SHIFT
MAPANY(PC_LCTRL,0,0,MODIFIER2); // MD2 is CTRL
MAPANY(PC_RCTRL,0,0,MODIFIER2); // MD2 is CTRL
MAPANY(PC_LALT,0,JOYFIRE,MODIFIER3); // MD3 is ALT. Also is FIRE for keyboard joystick
MAPANY(PC_RALT,0,JOYFIRE,MODIFIER3); // MD3 is ALT. Also is FIRE for keyboard joystick
MAPANY(PC_LWIN,SP_CAPS,0,0); // CAPS SHIFT
MAPANY(PC_RWIN,SP_SYMBOL,0,0); // SYMBOL SHIFT
// Basic mapping: each key from PC is mapped to a key in the Spectrum
MAP(PC_1,SP_1,0,0);
MAP(PC_2,SP_2,0,0);
MAP(PC_3,SP_3,0,0);
MAP(PC_4,SP_4,0,0);
MAP(PC_5,SP_5,0,0);
MAP(PC_6,SP_6,0,0);
MAP(PC_7,SP_7,0,0);
MAP(PC_8,SP_8,0,0);
MAP(PC_9,SP_9,0,0);
MAP(PC_0,SP_0,0,0);
MAP(PC_Q,SP_Q,0,0);
MAP(PC_W,SP_W,0,0);
MAP(PC_E,SP_E,0,0);
MAP(PC_R,SP_R,0,0);
MAP(PC_T,SP_T,0,0);
MAP(PC_Y,SP_Y,0,0);
MAP(PC_U,SP_U,0,0);
MAP(PC_I,SP_I,0,0);
MAP(PC_O,SP_O,0,0);
MAP(PC_P,SP_P,0,0);
MAP(PC_A,SP_A,0,0);
MAP(PC_S,SP_S,0,0);
MAP(PC_D,SP_D,0,0);
MAP(PC_F,SP_F,0,0);
MAP(PC_G,SP_G,0,0);
MAP(PC_H,SP_H,0,0);
MAP(PC_J,SP_J,0,0);
MAP(PC_K,SP_K,0,0);
MAP(PC_L,SP_L,0,0);
MAP(PC_Z,SP_Z,0,0);
MAP(PC_X,SP_X,0,0);
MAP(PC_C,SP_C,0,0);
MAP(PC_V,SP_V,0,0);
MAP(PC_B,SP_B,0,0);
MAP(PC_N,SP_N,0,0);
MAP(PC_M,SP_M,0,0);
MAP(MD1|PC_Q,SP_CAPS<<8|SP_Q,0,0);
MAP(MD1|PC_W,SP_CAPS<<8|SP_W,0,0);
MAP(MD1|PC_E,SP_CAPS<<8|SP_E,0,0);
MAP(MD1|PC_R,SP_CAPS<<8|SP_R,0,0);
MAP(MD1|PC_T,SP_CAPS<<8|SP_T,0,0);
MAP(MD1|PC_Y,SP_CAPS<<8|SP_Y,0,0);
MAP(MD1|PC_U,SP_CAPS<<8|SP_U,0,0);
MAP(MD1|PC_I,SP_CAPS<<8|SP_I,0,0);
MAP(MD1|PC_O,SP_CAPS<<8|SP_O,0,0);
MAP(MD1|PC_P,SP_CAPS<<8|SP_P,0,0);
MAP(MD1|PC_A,SP_CAPS<<8|SP_A,0,0);
MAP(MD1|PC_S,SP_CAPS<<8|SP_S,0,0);
MAP(MD1|PC_D,SP_CAPS<<8|SP_D,0,0);
MAP(MD1|PC_F,SP_CAPS<<8|SP_F,0,0);
MAP(MD1|PC_G,SP_CAPS<<8|SP_G,0,0);
MAP(MD1|PC_H,SP_CAPS<<8|SP_H,0,0);
MAP(MD1|PC_J,SP_CAPS<<8|SP_J,0,0);
MAP(MD1|PC_K,SP_CAPS<<8|SP_K,0,0);
MAP(MD1|PC_L,SP_CAPS<<8|SP_L,0,0);
MAP(MD1|PC_Z,SP_CAPS<<8|SP_Z,0,0);
MAP(MD1|PC_X,SP_CAPS<<8|SP_X,0,0);
MAP(MD1|PC_C,SP_CAPS<<8|SP_C,0,0);
MAP(MD1|PC_V,SP_CAPS<<8|SP_V,0,0);
MAP(MD1|PC_B,SP_CAPS<<8|SP_B,0,0);
MAP(MD1|PC_N,SP_CAPS<<8|SP_N,0,0);
MAP(MD1|PC_M,SP_CAPS<<8|SP_M,0,0);
MAPANY(PC_SPACE,SP_SPACE,0,0);
MAPANY(PC_ENTER,SP_ENTER,0,0);
//Complex mapping. This is for the spanish keyboard although many
//combos can be used with any other PC keyboard
MAPANY(PC_ESC,SP_BREAK,0,0);
MAPANY(PC_CPSLOCK,SP_CPSLOCK,0,0);
MAPANY(PC_TAB,SP_EXTEND,0,0);
MAP(PC_BKSPACE,SP_DELETE,0,0);
MAPANY(PC_UP,SP_UP,0,0);
MAPANY(PC_DOWN,SP_DOWN,0,0);
MAPANY(PC_LEFT,SP_LEFT,0,0);
MAPANY(PC_RIGHT,SP_RIGHT,0,0);
MAPANY(PC_F2,SP_EDIT,0,0);
MAP(PC_F5|MD2|MD3,0,NMI,0); // Ctrl-Alt-F5 for NMI
MAP(PC_F10,SP_GRAPH,0,0); // F10 habilita el modo gráfico. Esto es para Antonio, para la BIOS
MAP(PC_DELETE|MD2|MD3,0,URESET,0); //
MAP(PC_KP_DOT|MD2|MD3,0,URESET,0); // Ctrl-Alt-Del for user reset
MAP(PC_BKSPACE|MD2|MD3,0,MRESET,0); // Ctrl-Alt-BkSpace for master reset
//keypad
MAPANY(PC_KP_DIVIS,SP_SLASH,0,0);
MAPANY(PC_KP_MULT,SP_STAR,0,0);
MAPANY(PC_KP_MINUS,SP_MINUS,0,0);
MAPANY(PC_KP_PLUS,SP_PLUS,0,0);
MAPANY(PC_KP_ENTER,SP_ENTER,0,0);
// a 8-way keyboard joystick on the keypad
MAPANY(PC_KP_7,0,JOYUP|JOYLEFT,0);
MAPANY(PC_KP_8,0,JOYUP,0);
MAPANY(PC_KP_9,0,JOYUP|JOYRIGHT,0);
MAPANY(PC_KP_4,0,JOYLEFT,0);
MAPANY(PC_KP_5,0,JOYDOWN,0);
MAPANY(PC_KP_6,0,JOYRIGHT,0);
MAPANY(PC_KP_1,0,JOYDOWN|JOYLEFT,0);
MAPANY(PC_KP_2,0,JOYDOWN,0);
MAPANY(PC_KP_3,0,JOYDOWN|JOYRIGHT,0);
//Some shift+key mappings for the ES keyboard
MAP(MD1|PC_1,SP_BANG,0,0);
MAP(MD1|PC_2,SP_QUOTE,0,0);
MAP(MD1|PC_3,SP_HASH,0,0);
MAP(MD1|PC_4,SP_DOLLAR,0,0);
MAP(MD1|PC_5,SP_PERCEN,0,0);
MAP(MD1|PC_6,SP_AMP,0,0);
MAP(MD1|PC_7,SP_SLASH,0,0);
MAP(MD1|PC_8,SP_PAROPEN,0,0);
MAP(MD1|PC_9,SP_PARCLOS,0,0);
MAP(MD1|PC_0,SP_EQUAL,0,0);
MAP(PC_APOSTRO,SP_APOSTRO,0,0);
MAP(MD1|PC_APOSTRO,SP_QUEST,0,0);
MAP(PC_GRAVEAC,SP_POUND,0,0);
MAP(MD1|PC_GRAVEAC,SP_CARET,0,0);
MAP(PC_PLUS,SP_PLUS,0,0);
MAP(MD1|PC_PLUS,SP_STAR,0,0);
MAP(PC_ACUTEAC,SP_CUROPEN,0,0);
MAP(MD1|PC_ACUTEAC,SP_CUROPEN,0,0);
MAP(PC_ACUTEAC,SP_CUROPEN,0,0);
MAP(MD1|PC_ACUTEAC,SP_CUROPEN,0,0);
MAP(PC_CEDILLA,SP_CURCLOS,0,0);
MAP(MD1|PC_CEDILLA,SP_QUOTE,0,0);
MAP(PC_COMMA,SP_COMMA,0,0);
MAP(MD1|PC_COMMA,SP_SEMICOL,0,0);
MAP(PC_DOT,SP_DOT,0,0);
MAP(MD1|PC_DOT,SP_COLON,0,0);
MAP(PC_MINUS,SP_MINUS,0,0);
MAP(MD1|PC_MINUS,SP_UNDERSC,0,0);
MAP(PC_BACKSLA,SP_BACKSLA,0,0);
MAP(MD1|PC_BACKSLA,SP_BACKSLA,0,0);
MAP(PC_EGNE,SP_TILDE,0,0);
MAP(PC_LESS,SP_LESS,0,0);
MAP(MD1|PC_LESS,SP_GREATER,0,0);
MAP(MD2|PC_LESS,SP_LESSEQ,0,0);
MAP(MD2|MD1|PC_LESS,SP_GREATEQ,0,0);
MAP(MD3|PC_LESS,SP_NOTEQ,0,0);
MAP(MD3|MD1|PC_LESS,SP_NOTEQ,0,0);
MAP(MD3|MD2|PC_LESS,SP_NOTEQ,0,0);
MAP(MD3|MD2|MD1|PC_LESS,SP_NOTEQ,0,0);
// End of mapping. Save .HEX file for Verilog
SAVEMAPHEX("keyb_es_hex.txt");
// And map file for loading from ESXDOS
SAVEMAPBIN("keymaps\\ES");
}

View File

@ -0,0 +1,479 @@
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char BYTE;
/*
8 8 3 5 3 5
AAADDDDD AAADDDDD MRN JJJJJ MMM XXXXX
AAA = semifila del teclado a modificar | esta información está
DDDDD = dato (AND negado con lo que haya) de esa semifila | repetida para dos teclas
MRN = Master reset, Reset de usuario, NMI
JJJJJ = estado del joystick al pulsar tecla. Posiciones UDLRX
MMM = la tecla es un modificador
XXXXX = Reservado para uso futuro
Ej: en la dirección de memoria correspondiente al código de la tecla ESC,
que correspondería a la pulsación simultánea de CAPS SHIFT+SPACE, pondríamos:
00000001 11100001 000 00000 000 00000
Esto es: se activan las semifilas 0 y 7, y en cada una, se activa el bit 0
256 codigos + E0 = 512 codigos
SHIFT, CTRL, ALT = 8 combinaciones
512*8=4096 direcciones x 32 bits = 16384 bytes
En el core se dispondrá como una memoria de 16384x8 bits
Cada tecla ocupará cuatro direcciones consecutivas.
D+0 : tecla1 (o 0 si no la hay)
D+1 : tecla2 (o 0 si no la hay)
D+2 : señales de reset y joystick, 0 si no hay
D+3 : modificadores y señales de usuario, 0 si no hay
*/
// You shouldn't have to touch these defs unless your Spectrum has a different keyboard
// layout (because, for example, you are using a different ROM
#define SP_1 0x61
#define SP_2 0x62
#define SP_3 0x64
#define SP_4 0x68
#define SP_5 0x70
#define SP_0 0x81
#define SP_9 0x82
#define SP_8 0x84
#define SP_7 0x88
#define SP_6 0x90
#define SP_Q 0x41
#define SP_W 0x42
#define SP_E 0x44
#define SP_R 0x48
#define SP_T 0x50
#define SP_P 0xA1
#define SP_O 0xA2
#define SP_I 0xA4
#define SP_U 0xA8
#define SP_Y 0xB0
#define SP_A 0x21
#define SP_S 0x22
#define SP_D 0x24
#define SP_F 0x28
#define SP_G 0x30
#define SP_ENTER 0xC1
#define SP_L 0xC2
#define SP_K 0xC4
#define SP_J 0xC8
#define SP_H 0xD0
#define SP_CAPS 0x01
#define SP_Z 0x02
#define SP_X 0x04
#define SP_C 0x08
#define SP_V 0x10
#define SP_SPACE 0xE1
#define SP_SYMBOL 0xE2
#define SP_M 0xE4
#define SP_N 0xE8
#define SP_B 0xF0
#define SP_BANG (SP_SYMBOL<<8) | SP_1
#define SP_AT (SP_SYMBOL<<8) | SP_2
#define SP_HASH (SP_SYMBOL<<8) | SP_3
#define SP_DOLLAR (SP_SYMBOL<<8) | SP_4
#define SP_PERCEN (SP_SYMBOL<<8) | SP_5
#define SP_AMP (SP_SYMBOL<<8) | SP_6
#define SP_APOSTRO (SP_SYMBOL<<8) | SP_7
#define SP_PAROPEN (SP_SYMBOL<<8) | SP_8
#define SP_PARCLOS (SP_SYMBOL<<8) | SP_9
#define SP_UNDERSC (SP_SYMBOL<<8) | SP_0
#define SP_LESS (SP_SYMBOL<<8) | SP_R
#define SP_LESSEQ (SP_SYMBOL<<8) | SP_Q
#define SP_GREATER (SP_SYMBOL<<8) | SP_T
#define SP_GREATEQ (SP_SYMBOL<<8) | SP_E
#define SP_NOTEQ (SP_SYMBOL<<8) | SP_W
#define SP_BRAOPEN (SP_SYMBOL<<8) | SP_Y
#define SP_BRACLOS (SP_SYMBOL<<8) | SP_U
#define SP_SEMICOL (SP_SYMBOL<<8) | SP_O
#define SP_QUOTE (SP_SYMBOL<<8) | SP_P
#define SP_TILDE (SP_SYMBOL<<8) | SP_A
#define SP_PIPE (SP_SYMBOL<<8) | SP_S
#define SP_BACKSLA (SP_SYMBOL<<8) | SP_D
#define SP_CUROPEN (SP_SYMBOL<<8) | SP_F
#define SP_CURCLOS (SP_SYMBOL<<8) | SP_G
#define SP_CARET (SP_SYMBOL<<8) | SP_H
#define SP_MINUS (SP_SYMBOL<<8) | SP_J
#define SP_PLUS (SP_SYMBOL<<8) | SP_K
#define SP_EQUAL (SP_SYMBOL<<8) | SP_L
#define SP_COLON (SP_SYMBOL<<8) | SP_Z
#define SP_POUND (SP_SYMBOL<<8) | SP_X
#define SP_QUEST (SP_SYMBOL<<8) | SP_C
#define SP_SLASH (SP_SYMBOL<<8) | SP_V
#define SP_STAR (SP_SYMBOL<<8) | SP_B
#define SP_COMMA (SP_SYMBOL<<8) | SP_N
#define SP_DOT (SP_SYMBOL<<8) | SP_M
#define SP_EXTEND (SP_CAPS<<8) | SP_SYMBOL
#define SP_EDIT (SP_CAPS<<8) | SP_1
#define SP_CPSLOCK (SP_CAPS<<8) | SP_2
#define SP_TRUE (SP_CAPS<<8) | SP_3
#define SP_INVERSE (SP_CAPS<<8) | SP_4
#define SP_LEFT (SP_CAPS<<8) | SP_5
#define SP_DOWN (SP_CAPS<<8) | SP_6
#define SP_UP (SP_CAPS<<8) | SP_7
#define SP_RIGHT (SP_CAPS<<8) | SP_8
#define SP_GRAPH (SP_CAPS<<8) | SP_9
#define SP_DELETE (SP_CAPS<<8) | SP_0
#define SP_BREAK (SP_CAPS<<8) | SP_SPACE
// END of Spectrum keys definitions
// Definitions for additional signals generated by the keyboard core
// AAADDDDD AAADDDDD MRN JJJJJ MMM XXXXX
#define MODIFIER1 0x20
#define MODIFIER2 0x40
#define MODIFIER3 0x80
#define MRESET 0x80
#define URESET 0x40
#define NMI 0x20
#define JOYUP 0x10
#define JOYDOWN 0x08
#define JOYLEFT 0x04
#define JOYRIGHT 0x02
#define JOYFIRE 0x01
#define USER1 0x10
#define USER2 0x08
#define USER3 0x04
#define USER4 0x02
#define USER5 0x01
// End of additional signals
// A key can be pressed with up to three key modifiers
// which generates 8 combinations for each key
#define EXT 0x100
#define MD1 0x200
#define MD2 0x400
#define MD3 0x800
#define MAP(pc,sp,rj,mu) { \
rom[(pc)*4] = (((sp)>>8)&0xFF); \
rom[(pc)*4+1] = (((sp))&0xFF); \
rom[(pc)*4+2] = (rj); \
rom[(pc)*4+3] = (mu); \
}
#define MAPANY(pc,sp,rj,mu) { \
MAP(pc,sp,rj,mu); \
MAP(MD1|pc,sp,rj,mu); \
MAP(MD2|pc,sp,rj,mu); \
MAP(MD3|pc,sp,rj,mu); \
MAP(MD1|MD2|pc,sp,rj,mu); \
MAP(MD1|MD3|pc,sp,rj,mu); \
MAP(MD2|MD3|pc,sp,rj,mu); \
MAP(MD1|MD2|MD3|pc,sp,rj,mu); \
}
#define CLEANMAP { \
int i; \
for (i=0;i<(sizeof(rom)/sizeof(rom[0]));i++) \
rom[i] = 0; \
}
#define SAVEMAPHEX(name) { \
FILE *f; \
int i; \
f=fopen(name,"w"); \
for(i=0;i<(sizeof(rom)/sizeof(rom[0]));i++) \
fprintf(f,"%.2X\n",rom[i]); \
fclose(f); \
}
#define SAVEMAPBIN(name) { \
FILE *f; \
int i; \
f=fopen(name,"wb"); \
fwrite (rom, 1, sizeof(rom), f); \
fclose(f); \
}
// --------------- YOU MAY CUSTOMIZE FROM HERE ------------------------
// Scan code 2 list. First, non localized keys
#define PC_A 0x1C
#define PC_B 0x32
#define PC_C 0x21
#define PC_D 0x23
#define PC_E 0x24
#define PC_F 0x2B
#define PC_G 0x34
#define PC_H 0x33
#define PC_I 0x43
#define PC_J 0x3B
#define PC_K 0x42
#define PC_L 0x4B
#define PC_M 0x3A
#define PC_N 0x31
#define PC_O 0x44
#define PC_P 0x4D
#define PC_Q 0x15
#define PC_R 0x2D
#define PC_S 0x1B
#define PC_T 0x2C
#define PC_U 0x3C
#define PC_V 0x2A
#define PC_W 0x1D
#define PC_X 0x22
#define PC_Y 0x35
#define PC_Z 0x1A
#define PC_0 0x45 // also )
#define PC_1 0x16 // also !
#define PC_2 0x1E // also @
#define PC_3 0x26 // also #
#define PC_4 0x25 // also $
#define PC_5 0x2E // also %
#define PC_6 0x36 // also ^
#define PC_7 0x3D // also &
#define PC_8 0x3E // also *
#define PC_9 0x46 // also (
#define PC_F1 0x05
#define PC_F2 0x06
#define PC_F3 0x04
#define PC_F4 0x0C
#define PC_F5 0x03
#define PC_F6 0x0B
#define PC_F7 0x83
#define PC_F8 0x0A
#define PC_F9 0x01
#define PC_F10 0x09
#define PC_F11 0x78
#define PC_F12 0x07
#define PC_ESC 0x76
#define PC_SPACE 0x29
#define PC_LCTRL 0x14
#define PC_RCTRL 0x14 | EXT
#define PC_LSHIFT 0x12
#define PC_RSHIFT 0x59
#define PC_LALT 0x11
#define PC_RALT 0x11 | EXT
#define PC_LWIN 0x1F | EXT
#define PC_RWIN 0x27 | EXT
#define PC_APPS 0x2F | EXT
#define PC_TAB 0x0D
#define PC_CPSLOCK 0x58
#define PC_SCRLOCK 0x7E
#define PC_INSERT 0x70 | EXT
#define PC_DELETE 0x71 | EXT
#define PC_HOME 0x6C | EXT
#define PC_END 0x69 | EXT
#define PC_PGUP 0x7D | EXT
#define PC_PGDOWN 0x7A | EXT
#define PC_BKSPACE 0x66
#define PC_ENTER 0x5A
#define PC_UP 0x75 | EXT
#define PC_DOWN 0x72 | EXT
#define PC_LEFT 0x6B | EXT
#define PC_RIGHT 0x74 | EXT
#define PC_NUMLOCK 0x77
#define PC_KP_DIVIS 0x4A | EXT
#define PC_KP_MULT 0x7C
#define PC_KP_MINUS 0x7B
#define PC_KP_PLUS 0x79
#define PC_KP_ENTER 0x5A | EXT
#define PC_KP_DOT 0x71
#define PC_KP_0 0x70
#define PC_KP_1 0x69
#define PC_KP_2 0x72
#define PC_KP_3 0x7A
#define PC_KP_4 0x6B
#define PC_KP_5 0x73
#define PC_KP_6 0x74
#define PC_KP_7 0x6C
#define PC_KP_8 0x75
#define PC_KP_9 0x7D
// Localized keyboards usually start to differenciate from here
// Localized keyboard US
#define PC_GRAVEAC 0x0E // also ~
#define PC_MINUS 0x4E // also _
#define PC_EQUAL 0x55 // also +
#define PC_BRAOPEN 0x54 // also {
#define PC_BRACLOS 0x5B // also }
#define PC_BACKSLA 0x5D // also |
#define PC_SEMICOL 0x4C // also :
#define PC_APOSTRO 0x52 // also "
#define PC_COMMA 0x41 // also <
#define PC_DOT 0x49 // also >
#define PC_SLASH 0x4A // also ?
int main()
{
BYTE rom[16384];
CLEANMAP;
MAPANY(PC_LSHIFT,0,0,MODIFIER1); // MD1 is SHIFT
MAPANY(PC_RSHIFT,0,0,MODIFIER1); // MD1 is SHIFT
MAPANY(PC_LCTRL,0,0,MODIFIER2); // MD2 is CTRL
MAPANY(PC_RCTRL,0,0,MODIFIER2); // MD2 is CTRL
MAPANY(PC_LALT,0,JOYFIRE,MODIFIER3); // MD3 is ALT. Also is FIRE for keyboard joystick
MAPANY(PC_RALT,0,JOYFIRE,MODIFIER3); // MD3 is ALT. Also is FIRE for keyboard joystick
MAPANY(PC_LWIN,SP_CAPS,0,0); // CAPS SHIFT
MAPANY(PC_RWIN,SP_SYMBOL,0,0); // SYMBOL SHIFT
// Basic mapping: each key from PC is mapped to a key in the Spectrum
MAP(PC_1,SP_1,0,0);
MAP(PC_2,SP_2,0,0);
MAP(PC_3,SP_3,0,0);
MAP(PC_4,SP_4,0,0);
MAP(PC_5,SP_5,0,0);
MAP(PC_6,SP_6,0,0);
MAP(PC_7,SP_7,0,0);
MAP(PC_8,SP_8,0,0);
MAP(PC_9,SP_9,0,0);
MAP(PC_0,SP_0,0,0);
MAP(PC_Q,SP_Q,0,0);
MAP(PC_W,SP_W,0,0);
MAP(PC_E,SP_E,0,0);
MAP(PC_R,SP_R,0,0);
MAP(PC_T,SP_T,0,0);
MAP(PC_Y,SP_Y,0,0);
MAP(PC_U,SP_U,0,0);
MAP(PC_I,SP_I,0,0);
MAP(PC_O,SP_O,0,0);
MAP(PC_P,SP_P,0,0);
MAP(PC_A,SP_A,0,0);
MAP(PC_S,SP_S,0,0);
MAP(PC_D,SP_D,0,0);
MAP(PC_F,SP_F,0,0);
MAP(PC_G,SP_G,0,0);
MAP(PC_H,SP_H,0,0);
MAP(PC_J,SP_J,0,0);
MAP(PC_K,SP_K,0,0);
MAP(PC_L,SP_L,0,0);
MAP(PC_Z,SP_Z,0,0);
MAP(PC_X,SP_X,0,0);
MAP(PC_C,SP_C,0,0);
MAP(PC_V,SP_V,0,0);
MAP(PC_B,SP_B,0,0);
MAP(PC_N,SP_N,0,0);
MAP(PC_M,SP_M,0,0);
// a letter key with shift (MD1) is like pressing CAPS SHIFT + letter
MAP(MD1|PC_Q,SP_CAPS<<8|SP_Q,0,0);
MAP(MD1|PC_W,SP_CAPS<<8|SP_W,0,0);
MAP(MD1|PC_E,SP_CAPS<<8|SP_E,0,0);
MAP(MD1|PC_R,SP_CAPS<<8|SP_R,0,0);
MAP(MD1|PC_T,SP_CAPS<<8|SP_T,0,0);
MAP(MD1|PC_Y,SP_CAPS<<8|SP_Y,0,0);
MAP(MD1|PC_U,SP_CAPS<<8|SP_U,0,0);
MAP(MD1|PC_I,SP_CAPS<<8|SP_I,0,0);
MAP(MD1|PC_O,SP_CAPS<<8|SP_O,0,0);
MAP(MD1|PC_P,SP_CAPS<<8|SP_P,0,0);
MAP(MD1|PC_A,SP_CAPS<<8|SP_A,0,0);
MAP(MD1|PC_S,SP_CAPS<<8|SP_S,0,0);
MAP(MD1|PC_D,SP_CAPS<<8|SP_D,0,0);
MAP(MD1|PC_F,SP_CAPS<<8|SP_F,0,0);
MAP(MD1|PC_G,SP_CAPS<<8|SP_G,0,0);
MAP(MD1|PC_H,SP_CAPS<<8|SP_H,0,0);
MAP(MD1|PC_J,SP_CAPS<<8|SP_J,0,0);
MAP(MD1|PC_K,SP_CAPS<<8|SP_K,0,0);
MAP(MD1|PC_L,SP_CAPS<<8|SP_L,0,0);
MAP(MD1|PC_Z,SP_CAPS<<8|SP_Z,0,0);
MAP(MD1|PC_X,SP_CAPS<<8|SP_X,0,0);
MAP(MD1|PC_C,SP_CAPS<<8|SP_C,0,0);
MAP(MD1|PC_V,SP_CAPS<<8|SP_V,0,0);
MAP(MD1|PC_B,SP_CAPS<<8|SP_B,0,0);
MAP(MD1|PC_N,SP_CAPS<<8|SP_N,0,0);
MAP(MD1|PC_M,SP_CAPS<<8|SP_M,0,0);
MAPANY(PC_SPACE,SP_SPACE,0,0);
MAPANY(PC_ENTER,SP_ENTER,0,0);
//Complex mapping. This is for the US keyboard although many
//combos can be used with any other PC keyboard
MAPANY(PC_ESC,SP_BREAK,0,0);
MAPANY(PC_CPSLOCK,SP_CPSLOCK,0,0);
MAPANY(PC_TAB,SP_EXTEND,0,0);
MAP(PC_BKSPACE,SP_DELETE,0,0);
MAPANY(PC_UP,SP_UP,0,0);
MAPANY(PC_DOWN,SP_DOWN,0,0);
MAPANY(PC_LEFT,SP_LEFT,0,0);
MAPANY(PC_RIGHT,SP_RIGHT,0,0);
MAPANY(PC_F2,SP_EDIT,0,0);
MAP(PC_F5|MD2|MD3,0,NMI,0); // Ctrl-Alt-F5 for NMI
MAP(PC_F10,SP_GRAPH,0,0); // F10 habilita el modo gráfico. Esto es para Antonio, para la BIOS
MAP(PC_DELETE|MD2|MD3,0,URESET,0); //
MAP(PC_KP_DOT|MD2|MD3,0,URESET,0); // Ctrl-Alt-Del for user reset
MAP(PC_BKSPACE|MD2|MD3,0,MRESET,0); // Ctrl-Alt-BkSpace for master reset
//keypad
MAPANY(PC_KP_DIVIS,SP_SLASH,0,0);
MAPANY(PC_KP_MULT,SP_STAR,0,0);
MAPANY(PC_KP_MINUS,SP_MINUS,0,0);
MAPANY(PC_KP_PLUS,SP_PLUS,0,0);
MAPANY(PC_KP_ENTER,SP_ENTER,0,0);
// a 8-way keyboard joystick on the keypad
MAPANY(PC_KP_7,0,JOYUP|JOYLEFT,0);
MAPANY(PC_KP_8,0,JOYUP,0);
MAPANY(PC_KP_9,0,JOYUP|JOYRIGHT,0);
MAPANY(PC_KP_4,0,JOYLEFT,0);
MAPANY(PC_KP_5,0,JOYDOWN,0);
MAPANY(PC_KP_6,0,JOYRIGHT,0);
MAPANY(PC_KP_1,0,JOYDOWN|JOYLEFT,0);
MAPANY(PC_KP_2,0,JOYDOWN,0);
MAPANY(PC_KP_3,0,JOYDOWN|JOYRIGHT,0);
//Some keys and shift+key mappings for the US keyboard
MAP(MD1|PC_1,SP_BANG,0,0);
MAP(MD1|PC_2,SP_AT,0,0);
MAP(MD1|PC_3,SP_HASH,0,0);
MAP(MD1|PC_4,SP_DOLLAR,0,0);
MAP(MD1|PC_5,SP_PERCEN,0,0);
MAP(MD1|PC_6,SP_CARET,0,0);
MAP(MD1|PC_7,SP_AMP,0,0);
MAP(MD1|PC_8,SP_STAR,0,0);
MAP(MD1|PC_9,SP_PAROPEN,0,0);
MAP(MD1|PC_0,SP_PARCLOS,0,0);
MAP(PC_MINUS,SP_MINUS,0,0);
MAP(MD1|PC_MINUS,SP_UNDERSC,0,0);
MAP(PC_EQUAL,SP_EQUAL,0,0);
MAP(MD1|PC_EQUAL,SP_PLUS,0,0);
MAP(PC_BRAOPEN,SP_BRAOPEN,0,0);
MAP(MD1|PC_BRAOPEN,SP_CUROPEN,0,0);
MAP(PC_BRACLOS,SP_BRACLOS,0,0);
MAP(MD1|PC_BRACLOS,SP_BRACLOS,0,0);
MAP(PC_BACKSLA,SP_BACKSLA,0,0);
MAP(MD1|PC_BACKSLA,SP_PIPE,0,0);
MAP(PC_APOSTRO,SP_APOSTRO,0,0);
MAP(MD1|PC_APOSTRO,SP_QUOTE,0,0);
MAP(PC_COMMA,SP_COMMA,0,0);
MAP(MD1|PC_COMMA,SP_LESS,0,0);
MAP(PC_DOT,SP_DOT,0,0);
MAP(MD1|PC_DOT,SP_GREATER,0,0);
MAP(PC_SLASH,SP_SLASH,0,0);
MAP(MD1|PC_SLASH,SP_QUEST,0,0);
// End of mapping. Save .HEX file for Verilog
//SAVEMAPHEX("keyb_us_hex.txt");
// And map file for loading from ESXDOS
SAVEMAPBIN("keymaps\\US");
}

View File

@ -0,0 +1,137 @@
`timescale 1ns / 1ps
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 15:52:26 06/07/2015
// Design Name:
// Module Name: joystick_protocols
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module joystick_protocols(
input wire clk,
//-- cpu interface
input wire [15:0] a,
input wire iorq_n,
input wire rd_n,
input wire [7:0] din,
output reg [7:0] dout,
output reg oe_n,
//-- interface with ZXUNO reg bank
input wire [7:0] zxuno_addr,
input wire zxuno_regrd,
input wire zxuno_regwr,
//-- actual joystick and keyboard signals
input wire [4:0] kbdjoy_in,
input wire [4:0] db9joy_in,
input wire [4:0] kbdcol_in,
output reg [4:0] kbdcol_out,
input wire vertical_retrace_int_n // this is used as base clock for autofire
);
parameter
JOYCONFADDR = 8'h06,
KEMPSTONADDR = 8'h1F,
SINCLAIRP1ADDR = 12,
SINCLAIRP2ADDR = 11,
FULLERADDR = 8'h7F,
DISABLED = 3'h0,
KEMPSTON = 3'h1,
SINCLAIRP1 = 3'h2,
SINCLAIRP2 = 3'h3,
CURSOR = 3'h4,
FULLER = 3'h5;
// Input format: FUDLR . 0=pressed, 1=released
reg db9joyup = 1'b0;
reg db9joydown = 1'b0;
reg db9joyleft = 1'b0;
reg db9joyright = 1'b0;
reg db9joyfire = 1'b0;
reg kbdjoyup = 1'b0;
reg kbdjoydown = 1'b0;
reg kbdjoyleft = 1'b0;
reg kbdjoyright = 1'b0;
reg kbdjoyfire = 1'b0;
always @(posedge clk) begin
{db9joyfire,db9joyup,db9joydown,db9joyleft,db9joyright} <= ~db9joy_in;
{kbdjoyfire,kbdjoyup,kbdjoydown,kbdjoyleft,kbdjoyright} <= kbdjoy_in;
end
// Update JOYCONF from CPU
reg [7:0] joyconf = {1'b0,SINCLAIRP1, 1'b0,KEMPSTON};
always @(posedge clk) begin
if (zxuno_addr==JOYCONFADDR && zxuno_regwr==1'b1)
joyconf <= din;
end
// Autofire stuff
reg [2:0] cont_autofire = 3'b000;
reg [3:0] edge_detect = 4'b0000;
wire autofire = cont_autofire[2];
always @(posedge clk) begin
edge_detect <= {edge_detect[2:0], vertical_retrace_int_n};
if (edge_detect == 4'b0011)
cont_autofire <= cont_autofire + 1; // count only on raising edge of vertical retrace int
end
wire kbdjoyfire_processed = (joyconf[3]==1'b0)? kbdjoyfire : kbdjoyfire & autofire;
wire db9joyfire_processed = (joyconf[7]==1'b0)? db9joyfire : db9joyfire & autofire;
always @* begin
oe_n = 1'b1;
dout = 8'hZZ;
kbdcol_out = kbdcol_in;
if (zxuno_addr==JOYCONFADDR && zxuno_regrd==1'b1) begin
oe_n = 1'b0;
dout = joyconf;
end
else if (iorq_n == 1'b0 && a[7:0]==KEMPSTONADDR && rd_n==1'b0) begin
dout = 8'h00;
oe_n = 1'b0;
if (joyconf[2:0]==KEMPSTON)
dout = dout | {3'b000, kbdjoyfire_processed, kbdjoyup, kbdjoydown, kbdjoyleft, kbdjoyright};
if (joyconf[6:4]==KEMPSTON)
dout = dout | {3'b000, db9joyfire_processed, db9joyup, db9joydown, db9joyleft, db9joyright};
end
else if (iorq_n == 1'b0 && a[7:0]==FULLERADDR && rd_n==1'b0) begin
dout = 8'hFF;
oe_n = 1'b0;
if (joyconf[2:0]==FULLER)
dout = dout & {~kbdjoyfire_processed, 3'b111, ~kbdjoyright, ~kbdjoyleft, ~kbdjoydown, ~kbdjoyup};
if (joyconf[6:4]==FULLER)
dout = dout & {~db9joyfire_processed, 3'b111, ~db9joyright, ~db9joyleft, ~db9joydown, ~db9joyup};
end
else if (iorq_n==1'b0 && a[SINCLAIRP1ADDR]==1'b0 && a[0]==1'b0 && rd_n==1'b0) begin
if (joyconf[2:0]==SINCLAIRP1)
kbdcol_out = kbdcol_out & {~kbdjoyleft,~kbdjoyright,~kbdjoydown,~kbdjoyup,~kbdjoyfire_processed};
if (joyconf[6:4]==SINCLAIRP1)
kbdcol_out = kbdcol_out & {~db9joyleft,~db9joyright,~db9joydown,~db9joyup,~db9joyfire_processed};
if (joyconf[2:0]==CURSOR)
kbdcol_out = kbdcol_out & {~kbdjoydown,~kbdjoyup,~kbdjoyright,1'b1,~kbdjoyfire_processed};
if (joyconf[6:4]==CURSOR)
kbdcol_out = kbdcol_out & {~db9joydown,~db9joyup,~db9joyright,1'b1,~db9joyfire_processed};
end
else if (iorq_n==1'b0 && a[SINCLAIRP2ADDR]==1'b0 && a[0]==1'b0 && rd_n==1'b0) begin
if (joyconf[2:0]==SINCLAIRP2)
kbdcol_out = kbdcol_out & {~kbdjoyfire_processed,~kbdjoyup,~kbdjoydown,~kbdjoyright,~kbdjoyleft};
if (joyconf[6:4]==SINCLAIRP2)
kbdcol_out = kbdcol_out & {~db9joyfire_processed,~db9joyup,~db9joydown,~db9joyright,~db9joyleft};
if (joyconf[2:0]==CURSOR)
kbdcol_out = kbdcol_out & {~kbdjoyleft,4'b1111};
if (joyconf[6:4]==CURSOR)
kbdcol_out = kbdcol_out & {~db9joyleft,4'b1111};
end
end
endmodule

16384
cores/Spectrum/keyb_es_hex.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
cores/Spectrum/keymaps/ES Normal file

Binary file not shown.

BIN
cores/Spectrum/keymaps/US Normal file

Binary file not shown.

131
cores/Spectrum/ps2_keyb.v Normal file
View File

@ -0,0 +1,131 @@
`timescale 1ns / 1ps
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 15:18:53 06/03/2015
// Design Name:
// Module Name: ps2_keyb
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ps2_keyb(
input wire clk,
inout wire clkps2,
inout wire dataps2,
//---------------------------------
input wire [7:0] rows,
output wire [4:0] cols,
output wire [4:0] joy,
output wire rst_out_n,
output wire nmi_out_n,
output wire mrst_out_n,
output wire [4:0] user_toggles,
//---------------------------------
input wire [7:0] zxuno_addr,
input wire zxuno_regrd,
input wire zxuno_regwr,
input wire regaddr_changed,
input wire [7:0] din,
output wire [7:0] keymap_dout,
output wire oe_n_keymap,
output wire [7:0] scancode_dout,
output wire oe_n_scancode,
output reg [7:0] kbstatus_dout,
output wire oe_n_kbstatus
);
parameter SCANCODE = 8'h04;
parameter KBSTATUS = 8'h05;
parameter KEYMAP = 8'h07;
wire master_reset, user_reset, user_nmi;
assign mrst_out_n = ~master_reset;
assign rst_out_n = ~user_reset;
assign nmi_out_n = ~user_nmi;
assign oe_n_keymap = ~(zxuno_addr == KEYMAP && zxuno_regrd == 1'b1);
assign oe_n_scancode = ~(zxuno_addr == SCANCODE && zxuno_regrd == 1'b1);
assign oe_n_kbstatus = ~(zxuno_addr == KBSTATUS && zxuno_regrd == 1'b1);
wire [7:0] kbcode;
wire ps2busy;
wire kberror;
wire nueva_tecla;
wire extended;
wire released;
assign scancode_dout = kbcode;
/*
| BSY | x | x | x | ERR | RLS | EXT | PEN |
*/
reg reading_kbstatus = 1'b0;
always @(posedge clk) begin
kbstatus_dout[7:1] <= {ps2busy, 3'b000, kberror, released, extended};
if (nueva_tecla == 1'b1)
kbstatus_dout[0] <= 1'b1;
if (oe_n_kbstatus == 1'b0)
reading_kbstatus <= 1'b1;
else if (reading_kbstatus == 1'b1) begin
kbstatus_dout[0] <= 1'b0;
reading_kbstatus <= 1'b0;
end
end
ps2_port lectura_de_teclado (
.clk(clk),
.enable_rcv(~ps2busy),
.ps2clk_ext(clkps2),
.ps2data_ext(dataps2),
.kb_interrupt(nueva_tecla),
.scancode(kbcode),
.released(released),
.extended(extended)
);
scancode_to_speccy traductor (
.clk(clk),
.rst(1'b0),
.scan_received(nueva_tecla),
.scan(kbcode),
.extended(extended),
.released(released),
.sp_row(rows),
.sp_col(cols),
.joyup(joy[3]),
.joydown(joy[2]),
.joyleft(joy[1]),
.joyright(joy[0]),
.joyfire(joy[4]),
.master_reset(master_reset),
.user_reset(user_reset),
.user_nmi(user_nmi),
.user_toggles(user_toggles),
.din(din),
.dout(keymap_dout),
.cpuwrite(zxuno_addr == KEYMAP && zxuno_regwr == 1'b1),
.cpuread(zxuno_addr == KEYMAP && zxuno_regrd == 1'b1),
.rewind(regaddr_changed == 1'b1 && zxuno_addr == KEYMAP)
);
ps2_host_to_kb escritura_a_teclado (
.clk(clk),
.ps2clk_ext(clkps2),
.ps2data_ext(dataps2),
.data(din),
.dataload(zxuno_addr == SCANCODE && zxuno_regwr== 1'b1),
.ps2busy(ps2busy),
.ps2error(kberror)
);
endmodule

242
cores/Spectrum/ps2_port.v Normal file
View File

@ -0,0 +1,242 @@
`timescale 1ns / 1ps
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 20:16:31 12/26/2014
// Design Name:
// Module Name: ps2_port
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ps2_port (
input wire clk, // se recomienda 1 MHz <= clk <= 600 MHz
input wire enable_rcv, // habilitar la maquina de estados de recepcion
input wire ps2clk_ext,
input wire ps2data_ext,
output wire kb_interrupt, // a 1 durante 1 clk para indicar nueva tecla recibida
output reg [7:0] scancode, // make o breakcode de la tecla
output wire released, // soltada=1, pulsada=0
output wire extended // extendida=1, no extendida=0
);
`define RCVSTART 2'b00
`define RCVDATA 2'b01
`define RCVPARITY 2'b10
`define RCVSTOP 2'b11
reg [7:0] key = 8'h00;
// Fase de sincronizacion de señales externas con el reloj del sistema
reg [1:0] ps2clk_synchr;
reg [1:0] ps2dat_synchr;
wire ps2clk = ps2clk_synchr[1];
wire ps2data = ps2dat_synchr[1];
always @(posedge clk) begin
ps2clk_synchr[0] <= ps2clk_ext;
ps2clk_synchr[1] <= ps2clk_synchr[0];
ps2dat_synchr[0] <= ps2data_ext;
ps2dat_synchr[1] <= ps2dat_synchr[0];
end
// De-glitcher. Sólo detecto flanco de bajada
reg [15:0] negedgedetect = 16'h0000;
always @(posedge clk) begin
negedgedetect <= {negedgedetect[14:0], ps2clk};
end
wire ps2clkedge = (negedgedetect == 16'hFF00)? 1'b1 : 1'b0;
// Paridad instantánea de los bits recibidos
wire paritycalculated = ^key;
// Contador de time-out. Al llegar a 65536 ciclos sin que ocurra
// un flanco de bajada en PS2CLK, volvemos al estado inicial
reg [15:0] timeoutcnt = 16'h0000;
reg [1:0] state = `RCVSTART;
reg [1:0] regextended = 2'b00;
reg [1:0] regreleased = 2'b00;
reg rkb_interrupt = 1'b0;
assign released = regreleased[1];
assign extended = regextended[1];
assign kb_interrupt = rkb_interrupt;
always @(posedge clk) begin
if (rkb_interrupt == 1'b1) begin
rkb_interrupt <= 1'b0;
end
if (ps2clkedge && enable_rcv) begin
timeoutcnt <= 16'h0000;
if (state == `RCVSTART && ps2data == 1'b0) begin
state <= `RCVDATA;
key <= 8'h80;
//rkb_interrupt <= 1'b0;
end
else if (state == `RCVDATA) begin
key <= {ps2data, key[7:1]};
if (key[0] == 1'b1) begin
state <= `RCVPARITY;
end
end
else if (state == `RCVPARITY) begin
if (ps2data^paritycalculated == 1'b1) begin
state <= `RCVSTOP;
end
else begin
state <= `RCVSTART;
end
end
else if (state == `RCVSTOP) begin
state <= `RCVSTART;
if (ps2data == 1'b1) begin
scancode <= key;
if (key == 8'hE0) begin
regextended <= 2'b01;
end
else if (key == 8'hF0) begin
regreleased <= 2'b01;
end
else begin
regextended <= {regextended[0], 1'b0};
regreleased <= {regreleased[0], 1'b0};
rkb_interrupt <= 1'b1;
end
end
end
end
else begin
timeoutcnt <= timeoutcnt + 1;
if (timeoutcnt == 16'hFFFF) begin
state <= `RCVSTART;
end
end
end
endmodule
module ps2_host_to_kb (
input wire clk, // se recomienda 1 MHz <= clk <= 600 MHz
inout wire ps2clk_ext,
inout wire ps2data_ext,
input wire [7:0] data,
input wire dataload,
output wire ps2busy,
output wire ps2error
);
`define PULLCLKLOW 3'b000
`define PULLDATALOW 3'b001
`define SENDDATA 3'b010
`define SENDPARITY 3'b011
`define RCVACK 3'b100
`define RCVIDLE 3'b101
`define SENDFINISHED 3'b110
reg busy = 1'b0;
reg error = 1'b0;
assign ps2busy = busy;
assign ps2error = error;
// Fase de sincronizacion de señales externas con el reloj del sistema
reg [1:0] ps2clk_synchr;
reg [1:0] ps2dat_synchr;
wire ps2clk = ps2clk_synchr[1];
wire ps2data_in = ps2dat_synchr[1];
always @(posedge clk) begin
ps2clk_synchr[0] <= ps2clk_ext;
ps2clk_synchr[1] <= ps2clk_synchr[0];
ps2dat_synchr[0] <= ps2data_ext;
ps2dat_synchr[1] <= ps2dat_synchr[0];
end
// De-glitcher. Sólo detecto flanco de bajada
reg [15:0] edgedetect = 16'h0000;
always @(posedge clk) begin
edgedetect <= {edgedetect[14:0], ps2clk};
end
wire ps2clknedge = (edgedetect == 16'hF000)? 1'b1 : 1'b0;
wire ps2clkpedge = (edgedetect == 16'h0FFF)? 1'b1 : 1'b0;
// Contador de time-out. Al llegar a 65536 ciclos sin que ocurra
// un flanco de bajada en PS2CLK, volvemos al estado inicial
reg [15:0] timeoutcnt = 16'h0000;
reg [2:0] state = `SENDFINISHED;
reg [7:0] shiftreg = 8'h00;
reg [2:0] cntbits = 3'd0;
// Dato a enviar se guarda en rdata
reg [7:0] rdata = 8'h00;
// Paridad instantánea de los bits a enviar
wire paritycalculated = ~(^rdata);
always @(posedge clk) begin
// Carga de rdata desde el exterior
if (dataload) begin
rdata <= data;
busy <= 1'b1;
error <= 1'b0;
timeoutcnt <= 16'h0000;
state <= `PULLCLKLOW;
end
if (state == `PULLCLKLOW && timeoutcnt >= 16'd40000) begin // 40000 cuentas es poco más de 10ms
state <= `PULLDATALOW;
shiftreg <= rdata;
cntbits <= 3'd0;
timeoutcnt <= 16'h0000;
end
else if (state == `PULLDATALOW && ps2clknedge) begin
state <= `SENDDATA;
timeoutcnt <= 16'h0000;
end
else if (state == `SENDDATA && ps2clknedge) begin
timeoutcnt <= 16'h0000;
shiftreg <= {1'b0, shiftreg[7:1]};
cntbits <= cntbits + 1;
if (cntbits == 3'd7)
state <= `SENDPARITY;
end
else if (state == `SENDPARITY && ps2clknedge) begin
state <= `RCVIDLE;
timeoutcnt <= 16'h0000;
end
else if (state == `RCVIDLE && ps2clknedge /*&& ps2data_in == 1'b1*/) begin
state <= `RCVACK;
timeoutcnt <= 16'h0000;
end
else if (state == `RCVACK && ps2clknedge /*&& ps2data_in == 1'b0*/) begin
state <= `SENDFINISHED;
timeoutcnt <= 16'h0000;
end
else if (state == `SENDFINISHED) begin
busy <= 1'b0;
timeoutcnt <= 16'h0000;
end
else begin
timeoutcnt <= timeoutcnt + 1;
if (timeoutcnt == 16'hFFFF && state != `SENDFINISHED) begin
error <= 1'b1;
state <= `SENDFINISHED;
end
end
end
assign ps2data_ext = (state == `PULLCLKLOW || state == `PULLDATALOW) ? 1'b0 :
(state == `SENDDATA && shiftreg[0] == 1'b0) ? 1'b0 :
(state == `SENDPARITY && paritycalculated == 1'b0) ? 1'b0 : // si lo que se va a enviar es un 1
1'bZ; // no se manda, sino que se pone la línea a alta impedancia
assign ps2clk_ext = (state == `PULLCLKLOW) ? 1'b0 :
1'bZ;
endmodule

View File

@ -309,6 +309,14 @@ begin
when KEY_KP6 => joy(0) <= pressed; -- dato entregado por el joystick: derecha
when KEY_KP8 => joy(3) <= pressed; -- dato entregado por el joystick: arriba
when KEY_KP5 => joy(2) <= pressed; -- dato entregado por el joystick: abajo
when KEY_KP7 => joy(1) <= pressed;
joy(3) <= pressed; -- dato entregado por el joystick: arriba izquierda
when KEY_KP9 => joy(0) <= pressed;
joy(3) <= pressed; -- dato entregado por el joystick: arriba derecha
when KEY_KP1 => joy(1) <= pressed;
joy(2) <= pressed; -- dato entregado por el joystick: abajo izquierda
when KEY_KP3 => joy(0) <= pressed;
joy(2) <= pressed; -- dato entregado por el joystick: abajo derecha
when others=> null;
end case;
else -- process extended keys

View File

@ -24,18 +24,16 @@ module rom (
output reg [7:0] dout
);
reg [7:0] mem[0:63];
reg [7:0] mem[0:127];
integer i;
initial begin // usa $readmemb/$readmemh dependiendo del formato del fichero que contenga la ROM
for (i=0;i<64;i=i+1) begin
for (i=0;i<128;i=i+1) begin
mem[i] = 8'h00;
end
$readmemh ("bootloader_hex.txt", mem, 0);
//$readmemb ("rom_48k_bin.txt", mem, 0);
//$readmemh ("testcontenida_hex.txt", mem, 0);
end
always @(posedge clk) begin
dout <= mem[a[5:0]];
dout <= mem[a[6:0]];
end
endmodule

View File

@ -0,0 +1,267 @@
`timescale 1ns / 1ps
`default_nettype none
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:42:40 06/01/2015
// Design Name:
// Module Name: scancode_to_speccy
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module scancode_to_speccy (
input wire clk, // el mismo clk de ps/2
input wire rst,
input wire scan_received,
input wire [7:0] scan,
input wire extended,
input wire released,
//------------------------
input wire [7:0] sp_row,
output wire [4:0] sp_col,
output wire user_reset,
output wire master_reset,
output wire user_nmi,
output wire joyup,
output wire joydown,
output wire joyleft,
output wire joyright,
output wire joyfire,
output wire [4:0] user_toggles,
//------------------------
input wire [7:0] din,
output reg [7:0] dout,
input wire cpuwrite,
input wire cpuread,
input wire rewind
);
// las 40 teclas del Spectrum. Se inicializan a "no pulsadas".
reg [4:0] row[0:7];
initial begin
row[0] = 5'b11111;
row[1] = 5'b11111;
row[2] = 5'b11111;
row[3] = 5'b11111;
row[4] = 5'b11111;
row[5] = 5'b11111;
row[6] = 5'b11111;
row[7] = 5'b11111;
end
// El gran mapa de teclado y sus registros de acceso
reg [7:0] keymap[0:16383]; // 16K x 8 bits
reg [13:0] addr = 14'h0000;
reg [13:0] cpuaddr = 14'h0000; // Dirección E/S desde la CPU. Se autoincrementa en cada acceso
initial begin
$readmemh ("keyb_es_hex.txt", keymap);
end
reg [2:0] keyrow1 = 3'h0;
reg [4:0] keycol1 = 5'h00;
reg [2:0] keyrow2 = 3'h0;
reg [4:0] keycol2 = 5'h00;
reg [2:0] keymodifiers = 3'b000;
reg [2:0] signalstate = 3'b000;
reg [4:0] joystate = 5'b00000;
reg [4:0] togglestate = 5'h00;
reg rmaster_reset = 1'b0, ruser_reset = 1'b0, ruser_nmi = 1'b0;
reg rjoyup = 1'b0, rjoydown = 1'b0, rjoyleft = 1'b0, rjoyright = 1'b0, rjoyfire = 1'b0;
reg [4:0] ruser_toggles = 5'h00;
assign joyup = rjoyup;
assign joydown = rjoydown;
assign joyleft = rjoyleft;
assign joyright = rjoyright;
assign joyfire = rjoyfire;
assign master_reset = rmaster_reset;
assign user_reset = ruser_reset;
assign user_nmi = ruser_nmi;
assign user_toggles = ruser_toggles;
// Asi funciona la matriz de teclado cuando se piden semifilas
// desde la CPU.
// Un always @* hubiera quedado más claro en la descripción
// pero por algun motivo, el XST no lo ha admitido en este caso
assign sp_col = ((sp_row[0] == 1'b0)? row[0] : 5'b11111) &
((sp_row[1] == 1'b0)? row[1] : 5'b11111) &
((sp_row[2] == 1'b0)? row[2] : 5'b11111) &
((sp_row[3] == 1'b0)? row[3] : 5'b11111) &
((sp_row[4] == 1'b0)? row[4] : 5'b11111) &
((sp_row[5] == 1'b0)? row[5] : 5'b11111) &
((sp_row[6] == 1'b0)? row[6] : 5'b11111) &
((sp_row[7] == 1'b0)? row[7] : 5'b11111);
reg [2:0] modifiers = 3'b000;
reg [3:0] keycount = 4'b0000;
parameter
CLEANMATRIX = 4'd0,
IDLE = 4'd1,
ADDR0PUT = 4'd2,
ADDR1PUT = 4'd3,
ADDR2PUT = 4'd4,
ADDR3PUT = 4'd5,
TRANSLATE1 = 4'd6,
TRANSLATE2 = 4'd7,
TRANSLATE3 = 4'd8,
CPUTIME = 4'd9,
CPUREAD = 4'd10,
CPUWRITE = 4'd11,
CPUINCADD = 4'd12,
UPDCOUNTERS1= 4'd13,
UPDCOUNTERS2= 4'd14;
reg [3:0] state = CLEANMATRIX;
reg key_is_pending = 1'b0;
always @(posedge clk) begin
if (scan_received == 1'b1)
key_is_pending <= 1'b1;
if (rst == 1'b1)
state <= CLEANMATRIX;
else if (state == CLEANMATRIX) begin
modifiers <= 3'b000;
keycount <= 4'b0000;
row[0] <= 5'b11111;
row[1] <= 5'b11111;
row[2] <= 5'b11111;
row[3] <= 5'b11111;
row[4] <= 5'b11111;
row[5] <= 5'b11111;
row[6] <= 5'b11111;
row[7] <= 5'b11111;
state <= IDLE;
end
else if (state == IDLE) begin
if (key_is_pending == 1'b1) begin
addr <= {modifiers, extended, scan, 2'b00}; // 1 scan tiene 8 bits + 1 bit para indicar scan extendido + 3 bits para el modificador usado
state <= ADDR0PUT;
key_is_pending <= 1'b0;
end
else if (cpuread == 1'b1 || cpuwrite == 1'b1 || rewind == 1'b1)
state <= CPUTIME;
end
else if (state == ADDR0PUT) begin
{keyrow1,keycol1} <= keymap[addr];
addr <= {modifiers, extended, scan, 2'b01};
state <= ADDR1PUT;
end
else if (state == ADDR1PUT) begin
{keyrow2,keycol2} <= keymap[addr];
addr <= {modifiers, extended, scan, 2'b10};
state <= ADDR2PUT;
end
else if (state == ADDR2PUT) begin
{signalstate,joystate} <= keymap[addr];
addr <= {modifiers, extended, scan, 2'b11};
state <= ADDR3PUT;
end
else if (state == ADDR3PUT) begin
{keymodifiers,togglestate} <= keymap[addr];
state <= TRANSLATE1;
end
else if (state == TRANSLATE1) begin
// Actualiza las 8 semifilas del teclado con la primera tecla
if (~released) begin
row[keyrow1] <= row[keyrow1] & ~keycol1;
end
else begin
row[keyrow1] <= row[keyrow1] | keycol1;
end
state <= TRANSLATE2;
end
else if (state == TRANSLATE2) begin
// Actualiza las 8 semifilas del teclado con la segunda tecla
if (~released) begin
row[keyrow2] <= row[keyrow2] & ~keycol2;
end
else begin
row[keyrow2] <= row[keyrow2] | keycol2;
end
state <= TRANSLATE3;
end
else if (state == TRANSLATE3) begin
// Actualiza modificadores
if (~released)
modifiers <= modifiers | keymodifiers;
else
modifiers <= modifiers & ~keymodifiers;
// Y de la misma forma tendria que actualizar el joystick, resets y los user_toogles
if (~released)
{rjoyup,rjoydown,rjoyleft,rjoyright,rjoyfire} <= {rjoyup,rjoydown,rjoyleft,rjoyright,rjoyfire} | joystate;
else
{rjoyup,rjoydown,rjoyleft,rjoyright,rjoyfire} <= {rjoyup,rjoydown,rjoyleft,rjoyright,rjoyfire} & ~joystate;
if (~released)
{rmaster_reset,ruser_reset,ruser_nmi} <= {rmaster_reset,ruser_reset,ruser_nmi} | signalstate;
else
{rmaster_reset,ruser_reset,ruser_nmi} <= {rmaster_reset,ruser_reset,ruser_nmi} & ~signalstate;
if (~released)
ruser_toggles <= ruser_toggles | togglestate;
else
ruser_toggles <= ruser_toggles & ~togglestate;
//state <= UPDCOUNTERS1;
state <= IDLE;
end
else if (state == CPUTIME) begin
if (rewind == 1'b1) begin
cpuaddr = 14'h0000;
state <= IDLE;
end
else if (cpuread == 1'b1) begin
addr <= cpuaddr;
state <= CPUREAD;
end
else if (cpuwrite == 1'b1) begin
addr <= cpuaddr;
state <= CPUWRITE;
end
else
state <= IDLE;
end
else if (state == CPUREAD) begin // CPU wants to read from keymap
dout <= keymap[addr];
state <= CPUINCADD;
end
else if (state == CPUWRITE) begin
keymap[addr] <= din;
state <= CPUINCADD;
end
else if (state == CPUINCADD) begin
if (cpuread == 1'b0 && cpuwrite == 1'b0) begin
cpuaddr <= cpuaddr + 1;
state <= IDLE;
end
end
// else if (state == UPDCOUNTERS1) begin
// if (~released)
// keycount <= keycount + 4'b0001; // suma 1 al contador de pulsaciones
// else if (released && keycount != 4'b0000)
// keycount <= keycount + 4'b1111; // o le resta 1 al contador de pulsaciones, pero sin bajar de 0
// state <= UPDCOUNTERS2;
// end
// else if (state == UPDCOUNTERS2) begin
// if (keycount == 4'b0000) // si es la última tecla soltada, limpia la matriz de teclado del Spectrum
// state <= CLEANMATRIX;
// else
// state <= IDLE;
// end
else begin
state <= IDLE;
end
end
endmodule

View File

@ -0,0 +1,43 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 01:22:53 06/15/2015
// Design Name:
// Module Name: scratch_register
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module scratch_register(
input wire clk,
input wire poweron_rst_n,
input wire [7:0] zxuno_addr,
input wire zxuno_regrd,
input wire zxuno_regwr,
input wire [7:0] din,
output reg [7:0] dout,
output wire oe_n
);
parameter SCRATCH = 8'hFE;
assign oe_n = ~(zxuno_addr == SCRATCH && zxuno_regrd == 1'b1);
reg [7:0] scratch = 8'h00; // initial value
always @(posedge clk) begin
if (poweron_rst_n == 1'b0)
scratch <= 8'h00; // or after a hardware reset (not implemented yet)
else if (zxuno_addr == SCRATCH && zxuno_regwr == 1'b1)
scratch <= din;
dout <= scratch;
end
endmodule

View File

@ -5,7 +5,7 @@ Command Line: A:\ZZ\Xilinx\12.1\ISE_DS\ISE\bin\nt64\unwrapped\ngdbuild.exe
-filter iseconfig/filter.filter -intstyle ise -dd _ngo -nt timestamp -uc
pines_zxuno.ucf -p xc6slx9-tqg144-3 tld_zxuno.ngc tld_zxuno.ngd
Reading NGO file "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.ngc" ...
Reading NGO file "A:/zxuno/cores/spectrum_v2_spartan6/test16/tld_zxuno.ngc" ...
Gathering constraint information from source properties...
Done.
@ -27,10 +27,10 @@ NGDBUILD Design Results Summary:
Number of errors: 0
Number of warnings: 0
Total memory usage is 157796 kilobytes
Total memory usage is 155192 kilobytes
Writing NGD file "tld_zxuno.ngd" ...
Total REAL time to NGDBUILD completion: 5 sec
Total CPU time to NGDBUILD completion: 5 sec
Total REAL time to NGDBUILD completion: 10 sec
Total CPU time to NGDBUILD completion: 10 sec
Writing NGDBUILD log file "tld_zxuno.bld"...

View File

@ -1,30 +1,6 @@
xst -intstyle ise -filter "A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter" -ifn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.xst" -ofn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.syr"
xst -intstyle ise -filter "A:/zxuno/cores/spectrum_v2_spartan6/test16/iseconfig/filter.filter" -ifn "A:/zxuno/cores/spectrum_v2_spartan6/test16/tld_zxuno.xst" -ofn "A:/zxuno/cores/spectrum_v2_spartan6/test16/tld_zxuno.syr"
ngdbuild -filter "iseconfig/filter.filter" -intstyle ise -dd _ngo -nt timestamp -uc pines_zxuno.ucf -p xc6slx9-tqg144-3 tld_zxuno.ngc tld_zxuno.ngd
map -filter "iseconfig/filter.filter" -intstyle ise -p xc6slx9-tqg144-3 -w -ol high -xe n -t 1 -xt 0 -register_duplication off -global_opt speed -equivalent_register_removal on -ir off -pr off -lc off -power off -o tld_zxuno_map.ncd tld_zxuno.ngd tld_zxuno.pcf
par -filter "iseconfig/filter.filter" -w -intstyle ise -ol high tld_zxuno_map.ncd tld_zxuno.ncd tld_zxuno.pcf
trce -filter A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter -intstyle ise -v 3 -s 3 -n 3 -fastpaths -xml tld_zxuno.twx tld_zxuno.ncd -o tld_zxuno.twr tld_zxuno.pcf -ucf pines_zxuno.ucf
bitgen -filter "iseconfig/filter.filter" -intstyle ise -f tld_zxuno.ut tld_zxuno.ncd
xst -intstyle ise -filter "A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter" -ifn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.xst" -ofn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.syr"
xst -intstyle ise -filter "A:/zxuno/cores/spectrum_v2_spartan6/test16/iseconfig/filter.filter" -ifn "A:/zxuno/cores/spectrum_v2_spartan6/test16/tld_zxuno.xst" -ofn "A:/zxuno/cores/spectrum_v2_spartan6/test16/tld_zxuno.syr"
ngdbuild -filter "iseconfig/filter.filter" -intstyle ise -dd _ngo -nt timestamp -uc pines_zxuno.ucf -p xc6slx9-tqg144-3 tld_zxuno.ngc tld_zxuno.ngd
map -filter "iseconfig/filter.filter" -intstyle ise -p xc6slx9-tqg144-3 -w -ol high -xe n -t 1 -xt 0 -register_duplication off -global_opt speed -equivalent_register_removal on -ir off -pr off -lc off -power off -o tld_zxuno_map.ncd tld_zxuno.ngd tld_zxuno.pcf
par -filter "iseconfig/filter.filter" -w -intstyle ise -ol high tld_zxuno_map.ncd tld_zxuno.ncd tld_zxuno.pcf
trce -filter A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter -intstyle ise -v 3 -s 3 -n 3 -fastpaths -xml tld_zxuno.twx tld_zxuno.ncd -o tld_zxuno.twr tld_zxuno.pcf -ucf pines_zxuno.ucf
bitgen -filter "iseconfig/filter.filter" -intstyle ise -f tld_zxuno.ut tld_zxuno.ncd
xst -intstyle ise -filter "A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter" -ifn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.xst" -ofn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.syr"
ngdbuild -filter "iseconfig/filter.filter" -intstyle ise -dd _ngo -nt timestamp -uc pines_zxuno.ucf -p xc6slx9-tqg144-3 tld_zxuno.ngc tld_zxuno.ngd
map -filter "iseconfig/filter.filter" -intstyle ise -p xc6slx9-tqg144-3 -w -ol high -xe n -t 1 -xt 0 -register_duplication off -global_opt speed -equivalent_register_removal on -ir off -pr off -lc off -power off -o tld_zxuno_map.ncd tld_zxuno.ngd tld_zxuno.pcf
par -filter "iseconfig/filter.filter" -w -intstyle ise -ol high tld_zxuno_map.ncd tld_zxuno.ncd tld_zxuno.pcf
trce -filter A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter -intstyle ise -v 3 -s 3 -n 3 -fastpaths -xml tld_zxuno.twx tld_zxuno.ncd -o tld_zxuno.twr tld_zxuno.pcf -ucf pines_zxuno.ucf
bitgen -filter "iseconfig/filter.filter" -intstyle ise -f tld_zxuno.ut tld_zxuno.ncd
xst -intstyle ise -filter "A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter" -ifn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.xst" -ofn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.syr"
ngdbuild -filter "iseconfig/filter.filter" -intstyle ise -dd _ngo -nt timestamp -uc pines_zxuno.ucf -p xc6slx9-tqg144-3 tld_zxuno.ngc tld_zxuno.ngd
map -filter "iseconfig/filter.filter" -intstyle ise -p xc6slx9-tqg144-3 -w -ol high -xe n -t 1 -xt 0 -register_duplication off -global_opt speed -equivalent_register_removal on -ir off -pr off -lc off -power off -o tld_zxuno_map.ncd tld_zxuno.ngd tld_zxuno.pcf
par -filter "iseconfig/filter.filter" -w -intstyle ise -ol high tld_zxuno_map.ncd tld_zxuno.ncd tld_zxuno.pcf
trce -filter A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter -intstyle ise -v 3 -s 3 -n 3 -fastpaths -xml tld_zxuno.twx tld_zxuno.ncd -o tld_zxuno.twr tld_zxuno.pcf -ucf pines_zxuno.ucf
bitgen -filter "iseconfig/filter.filter" -intstyle ise -f tld_zxuno.ut tld_zxuno.ncd
xst -intstyle ise -filter "A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter" -ifn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.xst" -ofn "A:/zxuno/cores/spectrum_v2_spartan6/test14/tld_zxuno.syr"
ngdbuild -filter "iseconfig/filter.filter" -intstyle ise -dd _ngo -nt timestamp -uc pines_zxuno.ucf -p xc6slx9-tqg144-3 tld_zxuno.ngc tld_zxuno.ngd
map -filter "iseconfig/filter.filter" -intstyle ise -p xc6slx9-tqg144-3 -w -ol high -xe n -t 1 -xt 0 -register_duplication off -global_opt speed -equivalent_register_removal on -ir off -pr off -lc off -power off -o tld_zxuno_map.ncd tld_zxuno.ngd tld_zxuno.pcf
par -filter "iseconfig/filter.filter" -w -intstyle ise -ol high tld_zxuno_map.ncd tld_zxuno.ncd tld_zxuno.pcf
trce -filter A:/zxuno/cores/spectrum_v2_spartan6/test14/iseconfig/filter.filter -intstyle ise -v 3 -s 3 -n 3 -fastpaths -xml tld_zxuno.twx tld_zxuno.ncd -o tld_zxuno.twr tld_zxuno.pcf -ucf pines_zxuno.ucf
bitgen -filter "iseconfig/filter.filter" -intstyle ise -f tld_zxuno.ut tld_zxuno.ncd

View File

@ -1,5 +1,5 @@
vhdl work "T80_Pack.vhd"
vhdl work "T80_Reg.vhd"
vhdl work "T80_Pack.vhd"
vhdl work "T80_MCode.vhd"
vhdl work "T80_ALU.vhd"
vhdl work "T80.vhd"
@ -7,7 +7,7 @@ vhdl work "YM2149_linmix.vhd"
vhdl work "T80a.vhd"
verilog work "spi.v"
verilog work "rom.v"
verilog work "pal_sync_generator_progressive.v"
verilog work "pal_sync_generator_sinclair.v"
vhdl work "mapa_teclado_es.vhd"
verilog work "lut.v"
verilog work "dp_memory.v"
@ -15,10 +15,12 @@ verilog work "zxunoregs.v"
verilog work "ula_radas.v"
verilog work "tv80_to_t80_wrapper.v"
verilog work "turbosound.v"
vhdl work "ps2k.vhd"
vhdl work "ps2k_mcleod.vhd"
verilog work "memory.v"
verilog work "joystick_protocols.v"
verilog work "flash_spi.v"
verilog work "coreid.v"
verilog work "audio_management.v"
verilog work "zxuno.v"
verilog work "relojes.v"
verilog work "relojes_pll.v"
verilog work "tld_zxuno.v"

View File

@ -29,8 +29,8 @@ module tld_zxuno (
output wire [2:0] b,
output wire csync,
input wire ear,
input wire clkps2,
input wire dataps2,
inout wire clkps2,
inout wire dataps2,
output wire audio_out_left,
output wire audio_out_right,
output wire stdn,

View File

@ -37,7 +37,7 @@ run
-rom_style Auto
-auto_bram_packing NO
-resource_sharing NO
-async_to_sync NO
-async_to_sync YES
-shreg_min_size 2
-use_dsp48 auto
-iobuf YES

View File

@ -85,7 +85,7 @@ module ula_radas (
assign clkdac = clk7;
assign clkay = hc[0];
assign clkkbd = hc[4];
assign clkkbd = clk7; /* hc[4] */
pal_sync_generator_sinclair syncs (
.clk(clk7),

View File

@ -3,11 +3,11 @@
<!--The data in this file is primarily intended for consumption by Xilinx tools.
The structure and the elements are likely to change over the next few releases.
This means code written to parse this file will need to be revisited each subsequent release.-->
<application name="pn" timeStamp="Tue Dec 09 13:36:54 2014">
<application name="pn" timeStamp="Mon Jun 08 01:38:44 2015">
<section name="Project Information" visible="false">
<property name="ProjectID" value="45174291E9A04A838B31B9E73C842F3B" type="project"/>
<property name="ProjectIteration" value="5" type="project"/>
<property name="ProjectFile" value="A:/zxuno/cores/spectrum_v2_spartan6/test14/zxuno.xise" type="project"/>
<property name="ProjectIteration" value="0" type="project"/>
<property name="ProjectFile" value="A:/zxuno/cores/spectrum_v2_spartan6/test16/zxuno.xise" type="project"/>
<property name="ProjectCreationTimestamp" value="2014-02-16T16:54:30" type="project"/>
</section>
<section name="Project Statistics" visible="true">
@ -21,7 +21,7 @@ This means code written to parse this file will need to be revisited each subseq
<property name="PROP_ManualCompileOrderImp" value="false" type="design"/>
<property name="PROP_MapLogicOptimization_spartan6" value="true" type="process"/>
<property name="PROP_PropSpecInProjFile" value="Store all values" type="design"/>
<property name="PROP_SelectedInstanceHierarchicalPath" value="/tb_ula" type="process"/>
<property name="PROP_SelectedInstanceHierarchicalPath" value="/tb_zxuno" type="process"/>
<property name="PROP_Simulator" value="ISim (VHDL/Verilog)" type="design"/>
<property name="PROP_SynthOptEffort" value="High" type="process"/>
<property name="PROP_SynthResSharing" value="false" type="process"/>
@ -31,11 +31,13 @@ This means code written to parse this file will need to be revisited each subseq
<property name="PROP_UserConstraintEditorPreference" value="Text Editor" type="process"/>
<property name="PROP_intProjectCreationTimestamp" value="2014-02-16T16:54:30" type="design"/>
<property name="PROP_intWbtProjectID" value="45174291E9A04A838B31B9E73C842F3B" type="design"/>
<property name="PROP_intWbtProjectIteration" value="5" type="process"/>
<property name="PROP_intWorkingDirLocWRTProjDir" value="Same" type="design"/>
<property name="PROP_intWorkingDirUsed" value="No" type="design"/>
<property name="PROP_selectedSimRootSourceNode_behav" value="work.tb_ula" type="process"/>
<property name="PROP_selectedSimRootSourceNode_behav" value="work.tb_zxuno" type="process"/>
<property name="PROP_xilxBitgCfg_Rate_spartan6" value="10" type="process"/>
<property name="PROP_xilxBitgCfg_SpiBusWidth_spartan6" value="4" type="process"/>
<property name="PROP_xilxMapCoverMode" value="Speed" type="process"/>
<property name="PROP_xstAsynToSync" value="true" type="process"/>
<property name="PROPEXT_mapTimingMode_spartan6" value="Non Timing Driven" type="process"/>
<property name="PROP_AutoTop" value="false" type="design"/>
<property name="PROP_CompxlibEdkSimLib" value="false" type="process"/>
@ -51,8 +53,8 @@ This means code written to parse this file will need to be revisited each subseq
<property name="PROP_DevSpeed" value="-3" type="design"/>
<property name="PROP_PreferredLanguage" value="Verilog" type="design"/>
<property name="FILE_UCF" value="1" type="source"/>
<property name="FILE_VERILOG" value="19" type="source"/>
<property name="FILE_VHDL" value="9" type="source"/>
<property name="FILE_VERILOG" value="23" type="source"/>
<property name="FILE_VHDL" value="12" type="source"/>
</section>
</application>
</document>

View File

@ -22,9 +22,105 @@
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="zxuno.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_NCD" xil_pn:name="tld_zxuno_guide.ncd" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_DIRECTORY" xil_pn:name="_ngo"/>
<file xil_pn:fileType="FILE_XMSGS" xil_pn:name="_xmsgs/map.xmsgs"/>
<file xil_pn:fileType="FILE_XMSGS" xil_pn:name="_xmsgs/ngdbuild.xmsgs"/>
<file xil_pn:fileType="FILE_XMSGS" xil_pn:name="_xmsgs/xst.xmsgs"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_NGDBUILD_LOG" xil_pn:name="tld_zxuno.bld"/>
<file xil_pn:fileType="FILE_CMD_LOG" xil_pn:name="tld_zxuno.cmd_log"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_LSO" xil_pn:name="tld_zxuno.lso"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_NGC" xil_pn:name="tld_zxuno.ngc"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_NGD" xil_pn:name="tld_zxuno.ngd"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_NGR" xil_pn:name="tld_zxuno.ngr"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_XST_PROJECT" xil_pn:name="tld_zxuno.prj"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_XST_STX" xil_pn:name="tld_zxuno.stx"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_XST_REPORT" xil_pn:name="tld_zxuno.syr"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_XST" xil_pn:name="tld_zxuno.xst"/>
<file xil_pn:fileType="FILE_HTML" xil_pn:name="tld_zxuno_envsettings.html"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_MAP_REPORT" xil_pn:name="tld_zxuno_map.map" xil_pn:subbranch="Map"/>
<file xil_pn:branch="Implementation" xil_pn:fileType="FILE_MAP_REPORT" xil_pn:name="tld_zxuno_map.mrp" xil_pn:subbranch="Map"/>
<file xil_pn:fileType="FILE_XRPT" xil_pn:name="tld_zxuno_ngdbuild.xrpt"/>
<file xil_pn:fileType="FILE_HTML" xil_pn:name="tld_zxuno_summary.html"/>
<file xil_pn:fileType="FILE_XRPT" xil_pn:name="tld_zxuno_xst.xrpt"/>
<file xil_pn:fileType="FILE_FITTER_REPORT" xil_pn:name="webtalk_pn.xml"/>
<file xil_pn:fileType="FILE_DIRECTORY" xil_pn:name="xlnx_auto_0_xdb"/>
<file xil_pn:fileType="FILE_DIRECTORY" xil_pn:name="xst"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema"/>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1433720323" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1433720323">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1433720323" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="-3524997284752945764" xil_pn:start_ts="1433720323">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1433720323" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="7188828471653365900" xil_pn:start_ts="1433720323">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1433720323" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1433720323">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1433720323" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="-9129001642772221986" xil_pn:start_ts="1433720323">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1433720323" xil_pn:name="TRAN_SubProjectPreToStructuralProxy" xil_pn:prop_ck="250970745955965653" xil_pn:start_ts="1433720323">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1433720323" xil_pn:name="TRAN_platgen" xil_pn:prop_ck="9132046586730190230" xil_pn:start_ts="1433720323">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1433720546" xil_pn:in_ck="3594304594023129945" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="-841030919764162094" xil_pn:start_ts="1433720323">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForOutputs"/>
<status xil_pn:value="OutputChanged"/>
<outfile xil_pn:name="_xmsgs/xst.xmsgs"/>
<outfile xil_pn:name="tld_zxuno.cmd_log"/>
<outfile xil_pn:name="tld_zxuno.lso"/>
<outfile xil_pn:name="tld_zxuno.ngc"/>
<outfile xil_pn:name="tld_zxuno.ngr"/>
<outfile xil_pn:name="tld_zxuno.prj"/>
<outfile xil_pn:name="tld_zxuno.stx"/>
<outfile xil_pn:name="tld_zxuno.syr"/>
<outfile xil_pn:name="tld_zxuno.xst"/>
<outfile xil_pn:name="tld_zxuno_envsettings.html"/>
<outfile xil_pn:name="tld_zxuno_summary.html"/>
<outfile xil_pn:name="tld_zxuno_xst.xrpt"/>
<outfile xil_pn:name="webtalk_pn.xml"/>
<outfile xil_pn:name="xst"/>
</transform>
<transform xil_pn:end_ts="1433720547" xil_pn:in_ck="8146865349285220654" xil_pn:name="TRAN_compileBCD2" xil_pn:prop_ck="-8119187138760779895" xil_pn:start_ts="1433720546">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1433720559" xil_pn:in_ck="6001021794932523067" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="5213230963878834957" xil_pn:start_ts="1433720547">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForOutputs"/>
<status xil_pn:value="OutputChanged"/>
<outfile xil_pn:name="_ngo"/>
<outfile xil_pn:name="_xmsgs/ngdbuild.xmsgs"/>
<outfile xil_pn:name="tld_zxuno.bld"/>
<outfile xil_pn:name="tld_zxuno.cmd_log"/>
<outfile xil_pn:name="tld_zxuno.ngd"/>
<outfile xil_pn:name="tld_zxuno_ngdbuild.xrpt"/>
<outfile xil_pn:name="xlnx_auto_0_xdb"/>
</transform>
<transform xil_pn:end_ts="1433720562" xil_pn:in_ck="6001021794932523068" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="-1827537523135263760" xil_pn:start_ts="1433720559">
<status xil_pn:value="FailedRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/map.xmsgs"/>
<outfile xil_pn:name="tld_zxuno_map.map"/>
<outfile xil_pn:name="tld_zxuno_map.mrp"/>
</transform>
</transforms>
</generated_project>

View File

@ -31,8 +31,8 @@ module zxuno (
output wire [2:0] g,
output wire [2:0] b,
output wire csync,
input wire clkps2,
input wire dataps2,
inout wire clkps2,
inout wire dataps2,
input wire ear,
output wire audio_out,
@ -88,6 +88,7 @@ module zxuno (
// Señales de acceso a registro de direcciones ZX-Uno
wire [7:0] zxuno_addr_to_cpu; // al bus de datos de entrada del Z80
wire [7:0] zxuno_addr; // direccion de registro actual
wire regaddr_changed; // indica que se ha escrito un nuevo valor en el registro de direcciones
wire oe_n_zxunoaddr; // el dato en el bus de entrada del Z80 es válido
wire zxuno_regrd; // Acceso de lectura en el puerto de datos de ZX-Uno
wire zxuno_regwr; // Acceso de escritura en el puerto de datos del ZX-Uno
@ -108,19 +109,32 @@ module zxuno (
wire [4:0] kbdcol;
wire [7:0] kbdrow;
wire mrst_n,rst_n; // los dos resets suministrados por el teclado
wire [7:0] scancode; // scancode original desde el teclado PC
wire read_scancode = (zxuno_addr==8'h04 && zxuno_regrd);
wire [7:0] scancode_dout; // scancode original desde el teclado PC
wire oe_n_scancode;
wire [7:0] keymap_dout;
wire oe_n_keymap;
wire [7:0] kbstatus_dout;
wire oe_n_kbstatus;
// Interfaz kempston
// Interfaz joystick configurable
wire oe_n_joystick;
wire [4:0] kbd_joy;
wire [4:0] db9_joy = {~joyfire, ~joyup, ~joydown, ~joyleft, ~joyright};
wire oe_n_kempston = !(!iorq_n && !rd_n && cpuaddr[7:0]==8'd31);
wire [7:0] joystick_dout;
wire [4:0] kbdcol_to_ula;
// Configuración ULA
wire timming_ula;
wire issue2_keyboard;
wire disable_contention;
wire access_to_screen;
// CoreID
wire oe_n_coreid;
wire [7:0] coreid_dout;
// Scratch register
wire oe_n_scratch;
wire [7:0] scratch_dout;
assign kbdrow = cpuaddr[15:8]; // las filas del teclado son A8-A15 de la CPU
@ -128,10 +142,14 @@ module zxuno (
// conectados a ella.
assign cpudin = (oe_n_romyram==1'b0)? memory_dout :
(oe_n_ay==1'b0)? ay_dout :
(oe_n_kempston==1'b0)? {3'b000,(kbd_joy/* | db9_joy*/)} :
(oe_n_joystick==1'b0)? joystick_dout :
(oe_n_zxunoaddr==1'b0)? zxuno_addr_to_cpu :
(oe_n_spi==1'b0)? spi_dout :
(read_scancode==1'b1)? scancode :
(oe_n_scancode==1'b0)? scancode_dout :
(oe_n_kbstatus==1'b0)? kbstatus_dout :
(oe_n_coreid==1'b0)? coreid_dout :
(oe_n_keymap==1'b0)? keymap_dout :
(oe_n_scratch==1'b0)? scratch_dout :
ula_dout;
tv80n_wrapper el_z80 (
@ -185,15 +203,15 @@ module zxuno (
// I/O ports
.ear(ear),
.mic(mic),
.spk(spk),
.kbd(kbdcol),
.clkay(clkay),
.clkdac(clkdac),
.clkkbd(clkkbd),
.issue2_keyboard(issue2_keyboard),
.timming(timming_ula),
.disable_contention(disable_contention),
.mic(mic),
.spk(spk),
.kbd(kbdcol_to_ula),
.clkay(clkay),
.clkdac(clkdac),
.clkkbd(clkkbd),
.issue2_keyboard(issue2_keyboard),
.timming(timming_ula),
.disable_contention(disable_contention),
// Video
.r(r),
@ -204,8 +222,7 @@ module zxuno (
zxunoregs addr_reg_zxuno (
.clk(clk7),
.rst_n(rst_n),
.mrst_n(mrst_n & power_on_reset_n),
.rst_n(rst_n & mrst_n & power_on_reset_n),
.a(cpuaddr),
.iorq_n(iorq_n),
.rd_n(rd_n),
@ -215,7 +232,8 @@ module zxuno (
.oe_n(oe_n_zxunoaddr),
.addr(zxuno_addr),
.read_from_reg(zxuno_regrd),
.write_to_reg(zxuno_regwr)
.write_to_reg(zxuno_regwr),
.regaddr_changed(regaddr_changed)
);
flash_and_sd cacharros_con_spi (
@ -283,19 +301,87 @@ module zxuno (
.sram_we_n(sram_we_n)
);
ps2k el_teclado (
.clk(clkkbd),
.ps2clk(clkps2),
.ps2data(dataps2),
// ps2k el_teclado (
// .clk(clkkbd),
// .ps2clk(clkps2),
// .ps2data(dataps2),
// .rows(kbdrow),
// .cols(kbdcol),
// .joy(kbd_joy), // Implementación joystick kempston en teclado numerico
// .scancode(scancode), // El scancode original desde el teclado
// .rst(rst_n), // esto son salidas, no entradas
// .nmi(nmi_n), // Señales de reset y NMI
// .mrst(mrst_n) // generadas por pulsaciones especiales del teclado
// );
ps2_keyb el_teclado (
.clk(clk),
.clkps2(clkps2),
.dataps2(dataps2),
.rows(kbdrow),
.cols(kbdcol),
.joy(kbd_joy), // Implementación joystick kempston en teclado numerico
.scancode(scancode), // El scancode original desde el teclado
.rst(rst_n), // esto son salidas, no entradas
.nmi(nmi_n), // Señales de reset y NMI
.mrst(mrst_n) // generadas por pulsaciones especiales del teclado
.rst_out_n(rst_n), // esto son salidas, no entradas
.nmi_out_n(nmi_n), // Señales de reset y NMI
.mrst_out_n(mrst_n), // generadas por pulsaciones especiales del teclado
//----------------------------
.zxuno_addr(zxuno_addr),
.zxuno_regrd(zxuno_regrd),
.zxuno_regwr(zxuno_regwr),
.regaddr_changed(regaddr_changed),
.din(cpudout),
.keymap_dout(keymap_dout),
.oe_n_keymap(oe_n_keymap),
.scancode_dout(scancode_dout),
.oe_n_scancode(oe_n_scancode),
.kbstatus_dout(kbstatus_dout),
.oe_n_kbstatus(oe_n_kbstatus)
);
joystick_protocols los_joysticks (
.clk(clk),
//-- cpu interface
.a(cpuaddr),
.iorq_n(iorq_n),
.rd_n(rd_n),
.din(cpudout),
.dout(joystick_dout),
.oe_n(oe_n_joystick),
//-- interface with ZXUNO reg bank
.zxuno_addr(zxuno_addr),
.zxuno_regrd(zxuno_regrd),
.zxuno_regwr(zxuno_regwr),
//-- actual joystick and keyboard signals
.kbdjoy_in(kbd_joy),
.db9joy_in({joyfire, joyup, joydown, joyleft, joyright}),
.kbdcol_in(kbdcol),
.kbdcol_out(kbdcol_to_ula),
.vertical_retrace_int_n(int_n) // this is used as base clock for autofire
);
coreid identificacion_del_core (
.clk(clk),
.rst_n(rst_n & mrst_n & power_on_reset_n),
.zxuno_addr(zxuno_addr),
.zxuno_regrd(zxuno_regrd),
.regaddr_changed(regaddr_changed),
.dout(coreid_dout),
.oe_n(oe_n_coreid)
);
scratch_register scratch (
.clk(clk),
.poweron_rst_n(power_on_reset_n),
.zxuno_addr(zxuno_addr),
.zxuno_regrd(zxuno_regrd),
.zxuno_regwr(zxuno_regwr),
.din(cpudout),
.dout(scratch_dout),
.oe_n(oe_n_scratch)
);
///////////////////////////////////
// AY-3-8912 SOUND
///////////////////////////////////

View File

@ -29,7 +29,10 @@
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file>
<file xil_pn:name="mapa_teclado_es.vhd" xil_pn:type="FILE_VHDL"/>
<file xil_pn:name="mapa_teclado_es.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file>
<file xil_pn:name="T80.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
@ -125,12 +128,33 @@
<association xil_pn:name="Implementation"/>
</file>
<file xil_pn:name="ps2k_av.vhd" xil_pn:type="FILE_VHDL"/>
<file xil_pn:name="ps2k_mcleod.vhd" xil_pn:type="FILE_VHDL"/>
<file xil_pn:name="ps2k_mcleod.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
<file xil_pn:name="ps2k_uk.vhd" xil_pn:type="FILE_VHDL">
</file>
<file xil_pn:name="mapa_teclado_uk.vhd" xil_pn:type="FILE_VHDL">
<file xil_pn:name="ps2k_uk.vhd" xil_pn:type="FILE_VHDL"/>
<file xil_pn:name="mapa_teclado_uk.vhd" xil_pn:type="FILE_VHDL"/>
<file xil_pn:name="ps2_keyb.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file>
<file xil_pn:name="ps2_port.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file>
<file xil_pn:name="scancode_to_speccy.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file>
<file xil_pn:name="joystick_protocols.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file>
<file xil_pn:name="coreid.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file>
<file xil_pn:name="scratch_register.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation"/>
<association xil_pn:name="Implementation"/>
</file>
@ -160,7 +184,7 @@
<property xil_pn:name="Case Implementation Style" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Change Device Speed To" xil_pn:value="-3" xil_pn:valueState="default"/>
<property xil_pn:name="Change Device Speed To Post Trace" xil_pn:value="-3" xil_pn:valueState="default"/>
<property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="false" xil_pn:valueState="non-default"/>
<property xil_pn:name="Compile SIMPRIM (Timing) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Compile UNISIM (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/>
@ -240,7 +264,7 @@
<property xil_pn:name="Generate Timegroups Section Post Trace" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Generics, Parameters" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Global Optimization Goal" xil_pn:value="AllClockNets" xil_pn:valueState="default"/>
<property xil_pn:name="Global Optimization map" xil_pn:value="Speed" xil_pn:valueState="non-default"/>
<property xil_pn:name="Global Optimization map" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="Global Set/Reset Port Name" xil_pn:value="GSR_PORT" xil_pn:valueState="default"/>
<property xil_pn:name="Global Tristate Port Name" xil_pn:value="GTS_PORT" xil_pn:valueState="default"/>
<property xil_pn:name="Hierarchy Separator" xil_pn:value="/" xil_pn:valueState="default"/>
@ -262,7 +286,7 @@
<property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/>
<property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="LUT Combining Map" xil_pn:value="Off" xil_pn:valueState="default"/>
<property xil_pn:name="LUT Combining Map" xil_pn:value="Area" xil_pn:valueState="non-default"/>
<property xil_pn:name="LUT Combining Xst" xil_pn:value="Auto" xil_pn:valueState="default"/>
<property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/>
<property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/>
@ -328,7 +352,7 @@
<property xil_pn:name="Place MultiBoot Settings into Bitstream spartan6" xil_pn:value="false" xil_pn:valueState="default"/>
<property xil_pn:name="Placer Effort Level (Overrides Overall Level)" xil_pn:value="None" xil_pn:valueState="default"/>
<property xil_pn:name="Placer Effort Level Map" xil_pn:value="High" xil_pn:valueState="default"/>
<property xil_pn:name="Placer Extra Effort Map" xil_pn:value="Normal" xil_pn:valueState="non-default"/>
<property xil_pn:name="Placer Extra Effort Map" xil_pn:value="Continue on Impossible" xil_pn:valueState="non-default"/>
<property xil_pn:name="Port to be used" xil_pn:value="Auto - default" xil_pn:valueState="default"/>
<property xil_pn:name="Post Map Simulation Model Name" xil_pn:value="tld_zxuno_map.v" xil_pn:valueState="default"/>
<property xil_pn:name="Post Place &amp; Route Simulation Model Name" xil_pn:value="tld_zxuno_timesim.v" xil_pn:valueState="default"/>

View File

@ -23,7 +23,6 @@
module zxunoregs (
input wire clk,
input wire rst_n,
input wire mrst_n,
input wire [15:0] a,
input wire iorq_n,
input wire rd_n,
@ -33,7 +32,8 @@ module zxunoregs (
output reg oe_n,
output wire [7:0] addr,
output wire read_from_reg,
output wire write_to_reg
output wire write_to_reg,
output wire regaddr_changed
);
parameter
@ -43,12 +43,20 @@ module zxunoregs (
// Manages register addr ($00 - $FF)
reg [7:0] raddr = 8'h00;
assign addr = raddr;
reg rregaddr_changed = 1'b0;
assign regaddr_changed = rregaddr_changed;
always @(posedge clk) begin
if (!rst_n)
if (!rst_n) begin
raddr <= 8'h00;
else if (!iorq_n && a==IOADDR && !wr_n)
rregaddr_changed <= 1'b1;
end
else if (!iorq_n && a==IOADDR && !wr_n) begin
raddr <= din;
rregaddr_changed <= 1'b1;
end
else
rregaddr_changed <= 1'b0;
end
always @* begin