Files
vhdl/projects/ac97_Controller/asm/test.jsm
T
jens 67d79572d7 - added ac97 Controller
git-svn-id: http://moon:8086/svn/vhdl/trunk@1411 cc03376c-175c-47c8-b038-4cd826a8556b
2021-03-21 09:07:16 +00:00

534 lines
12 KiB
JavaScript

; -------------------------------------------------
; Constants
; -------------------------------------------------
include "../../../lib/jasm/cregs.inc.jsm"
; XIO registers
reg_led: equ 0x00 ; R/W
reg_pcmmode: equ 0x01 ; R/W
reg_freq: equ 0x02 ; R/W
reg_cmd_addr: equ 0x04 ; WO
reg_cmd_data: equ 0x06 ; WO
lcd_port: equ 0x08 ; R/W
reg_mix_dc_adj_left: equ 0x09 ; R/W
reg_mix_dc_adj_right: equ 0x0B ; R/W
reg_pcmin_dc_adj_left: equ 0x0D ; R/W
reg_pcmin_dc_adj_right: equ 0x0F ; R/W
reg_stat_addr: equ 0x04 ; RO
reg_stat_data: equ 0x06 ; RO
reg_btn: equ 0x80 ; RO
reg_dip: equ 0x81 ; RO
reg_pcm_left: equ 0x82 ; RO
reg_pcm_right: equ 0x84 ; RO
reg_mix_x_left: equ 0x86 ; RO
reg_mix_x_right: equ 0x88 ; RO
reg_mix_y_left: equ 0x8A ; RO
reg_mix_y_right: equ 0x8C ; RO
reg_stat_hw: equ 0xA0 ; RO
reg_beef: equ 0x8E
; reg_stat_hw
; Bits
omsk_ac_rdy: equ 0x01
omsk_cmd_rdy: equ 0x02
omsk_stat_rdy: equ 0x04
omsk_fir_rdy: equ 0x08
; Flag masks
omsk_led0: equ 0x01
omsk_led1: equ 0x02
omsk_led2: equ 0x04
omsk_led3: equ 0x08
amsk_led0: equ 0xFE
amsk_led1: equ 0xFD
amsk_led2: equ 0xFB
amsk_led3: equ 0xF7
omsk_btn_W: equ 0x01
omsk_btn_N: equ 0x02
omsk_btn_E: equ 0x04
omsk_btn_S: equ 0x08
omsk_btn_C: equ 0x10
DC_CORR_PCM: equ 0xFF40
DC_CORR_MIX: equ 0x005C
NCO_FREQ: equ 0x4000
BAR_UPD_INTERVAL: equ 0x0080
; -------------------------------------------------
; On-Chip memory
; -------------------------------------------------
cmem 0
btn_state: db 1
dip_state: db 1
stat_addr: db 2
stat_data: db 2
bar_value: db 2
bar_data: db 2
lcd_disp: db 4
bar_upd_count: db 2
count: db 2
xmem
msg_txt: dc "AC'97 Test V1.2", 0
ac97_cfg_addr: dc 0x00, 0x2A ; W: Extended Audio CTRL/STATUS
dc 0x00, 0x1A ; W: Record select
dc 0x00, 0x1C ; W: Record gain
dc 0x00, 0x2C ; W: PCM DAC rate
dc 0x00, 0x32 ; W: PCM ADC rate
dc 0x00, 0x20 ; W: General purpose
dc 0x00, 0x02 ; W: Master volume
dc 0x00, 0x04 ; W: Headphone volume
dc 0x00, 0x18 ; W: PCM volume
ac97_cfg_data: dc 0x01, 0x00 ; W: VRA=1
dc 0x04, 0x04 ; W: Record source = LINE_IN
dc 0x00, 0x00 ; W: Record gain = 0dB
dc 0x80, 0xBB ; W: DAC rate 48000Hz
dc 0x80, 0xBB ; W: ADC rate 48000Hz
dc 0x00, 0x80 ; W: POP=1
dc 0x00, 0x00 ; W: Master volume = 0dB
dc 0x00, 0x00 ; W: Headphone volume = 0dB, muted
dc 0x0A, 0x0A ; W: PCM volume = -3dB
; -------------------------------------------------
; Program
; -------------------------------------------------
code
org 0x000
reset: jmp init
org 0x001
jmp frame_isr
; -------------------------------------------------
; Main
; -------------------------------------------------
init: mov R0, 0x00
mov R1, 0x00
mov R2, 0x00
mov R3, 0x00
xout (reg_led), R0
movc (btn_state), R0
movc (count+0), R0
movc (count+1), R0
movc (bar_data+0), R0
movc (bar_data+1), R0
mov R0, BAR_UPD_INTERVAL,'low
mov R1, BAR_UPD_INTERVAL,'high
movc (bar_upd_count+0), R0
movc (bar_upd_count+1), R1
call LCD_init
call LCD_INIT_CGRAM
; Print Hello world
mov R0, LCD_CMD_CLEAR
call LCD_writecmd
mov R1, msg_txt
call LCD_putsx
wait_ac_rdy: xin R0, (reg_stat_hw)
and R0, omsk_ac_rdy
jz wait_ac_rdy
wait_fir_rdy: xin R0, (reg_stat_hw)
and R0, omsk_fir_rdy
jz wait_fir_rdy
call delay1s
; Send AC97 Status register read-request (CODEC_ID)
mov R0, 0x00
mov R1, 0x80
mov R2, 0x00
mov R3, 0x00
call AC_status_io
movc (stat_addr+0), R0
movc (stat_addr+1), R1
movc (stat_data+0), R2
movc (stat_data+1), R3
; Initialize AC97
; check status
ac97_rdy_lp: mov R0, 0x00
mov R1, 0xA6
mov R2, 0x00
mov R3, 0x00
call AC_status_io
and R2, 0x0F
cmp R2, 0x0F
jne ac97_rdy_lp
mov R15, 9
mov R7, ac97_cfg_addr
mov R8, ac97_cfg_data
ac97_init_lp: movx R0, (R7)
inc R7
movx R1, (R7)
inc R7
movx R2, (R8)
inc R8
movx R3, (R8)
inc R8
call AC_status_io
dec R15
jnz ac97_init_lp
; Print status address
label: mov R0, LCD_CMD_CLEAR
call LCD_writecmd
mov R0, 65
call LCD_writechar
mov R0, 58
call LCD_writechar
movc R0, (stat_addr+1)
call PutHexByte
movc R0, (stat_addr+0)
call PutHexByte
; Print status data
mov R0, 32
call LCD_writechar
mov R0, 68
call LCD_writechar
mov R0, 58
call LCD_writechar
movc R0, (stat_data+1)
call PutHexByte
movc R0, (stat_data+0)
call PutHexByte
; Set PCM mode
mov R0, 0x00
xout (reg_pcmmode), R0
; Set NCO frequency
mov R0, NCO_FREQ'high
xout (reg_freq+1), R0
mov R0, NCO_FREQ'low
xout (reg_freq+0), R0
; PCM-IN: Set DC correction LEFT
mov R0, DC_CORR_PCM'high
xout (reg_pcmin_dc_adj_left+1), R0
mov R0, DC_CORR_PCM'low
xout (reg_pcmin_dc_adj_left+0), R0
; PCM-IN: Set DC correction RIGHT
mov R0, DC_CORR_PCM'high
xout (reg_pcmin_dc_adj_right+1), R0
mov R0, DC_CORR_PCM'low
xout (reg_pcmin_dc_adj_right+0), R0
; Mixer: Set DC correction LEFT
mov R0, DC_CORR_MIX'high
xout (reg_mix_dc_adj_left+1), R0
mov R0, DC_CORR_MIX'low
xout (reg_mix_dc_adj_left+0), R0
; Mixer: Set DC correction RIGHT
mov R0, DC_CORR_MIX'high
xout (reg_mix_dc_adj_right+1), R0
mov R0, DC_CORR_MIX'low
xout (reg_mix_dc_adj_right+0), R0
; Switch on LED
xin R0, (reg_led)
or R0, omsk_led0
xout (reg_led), R0
; Enable Interrupt
mov R0, 0x07
cout (cpu_int_ctrl), R0
; Sample switches and buttons
main: xin R0, (reg_dip)
movc (dip_state), R0
xin R0, (reg_btn)
movc (btn_state), R0
movc R0, (dip_state)
xout (reg_pcmmode), R0
xin R0, (reg_led)
and R0, omsk_led3
jnz main
mov R0, LCD_CMD_Z2
call LCD_writecmd
movc R0, (btn_state)
and R0, omsk_btn_C
jnz disp_mix
xin R0, (reg_pcm_left+0)
movc (lcd_disp+0), R0
xin R0, (reg_pcm_left+1)
movc (lcd_disp+1), R0
xin R0, (reg_pcm_right+0)
movc (lcd_disp+2), R0
xin R0, (reg_pcm_right+1)
movc (lcd_disp+3), R0
jmp print
disp_mix: xin R0, (reg_mix_x_left+0)
movc (lcd_disp+0), R0
xin R0, (reg_mix_x_left+1)
movc (lcd_disp+1), R0
xin R0, (reg_mix_x_right+0)
movc (lcd_disp+2), R0
xin R0, (reg_mix_x_right+1)
movc (lcd_disp+3), R0
print: call bar_div
mov R0, 76
call LCD_writechar
mov R0, 58
call LCD_writechar
movc R0, (lcd_disp+1)
call PutHexByte
movc R0, (lcd_disp+0)
call PutHexByte
mov R0, 32
call LCD_writechar
mov R0, 82
call LCD_writechar
mov R0, 58
call LCD_writechar
movc R0, (lcd_disp+3)
call PutHexByte
movc R0, (lcd_disp+2)
call PutHexByte
chk_wm: movc R0, (btn_state)
and R0, omsk_btn_W
jz chk_em
; Decrease NCO frequency
xin R0, (reg_freq+0)
xin R1, (reg_freq+1)
sub R0, 0x64
jnc upd_regs
dec R1
jmp upd_regs
chk_em: movc R0, (btn_state)
and R0, omsk_btn_E
jz ex_chk
; Increase NCO frequency
xin R0, (reg_freq+0)
xin R1, (reg_freq+1)
add R0, 0x64
jnc upd_regs
inc R1
jmp upd_regs
upd_regs: xout (reg_freq+1), R1
xout (reg_freq+0), R0
w4led: xin R0, (reg_led)
and R0, omsk_led3
jz w4led
ex_chk: jmp main
; -------------------------------------------------
frame_isr: push R0
push R1
movc R0, (count+0)
movc R1, (count+1)
inc R0
cmp R0, 0x30
jnz ex_isr
mov R0, 0
push R0
xin R0, (reg_btn)
movc (btn_state), R0
pop R0
inc R1
cmp R1, 0x64
jnz ex_isr
call subr
mov R1, 0
ex_isr: movc (count+0), R0
movc (count+1), R1
pop R1
pop R0
reti
; -------------------------------------------------
subr: xin R0, (reg_led)
mov R1, R0
and R1, omsk_led3
jnz switch_off
or R0, omsk_led3
jmp switch
switch_off: and R0, amsk_led3
switch: xout (reg_led), R0
ret
; -------------------------------------------------
; AC Read/Write register
; R0 : IN/OUT AC register address 7..0. Written, if cmd was READ (i.e. address[15] = 1)
; R1 : IN/OUT AC register address 15..8. Written, if cmd was READ (i.e. address[15] = 1)
; R2 : IN/OUT AC register data 7..0. Written, if cmd was READ (i.e. address[15] = 1)
; R3 : IN/OUT AC register data 15..8. Written, if cmd was READ (i.e. address[15] = 1)
AC_status_io: call wait_cmd_rdy
xout (reg_cmd_addr+1), R1
xout (reg_cmd_addr+0), R0
xout (reg_cmd_data+1), R3
xout (reg_cmd_data+0), R2
; Check if command was read
and R1, 0x80
jnz wait_read
ret
; Wait for READ command being processed
wait_read: call wait_stat_rdy
; Read AC97 Status register address
xin R1, (reg_stat_addr+1)
xin R0, (reg_stat_addr+0)
; Read AC97 Status register data
xin R3, (reg_stat_data+1)
xin R2, (reg_stat_data+0)
ret
; -------------------------------------------------
wait_cmd_rdy: push R0
wcr_loop: xin R0, (reg_stat_hw)
and R0, omsk_cmd_rdy
jz wcr_loop
pop R0
ret
; -------------------------------------------------
wait_stat_rdy: push R0
wsr_loop: xin R0, (reg_stat_hw)
and R0, omsk_stat_rdy
jz wsr_loop
pop R0
ret
; -------------------------------------------------
; PutHexByte
; R0 : Byte value
PutHexByte: call bin2hex
call LCD_writechar
mov R0, R1
call LCD_writechar
ret
; -------------------------------------------------
; Init LCD CG-RAM
LCD_INIT_CGRAM:
mov R0, 0x40
call LCD_writecmd
mov R1, 0xE0
mov R15, 6
write_char: mov R14, 7
write_cols: mov R0, R1
call LCD_writedata
dec R14
jnz write_cols
mov R0, 0
call LCD_writedata
mov R0, 1
shr R0
rorc R1
dec R15
jnz write_char
ret
; -------------------------------------------------
bar_div:
push R0
push R1
push R15
movc R0, (bar_upd_count+0)
movc R1, (bar_upd_count+1)
dec R0
subc R1, 0
movc (bar_upd_count+0), R0
movc (bar_upd_count+1), R1
tst R1
jz chk_lsb
jmp ex_div
chk_lsb: tst R0
jz reload
jmp ex_div
reload: mov R0, BAR_UPD_INTERVAL,'low
mov R1, BAR_UPD_INTERVAL,'high
movc (bar_upd_count+0), R0
movc (bar_upd_count+1), R1
mov R15, 11
mov R0, 0
movc R1, (lcd_disp+1)
cmp R1, 0x80
jge skip_l
go_l: movc R1, (lcd_disp+1)
movc R0, (lcd_disp+0)
div_lp_l: shr R1
rorc R0
dec R15
jnz div_lp_l
skip_l: movc (bar_value+0), R0
mov R15, 11
mov R0, 0
movc R1, (lcd_disp+3)
cmp R1, 0x80
jge skip_r
go_r: movc R0, (lcd_disp+2)
movc R1, (lcd_disp+3)
div_lp_r: shr R1
rorc R0
dec R15
jnz div_lp_r
skip_r: movc (bar_value+1), R0
movc R0, (bar_value+0)
movc R1, (bar_data+0)
tst R1
jz bot_l
dec R1
bot_l: cmp R0, R1
jlt no_upd_l
mov R1, R0
no_upd_l: movc (bar_data+0), R1
movc R0, (bar_value+1)
movc R1, (bar_data+1)
tst R1
jz bot_r
dec R1
bot_r: cmp R0, R1
jlt no_upd_r
mov R1, R0
no_upd_r: movc (bar_data+1), R1
ex_div: pop R15
pop R1
pop R0
ret
include "../../../lib/jasm/delays.inc.jsm"
include "../../../lib/jasm/lcd.inc.jsm"
include "../../../lib/jasm/utils.inc.jsm"