mirror of https://github.com/zxdos/zxuno.git
631 lines
11 KiB
C
631 lines
11 KiB
C
/*
|
|
Compilar con:
|
|
sdcc -mz80 --reserve-regs-iy --opt-code-size --max-allocs-per-node X
|
|
--alow-unsafe-reads --nostdlib --nostdinc --no-std-crt0 --out-fmt-s19
|
|
--port-mode=z80 --code-loc 8192 --data-loc 0 --stack-loc 65535 joyconf.sdcc
|
|
*/
|
|
|
|
typedef unsigned char BYTE;
|
|
typedef unsigned short WORD;
|
|
|
|
enum {IBLACK=0, IBLUE, IRED, IMAG, IGREEN, ICYAN, IYELLOW, IWHITE};
|
|
enum {PBLACK=0, PBLUE=8, PRED=16, PMAG=24, PGREEN=32, PCYAN=40, PYELLOW=48, PWHITE=56};
|
|
#define BRIGHT 64
|
|
#define FLASH 128
|
|
|
|
__sfr __at (0xfe) ULA;
|
|
__sfr __at (0xff) ATTR;
|
|
__sfr __at (0x1f) KEMPSTONADDR;
|
|
|
|
__sfr __banked __at (0xf7fe) SEMIFILA1;
|
|
__sfr __banked __at (0xeffe) SEMIFILA2;
|
|
__sfr __banked __at (0xfbfe) SEMIFILA3;
|
|
__sfr __banked __at (0xdffe) SEMIFILA4;
|
|
__sfr __banked __at (0xfdfe) SEMIFILA5;
|
|
__sfr __banked __at (0xbffe) SEMIFILA6;
|
|
__sfr __banked __at (0xfefe) SEMIFILA7;
|
|
__sfr __banked __at (0x7ffe) SEMIFILA8;
|
|
|
|
#define COORDS 23296
|
|
#define SPOSN 23298
|
|
#define ATTRP 23300
|
|
#define BORDR 23301
|
|
#define CHARS 23606
|
|
#define LASTK 23560
|
|
|
|
#define COLUMN (SPOSN)
|
|
#define ROW (SPOSN+1)
|
|
|
|
#define WAIT_VRETRACE __asm halt __endasm
|
|
#define WAIT_HRETRACE while(ATTR!=0xff)
|
|
#define SETCOLOR(x) *(BYTE *)(ATTRP)=(x)
|
|
#define LASTKEY *(BYTE *)(LASTK)
|
|
|
|
__sfr __banked __at (0xfc3b) ZXUNOADDR;
|
|
__sfr __banked __at (0xfd3b) ZXUNODATA;
|
|
#define MASTERCONF 0
|
|
#define SCANCODE 4
|
|
#define KEYBSTAT 5
|
|
#define JOYCONF 6
|
|
#define COREID 255
|
|
|
|
void __sdcc_enter_ix (void) __naked;
|
|
void cls (BYTE);
|
|
void border (BYTE);
|
|
void locate (BYTE, BYTE);
|
|
|
|
void puts (BYTE *);
|
|
void putdec (WORD);
|
|
void u16todec (WORD, char *);
|
|
void u16tohex (WORD, char *);
|
|
void u8tohex (BYTE, char *);
|
|
|
|
void memset (BYTE *, BYTE, WORD);
|
|
void memcpy (BYTE *, BYTE *, WORD);
|
|
|
|
int abs (int);
|
|
signed char sgn (int);
|
|
|
|
long frames (void) __naked;
|
|
void pause (BYTE);
|
|
|
|
void wait_key (void);
|
|
BYTE inkey (BYTE, BYTE);
|
|
|
|
void beep (WORD, BYTE) __critical;
|
|
|
|
/* --------------------------------------------------------------------------------- */
|
|
/* --------------------------------------------------------------------------------- */
|
|
/* --------------------------------------------------------------------------------- */
|
|
BYTE printconf (void);
|
|
void printstatictext (void);
|
|
void getcoreid(BYTE *s);
|
|
|
|
void main (void)
|
|
{
|
|
border(IBLACK);
|
|
cls(BRIGHT|PBLACK|IWHITE);
|
|
printstatictext();
|
|
while(!printconf());
|
|
|
|
border(*(BYTE *)(23624));
|
|
cls(*(BYTE *)(23693));
|
|
}
|
|
|
|
void printstatictext (void)
|
|
{
|
|
char coreid[32];
|
|
|
|
locate(0,0);
|
|
puts ("\x4\x78\x6JOYSTICK CONFIGURATION AND TEST ");
|
|
|
|
locate(2,0);
|
|
puts ("KBD joystick: ");
|
|
|
|
locate(3,0);
|
|
puts ("DB9 joystick: ");
|
|
|
|
locate(5,0);
|
|
puts("\x4\x45Q/A to change KBD/DB9 protocol");
|
|
|
|
locate(6,0);
|
|
puts("\x4\x45W/S to change KBD/DB9 autofire");
|
|
|
|
locate(20,0);
|
|
puts("\x4\x47ZX-UNO Core ID: ");
|
|
coreid[0]=0x4;
|
|
coreid[1]=0x46;
|
|
getcoreid(coreid+2);
|
|
if (coreid[2]==0)
|
|
puts("\x4\x46NOT AVAILABLE");
|
|
else
|
|
puts(coreid);
|
|
|
|
locate(22,0);
|
|
puts("\x4\x70 Press SPACE to exit ");
|
|
}
|
|
|
|
void getcoreid(BYTE *s)
|
|
{
|
|
BYTE cont;
|
|
volatile BYTE letra;
|
|
|
|
s[0]='\0';
|
|
ZXUNOADDR = COREID;
|
|
cont=0;
|
|
while (ZXUNODATA!=0 && cont<32) cont++;
|
|
if (cont==32)
|
|
return;
|
|
cont=0;
|
|
do
|
|
{
|
|
letra = ZXUNODATA;
|
|
cont++;
|
|
}
|
|
while (letra==0 && cont<32);
|
|
if (cont==32)
|
|
return;
|
|
*(s++) = letra;
|
|
do
|
|
{
|
|
letra = ZXUNODATA;
|
|
*(s++) = letra;
|
|
}
|
|
while (letra!=0);
|
|
}
|
|
|
|
void printjoystat (char *proto, BYTE joy) // FUDLR
|
|
{
|
|
puts (proto);
|
|
if (joy&0x8)
|
|
puts ("\x4\x78 U ");
|
|
else
|
|
puts (" U ");
|
|
if (joy&0x4)
|
|
puts ("\x4\x78 D ");
|
|
else
|
|
puts (" D ");
|
|
if (joy&0x2)
|
|
puts ("\x4\x78 L ");
|
|
else
|
|
puts (" L ");
|
|
if (joy&0x1)
|
|
puts ("\x4\x78 R ");
|
|
else
|
|
puts (" R ");
|
|
if (joy&0x10)
|
|
puts ("\x4\x78 F ");
|
|
else
|
|
puts (" F ");
|
|
}
|
|
|
|
BYTE printconf (void)
|
|
{
|
|
BYTE kbconf, db9conf, kbdis=0, db9dis=0;
|
|
BYTE joy, joy1, joy2;
|
|
|
|
WAIT_VRETRACE;
|
|
ZXUNOADDR = JOYCONF;
|
|
kbconf = ZXUNODATA & 0x0f;
|
|
db9conf = (ZXUNODATA >> 4) & 0x0f;
|
|
locate(2,14);
|
|
switch (kbconf&0x7)
|
|
{
|
|
case 1: puts("\x4\x46""KEMPSTON"); break;
|
|
case 2: puts("\x4\x46""SINCL P1"); break;
|
|
case 3: puts("\x4\x46""SINCL P2"); break;
|
|
case 4: puts("\x4\x46""CURSOR "); break;
|
|
default: puts("\x4\x46""DISABLED"); kbdis=1; break;
|
|
}
|
|
if (!kbdis && kbconf&0x8)
|
|
puts("\x4\x45 AUTOFIRE");
|
|
else
|
|
puts(" ");
|
|
|
|
locate(3,14);
|
|
switch (db9conf&0x7)
|
|
{
|
|
case 1: puts("\x4\x46""KEMPSTON"); break;
|
|
case 2: puts("\x4\x46""SINCL P1"); break;
|
|
case 3: puts("\x4\x46""SINCL P2"); break;
|
|
case 4: puts("\x4\x46""CURSOR "); break;
|
|
default: puts("\x4\x46""DISABLED"); db9dis=1; break;
|
|
}
|
|
if (!db9dis && db9conf&0x8)
|
|
puts("\x4\x45 AUTOFIRE");
|
|
else
|
|
puts(" ");
|
|
|
|
if (LASTKEY == 'q' || LASTKEY == 'Q')
|
|
{
|
|
kbconf = kbconf&0x8 | (((kbconf&7)+1==5)? 0 : (kbconf&7)+1);
|
|
LASTKEY = 0;
|
|
}
|
|
else if (LASTKEY == 'a' || LASTKEY == 'A')
|
|
{
|
|
db9conf = db9conf&0x8 | (((db9conf&7)+1==5)? 0 : (db9conf&7)+1);
|
|
LASTKEY = 0;
|
|
}
|
|
else if (LASTKEY == 'w' || LASTKEY == 'W')
|
|
{
|
|
kbconf ^= 0x8;
|
|
LASTKEY = 0;
|
|
}
|
|
else if (LASTKEY == 's' || LASTKEY == 's')
|
|
{
|
|
db9conf ^= 0x8;
|
|
LASTKEY = 0;
|
|
}
|
|
ZXUNODATA = db9conf<<4 | kbconf;
|
|
|
|
joy = KEMPSTONADDR;
|
|
locate(9,0); printjoystat("\x4\x7Kempston : ", joy);
|
|
|
|
joy = ~SEMIFILA2; // LRDUF a FUDLR
|
|
joy = (joy&1)<<4 | (joy&2)<<2 | (joy&4) | (joy&0x10)>>3 | (joy&8)>>3;
|
|
locate(11,0); printjoystat("\x4\x7Sinclair 1: ", joy);
|
|
|
|
joy = ~SEMIFILA1; // FUDRL a FUDLR
|
|
joy = (joy&0x1c) | (joy&2)>>1 | (joy&1)<<1;
|
|
locate(13,0); printjoystat("\x4\x7Sinclair 2: ", joy);
|
|
|
|
joy1 = ~SEMIFILA2; // DUR-F a FUDLR
|
|
joy2 = ~SEMIFILA1; // L---- a FUDLR
|
|
joy = (joy1&1)<<4 | (joy1&8) | (joy1&0x10)>>2 | (joy2&0x10)>>3 | (joy1&4)>>2;
|
|
locate(15,0); printjoystat("\x4\x7""Cursor : ", joy);
|
|
|
|
if (LASTKEY==' ')
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* --------------------------------------------------------------------------------- */
|
|
/* --------------------------------------------------------------------------------- */
|
|
/* --------------------------------------------------------------------------------- */
|
|
#pragma disable_warning 85
|
|
int abs (int n)
|
|
{
|
|
return (n>=0)?n:-n;
|
|
}
|
|
|
|
signed char sgn (int n)
|
|
{
|
|
return (n>=0)?1:-1;
|
|
}
|
|
|
|
long frames (void) __naked
|
|
{
|
|
__asm
|
|
ld a,(#23672)
|
|
ld l,a
|
|
ld a,(#23673)
|
|
ld h,a
|
|
ld a,(#23674)
|
|
ld e,a
|
|
ld d,#0
|
|
ret
|
|
__endasm;
|
|
}
|
|
|
|
void pause (BYTE frames)
|
|
{
|
|
BYTE i;
|
|
|
|
for (i=0;i!=frames;i++)
|
|
{
|
|
WAIT_VRETRACE;
|
|
}
|
|
}
|
|
|
|
void memset (BYTE *dir, BYTE val, WORD nby)
|
|
{
|
|
__asm
|
|
push bc
|
|
push de
|
|
ld l,4(ix)
|
|
ld h,5(ix)
|
|
ld a,6(ix)
|
|
ld c,7(ix)
|
|
ld b,8(ix)
|
|
ld d,h
|
|
ld e,l
|
|
inc de
|
|
dec bc
|
|
ld (hl),a
|
|
ldir
|
|
pop de
|
|
pop bc
|
|
__endasm;
|
|
}
|
|
|
|
void memcpy (BYTE *dst, BYTE *fue, WORD nby)
|
|
{
|
|
__asm
|
|
push bc
|
|
push de
|
|
ld e,4(ix)
|
|
ld d,5(ix)
|
|
ld l,6(ix)
|
|
ld h,7(ix)
|
|
ld c,8(ix)
|
|
ld b,9(ix)
|
|
ldir
|
|
pop de
|
|
pop bc
|
|
__endasm;
|
|
}
|
|
|
|
void cls (BYTE attr)
|
|
{
|
|
#ifdef USEROM
|
|
__asm
|
|
push bc
|
|
push de
|
|
ld a,4(ix)
|
|
ld (#ATTRP),a
|
|
call #0x0d6b
|
|
ld a,#0xfe
|
|
call #0x1601
|
|
pop de
|
|
pop bc
|
|
__endasm;
|
|
#else
|
|
memset((BYTE *)16384,0,6144);
|
|
memset((BYTE *)22528,attr,768);
|
|
SETCOLOR(attr);
|
|
*((WORD *)SPOSN)=0;
|
|
#endif
|
|
}
|
|
|
|
void border (BYTE b)
|
|
{
|
|
ULA=(b>>3)&0x7;
|
|
*((BYTE *)BORDR)=b;
|
|
}
|
|
|
|
void puts (BYTE *str)
|
|
{
|
|
volatile BYTE over=0;
|
|
volatile BYTE bold=0;
|
|
volatile BYTE backup_attrp = *(BYTE *)(ATTRP);
|
|
|
|
__asm
|
|
push bc
|
|
push de
|
|
ld l,4(ix)
|
|
ld h,5(ix)
|
|
buc_print:
|
|
ld a,(hl)
|
|
or a
|
|
jr nz,no_fin_print
|
|
jp fin_print
|
|
no_fin_print:
|
|
cp #22
|
|
jr nz,no_at
|
|
inc hl
|
|
ld a,(hl)
|
|
ld (#ROW),a
|
|
inc hl
|
|
ld a,(hl)
|
|
ld (#COLUMN),a
|
|
inc hl
|
|
jr buc_print
|
|
no_at:
|
|
cp #13
|
|
jr nz,no_cr
|
|
xor a
|
|
ld (#COLUMN),a
|
|
ld a,(#ROW)
|
|
inc a
|
|
ld (#ROW),a
|
|
inc hl
|
|
jr buc_print
|
|
no_cr:
|
|
cp #4
|
|
jr nz,no_attr
|
|
inc hl
|
|
ld a,(hl)
|
|
ld (#ATTRP),a
|
|
inc hl
|
|
jr buc_print
|
|
no_attr:
|
|
cp #5
|
|
jr nz,no_pr_over
|
|
ld -1(ix),#0xff
|
|
inc hl
|
|
jr buc_print
|
|
no_pr_over:
|
|
cp #6
|
|
jr nz,no_pr_bold
|
|
ld -2(ix),#0xff
|
|
inc hl
|
|
jr buc_print
|
|
no_pr_bold:
|
|
cp #32
|
|
jr nc,imprimible
|
|
ld a,#32
|
|
imprimible:
|
|
push hl
|
|
ld hl,(#COLUMN)
|
|
push hl
|
|
push af
|
|
ld de,#16384
|
|
add hl,de
|
|
ld a,h
|
|
and #7
|
|
rrca
|
|
rrca
|
|
rrca
|
|
or l
|
|
ld l,a
|
|
ld a,#248
|
|
and h
|
|
ld h,a
|
|
pop af
|
|
push hl
|
|
ld de,(#CHARS)
|
|
ld l,a
|
|
ld h,#0
|
|
add hl,hl
|
|
add hl,hl
|
|
add hl,hl
|
|
add hl,de
|
|
pop de
|
|
|
|
ld b,#8
|
|
print_car:
|
|
ld a,(hl)
|
|
sra a
|
|
and -2(ix)
|
|
or (hl)
|
|
ld c,a
|
|
ld a,(de)
|
|
and -1(ix)
|
|
xor c
|
|
ld (de),a
|
|
inc hl
|
|
inc d
|
|
djnz print_car
|
|
|
|
pop hl
|
|
push hl
|
|
ld de,#22528
|
|
ld b,h
|
|
ld h,#0
|
|
add hl,de
|
|
xor a
|
|
or b
|
|
jr z,fin_ca_attr
|
|
ld de,#32
|
|
calc_dirat:
|
|
add hl,de
|
|
djnz calc_dirat
|
|
fin_ca_attr:
|
|
ld a,(#ATTRP)
|
|
ld (hl),a
|
|
pop hl
|
|
inc l
|
|
bit 5,l
|
|
jr z,no_inc_fila
|
|
res 5,l
|
|
inc h
|
|
no_inc_fila:
|
|
ld (#COLUMN),hl
|
|
pop hl
|
|
inc hl
|
|
jp buc_print
|
|
|
|
fin_print:
|
|
pop de
|
|
pop bc
|
|
__endasm;
|
|
|
|
SETCOLOR(backup_attrp);
|
|
}
|
|
|
|
void locate (BYTE row, BYTE col)
|
|
{
|
|
*((BYTE *)ROW)=row;
|
|
*((BYTE *)COLUMN)=col;
|
|
}
|
|
|
|
// void putdec (WORD n)
|
|
// {
|
|
// BYTE num[6];
|
|
//
|
|
// u16todec (n,num);
|
|
// puts (num);
|
|
// }
|
|
//
|
|
// void u16todec (WORD n, char *s)
|
|
// {
|
|
// BYTE i=4;
|
|
// WORD divisor=10, resto;
|
|
//
|
|
// memset(s,' ',5);
|
|
// do
|
|
// {
|
|
// resto=n%divisor;
|
|
// n/=divisor;
|
|
// s[i--]=resto+'0';
|
|
// }
|
|
// while (n);
|
|
// s[5]='\0';
|
|
// }
|
|
|
|
void u16tohex (WORD n, char *s)
|
|
{
|
|
u8tohex((n>>8)&0xFF,s);
|
|
u8tohex(n&0xFF,s+2);
|
|
}
|
|
|
|
void u8tohex (BYTE n, char *s)
|
|
{
|
|
BYTE i=1;
|
|
BYTE resto;
|
|
|
|
resto=n&0xF;
|
|
s[1]=(resto>9)?resto+55:resto+48;
|
|
resto=n>>4;
|
|
s[0]=(resto>9)?resto+55:resto+48;
|
|
s[2]='\0';
|
|
}
|
|
|
|
void wait_key (void)
|
|
{
|
|
while ((ULA&0x1f)==0x1f);
|
|
}
|
|
|
|
BYTE inkey (BYTE semif, BYTE pos)
|
|
{
|
|
BYTE teclas;
|
|
BYTE posbit;
|
|
|
|
switch (semif)
|
|
{
|
|
case 1: teclas=SEMIFILA1; break;
|
|
case 2: teclas=SEMIFILA2; break;
|
|
case 3: teclas=SEMIFILA3; break;
|
|
case 4: teclas=SEMIFILA4; break;
|
|
case 5: teclas=SEMIFILA5; break;
|
|
case 6: teclas=SEMIFILA6; break;
|
|
case 7: teclas=SEMIFILA7; break;
|
|
case 8: teclas=SEMIFILA8; break;
|
|
default: teclas=ULA; break;
|
|
}
|
|
posbit=1<<(pos-1);
|
|
return (teclas&posbit)?0:1;
|
|
}
|
|
|
|
void beep (WORD durmili, BYTE freq) __critical
|
|
{
|
|
volatile BYTE cborde;
|
|
|
|
cborde=(*(BYTE *)(BORDR));
|
|
__asm
|
|
push bc
|
|
push de
|
|
|
|
ld l,6(ix) ;se desplaza dos byte por ser "critical".
|
|
ld h,7(ix)
|
|
ld d,-1(ix)
|
|
|
|
ld b,8(ix)
|
|
xor a
|
|
sub b
|
|
ld b,a
|
|
ld c,a
|
|
|
|
bucbeep:
|
|
ld a,d
|
|
xor #0x18
|
|
ld d,a
|
|
out (#254),a
|
|
|
|
ld b,c
|
|
bucperiodobeep:
|
|
djnz bucperiodobeep
|
|
|
|
dec hl
|
|
ld a,h
|
|
or l
|
|
jr nz,bucbeep
|
|
|
|
pop de
|
|
pop bc
|
|
__endasm;
|
|
}
|
|
|
|
void __sdcc_enter_ix (void) __naked
|
|
{
|
|
__asm
|
|
pop hl ; return address
|
|
push ix ; save frame pointer
|
|
ld ix,#0
|
|
add ix,sp ; set ix to the stack frame
|
|
jp (hl) ; and return
|
|
__endasm;
|
|
}
|