Implemented the SMC FDC37C932QFP NVR stuff. It doesn't fix that HP Vectra, but it's still nice to have it just in case.
This commit is contained in:
@@ -50,7 +50,7 @@
|
|||||||
# define EMU_NVR_H
|
# define EMU_NVR_H
|
||||||
|
|
||||||
|
|
||||||
#define NVR_MAXSIZE 256 /* max size of NVR data */
|
#define NVR_MAXSIZE 512 /* max size of NVR data */
|
||||||
|
|
||||||
/* Conversion from BCD to Binary and vice versa. */
|
/* Conversion from BCD to Binary and vice versa. */
|
||||||
#define RTC_BCD(x) (((x) % 10) | (((x) / 10) << 4))
|
#define RTC_BCD(x) (((x) % 10) | (((x) / 10) << 4))
|
||||||
@@ -113,7 +113,10 @@ extern void nvr_time_get(struct tm *);
|
|||||||
extern void nvr_time_set(struct tm *);
|
extern void nvr_time_set(struct tm *);
|
||||||
|
|
||||||
extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr);
|
extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr);
|
||||||
|
extern void nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr);
|
||||||
extern void nvr_wp_set(int set, int h, nvr_t *nvr);
|
extern void nvr_wp_set(int set, int h, nvr_t *nvr);
|
||||||
|
extern void nvr_bank_set(int base, uint8_t bank, nvr_t *nvr);
|
||||||
|
extern void nvr_lock_set(int base, int size, int lock, nvr_t *nvr);
|
||||||
|
|
||||||
|
|
||||||
#endif /*EMU_NVR_H*/
|
#endif /*EMU_NVR_H*/
|
||||||
|
|||||||
@@ -427,7 +427,7 @@ machine_at_vectra54_init(const machine_t *model)
|
|||||||
if (bios_only || !ret)
|
if (bios_only || !ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
machine_at_common_init(model);
|
machine_at_common_init_ex(model, 2);
|
||||||
|
|
||||||
pci_init(PCI_CONFIG_TYPE_1);
|
pci_init(PCI_CONFIG_TYPE_1);
|
||||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ const machine_t machines[] = {
|
|||||||
|
|
||||||
{ "[Socket 5 FX] AMI Apollo", "apollo", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_apollo_init, NULL },
|
{ "[Socket 5 FX] AMI Apollo", "apollo", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_apollo_init, NULL },
|
||||||
#if defined(DEV_BRANCH) && defined(USE_VECTRA54)
|
#if defined(DEV_BRANCH) && defined(USE_VECTRA54)
|
||||||
{ "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 767, machine_at_vectra54_init, NULL },
|
{ "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 511, machine_at_vectra54_init, NULL },
|
||||||
#endif
|
#endif
|
||||||
{ "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL },
|
{ "[Socket 5 FX] Intel Advanced/ZP", "zappa", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_zappa_init, NULL },
|
||||||
{ "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL },
|
{ "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL },
|
||||||
|
|||||||
58
src/nvr_at.c
58
src/nvr_at.c
@@ -296,7 +296,8 @@ typedef struct {
|
|||||||
uint8_t cent;
|
uint8_t cent;
|
||||||
uint8_t def, flags;
|
uint8_t def, flags;
|
||||||
|
|
||||||
uint8_t addr[8], wp[2];
|
uint8_t addr[8], wp[2],
|
||||||
|
bank[8], *lock;
|
||||||
|
|
||||||
int16_t count, state;
|
int16_t count, state;
|
||||||
|
|
||||||
@@ -566,6 +567,8 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
sub_cycles(ISA_CYCLES(8));
|
sub_cycles(ISA_CYCLES(8));
|
||||||
|
|
||||||
if (addr & 1) {
|
if (addr & 1) {
|
||||||
|
if (local->bank[addr_id] == 0xff)
|
||||||
|
return;
|
||||||
old = nvr->regs[local->addr[addr_id]];
|
old = nvr->regs[local->addr[addr_id]];
|
||||||
switch(local->addr[addr_id]) {
|
switch(local->addr[addr_id]) {
|
||||||
case RTC_REGA:
|
case RTC_REGA:
|
||||||
@@ -603,6 +606,8 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
if ((local->addr[addr_id] >= 0xb8) && (local->addr[addr_id] <= 0xbf) && local->wp[1])
|
if ((local->addr[addr_id] >= 0xb8) && (local->addr[addr_id] <= 0xbf) && local->wp[1])
|
||||||
break;
|
break;
|
||||||
|
if (local->lock[local->addr[addr_id]])
|
||||||
|
break;
|
||||||
if (nvr->regs[local->addr[addr_id]] != val) {
|
if (nvr->regs[local->addr[addr_id]] != val) {
|
||||||
nvr->regs[local->addr[addr_id]] = val;
|
nvr->regs[local->addr[addr_id]] = val;
|
||||||
nvr_dosave = 1;
|
nvr_dosave = 1;
|
||||||
@@ -627,6 +632,8 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
local->addr[addr_id] &= 0x7f;
|
local->addr[addr_id] &= 0x7f;
|
||||||
else if ((addr_id == 0x1) && (local->flags & FLAG_PIIX4))
|
else if ((addr_id == 0x1) && (local->flags & FLAG_PIIX4))
|
||||||
local->addr[addr_id] = (local->addr[addr_id] & 0x7f) | 0x80;
|
local->addr[addr_id] = (local->addr[addr_id] & 0x7f) | 0x80;
|
||||||
|
if (local->bank[addr_id] > 0)
|
||||||
|
local->addr[addr_id] = (local->addr[addr_id] & 0x7f) | (0x80 * local->bank[addr_id]);
|
||||||
if (!(machines[machine].flags & MACHINE_MCA) &&
|
if (!(machines[machine].flags & MACHINE_MCA) &&
|
||||||
!(machines[machine].flags & MACHINE_NONMI))
|
!(machines[machine].flags & MACHINE_NONMI))
|
||||||
nmi_mask = (~val & 0x80);
|
nmi_mask = (~val & 0x80);
|
||||||
@@ -646,6 +653,9 @@ nvr_read(uint16_t addr, void *priv)
|
|||||||
|
|
||||||
sub_cycles(ISA_CYCLES(8));
|
sub_cycles(ISA_CYCLES(8));
|
||||||
|
|
||||||
|
if ((addr & 1) && (local->bank[addr_id] == 0xff))
|
||||||
|
return 0xff;
|
||||||
|
|
||||||
if (addr & 1) switch(local->addr[addr_id]) {
|
if (addr & 1) switch(local->addr[addr_id]) {
|
||||||
case RTC_REGA:
|
case RTC_REGA:
|
||||||
ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat;
|
ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat;
|
||||||
@@ -693,6 +703,22 @@ nvr_read(uint16_t addr, void *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Secondary NVR write - used by SMC. */
|
||||||
|
static void
|
||||||
|
nvr_sec_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
nvr_write(0x72 + (addr & 1), val, priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Secondary NVR read - used by SMC. */
|
||||||
|
static uint8_t
|
||||||
|
nvr_sec_read(uint16_t addr, void *priv)
|
||||||
|
{
|
||||||
|
return nvr_read(0x72 + (addr & 1), priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Reset the RTC state to 1980/01/01 00:00. */
|
/* Reset the RTC state to 1980/01/01 00:00. */
|
||||||
static void
|
static void
|
||||||
nvr_reset(nvr_t *nvr)
|
nvr_reset(nvr_t *nvr)
|
||||||
@@ -771,6 +797,14 @@ nvr_at_handler(int set, uint16_t base, nvr_t *nvr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nvr_at_sec_handler(int set, uint16_t base, nvr_t *nvr)
|
||||||
|
{
|
||||||
|
io_handler(set, base, 2,
|
||||||
|
nvr_sec_read,NULL,NULL, nvr_sec_write,NULL,NULL, nvr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nvr_wp_set(int set, int h, nvr_t *nvr)
|
nvr_wp_set(int set, int h, nvr_t *nvr)
|
||||||
{
|
{
|
||||||
@@ -780,6 +814,26 @@ nvr_wp_set(int set, int h, nvr_t *nvr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nvr_bank_set(int base, uint8_t bank, nvr_t *nvr)
|
||||||
|
{
|
||||||
|
local_t *local = (local_t *) nvr->data;
|
||||||
|
|
||||||
|
local->bank[base] = bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nvr_lock_set(int base, int size, int lock, nvr_t *nvr)
|
||||||
|
{
|
||||||
|
local_t *local = (local_t *) nvr->data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
local->lock[base + i] = lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
nvr_at_init(const device_t *info)
|
nvr_at_init(const device_t *info)
|
||||||
{
|
{
|
||||||
@@ -797,6 +851,8 @@ nvr_at_init(const device_t *info)
|
|||||||
|
|
||||||
/* This is machine specific. */
|
/* This is machine specific. */
|
||||||
nvr->size = machines[machine].nvrmask + 1;
|
nvr->size = machines[machine].nvrmask + 1;
|
||||||
|
local->lock = (uint8_t *) malloc(nvr->size);
|
||||||
|
memset(local->lock, 0x00, nvr->size);
|
||||||
local->def = 0x00;
|
local->def = 0x00;
|
||||||
local->flags = 0x00;
|
local->flags = 0x00;
|
||||||
switch(info->local & 7) {
|
switch(info->local & 7) {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <86box/hdc_ide.h>
|
#include <86box/hdc_ide.h>
|
||||||
#include <86box/fdd.h>
|
#include <86box/fdd.h>
|
||||||
#include <86box/fdc.h>
|
#include <86box/fdc.h>
|
||||||
|
#include <86box/nvr.h>
|
||||||
#include <86box/sio.h>
|
#include <86box/sio.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -51,12 +52,13 @@ typedef struct {
|
|||||||
regs[48],
|
regs[48],
|
||||||
ld_regs[10][256];
|
ld_regs[10][256];
|
||||||
uint16_t gpio_base, /* Set to EA */
|
uint16_t gpio_base, /* Set to EA */
|
||||||
auxio_base;
|
auxio_base, nvr_sec_base;
|
||||||
int locked,
|
int locked,
|
||||||
cur_reg;
|
cur_reg;
|
||||||
fdc_t *fdc;
|
fdc_t *fdc;
|
||||||
serial_t *uart[2];
|
serial_t *uart[2];
|
||||||
access_bus_t *access_bus;
|
access_bus_t *access_bus;
|
||||||
|
nvr_t *nvr;
|
||||||
} fdc37c93x_t;
|
} fdc37c93x_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -72,6 +74,18 @@ make_port(fdc37c93x_t *dev, uint8_t ld)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint16_t
|
||||||
|
make_port_sec(fdc37c93x_t *dev, uint8_t ld)
|
||||||
|
{
|
||||||
|
uint16_t r0 = dev->ld_regs[ld][0x62];
|
||||||
|
uint16_t r1 = dev->ld_regs[ld][0x63];
|
||||||
|
|
||||||
|
uint16_t p = (r0 << 8) + r1;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
fdc37c93x_auxio_read(uint16_t port, void *priv)
|
fdc37c93x_auxio_read(uint16_t port, void *priv)
|
||||||
{
|
{
|
||||||
@@ -162,7 +176,34 @@ fdc37c93x_serial_handler(fdc37c93x_t *dev, int uart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fdc37c93x_auxio_handler(fdc37c93x_t *dev)
|
static void
|
||||||
|
fdc37c93x_nvr_pri_handler(fdc37c93x_t *dev)
|
||||||
|
{
|
||||||
|
uint8_t local_enable = !!dev->ld_regs[6][0x30];
|
||||||
|
|
||||||
|
nvr_at_handler(0, 0x70, dev->nvr);
|
||||||
|
if (local_enable)
|
||||||
|
nvr_at_handler(1, 0x70, dev->nvr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev)
|
||||||
|
{
|
||||||
|
uint16_t ld_port = 0;
|
||||||
|
uint8_t local_enable = !!dev->ld_regs[6][0x30];
|
||||||
|
|
||||||
|
nvr_at_sec_handler(0, dev->nvr_sec_base, dev->nvr);
|
||||||
|
if (local_enable) {
|
||||||
|
dev->nvr_sec_base = ld_port = make_port_sec(dev, 6);
|
||||||
|
if ((ld_port >= 0x0100) && (ld_port <= 0x0FFE))
|
||||||
|
nvr_at_sec_handler(1, ld_port, dev->nvr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
fdc37c93x_auxio_handler(fdc37c93x_t *dev)
|
||||||
{
|
{
|
||||||
uint16_t ld_port = 0;
|
uint16_t ld_port = 0;
|
||||||
uint8_t local_enable = !!dev->ld_regs[8][0x30];
|
uint8_t local_enable = !!dev->ld_regs[8][0x30];
|
||||||
@@ -321,7 +362,6 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
else switch (dev->regs[7]) {
|
else switch (dev->regs[7]) {
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
case 6:
|
|
||||||
case 7:
|
case 7:
|
||||||
return;
|
return;
|
||||||
case 9:
|
case 9:
|
||||||
@@ -443,6 +483,60 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
/* RTC/NVR */
|
||||||
|
if (dev->chip_id != 0x30)
|
||||||
|
break;
|
||||||
|
switch(dev->cur_reg) {
|
||||||
|
case 0x30:
|
||||||
|
if (valxor)
|
||||||
|
fdc37c93x_nvr_pri_handler(dev);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 0x60:
|
||||||
|
case 0x61:
|
||||||
|
if (valxor)
|
||||||
|
fdc37c93x_nvr_sec_handler(dev);
|
||||||
|
break;
|
||||||
|
case 0xf0:
|
||||||
|
if (valxor) {
|
||||||
|
nvr_lock_set(0x80, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x01), dev->nvr);
|
||||||
|
nvr_lock_set(0xa0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x02), dev->nvr);
|
||||||
|
nvr_lock_set(0xc0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x04), dev->nvr);
|
||||||
|
nvr_lock_set(0xe0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x08), dev->nvr);
|
||||||
|
if (dev->ld_regs[6][dev->cur_reg] & 0x80) switch ((dev->ld_regs[6][dev->cur_reg] >> 4) & 0x07) {
|
||||||
|
case 0x00:
|
||||||
|
default:
|
||||||
|
nvr_bank_set(0, 0xff, dev->nvr);
|
||||||
|
nvr_bank_set(1, 1, dev->nvr);
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
nvr_bank_set(0, 0, dev->nvr);
|
||||||
|
nvr_bank_set(1, 1, dev->nvr);
|
||||||
|
break;
|
||||||
|
case 0x02: case 0x04:
|
||||||
|
nvr_bank_set(0, 0xff, dev->nvr);
|
||||||
|
nvr_bank_set(1, 0xff, dev->nvr);
|
||||||
|
break;
|
||||||
|
case 0x03: case 0x05:
|
||||||
|
nvr_bank_set(0, 0, dev->nvr);
|
||||||
|
nvr_bank_set(1, 0xff, dev->nvr);
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
nvr_bank_set(0, 0xff, dev->nvr);
|
||||||
|
nvr_bank_set(1, 2, dev->nvr);
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
nvr_bank_set(0, 0, dev->nvr);
|
||||||
|
nvr_bank_set(1, 2, dev->nvr);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
nvr_bank_set(0, 0, dev->nvr);
|
||||||
|
nvr_bank_set(1, 0xff, dev->nvr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
/* Auxiliary I/O */
|
/* Auxiliary I/O */
|
||||||
switch(dev->cur_reg) {
|
switch(dev->cur_reg) {
|
||||||
@@ -508,8 +602,8 @@ fdc37c93x_reset(fdc37c93x_t *dev)
|
|||||||
memset(dev->regs, 0, 48);
|
memset(dev->regs, 0, 48);
|
||||||
|
|
||||||
dev->regs[0x03] = 0x03;
|
dev->regs[0x03] = 0x03;
|
||||||
dev->regs[0x21] = 0x01;
|
|
||||||
dev->regs[0x20] = dev->chip_id;
|
dev->regs[0x20] = dev->chip_id;
|
||||||
|
dev->regs[0x21] = 0x01;
|
||||||
dev->regs[0x22] = 0x39;
|
dev->regs[0x22] = 0x39;
|
||||||
dev->regs[0x24] = 0x04;
|
dev->regs[0x24] = 0x04;
|
||||||
dev->regs[0x26] = 0xF0;
|
dev->regs[0x26] = 0xF0;
|
||||||
@@ -571,7 +665,8 @@ fdc37c93x_reset(fdc37c93x_t *dev)
|
|||||||
serial_setup(dev->uart[1], 0x2f8, dev->ld_regs[5][0x70]);
|
serial_setup(dev->uart[1], 0x2f8, dev->ld_regs[5][0x70]);
|
||||||
|
|
||||||
/* Logical device 6: RTC */
|
/* Logical device 6: RTC */
|
||||||
dev->ld_regs[6][0x63] = 0x70;
|
dev->ld_regs[5][0x30] = 1;
|
||||||
|
dev->ld_regs[6][0x63] = 0x00;
|
||||||
dev->ld_regs[6][0xF4] = 3;
|
dev->ld_regs[6][0xF4] = 3;
|
||||||
|
|
||||||
/* Logical device 7: Keyboard */
|
/* Logical device 7: Keyboard */
|
||||||
@@ -652,6 +747,13 @@ fdc37c93x_init(const device_t *info)
|
|||||||
dev->gpio_regs[0] = 0xFD;
|
dev->gpio_regs[0] = 0xFD;
|
||||||
dev->gpio_regs[1] = 0xFF;
|
dev->gpio_regs[1] = 0xFF;
|
||||||
|
|
||||||
|
if (dev->chip_id == 0x30) {
|
||||||
|
dev->nvr = device_add(&at_nvr_device);
|
||||||
|
|
||||||
|
nvr_bank_set(0, 0, dev->nvr);
|
||||||
|
nvr_bank_set(1, 0xff, dev->nvr);
|
||||||
|
}
|
||||||
|
|
||||||
if (dev->chip_id == 0x03)
|
if (dev->chip_id == 0x03)
|
||||||
dev->access_bus = device_add(&access_bus_device);
|
dev->access_bus = device_add(&access_bus_device);
|
||||||
|
|
||||||
@@ -676,7 +778,7 @@ const device_t fdc37c932fr_device = {
|
|||||||
const device_t fdc37c932qf_device = {
|
const device_t fdc37c932qf_device = {
|
||||||
"SMC FDC37C932QF Super I/O",
|
"SMC FDC37C932QF Super I/O",
|
||||||
0,
|
0,
|
||||||
0x02, /* Share the same ID with the 935. */
|
0x30, /* Share the same ID with the 935. */
|
||||||
fdc37c93x_init, fdc37c93x_close, NULL,
|
fdc37c93x_init, fdc37c93x_close, NULL,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
NULL
|
NULL
|
||||||
|
|||||||
Reference in New Issue
Block a user