📄 ts201_link.asm
字号:
xr0 = 0x0;; // xr0 = destination index
xr1 = (4 << 16) | 4;; // count = 4, modify = 4
xr3 = TCB_INTMEM | TCB_QUAD | TCB_INT | TCB_DMAR;; // int mem,prio=norm,2D=no,word=quad,int=yes,RQ=enbl,chain=no
jL2 = j31 + 4;; // J2 is the intermediate link data buffer pointer...
jB2 = j31 + 0;; // ...of length 4, base at 0x00
j2 = j31 + 0;;
yr7 = 1;;
/**********************************************************************************************/
_boot_loop:
call _read_word (NP);; // read word
yr8 = xr4;; // read type and count
nop; nop;;
call _read_word (NP);; // read word
j0 = xr4;; // read destination
yr2 = 0x0000FFFF;;
yr2 = r2 and r8;; // mask count
yr1 = 0x00001E02;;
yr1 = fext r8 by r1;; // extract type
if yseq, jump _final_init (NP);; // if zero - final init...
yr1 = r1 - r7;; // ...else if 1...
if yaeq, jump _init_data (NP);; // ...non-zero data init...
/***********************************************************************************************/
_zero_init: // ...else zero-data init
LC0 = yr2;; // put count into counter
_zero_init_loop:
[j0+=1] = yr0;; // init with 0's
if NLC0E, jump _zero_init_loop (NP);;
jump _boot_loop (NP);; // check next block
/***********************************************************************************************/
_init_data:
LC0 = yr2;; // put count into loop counter
_init_data_1:
call _read_word (NP);; // read word
[j0 += 1] = xr4;; // write word
if NLC0E, jump _init_data_1 (NP);;
jump _boot_loop (NP);; // check next block
/**************************************************************************************************
This routine waits till the cache commands are complete
***************************************************************************************************/
_wait_for_cache:
xr0 = CASTAT0;;
xbitest r0 by CASTAT_COM_ACTIVE_P;; // is the command still active?
if nxseq, jump _wait_for_cache (NP);;// wait till the command is done
_chk_castat_init2:
xr0 = CASTAT2;;
xbitest r0 by CASTAT_COM_ACTIVE_P;; // is the command still active?
if nxseq, jump _chk_castat_init2 (NP);;// wait till the command is done
_chk_castat_init4:
xr0 = CASTAT4;;
xbitest r0 by CASTAT_COM_ACTIVE_P;; // is the command still active?
if nxseq, jump _chk_castat_init4 (NP);;// wait till the command is done
_chk_castat_init6:
xr0 = CASTAT6;;
xbitest r0 by CASTAT_COM_ACTIVE_P;; // is the command still active?
if nxseq, jump _chk_castat_init6 (NP);;// wait till the command is done
_chk_castat_init8:
xr0 = CASTAT8;;
xbitest r0 by CASTAT_COM_ACTIVE_P;; // is the command still active?
if nxseq, jump _chk_castat_init8 (NP);;// wait till the command is done
_chk_castat_init10:
xr0 = CASTAT10;;
xbitest r0 by CASTAT_COM_ACTIVE_P;; // is the command still active?
if nxseq, jump _chk_castat_init10 (NP);;// wait till the command is done
CJMP (NP)(ABS);;
/*************************************************************************************************
Final Init
*************************************************************************************************/
_final_init:
xr8 = xr4;; // put first four user instrucions into xr11:8
call _read_word (NP);; // read word
xr9 = xr4;;
call _read_word (NP);; // read word
xr10 = xr4;;
call _read_word (NP);; // read word
xr11 = xr4;;
call _read_word (NP);; // put next four user instrucions into xr15:12
xr12 = xr4;;
call _read_word (NP);; // read word
xr13 = xr4;;
call _read_word (NP);; // read word
xr14 = xr4;;
call _read_word (NP);; // read word
xr15 = xr4;;
call _read_word (NP);; // put next four user instrucions into xr19:16
xr16 = xr4;;
call _read_word (NP);; // read word
xr17 = xr4;;
call _read_word (NP);; // read word
xr18 = xr4;;
call _read_word (NP);; // read word
xr19 = xr4;;
call _read_word (NP);; // put next four user instrucions into xr23:20
xr20 = xr4;;
call _read_word (NP);; // read word
xr21 = xr4;;
call _read_word (NP);; // read word
xr22 = xr4;;
call _read_word (NP);; // read word
xr23 = xr4;;
call _read_word (NP);; // put next four user instrucions into xr27:24
xr24 = xr4;;
call _read_word (NP);; // read word
xr25 = xr4;;
call _read_word (NP);; // read word
xr26 = xr4;;
call _read_word (NP);; // read word
xr27 = xr4;;
call _read_word (NP);; // put next four user instrucions into xr31:28
xr28 = xr4;;
call _read_word (NP);; // read word
xr29 = xr4;;
call _read_word (NP);; // read word
xr30 = xr4;;
call _read_word (NP);; // read word
xr31 = xr4;;
call _read_word (NP);; // put next four user instrucions into yr31:28
yr24 = xr4;;
call _read_word (NP);; // read word
yr25 = xr4;;
call _read_word (NP);; // read word
yr26 = xr4;;
call _read_word (NP);; // read word
yr27 = xr4;;
call _read_word (NP);; // put next four user instrucions into yr31:28
yr28 = xr4;;
call _read_word (NP);; // read word
yr29 = xr4;;
call _read_word (NP);; // read word
yr30 = xr4;;
call _read_word (NP);; // read word
yr31 = xr4;;
j0 = j31 + _dma_int;;
j1 = j31 + 4;; // move ISR into 0x04-0x08
xr4 = [j0 += 1];;
[j1 += 1] = xr4;;
xr4 = [j0 += 1];;
[j1 += 1] = xr4;;
xr4 = [j0 += 1];;
[j1 += 1] = xr4;;
xr4 = [j0 += 1];;
[j1 += 1] = xr4;;
xr4 = [j0 += 1];;
[j1 += 1] = xr4;;
j0 = j31 + _last_patch_code;; // move patch into locations 0x09-0x1f
LC0 = 0x17;;
_patch_loop:
xr4 = [j0 += 1];;
[j1 += 1] = xr4;;
if NLC0E, jump _patch_loop (NP);;
btbinv;; // invalidate BTB
CACMDALL = CACMD_EN;; // re-enable the cache
xr4 = 0x04;; // set the interrupt vector to the relocated ISR
#if LINK==0
IVDMA8 = xr4;;
#endif
#if LINK==1
IVDMA9 = xr4;;
#endif
#if LINK==2
IVDMA10 = xr4;;
#endif
#if LINK==3
IVDMA11 = xr4;;
#endif
yr0 = SQCTL_NMOD | SQCTL_TRCBEN;; // DBGEN, NMOD, TRCBEN set, global ints disabled
j0 = 0x20;; // final init of 0x20-0xff
LC0 = 0xe0;;
jump 0x12 (ABS)(NP);; // and jump to patch - _final_init1
/*************************************************************************************************
LINK DMA ISR
*************************************************************************************************/
.align_code 4;
_dma_int:
nop; nop; nop; nop;; // RTI can not be in the first quad of an ISR
rti (ABS)(NP);;
/*********************************** Last Patch *************************************************/
_last_patch_code:
/**************************************************************************************************
This routine reads buffer data and, if buffer is finished, transfers more data via link ports
Input: j2 -> word in data buffer
Output: xr4 = data word, j2 -> next word in buffer
***************************************************************************************************/
_read_word:
comp(j2,0);; // if J2 -> start of the buffer...
if njeq, jump _read_buffer (NP);;
// ...bring in more data
#if LINK==0
DC8 = xr3:0;; // start the DMA
#endif
#if LINK==1
DC9 = xr3:0;; // start the DMA
#endif
#if LINK==2
DC10 = xr3:0;; // start the DMA
#endif
#if LINK==3
DC11 = xr3:0;; // start the DMA
#endif
nop;; // 3 NOPs before idle are required...
nop;; // ... because of anomaly #03-00-0306
nop;;
idle;; // wait till DMA interrupts
_read_buffer:
xr4 = cb[j2+=1];; // read the word from the buffer
cjmp (ABS) (NP);; // and return
/*************************************************************************************************/
_final_init1:
call _read_word (NP);; // read word
[j0 += 1] = xr4;; // write it
if NLC0E, jump _final_init1 (NP);;
SQCTL = yr0;; // disable interrupts
Q[j31 + 0] = xr11:8;; // overwrite 0x00-0x03
Q[j31 + 4] = xr15:12;; // overwrite 0x04-0x07
Q[j31 + 8] = xr19:16;; // overwrite 0x08-0x0b
Q[j31 + 0xc] = xr23:20;; // overwrite 0x0c-0x0f
Q[j31 + 0x10] = xr27:24;; // overwrite 0x10-0x13
Q[j31 + 0x14] = xr31:28;; // overwrite 0x14-0x17
Q[j31 + 0x18] = yr27:24;; // overwrite 0x18-0x1b
jump 0x0 (ABS)(NP); Q[j31 + 0x1c] = yr31:28;;// overwrite 0x1c-0x1f and start from 0x00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -