Skip to content

Commit 532c408

Browse files
Manipulador de interrupções e correções
1 parent 86e4794 commit 532c408

File tree

9 files changed

+125
-17
lines changed

9 files changed

+125
-17
lines changed

Analise.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,16 @@ private Rotina processaSubFunction(Modulo mod, NivelPublicidade publi, bool reto
671671
rot.TipoRetorno = processaTipo(ref trechos);
672672
trechos.Proximo();
673673
}
674+
if(trechos.EhIdentificador("handles"))
675+
{
676+
trechos.Proximo();
677+
if(trechos.EhIdentificador("interrupt"))
678+
{
679+
trechos.Proximo();
680+
rot.ManipuladorDeInterrupcao = true;
681+
}
682+
else trechos.Erro("Tipo de evento não suportado");
683+
}
674684
trechos.ExigeFimDaLinha("Esperado fim da linha depois da declaração da rotina.");
675685
trechos.ExigeProximaLinha(subTrecho, "Encontrado fim do arquivo com um 'sub'/'function' aberta");
676686
nivelRotina(mod, rot, rot.Comandos, false, ref trechos);

Distro/Atual/hcbasic.dll

2 KB
Binary file not shown.

Distro/Atual/hcbasic.pdb

412 Bytes
Binary file not shown.

Makefile

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
2+
all:
3+
make fonts
4+
dotnet publish -c Release -o Distro/Atual
5+
16
fonts:
27
nasm -f bin -o Plataformas/8086/Font.hfn Plataformas/Font.asm
38

4-
all: fonts
5-
dotnet publish -c Release -o Distro/Atual
69

710
distro: distro-win distro-linux distro-mac
811

