📄 test1.asc.bak
字号:
***********************************
* Playstation Pad Driver *
* For 68Hc11A1FN *
* December 1st, 2001 *
* Laurent SAINT-MARCEL *
* lstmarcel@yahoo.fr *
***********************************
*
**************************
* REGISTER DECLARATION *
**************************
BASE EQU $1000
PILE EQU $1F
* serial port
BAUD EQU $2B
SCCR1 EQU $2C
SCCR2 EQU $2D
SCSR EQU $2E
SCDR EQU $2F
TDRE EQU $80 * bit in SCSR
RDRF EQU $20 * bit in SCSR
* io port
PORTF EQU $04 * Output // in fact it is port B but I used port F on a 68CV11F1FN
PORTC EQU $03 * Input
DDRC EQU $07
*
************
* PINOUT *
************
* Controller pin Inputs (pad->uc)
PIN_DATA EQU $20 * (1) Brown
PIN_ACK EQU $80 * (9) Green
* Controller pin Outputs (uc->pad)
*PIN_COMMAND EQU $04 * (2) Orange
*PIN_CLOCK EQU $02 * (7) Blue
*PIN_ATT EQU $01 * (6) Yellow or White
*
*********
* RAM *
*********
CMD RMB 1 * COMMAND(from uc)
DATA RMB 1 * DATA(from pad)
COUNT RMB 1 * bit counter when sending/receiving data
PAD_T RMB 1 * Pad type
PAD_D0 RMB 1 * DATA sent by the pad
PAD_D1 RMB 1 * DATA sent by the pad
PAD_D2 RMB 1 * DATA sent by the pad
PAD_D3 RMB 1 * DATA sent by the pad
PAD_D4 RMB 1 * DATA sent by the pad
PAD_D5 RMB 1 * DATA sent by the pad
*
*****************************
* PROGRAM POSITION IN EPROM *
*****************************
ORG $B600 ** START OF EEPROM. $F800 FOR 68hc11E2 $FE00 FOR 68hc11F1 $B600 FOR 68hc11A1
LDX #BASE ** Base register
LDS #PILE ** Stack address
BRA RESET
*
*********
* RESET *
*********
RESET BSR SCI_INI ** initialize serial port
JSR IO_INI ** initialize io
JMP MAIN ** jump to main program
*
*****************
* SERIAL PORT *
*****************
**** Init serial port ****
SCI_INI CLR SCCR1,X
LDD #$300C
STAA BAUD,X ** 9600 bauds
STAB SCCR2,X ** Transmitter and receiver enabled
RTS
*
**** send one byte on serial port : register A ****
SCI_SND PSHA
SCI_SN1 LDAA SCSR,X ** sci status register
ANDA #TDRE ** Write Data register empty ?
BEQ SCI_SN1 ** if No => retry
PULA
STAA SCDR,X ** write data on serial port
RTS
*
**** receive one bytes from serial port and store it in register A (if no Byte waiting, return 0xFF)****
SCI_RCV LDAA SCSR,X ** sci status register
ANDA #RDRF ** Read Data register full ?
BEQ SCI_RC2 ** if No => do not retry but put FF in register A
LDAA SCDR,X ** read data from serial port
RTS
SCI_RC2 LDAA #$FF ** Register A filled with FF if nothing waiting on serial port
RTS
*
***************************
* 68HC11 board, init IO *
***************************
**** IO_ INITIALIZE ****
IO_INI LDAA #$FF ** set one on all ouputs
STAA PORTF,X
CLR DDRC,X ** set C as input
STAA PORTC,X
RTS
*
*************************
* PSX PAD SET ATT BIT *
*************************
**** ATT Hight ****
PAD_AH LDAA #$07 ** cmd=1, clk=1, att=1
STAA PORTF,X
RTS
*
**** ATT Low ****
PAD_AL LDAA #$06 ** cmd=1, clk=1, att=0
STAA PORTF,X
RTS
*
***********************************
* PSX PAD SEND/RECEIVE ONE BYTE *
***********************************
**** Send a request from register A and get response in register B ****
*-- Init counter (for i=1; i<8; ++i)
PAD_SR STAA CMD
LDAA #$08 ** wait 8 bits
STAA COUNT
*-- rotate B bits (DATA received fron the pad)
PAD_S1 LSRB ** move bits from B to the right
*
**** Send a bit (Command) to the PAD ****
LDAA CMD
*-- If (A.bit[0] == 1) SND1 else SND0
ANDA #$01
CMPA #$01
BEQ SND1
*-- cmd == 0 & clock down
SND0 LDAA #$00 ** cmd=0, clk=0, att=0
STAA PORTF,X
NOP
NOP
*-- cmd == 0 & clock up
LDAA #$02 ** cmd=0, clk=1, att=0
STAA PORTF,X
*-- jump read data
BRA PAD_R
*-- cmd == 1 & clock down
SND1 LDAA #$04 ** cmd=1, clk=0, att=0
STAA PORTF,X
NOP
NOP
*-- cmd == 0 & clock up
LDAA #$06 ** cmd=1, clk=1, att=0
STAA PORTF,X
*-- jump read data
BRA PAD_R
*
**** Reveive a bit (Data) from PAD ****
PAD_R NOP
NOP
LDAA PORTC,X
ANDA #$20 ** data=1
CMPA #$20
BNE PAD_WA ** if data==0 => jump to wai ack
*-- Bit received=1
PAD_R1 ORAB #$80 ** B = B | 0x80
BRA PAD_WA
*
**** Wait Ack ****
PAD_WA BRA PAD_E1 ** do not wait ack else infinite loop... why?
LDAA PORTC,X
ANDA #$80 ** ack=2
CMPA #$80
BEQ PAD_WA ** while ack up, wait ack
*
**** End of the loop ***
PAD_E1 LDAA COUNT
DECA ** --i (loop)
STAA COUNT
CMPA #$00
BEQ PAD_E ** if(count == 0) exit
*-- Get next bit to send
LDAA CMD
LSRA ** rotate bits of CMD
STAA CMD
BRA PAD_S1
*-- Exit
PAD_E RTS
*
******************
* PSX PAD READ *
******************
PAD_RCV
* Set ATT/Select
JSR PAD_AL
* Start
LDAA #$01 ** start request
JSR PAD_SR
* Read
LDAA #$42 ** read request
JSR PAD_SR
STAB PAD_T ** store the result in PAD_TYPE
* Pad will answer ?
LDAA #$00 ** idle (wait data from pad)
JSR PAD_SR
CMPB #$5A ** pad ready to write its data
BNE PAD_END ** pad not ready => stop
* Data0
LDAA #$01 ** idle (wait data from pad)
JSR PAD_SR
STAB PAD_D0 ** store the result in PAD_DATA_0
* Data1
LDAA #$01 ** idle (wait data from pad)
JSR PAD_SR
STAB PAD_D1 ** store the result in PAD_DATA_1
* Check data type
LDAB PAD_T
CMPB #$41
BEQ PAD_END ** if pad type=Standard Digital Pad => stop waiting data (only 2 bytes already read)
* Data2
LDAA #$00 ** idle (wait data from pad)
JSR PAD_SR
STAB PAD_D2 ** store the result in PAD_DATA_2
* Data3
LDAA #$00 ** idle (wait data from pad)
JSR PAD_SR
STAB PAD_D3 ** store the result in PAD_DATA_3
* Data4
LDAA #$00 ** idle (wait data from pad)
JSR PAD_SR
STAB PAD_D4 ** store the result in PAD_DATA_4
* Data5
LDAA #$00 ** idle (wait data from pad)
JSR PAD_SR
STAB PAD_D5 ** store the result in PAD_DATA_5
* End : unset ATT
PAD_END JSR PAD_AH
RTS
*
******************************
* SEND DATA ON SERIAL PORT *
******************************
PAD_SND LDAA PAD_T
JSR SCI_SND
LDAA PAD_D0
JSR SCI_SND
LDAA PAD_D1
JSR SCI_SND
LDAA PAD_D2
JSR SCI_SND
LDAA PAD_D3
JSR SCI_SND
LDAA PAD_D4
JSR SCI_SND
LDAA PAD_D5
JSR SCI_SND
RTS
*
****************
* MAIN PROGRAM *
****************
MAIN JSR PAD_RCV * read data from playstation pad
JSR SCI_RCV * read a character from serial port
CMPA #$FF * if no character on serial port
BEQ MAIN * then continue loop
JSR PAD_SND * else send last pad data on serial port
BRA MAIN
*
***********************************
* SET Boot stack pointer position *
***********************************
ORG $FFFE * reset vector address
FDB $B600 * go to the begin of the eeprom
*
ORG $BFFE * reset vector address (special mode)
FDB $B600 * go to the begin of the eeprom
*
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -