DPTR extrapolando?

Boa tarde!
Fiz um programa um pouco complexo que carrega informações num LCD 2x16 ao apertar das teclas.
O programa está todo em assembly.
Para cada nova informação, o algoritmo busca as referência numa tabela de dados.
Porém percebi que, num certo ponto, o display simplesmente fica doido!
Fiz muitos teste sem sucesso. Eliminei ao máximo as informações desnecessárias no programa, que agora conta simplesmente com as rotinas de inicialização do LCD e escrita nas duas linhas, mais nada! O defeito, entretanto, persiste...
Assim, comecei a desconfiar de duas coisas:
1) Problemas com o meu compilador (8051IDE);
2) Limitações na utilização do DPTR inerentes ao AT89S8252, impedindo a busca de dados após a posição de memória de programa 2000h.
Anexo a seguir o programa.
Na sub-rotina "TelaUm", a linha "mov DPTR,#teste3" está descomentada, ou seja, sem o ponto-e-vírgula, de modo que será executada pelo programa e gerará o defeito. Com a colocação do ponto-e-vírgula nela, o compilador irá ignorá-la na geração do .HEX. Se descomentarem a linha teste1 ou teste2, verão que o programa irá funcionar sem problemas...
Alguém saberia informar o motivo do mau-funcionamento?
OBS.: não consegui anexar o esquema do circuito aqui...
Segue o programa:
asm code
Fiz um programa um pouco complexo que carrega informações num LCD 2x16 ao apertar das teclas.
O programa está todo em assembly.
Para cada nova informação, o algoritmo busca as referência numa tabela de dados.
Porém percebi que, num certo ponto, o display simplesmente fica doido!
Fiz muitos teste sem sucesso. Eliminei ao máximo as informações desnecessárias no programa, que agora conta simplesmente com as rotinas de inicialização do LCD e escrita nas duas linhas, mais nada! O defeito, entretanto, persiste...
Assim, comecei a desconfiar de duas coisas:
1) Problemas com o meu compilador (8051IDE);
2) Limitações na utilização do DPTR inerentes ao AT89S8252, impedindo a busca de dados após a posição de memória de programa 2000h.
Anexo a seguir o programa.
Na sub-rotina "TelaUm", a linha "mov DPTR,#teste3" está descomentada, ou seja, sem o ponto-e-vírgula, de modo que será executada pelo programa e gerará o defeito. Com a colocação do ponto-e-vírgula nela, o compilador irá ignorá-la na geração do .HEX. Se descomentarem a linha teste1 ou teste2, verão que o programa irá funcionar sem problemas...
Alguém saberia informar o motivo do mau-funcionamento?
OBS.: não consegui anexar o esquema do circuito aqui...
Segue o programa:
asm code
;TESTE DE MENUS LCD
tempo equ 60535 ;5.000us = 5ms (65535 - 60535 = 5000 pulsos)
tempo2 equ 15535 ;50.000us = 50ms (65535 - 15535 = 50000 pulsos)
LCDRot equ 1300h
MenuInicial equ 14E4h
MenuDetalhado equ 1FD4h
;PINOS DA PORTA P3 PARA CONTROLE DO LCD. PORTA DE ACIONAMENTO DO BARRAMENTO DO LCD: P0
LCD equ P0
EN equ P3.7
RS equ P3.6
RW equ P3.5
org 0030h
inicio: mov tmod,#1h ;habilita Timer0 em Modo 1 (contador 16 bits)
mov SP,#60h ;Stack Pointer inicializa na área de bytes endereçáveis (30h a 7Fh) acima dos outros bytes já utilizados
;*********************************************************************************************************
;INICIALIZAÇÃO DO DISPLAY
lcall inic_display ;inicializa display
lcall TelaUm
TelaUm: mov a,#80h ;posiciona o cursor: 80h=1ª linha (1ª coluna).
lcall wrcomando ;escreve a instrução
mov DPTR, #MenuInicial
lcall writestring ;escreve mensagem
mov a,#0C0h ;posiciona o cursor: C0h=2ª linha (1ª coluna).
lcall wrcomando ;escreve a instrução
; mov DPTR,#teste1 ;esta linha fica OK quando descomentada
; mov DPTR,#teste2 ;esta linha fica OK quando descomentada
mov DPTR,#teste3 ;o problema ocorre quando esta linha é descomentada (quando está sem o ponto-e-vírgula)
lcall writestring ;escreve mensagem
Loop: sjmp $ ;loop infinito
;*********************************************************************************************************
;Sub-rotinas LCD
inic_display:
lcall t15ms
lcall t15ms
mov a, #38h ;00111000b. Function set (8-bit interface, 2 linhas,matriz de 5*7)
lcall wrcomando
mov a, #38h ;idem
lcall wrcomando
mov a, #06h ;00000110b. Deslocar cursor à DIREITA à entrada de novo caractere
lcall wrcomando
mov a, #0ch ;00001100b. Liga o display, cursor desabilitado.
lcall wrcomando
mov a, #01h ;00000001b. Limpa display
lcall wrcomando
lcall t5ms ;chama atraso 5ms
ret
wrcomando: clr RW
clr RS
mov LCD,a
setb EN
clr EN
lcall t5ms
ret
wrdados: clr RW
setb RS
mov LCD,a
setb EN
clr EN
lcall t5ms
ret
writestring:
mov a, #0 ;utilização das STRINGs como segue abaixo:
movc a, @a+DPTR ;"varre" (incrementa)o DPTR até que encontre a letra "$" e aí pára de ler.
cjne a, #'$', write_next
sjmp finis_string
write_next:
lcall wrdados
inc DPTR
sjmp writestring
finis_string:
ret
;*********************************************************************************************************
;TEMPORIZADORES
t5ms: mov TL0, #low(tempo) ;carrega em TL0 a parte baixa do valor de 5ms
mov TH0, #high(tempo) ;carrega em TH0 a parte alta do valor de 5ms
setb tr0
jnb tf0, $
clr tr0
clr tf0
ret
t15ms: mov TL0, #low(tempo2) ;carrega em TL0 a parte baixa do valor de 15ms
mov TH0, #high(tempo2) ;carrega em TH0 a parte alta do valor de 15ms
setb tr0
jnb tf0, $
clr tr0
clr tf0
ret
;*********************************************************************************************************
org MenuInicial
db 'Menu Inicial $'
org MenuDetalhado
teste1: db 'LARANJA $'
teste2: db 'LIMAO $'
teste3: db 'ABACAXI $'
end