@@ -71,15 +74,16 @@ install:
7174
mkdir -p /usr/lib/hcbasic/8086-kernel
7275
install Plataformas/8086-KERNEL/* /usr/lib/hcbasic/8086-kernel/
7376

74-
teste-hcb: fonts
77+
teste-hcb:
78+
make fonts
7579
Distro/Atual/hcbasic teste.hcb teste.asm Plataformas/8086-DOS / Plataformas/8086/
7680
nasm -f bin -o teste.com teste.asm
7781
dosbox -C "mount c: ." -C "c:" -C "teste.com"
7882

79-
teste: all
83+
teste: all
8084
make teste-hcb
8185

8286
clean:
8387
-rm -Rf Distro/Atual
8488
-rm -Rf obj
85-
-rm -Rf bin
89+
-rm -Rf bin

Nos/Acao.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ void acaoPonteiro(Ambiente amb, DeclaraVariavel variavel, TipoAcaoPonteiro tipoP
345345
if(ValorGravacao is Acao && ((Acao)ValorGravacao).TipoCompilado == TipoVariavel.Desconhecido) throw Erro($"Falha de compilador: falta o Acao definir o TipoCompilado para {((Acao)ValorGravacao).Tipo} {string.Join('.',((Acao)ValorGravacao).Nome)}");
346346
if(ValorGravacao is Acao && ((Acao)ValorGravacao).TipoCompiladoPonteiro)
347347
amb.Saida.EmiteCopiaPonteiroRemotoParaVariavelGlobal(variavel.NomeGlobal);
348-
if(tipoPonteiro == TipoAcaoPonteiro.Byte)
348+
else if(tipoPonteiro == TipoAcaoPonteiro.Byte)
349349
amb.Saida.EmiteCopiaAcumuladorParaByteArrayDaVariavelGlobal(variavel.NomeGlobal, desvioNoPonteiro);
350350
else if(tipoPonteiro == TipoAcaoPonteiro.Word)
351351
amb.Saida.EmiteCopiaAcumuladorParaWordArrayDaVariavelGlobal(variavel.NomeGlobal, desvioNoPonteiro);
@@ -919,6 +919,7 @@ protected override void CompilaInterno(Ambiente amb)
919919
throw Erro("Rotina não encontrada");
920920
referencia.Dequeue();
921921
if(referencia.Any()) throw Erro("Caminho indisponível para rotina");
922+
if(rot.ManipuladorDeInterrupcao) throw Erro("Não é possível chamar manipuladores de interrupção diretamente");
922923
var tipoAnterior = amb.Tipo;
923924
var variavelAnterior = amb.VariavelDestino;
924925
List<No> args = new List<No>();

Nos/Rotina.cs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
class Rotina : No
22
{
3+
public bool ManipuladorDeInterrupcao { get; set; } = false;
34
public bool TemTryCatch { get; set; } = false;
45
public Modulo Modulo { get; set; }
56
public bool IgnorarCabecalhoRodape { get; set; } = false;
@@ -35,22 +36,32 @@ protected override void CompilaInterno(Ambiente amb)
3536
{
3637
amb.DentroDeUmTryCatch = false;
3738
amb.Rotina = this;
39+
if(ManipuladorDeInterrupcao & RetornaValor)
40+
throw Erro("Manipuladores de interrupção não podem ser funções, devendo retornar valores via os registradores.");
3841
if(!IgnorarCabecalhoRodape)
3942
{
40-
amb.Saida.EmiteRotina(Nome);
43+
if(ManipuladorDeInterrupcao)
44+
amb.Saida.EmiteInterrupcao(Nome);
45+
else
46+
amb.Saida.EmiteRotina(Nome);
4147
}
4248
if(Argumentos.Any() | Variaveis.Any())
4349
{
4450
amb.Saida.EmiteEntraNaRotina();
4551
if(PosicaoVar != 0)
52+
{
4653
amb.Saida.EmiteSubtraiDoPtrPilha(PosicaoVar);
47-
amb.Saida.EmiteCopiaVariavelGlobalParaAcumulador("_os_minstackptr");
48-
amb.Saida.EmiteCopiaPonteiroPilhaParaAuxiliar();
49-
amb.Saida.EmiteComparaAcumuladorComAuxiliar();
50-
string semErro = amb.Saida.GeraRotulo();
51-
amb.Saida.EmitePulaSeMenorQue(semErro, true);
52-
EmiteErro.GeraECompila(amb, "StackOverflowError");
53-
amb.Saida.EmiteRotulo(semErro);
54+
if(!ManipuladorDeInterrupcao)
55+
{
56+
amb.Saida.EmiteCopiaVariavelGlobalParaAcumulador("_os_minstackptr");
57+
amb.Saida.EmiteCopiaPonteiroPilhaParaAuxiliar();
58+
amb.Saida.EmiteComparaAcumuladorComAuxiliar();
59+
string semErro = amb.Saida.GeraRotulo();
60+
amb.Saida.EmitePulaSeMenorQue(semErro, true);
61+
EmiteErro.GeraECompila(amb, "StackOverflowError");
62+
amb.Saida.EmiteRotulo(semErro);
63+
}
64+
}
5465
foreach (var variavel in Argumentos)
5566
{
5667
amb.Saida.EmiteComentario($"ARG: {variavel.Nome} TAM: {amb.Saida.CalculaTamanho(variavel.Tipo)} POS: BP+{variavel.Posicao} ");
@@ -71,13 +82,17 @@ protected override void CompilaInterno(Ambiente amb)
7182
}
7283
if(!IgnorarCabecalhoRodape)
7384
{
74-
amb.Saida.EmiteRotinaFim(Nome);
85+
if(ManipuladorDeInterrupcao)
86+
amb.Saida.EmiteInterrupcaoFim(Nome);
87+
else
88+
amb.Saida.EmiteRotinaFim(Nome);
7589
}
7690
amb.Rotina = null;
7791
}
7892

7993
protected override void InicializaInterno(Ambiente amb)
8094
{
95+
if(ManipuladorDeInterrupcao) PosicaoArg = 2;
8196
amb.Rotina = this;
8297
InicializaLista(Comandos, amb);
8398
if(TemTryCatch) PosicaoVar = 10;

Plataformas/8086/System.hcb

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,39 @@ module UInt32
407407
asm "mov [si], ax\n"
408408
asm "mov [si+2], bx\n"
409409
end
410-
end
410+
end
411+
412+
Module IO
413+
Public Sub OutputByte(port as UInt16, value as UInt8)
414+
asm "mov dx, [bp+6]"
415+
asm "mov ax, [bp+8]"
416+
asm "out dx, al"
417+
End
418+
419+
Public Sub OutputWord(port as UInt16, value as UInt16)
420+
asm "mov dx, [bp+6]"
421+
asm "mov ax, [bp+8]"
422+
asm "out dx, ax"
423+
End
424+
425+
Public Function InputByte(port as UInt16) as UInt8
426+
asm "mov dx, [bp+6]"
427+
asm "xor ax, ax"
428+
asm "in al, dx"
429+
End
430+
431+
Public Function InputWord(port as UInt16) as UInt16
432+
asm "mov dx, [bp+6]"
433+
asm "in ax, dx"
434+
End
435+
436+
Public Sub RegisterHandler(interrupt as UInt8, handler as PtrByteArray)
437+
Dim ptr as PtrWordArray
438+
#ptr = 0
439+
@ptr = interrupt * 4
440+
ptr = @handler
441+
@ptr ++
442+
@ptr ++
443+
ptr = #handler
444+
End
445+
End

Saida.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,5 +160,7 @@ public void Fecha()
160160
public abstract void EmiteCopiaVariavelGlobalParaPonteiroBase(string rotulo);
161161
public abstract void EmiteCopiaVariavelGlobalParaPonteiroPilha(string rotulo);
162162
public abstract void EmiteInverteAcumulador();
163+
public abstract void EmiteInterrupcao(string nome);
164+
public abstract void EmiteInterrupcaoFim(string nome);
163165

164166
}

Saida8086.cs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,47 @@ public override void EmiteRotinaFim(string nome)
4949
EmiteL("retf");
5050
}
5151

52+
public override void EmiteInterrupcao(string nome)
53+
{
54+
EmiteL($"_{Modulo}_{nome}:");
55+
PonteiroDefinido = false;
56+
EmiteL("push di");
57+
EmiteL("push es");
58+
EmiteL("push si");
59+
EmiteL("push ds");
60+
EmiteL("push dx");
61+
EmiteL("push cx");
62+
EmiteL("push bx");
63+
EmiteL("push ax");
64+
EmiteL("push bp");
65+
EmiteL("mov ax, sp");
66+
EmiteL("push ax");
67+
EmiteL("push ss");
68+
// DS = SS
69+
EmiteL("push ss");
70+
EmiteL("pop ds");
71+
}
72+
73+
public override void EmiteInterrupcaoFim(string nome)
74+
{
75+
PonteiroDefinido = false;
76+
EmiteL("pop ax");
77+
EmiteL("pop bx");
78+
EmiteL("mov ss, ax");
79+
EmiteL("mov sp, bx");
80+
EmiteL("pop bp");
81+
EmiteL("pop ax");
82+
EmiteL("pop bx");
83+
EmiteL("pop cx");
84+
EmiteL("pop dx");
85+
EmiteL("pop ds");
86+
EmiteL("pop si");
87+
EmiteL("pop es");
88+
EmiteL("pop di");
89+
EmiteL($"FIM_{Modulo}_{nome}:");
90+
EmiteL("iret");
91+
}
92+
5293
public override void EmiteEntraNaRotina()
5394
{
5495
EmiteL("push bp");
@@ -728,7 +769,7 @@ public override void EmiteCopiaWordArrayDaVariavelLocalParaPonteiroRemoto(int po
728769
public override void EmiteCopiaPonteiroRemotoParaVariavelGlobal(string rotulo)
729770
{
730771
EmiteL($"push es");
731-
EmiteL($"cs pop word [{rotulo}]");
772+
EmiteL($"cs pop word [{rotulo}+2]");
732773
EmiteL($"cs mov [{rotulo}], di");
733774
PonteiroDefinido = true;
734775
PonteiroLocal = false;

0 commit comments

Comments
 (0)