284 lines
7.5 KiB
NASM
284 lines
7.5 KiB
NASM
;param 1 (in r4) : Adress of an array of two unsigned char, with in the first cell the col, and in the second the row
|
|
;param 2 (in r5) : slowMode : this determine the time this function will wait to emulate the olds functions
|
|
; -n : number of loop
|
|
; 0 : fatest as possible
|
|
; 1 : = duration of IsKeyDown function
|
|
; 2 : = duration of IsKeyUp function
|
|
; 3 : = duration of KeyDown function
|
|
;return (in r0) 1 if the key is pressed.
|
|
_GetKeyState
|
|
;First put current register values in the stack
|
|
sts.l pr,@-r15
|
|
mov.l r1,@-r15
|
|
mov.l r2,@-r15
|
|
mov.l r3,@-r15
|
|
mov.l r6,@-r15
|
|
mov.l r7,@-r15
|
|
mov.l r8,@-r15
|
|
mov.l r9,@-r15
|
|
mov r4,r8 ; first param
|
|
mov r5,r9 ; second param
|
|
|
|
;check the os version with the syscall 0x0015 | if I use only 1 byte for chars, and 2 for short, it crash on all calc but not on emulator. But these type are valid because the syscall only edit the correct number of byte.
|
|
add #-4,r15 ; main version : unsigned char
|
|
mov r15,r4
|
|
add #-4,r15 ; minor version : unsigned char
|
|
mov r15,r5
|
|
add #-4,r15 ; release : unsigned short
|
|
mov r15,r6
|
|
add #-4,r15 ; build : unsigned short
|
|
mov r15,r7
|
|
;call syscall
|
|
mov.l #h'80010070,r2
|
|
jsr @r2
|
|
mov #h'15,r0
|
|
;put os version into r6
|
|
add #8,r15
|
|
mov.b @r15,r6 ; minor version
|
|
add #4,r15
|
|
mov.b @r15,r0 ; main version
|
|
add #4,r15
|
|
shll8 r0 ; r0 = r0<<8
|
|
add r0,r6
|
|
;reserved registers :
|
|
;r9 second param
|
|
;r6 OS version
|
|
; read and checks coords
|
|
mov.b @r8,r7 ; r7 = Key's column
|
|
mov.b @(1,r8),r0
|
|
mov r0,r8 ; r8 = Key's row
|
|
;verify the row value : 0 ≤ row ≤ 9
|
|
mov #0, r0
|
|
cmp/gt r8,r0 ; if r0 > r8 ⇒ if 0 > row
|
|
bt NegativeEnd
|
|
mov #9,r1
|
|
cmp/gt r1,r8 ; if r8 > r1 ⇒ if row > 9
|
|
bt NegativeEnd
|
|
;verify the column value : 0 ≤ row ≤ 6
|
|
cmp/gt r7,r0 ; if r0 > r7 ⇒ if 0 > column
|
|
bt NegativeEnd
|
|
mov #6,r1
|
|
cmp/gt r1,r7 ; if r7 > r1 ⇒ if column > 6
|
|
bt NegativeEnd
|
|
;check if os is > 2.02
|
|
mov.w #h'0202,r0
|
|
cmp/ge r0,r6 ; r0 ≤ r6
|
|
bt SH4
|
|
;reserved registers :
|
|
;r9 second param
|
|
;r8 Key's row
|
|
;r7 Key's col
|
|
;SH3 part
|
|
;r6 = smask = 0x0003 << (( row %8)*2);
|
|
mov r8,r0 ; row->r0
|
|
and #7,r0 ; %8
|
|
add r0,r0 ; *2
|
|
mov #3,r6
|
|
shld r0,r6 ; 3<<
|
|
;r5 = cmask = ~( 1 << ( row %8) );
|
|
mov r8,r0 ; row->r0
|
|
and #7,r0 ; %8
|
|
mov #1,r5
|
|
shld r0,r5 ; 1<<
|
|
not r5,r5 ; ~
|
|
;reserved registers :
|
|
;r9 second param
|
|
;r8 Key's row
|
|
;r7 Key's col
|
|
;r6 smask
|
|
;r5 cmask
|
|
;Preparation of the gbr register
|
|
mov.l #h'A4000100,r0
|
|
ldc r0,gbr
|
|
;RowCond : if(row <8)
|
|
mov #8,r0
|
|
cmp/gt r8,r0 ; if r0>r8 ; row>=8
|
|
bf rowCond_Else
|
|
;rowCond_begin
|
|
;*PORTB_CTRL = 0xAAAA ^ smask;
|
|
mov r6,r0
|
|
mov.w #h'AAAA,r1
|
|
xor r1,r0
|
|
mov.w r0,@(h'02,gbr)
|
|
;*PORTM_CTRL = (*PORTM_CTRL & 0xFF00 ) | 0x00AA;
|
|
mov.w @(h'18,gbr),r0 ; *PORTM_CTRL->r0
|
|
mov.w #h'FF00,r1
|
|
and r1,r0 ; *PORTM_CTRL & 0xFF00
|
|
or #h'AA,r0 ; | 0x00AA;
|
|
mov.w r0,@(h'18,gbr)
|
|
;delay()
|
|
bsr delay
|
|
mov #-10,r4
|
|
;*PORTB = cmask;
|
|
mov r5,r0
|
|
mov.b r0,@(h'22,gbr) ;PORTB = cmask
|
|
;*PORTM = (*PORTM & 0xF0 ) | 0x0F;
|
|
mov.b @(h'38,gbr),r0 ; *PORTM->r0
|
|
and #h'F0,r0 ; *PORTM & 0xF0
|
|
or #h'0F,r0 ; | 0x0F;
|
|
mov.b r0,@(h'38,gbr)
|
|
bra rowCond_End
|
|
nop
|
|
rowCond_Else:
|
|
; *PORTB_CTRL = 0xAAAA;
|
|
mov.w #h'AAAA,r0
|
|
mov.w r0,@(h'02,gbr)
|
|
; *PORTM_CTRL = ((*PORTM_CTRL & 0xFF00 ) | 0x00AA) ^ smask;
|
|
mov.w @(h'18,gbr),r0
|
|
mov.w #h'FF00,r1
|
|
and r1,r0 ; *PORTM_CTRL & 0xFF00
|
|
or #h'AA,r0 ; | 0x00AA;
|
|
xor r6,r0 ; ^ smask;
|
|
mov.b r0,@(h'18,gbr)
|
|
;delay()
|
|
bsr delay
|
|
mov #-10,r4 ;In the begin this was 5, but as the delay function is faster, i need to put more
|
|
;*PORTB = 0xFF;
|
|
mov.b #h'ff,r0
|
|
mov.b r0,@(h'22,gbr) ;PORTB = 0xFF
|
|
;*PORTM = (*PORTM & 0xF0 ) | cmask;
|
|
mov.b @(h'38,gbr),r0
|
|
and #h'F0,r0 ; *PORTM & 0xF0
|
|
or r5,r0 ; | cmask;
|
|
mov.b r0,@(h'38,gbr)
|
|
rowCond_End:
|
|
;reserved registers :
|
|
;r9 second param
|
|
;r8 Key's row
|
|
;r7 Key's col
|
|
;delay()
|
|
bsr delay
|
|
mov #-10,r4
|
|
;result = (~(*PORTA))>>column & 1;
|
|
mov.b @(h'20,gbr),r0
|
|
not r0,r6 ; r6 = ~r0
|
|
neg r7,r0 ; r0 = -column
|
|
shld r0,r6 ; r6 = r6>>column
|
|
mov.b #1,r0
|
|
and r0,r6
|
|
;reserved registers :
|
|
;r9 second param
|
|
;r8 Key's row
|
|
;r7 Key's col
|
|
;r6 result
|
|
;delay()
|
|
bsr delay
|
|
mov #-10,r4
|
|
; *PORTB_CTRL = 0xAAAA;
|
|
mov.w #h'AAAA,r0
|
|
mov.w r0,@(h'02,gbr)
|
|
;*PORTM_CTRL = (*PORTM_CTRL & 0xFF00 ) | 0x00AA;
|
|
mov.w @(h'18,gbr),r0
|
|
mov.w #h'FF00,r1
|
|
and r1,r0 ; *PORTM_CTRL & 0xFF00
|
|
or #h'AA,r0 ; | 0x00AA;
|
|
mov.w r0,@(h'18,gbr)
|
|
;delay()
|
|
bsr delay
|
|
mov #-10,r4
|
|
; *PORTB_CTRL = 0x5555;
|
|
mov.w #h'5555,r0
|
|
mov.w r0,@(h'02,gbr)
|
|
;*PORTM_CTRL = (*PORTM_CTRL & 0xFF00 ) | 0x0055;
|
|
mov.w @(h'18,gbr),r0
|
|
mov.w #h'FF00,r1
|
|
and r1,r0 ; *PORTM_CTRL & 0xFF00
|
|
or #h'55,r0 ; | 0x0055;
|
|
mov.w r0,@(h'18,gbr)
|
|
;delay()
|
|
bsr delay
|
|
mov #-10,r4
|
|
;End of SH3 part
|
|
bra AllEnd
|
|
nop
|
|
SH4:
|
|
;Add 3 to the second param (if >0)to select the right wait time
|
|
mov #0,r0
|
|
cmp/gt r0,r9
|
|
bf negatif2ndParam
|
|
add #3,r9
|
|
negatif2ndParam:
|
|
;get the main keyboard regsiter address+1
|
|
mov.l #H'A44B0001,r1
|
|
mov r8,r0
|
|
tst #1,r0 ;if row is even T=1 else T=0
|
|
add r8,r1
|
|
bt row_even ; Jump if T=1
|
|
add #-2,r1
|
|
row_even:
|
|
mov.b @r1,r0 ; The byte that contain the row data is now in R0
|
|
mov #1,r1
|
|
shld r7,r1 ; R9 now contain 1<<col
|
|
tst r1,r0 ; if key is pressed T=0
|
|
movt r0
|
|
not r0,r0
|
|
and #h'1,r0
|
|
mov r0,r6
|
|
bra AllEnd
|
|
nop
|
|
NegativeEnd:
|
|
mov #0,r6
|
|
;reserved registers :
|
|
;r9 second param
|
|
;r8 Key's row
|
|
;r7 Key's col
|
|
;r6 result
|
|
AllEnd:
|
|
;Wait the correct time to emulate old functions
|
|
bsr delay
|
|
mov r9,r4
|
|
;put result to return register : r0
|
|
mov r6,r0
|
|
;take out data from stack
|
|
mov.l @r15+,r9
|
|
mov.l @r15+,r8
|
|
mov.l @r15+,r7
|
|
mov.l @r15+,r6
|
|
mov.l @r15+,r3
|
|
mov.l @r15+,r2
|
|
mov.l @r15+,r1
|
|
lds.l @r15+,pr
|
|
rts
|
|
nop
|
|
|
|
|
|
|
|
; delay : Wait a defined time
|
|
;param 1 (in r4) : slowMode : this determine the time this function will wait to emulate the olds functions
|
|
; -n : number of loop
|
|
; 0 : fatest as possible (equivalent to -1)
|
|
; 1 : = duration of IsKeyDown function for SH3
|
|
; 2 : = duration of IsKeyUp function for SH3
|
|
; 3 : = duration of KeyDown function for SH3
|
|
; 4 : = duration of IsKeyDown function for SH4
|
|
; 5 : = duration of IsKeyUp function for SH4
|
|
; 6 : = duration of KeyDown function for SH4
|
|
delay:
|
|
;if r4<=0 then it's the number of loop
|
|
mov #0,r0
|
|
cmp/ge r0,r4
|
|
bf LoopNumber
|
|
;Search the number of loop needed
|
|
add r4,r4 ; *2
|
|
mova loopNumbersList,r0
|
|
add r4,r4 ; *2 because there is 4 byte per number of loop (this method take less space than use "MUL.L")
|
|
add r4,r0
|
|
mov.l @r0,r1
|
|
bra target_loopBegin
|
|
nop ; this nop is added because without the loopNumbersList is not divisible per 4
|
|
loopNumbersList:
|
|
.data.l h'00000001 ;fastest (can't be under 1)
|
|
.data.l h'000006F7 ;IsKeyDown SH3
|
|
.data.l h'00012D1F ;IsKeyUp SH3
|
|
.data.l h'00000001 ;KeyDown SH3
|
|
.data.l h'000005CD ;IsKeyDown SH4
|
|
.data.l h'0000F1A8 ;IsKeyUp SH4
|
|
.data.l h'00000001 ;KeyDown SH4
|
|
LoopNumber:
|
|
neg r4,r1
|
|
;Begin : r1 contain the number of loop
|
|
target_loopBegin:
|
|
dt r1 ; decrement and test if(r1==0)
|
|
bf target_loopBegin
|
|
rts
|
|
nop |