; psxkeys.src ; version for scenix sx28ac50 ; porta psx dedicated ; portb user port ; portc data bus ; 50mhzturbo=20x DEVICE SX28L,TURBO,STACKX_OPTIONX ID 'PSXKEYS' reset cold_start ; global port regs rb_dir equ $08 rb_dat equ $09 ra_dat equ $0a timer equ $0b timer2 equ $0c timer3 equ $0d ; watchdog waits wdreturn MACRO test timer snz retw $fc ENDM wdwaithi MACRO ;port,bit 100*256*9=230K=~1/160 sec mov timer,#100 clr timer2 :loop dec timer2 ;1 snz ;2 dec timer snz ;2 retw $fc sb \1 ;1 jmp :loop ;3 ENDM wdwaitlo MACRO ;port,bit mov timer,#100 clr timer2 :loop dec timer2 snz dec timer snz retw $fc snb \1 jmp :loop ENDM ; busy waits ifwne MACRO ;imm,label xor w,#\1 sz jmp \2 ENDM ifweq MACRO ;imm,label xor w,#\1 snz jmp \2 ENDM bin MACRO ;pin setb rb_dir.\1 mov !rb,rb_dir ENDM bout MACRO ;pin clrb rb_dir.\1 mov !rb,rb_dir ENDM bsethi MACRO setb rb_dat.\1 mov rb,rb_dat ENDM bsetlo MACRO clrb rb_dat.\1 mov rb,rb_dat ENDM ; ===================================================================== ; register set ; ===================================================================== org $10 pcount ds 1 padout ds 1 padin ds 1 parity ds 1 kout ds 1 kin ds 1 mout ds 1 min ds 1 count ds 1 dins ds 1 key ds 1 flags ds 1 mousex ds 1 mousey ds 1 mouseb ds 1 ; ===================================================================== ; object code starts here ; ===================================================================== org 0 ;port b clk0 equ 0 clk1 equ 1 dat0 equ 2 dat1 equ 2 ale equ 3 cle equ 4 write equ 5 read equ 6 busy equ 7 LEVEL equ $0d PULLUP equ $0e DIR equ $0f ; initialise user port default output=0 dir=input pullups=on cold_start clr ra mov w,#$60 mov rb_dat,w mov rb,w mode LEVEL mov !ra,#$0f ;TTL inputs mov !rb,#$ff ;TTL inputs mode PULLUP mov !ra,#$f0 mov !rb,#$f8 mode DIR mov !ra,#$0f ;port a=inputs mov w,#$84 ;dat,rb inputs mov rb_dir,w mov !rb,w clr dins ; call mediaid mainloop clr key clr flags ;reset data in pacmet dec flags clr mousex clr mousey call @readkeys call @readmouse call @padsend jmp @mainloop wait mov timer,w wa mov timer2,#12 wb decsz timer2 ;1 jmp wb ;3 decsz timer jmp wa retp ; ===================================================================== ; smartmedia driver ; ===================================================================== mediaid clr w mov !rc,w ;output bsethi cle bsetlo write mov rc,#$90 ;cmd=readid bsethi write bsetlo cle bsethi ale bsetlo write clr rc bsethi write bsetlo ale nop nop nop mov w,#$ff ;input mov !rc,w bsetlo read nop nop mov w,rc mov mousex,w bsethi read bsetlo read nop nop mov w,rc mov mousey,w bsethi read retp ; poke.h memf,0x0100 ; poke.b flashcmd,0x90 ;status ; poke.b flashloc,0x00 ; peek.b t0,flashdata ; peek.b t1,flashdata ; peek.b t2,flashdata ; brk ; ; ps/2 drivers for mouse and keyboard interface ; ;dins mouse equ 0 keyboard equ 1 ;flags mleft equ 2 mright equ 3 krelease equ 6 kextended equ 7 ; ===================================================================== ; keyboard driver (din0) ; ===================================================================== org $200 release MACRO bin \1 ENDM drive MACRO bout \1 ENDM ; write ps2 din0 kput mov kout,w ;paramater in w release dat0 ;release data drive clk0 ;drive clock mov w,#$64 call @wait ;wait 100 usecs drive dat0 ;drive data lo release clk0 ;release clock clr parity inc parity mov count,#8 kshift rr kout snc inc parity call kbitout wdreturn decsz count jmp kshift rr parity ;parity bit call kbitout wdreturn stc call kbitout wdreturn wdwaitlo rb.clk0 ;line control (must be 0) snb rb.dat0 retw $fc wdwaithi rb.clk0 jmp kget ;receive ack kbitout wdwaitlo rb.clk0 snc jmp kset drive dat0 wdwaithi rb.clk0 ret kset release dat0 wdwaithi rb.clk0 ret ; read ps2 din0 kget release clk0 release dat0 mov w,#$08 call @wait ;wait 100 usecs mov count,#$08 wdwaitlo rb.clk0 ;start bit wdwaithi rb.clk0 kbitin wdwaitlo rb.clk0 clc snb rb.dat0 stc rr kin wdwaithi rb.clk0 decsz count jmp kbitin wdwaitlo rb.clk0 ;parity check? wdwaithi rb.clk0 wdwaitlo rb.clk0 ;stop bit drive clk0 mov w,#$32 call @wait ;wait 100 usecs mov w,kin ret readkeys sb dins.keyboard jmp nokeyboard getkey call kget ifweq $fc,nokey mov w,kin ifwne $f0,notrelease clrb flags.krelease jmp getkey notrelease mov w,kin ifwne $e0,notextended clrb flags.kextended jmp getkey notextended mov w,kin mov key,w nokey drive clk0 ;inhibit release dat0 retp nokeyboard call kget ;poweron response ;start with reset? ifwne $aa,keyboarderr mov w,#$ed ;set leds call kput ifwne $fa,keyboarderr mov w,#$01 call kput ifwne $fa,keyboarderr setb dins.keyboard retp keyboarderr drive clk0 ;inhibit release dat0 ;release data clrb dins.keyboard retp ; ===================================================================== ; mouse driver (din1) ; ===================================================================== org $400 mput mov mout,w ;paramater in w release dat1 ;release data drive clk1 ;drive clock mov w,#$64 call @wait ;wait 100 usecs drive dat1 ;drive data lo release clk1 ;release clock clr parity inc parity mov count,#8 mshift rr mout snc inc parity call mbitout wdreturn decsz count jmp mshift rr parity ;parity bit call mbitout wdreturn stc call mbitout wdreturn wdwaitlo rb.clk1 ;line control (must be 0) snb rb.dat1 retw $fc wdwaithi rb.clk1 jmp mget ;receive ack mbitout wdwaitlo rb.clk1 snc jmp mset drive dat1 wdwaithi rb.clk1 ret mset release dat1 wdwaithi rb.clk1 ret ; read ps2 din1 mget release clk1 release dat1 mov w,#$08 call @wait ;wait 8 usecs mov count,#$08 wdwaitlo rb.clk1 ;start bit wdwaithi rb.clk1 mbitin wdwaitlo rb.clk1 clc snb rb.dat1 stc rr min wdwaithi rb.clk1 decsz count jmp mbitin wdwaitlo rb.clk1 ;parity check? wdwaithi rb.clk1 wdwaitlo rb.clk1 ;stop bit drive clk1 mov w,#$32 call @wait ;wait 50 usecs mov w,min ret readmouse sb dins.mouse jmp nomouse mov w,#$eb call mput ifwne $fa,mouseerr call mget mov mouseb,w call mget mov mousex,w call mget mov mousey,w snb mouseb.0 clrb flags.mright snb mouseb.1 clrb flags.mleft not mousey inc mousey retp nomouse call mget ;poweron response ifwne $aa,mouseerr call mget ifwne $00,mouseerr mov w,#$f0 ;set remote mode call mput ifwne $fa,mouseerr setb dins.mouse retp mouseerr drive clk1 ;inhibit release dat1 ;release data clrb dins.mouse retp ; ===================================================================== ; psx pad driver (port a) ; ===================================================================== org $600 dat equ 0 cmd equ 1 ack equ 2 clk equ 3 sel equ 4 ;rtcc waitsello MACRO :wlo snb rb.4 jmp :wlo ENDM waitselhi MACRO :whi sb rb.4 jmp :whi ENDM padsend ;waitselhi ;waitsello mov rtcc,#$ff mov !OPTION,#$ff nop wrc1 mov w,rtcc sz jmp wrc1 mov !ra,#$fe ;dat=output mov w,#$ff call dobyte decsz padin ;if padin!=01 ps0 jmp ps0 call doack mov w,#$12 call dobyte call doack mov w,#$5a call dobyte call doack mov w,key ;keys call dobyte call doack mov w,flags ;flags call dobyte call doack mov w,mousex ;deltax call dobyte call doack mov w,mousey ;deltay call dobyte ps0 clr ra mov !ra,#$ff ;float port ; waitselhi retp dobyte mov padout,w ;padout=w mov count,#8 mov w,#$80 ;w=1 dobit rr padout rl ra wl snb ra.clk ;wait clk lo jmp wl wh sb ra.clk ;wait clk hi jmp wh clc rr padin snb ra.cmd or padin,w decsz count jmp dobit ret doack mov count,#50 ;100/50mhz=2usecs db decsz count jmp db clr ra ;drive ack (ra.2) lo mov !ra,#$fa mov count,#25 ;100/50mhz=2usecs da decsz count jmp da mov !ra,#$fe ret