Code:
'
'
' -----------------------------------------------------
' Amiga CD32 Controller & CDTV IR Receiver Interface V3
' -----------------------------------------------------
' Copyright Brek Martin 2016.
' -----------------------------------------------------
'
DEFINE OSC 10 ' 10 MHz high speed oscillator
DEFINE NO_CLRWDT ' watchdog is cleared manually
'
keycode var byte[7] ' combination keycode buffer
decodedir var byte[3] '
decodedira var decodedir[0] ' decoded command sentence
decodedirb var decodedir[1] '
decodedirc var decodedir[2] '
irworda var word ' 12 bit ir command
irwordb var word ' 12 bit inverted ir command
rotcnt var word ' loop counter
releasecnt var word '
repeatdel var word '
repeatlen var word '
rawdelay var byte '
headerlen var byte '
ircount var byte ' pulse length counter
irbitcnt var byte ' ir bit counter
irbuff var byte ' byte buffer
leadcnt var byte ' header length counter
sndval var byte ' sound frequency
mousejoy var byte ' mouse or joy mode value
qualifyir var bit ' useless but left for timing
gotpulse var bit ' ir signal edge detect flag
irbit var bit ' ir bit status buffer
keyrot var bit ' rotate key code flag
dualtone var bit ' dtmf keypad flag
debugwrite var byte ' debug mode flag
cdkey var byte ' cd player button beep value
mute var byte ' mute setting
dual var byte ' dtmf keypad setting
sndbuff var byte '
sndspd var byte ' intro sound speed
sndsine var byte ' pseudo sine
'
goto startup ' do program startup
'
main:
@ clrwdt '
if qualifyir = 0 then ' look for initial ir burst * only here for timing now
if porta.5 = 0 then ' look for ir header
leadcnt = leadcnt + 1 ' count time for header length
else '
leadcnt = 0 ' reset time for header length
if releasecnt != 0 then ' release contunuous button presses
releasecnt = releasecnt - 1 ' decrement button cancel delay
if releasecnt = 1 then ' trigger button cancel
portb = %11111111 ' set all cd32 controller pins high and led off
porta = %1111 ' set all cd32 controller pins high
endif '
endif '
endif '
'
if leadcnt > headerlen then ' qualify initial ir burst duration
burst: ' allow initial ir burst to finish
if porta.5 = 0 then ' wait here until ir header is finished
goto burst '
endif '
'
pauseus repeatlen '
if porta.5 = 0 then ' repeat code detected
goto checkcont ' skip decoding of ir data for repeat code
endif '
'
gotpulse = 0 ' decode pulse coded ir signal
irbitcnt = 0 '
ircount = 0 '
'
for rotcnt = 0 to 407 ' sample ir data into buffer
'
for irbuff = 0 to 11 ' waste 58 instructions
next irbuff ' delay replacement for previous bitwise rotation routine
irbit = porta.5 ' sample ir port
'
if irbit = 1 then ' look for edge of pulse
irbitcnt = irbitcnt + 1 '
gotpulse = 1 '
endif '
'
if irbit = 0 then ' shift in decoded bit
if gotpulse = 1 then '
@ rlf _decodedir+2 ,F ;
@ rlf _decodedir+1 ,F ;
@ rlf _decodedir+0 ,F ;
@ bcf _decodedir+2 ,0 ; clear msb
irbuff = decodedir[2] '
if irbitcnt < 11 then '
irbuff.bit0 = 0 '
else '
irbuff.bit0 = 1 '
endif '
decodedir[2] = irbuff '
'
if irbitcnt > 0 then '
irbitcnt = 0 '
ircount = ircount + 1 ' increment the ir bit count
endif '
endif '
gotpulse = 0 ' reset flag to look for next ir pulse
endif '
'
if ircount > 24 then ' limit number of decoded bits
rotcnt = 407 ' cause loop termination
endif '
'
pauseus rawdelay ' raw pulse sample delay
next rotcnt '
'
' copy the 12 bit decoded data to a pair of word variables
' the second copy is the same command with inverted bits
' the four unused bits in both commands are leading zeros
'
irworda = irworda << 4 '
for rotcnt = 0 to 11 '
irworda = irworda << 1 '
irworda.bit0 = decodedira.bit7 '
@ rlf _decodedir+2 ,F ;
@ rlf _decodedir+1 ,F ;
@ rlf _decodedir+0 ,F ;
@ bcf _decodedir+2 ,0 ; clear msb
next rotcnt '
irwordb = irwordb << 4 '
for rotcnt = 0 to 11 '
irwordb = irwordb << 1 '
irwordb.bit0 = decodedira.bit7 '
@ rlf _decodedir+2 ,F ;
@ rlf _decodedir+1 ,F ;
@ rlf _decodedir+0 ,F ;
@ bcf _decodedir+2 ,0 ; clear msb
next rotcnt '
'
irwordb = irwordb^%111111111111 ' invert copy to compare
if irworda != irwordb then ' potentially do somethng for invalid command
goto main ' disqualified command data packet
endif '
'
portb.3 = 0 ' turn blue led on
'
checkcont:
'
' lookup tables translate all joypad related commands
' from decoded ir commands to both port values
'
if irworda.byte1 = mousejoy then ' qualify joypad or mouse mode related command
if irworda.byte0 < 193 then ' check for in lookup table range
'
lookup irworda.byte0,[_ ' convert decoded command lsb to portb value
$F7,$F7,$F7,$F7,$77,$F7,$F7,$F7,$B7,$F7,_ ' 00-09 *** 192 - 0xC0 is the highest for fire a + b
$F7,$F7,$F7,$F7,$F7,$F7,$D7,$F7,$F7,$F7,_ ' 10-19
$57,$F7,$F7,$F7,$97,$F7,$F7,$F7,$F7,$F7,_ ' 20-29
$F7,$F7,$E7,$F7,$F7,$F7,$67,$F7,$F7,$F7,_ ' 30-39
$A7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,_ ' 40-49
$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,_ ' 50-59
$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$77,$F7,_ ' 60-69
$F7,$F7,$B7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,_ ' 70-79
$D7,$F7,$F7,$F7,$57,$F7,$F7,$F7,$97,$F7,_ ' 80-89
$F7,$F7,$F7,$F7,$F7,$F7,$E7,$F7,$F7,$F7,_ ' 90-99
$67,$F7,$F7,$F7,$A7,$F7,$F7,$F7,$F7,$F7,_ ' 100-109
$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,_ ' 110-119
$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F5,$F7,_ ' 120-129
$F7,$F7,$75,$F7,$F7,$F7,$B5,$F7,$F7,$F7,_ ' 130-139
$F7,$F7,$F7,$F7,$D5,$F7,$F7,$F7,$55,$F7,_ ' 140-149
$F7,$F7,$95,$F7,$F7,$F7,$F7,$F7,$F7,$F7,_ ' 150-159
$E5,$F7,$F7,$F7,$65,$F7,$F7,$F7,$A5,$F7,_ ' 160-169
$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,_ ' 170-179
$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,$F7,_ ' 180-189
$F7,$F7,$F5_ ' 190-192
],portb ' destination is portb
'
lookup irworda.byte0,[_ ' convert decoded command lsb to porta value
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 00-09
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 10-19
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 20-29
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 30-39
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 40-49
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 50-59
$0F,$0F,$0F,$0F,$0E,$0F,$0F,$0F,$0E,$0F,_ ' 60-69
$0F,$0F,$0E,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 70-79
$0E,$0F,$0F,$0F,$0E,$0F,$0F,$0F,$0E,$0F,_ ' 80-89
$0F,$0F,$0F,$0F,$0F,$0F,$0E,$0F,$0F,$0F,_ ' 90-99
$0E,$0F,$0F,$0F,$0E,$0F,$0F,$0F,$0F,$0F,_ ' 100-109
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 110-119
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 120-129
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 130-139
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 140-149
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 150-159
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 160-169
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 170-179
$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,_ ' 180-189
$0F,$0F,$0E_ ' 190-192
],porta ' destination is porta
'
releasecnt = repeatdel ' set the repeat cancel delay
goto donecheckcont ' skip further checking
else '
goto donecheck ' out of range of lookup tables
endif '
endif '
'
'
if irworda.byte1 = $00 then ' qualify keypad related command
if irworda.byte0 = %00110101 then ' enter
portb = %11110011 '
releasecnt = repeatdel '
goto donecheckcont '
endif '
'
if irworda.byte0 = %00110001 then ' escape
portb = %11110110 '
releasecnt = repeatdel '
goto donecheckcont '
endif '
'
'
cdkey = 0 ' clear cd player button beep value
'
if irworda.byte0 = %00001010 then ' play
porta = %1011 '
if releasecnt = 0 then '
cdkey = 120 '
endif '
releasecnt = repeatdel '
goto donecheckcontcd '
endif '
'
if irworda.byte0 = %00101010 then ' stop
porta = %1110 '
if releasecnt = 0 then '
cdkey = 90 '
endif '
releasecnt = repeatdel '
goto donecheckcontcd '
endif '
'
if irworda.byte0 = %00011010 then ' skip forward
porta = %1101 '
if releasecnt = 0 then '
cdkey = 115 '
endif '
releasecnt = repeatdel '
goto donecheckcontcd '
endif '
'
if irworda.byte0 = %00110010 then ' skip reverse
porta = %0111 '
if releasecnt = 0 then '
cdkey = 115 '
endif '
releasecnt = repeatdel '
goto donecheckcontcd '
endif '
'
'
keyrot = 0 ' clear key rotation flag
'
if irworda.byte0 = %00111001 then ' 0
if releasecnt = 0 then '
keycode[0] = $30 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00000001 then ' 1
if releasecnt = 0 then '
keycode[0] = $31 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00100001 then ' 2
if releasecnt = 0 then '
keycode[0] = $32 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00010001 then ' 3
if releasecnt = 0 then '
keycode[0] = $33 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00001001 then ' 4
if releasecnt = 0 then '
keycode[0] = $34 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00101001 then ' 5
if releasecnt = 0 then '
keycode[0] = $35 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00011001 then ' 6
if releasecnt = 0 then '
keycode[0] = $36 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00000101 then ' 7
if releasecnt = 0 then '
keycode[0] = $37 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00100101 then ' 8
if releasecnt = 0 then '
keycode[0] = $38 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00010101 then ' 9
if releasecnt = 0 then '
keycode[0] = $39 '
keyrot = 1 '
endif '
endif '
'
if irworda.byte0 = %00100010 then ' genlock
if releasecnt = 0 then '
keycode[0] = $3B ' hash key for dtmf mode
keyrot = 1 '
endif '
endif '
'
' cd/tv - %00000010 power - %00010010
' >>vol>> - %00000110 <<vol<< - %00111010
'
if keyrot = 1 then ' rotate key code buffer
'
if dualtone = 1 then '
DTMFOUT porta.4,400,10,[keycode[0]-$30] '
else '
SOUND porta.4,[110,1] '
endif '
'
if keycode[0] = $3B then ' check for genlock button
if keycode[6] = $31 then ' 1
if keycode[5] = $33 then ' 3
if keycode[4] = $33 then ' 3
if keycode[3] = $37 then ' 7
'
'
if keycode[2] = $31 then ' 1
if keycode[1] = $36 then ' 6
if debugwrite = 0 then '
debugwrite = $AA '
else '
debugwrite = 0 '
endif '
write 10,debugwrite '
goto codefunction '
endif '
endif '
'
'
if keycode[2] = $30 then ' 0
'
if keycode[1] = $30 then ' 0
sndval = sndval + 2 ' increment intro frequency value
write 0,sndval '
goto codefunction '
endif '
'
if keycode[1] = $31 then ' 1
if dual = 0 then ' toggle dtmf setting
write 8,1 '
else '
write 8,0 '
endif '
goto codefunction '
endif '
'
if keycode[1] = $32 then ' 2
if mute = 0 then ' toggle mute setting
write 7,1 '
else '
write 7,0 '
endif '
goto codefunction '
endif '
'
if keycode[1] = $33 then ' 3
goto codefunction '
endif '
'
if keycode[1] = $34 then ' 4
SOUND porta.4,[120,16] ' sound for correct keypad code
mousejoy = $00 ' cdtv mouse mode
endif '
'
if keycode[1] = $36 then ' 6
write 0,$F9 ' reset default intro value
goto codefunction '
endif '
'
if keycode[1] = $39 then ' 9
repeatdel = repeatdel + 10 ' increment repeat delay
goto setrepeat '
endif '
'
if keycode[1] = $38 then ' 8
repeatdel = repeatdel - 10 ' decrement repeat delay
goto setrepeat '
endif '
'
if keycode[1] = $37 then ' 7
repeatdel = 1820 ' set default repeat delay
setrepeat: '
write 3,repeatdel.byte1 '
write 4,repeatdel.byte0 '
goto codefunction '
endif '
'
endif '
endif '
endif '
endif '
endif '
else ' else not genlock button
keycode[6] = keycode [5] '
keycode[5] = keycode [4] '
keycode[4] = keycode [3] '
keycode[3] = keycode [2] '
keycode[2] = keycode [1] '
keycode[1] = keycode [0] '
endif '
endif ' not genlock button
'
releasecnt = repeatdel '
goto donecheckcont '
endif '
'
donecheck: ' invalid or unknown ir code
porta = %1111 ' set all cd32 controller pins high
portb = $FF ' and turn off blue led
if mute = 0 then '
SOUND porta.4,[90,1] ' buzz for invalid or unknown command
endif '
'
'********************************************
' sound the 12 bit command out of speaker
'********************************************
if debugwrite != 0 then '
irwordb = irworda '
for rotcnt = 0 to 11 '
@ clrwdt ;
if irwordb.bit11 = 0 then '
cdkey = 90 '
else '
cdkey = 120 '
endif '
SOUND porta.4,[cdkey,2] '
pause 900 '
irwordb = irwordb << 1 '
next rotcnt '
endif '
'********************************************
'
donecheckcontcd: ' cd player buttons sound
if cdkey != 0 then '
if mute != 0 then '
cdkey = 0 '
endif '
SOUND porta.4,[cdkey,1] '
endif '
donecheckcont: '
leadcnt = 0 ' reset the header counter
endif '
endif '
goto main ' cycle program
'
codefunction:
SOUND porta.4,[120,16] ' sound for correct keypad code
wdtresetl: '
goto wdtresetl ' cause watchdog timer reset
'
startup:
CMCON = $07 ' set ports as digital
trisa = %100000 '
porta = %1111 '
trisb = %00000000 '
portb = %11110111 ' set all cd32 controller pins high
pause 100 ' delay
portb = %11111111 ' turn blue led off this time
'
leadcnt = 0 ' reset variables
qualifyir = 0 '
decodedira = 0 '
decodedirb = 0 '
decodedirc = 0 '
releasecnt = 0 ' *** try 2?
irworda = 0 '
irwordb = 0 '
irbit = 0 '
dualtone = 0 ' set dtmf initially off
sndsine = 0 ' set intitial sine
mousejoy = $08 ' set joypad mode default
'
'
'repeatlen = 2400 ' repeat ir pulse delay (program setting) *** 2400
'repeatdel = 1820 ' repeat cancel delay (program setting) *** 1820
'headerlen = 150 ' header pulse length (program setting) *** 150
'rawdelay = 36 ' raw ir signal sample delay (program setting) *** 36
'sndval = 120 ' sound frequency for intro (program setting) *** 120
'mute = 0 ' mute sound from speaker (program setting) *** 0
'dual = 0 ' dtmf keypad (program setting) *** 0
'sndspd = 1 ' intro sound speed (program setting) *** 1
'debugwrite = 0 ' sound out invalid ir codes (program setting) *** 0
'
' defaults 1820 msb 1820 lsb 2400 msb 2400 lsb
DATA $F9,36,150,%00000111,%00011100,%00001001,%01100000,0,0,1,0
'
read 0,sndval ' read program settings from on-chip eeprom
read 1,rawdelay '
read 2,headerlen '
read 3,repeatdel.byte1 '
read 4,repeatdel.byte0 '
read 5,repeatlen.byte1 '
read 6,repeatlen.byte0 '
read 7,mute '
read 8,dual '
read 9,sndspd '
read 10,debugwrite '
'
if dual != 0 then '
dualtone = 1 '
endif '
'
if mute = 0 then ' if sound not muted
sndbuff = $FF '
sloop: '
sndbuff = sndbuff + sndval '
SOUND porta.4,[sndbuff,sndspd+sndsine] ' output sound
@ clrwdt ;
sndsine = sndbuff.bit3 '
IF sndbuff != 0 THEN sloop '
endif '
porta = %1111 '
goto main '
'
'
'RA0 = 0 - cd32 control port
'RA1 = 0
'RA2 = 0
'RA3 = 0
'RA4 = 0 - piezo speaker port
'RA5 = 1 - infrared receiver input
'RB0 = 0 - cd32 controller yellow button
'RB1 = 0 - cd32 controller red button
'RB2 = 0 - cd32 controller green button
'RB3 = 0 - led indicator
'RB4 = 0 - joypad up
'RB5 = 0 - joypad down
'RB6 = 0 - joypad left
'RB7 = 0 - joypad right
'
'
'
Cheers, Art.
Bookmarks