Il primo programma

In questo capitolo andiamo ad esaminare i vari aspetti del "Linguaggio macchina" e le sue dirette funzionalità su di un calcolatore, andiamo ad esaminare la relativa codifica e la sua esecuzione, in quanto non avendo funzioni di supporto per scrivere il primo programma siamo obbligati ad utilizzare solamente il "Linguaggio macchina". Su internet cirolano migliaia di pagine alla voce linguaggio-macchina complentamente inutili in quanto propongono più che altro giri di parole sull'argomento, discutono la teoria magari ricavata o copiata da altri siti ma non propongono lezioni di pratica, la pratica è quella che serve e ci fa capire il funzionamento di un calcolatore. La pratica ci permette di imparare un mestiere quale esso sia e con l'intelligenza cercare di affinarlo o migliorarlo mettendolo in esecuzione. Naturalmente la pratica richiede tempo e buona volontà.
Con il nostro primo programma andiamo a codificare le istruzioni di base come al solito per la loro stesura possiamo utilizzare il debug di un qualsiasi sistema operativo poi dobbiamo copiare il relativo codice-macchina e andarlo a depositare nelle locazioni ad esso riservato, quindi con il relativo "mbr" possiamo metterlo in esucuzione sulla macchina per poterlo testare. Il nostro primo programma occupa un intero segmento di codice, vedremo di ripartizionarlo nel modo più adatto sarà un programma a 32-bit e relativa memoria protetta, andremo a costruire un ambiente grafico con i relativi colori della scheda-video e il blocco principale del programma conterrà le funzioni per l'esecuzione di un editor di testo e un compilatore per istruzioni in "assembler". Tutto questo lo possiamo fare se riusciamo a comprendere il vero funzionamento della macchina, la cosa diventa fattibile e con un minimo sforzo realizzabile, certo la teoria non ci basta ma ci vuole della buona pratica.
Scrivere il codice direttamente in "Linguaggio macchina" non è che sia poi così difficile, il vero problema che si crea è riuscire a mantenere un ottimo ordine nella codifica delle istruzioni, in quanto rimane difficile la modifica del codice stesso, mi spiego meglio, se noi scriviamo dieci righe di codice poi decidiamo di inserire ad esempio una nuova riga in mezzo a quelle già scritte la cosa non è più fattibile, in quanto il linguaggio-macchina è una struttura rigida, quindi per aggiungere quella riga praticamente ci dobbiamo rifare il nostro codice, quindi massimo ordine, scrivere poche istruzioni ed andarle a testare. Per il resto il liguaggio-macchina è molto più semplice e molto più sbrigativo di in qualsiasi linguaggio compilato.

      Una piccola legenda di defininzioni che useremo per la scrittura del codice, numerazione in esadecimale
      00,00,00,00  = numero di settore del disco-fisso
      :0000        = locazione di memoria
      *00 00 00 00 = locazioni di menoria contenenti dati fissi o variabili
      ;commento    = testo di commento all'interno del codice
      
Il nostro primo programma lo chiameremo "Avvio" e sarà caricato in memoria ed eseguito dal suo omonimo mbr.
Il codice del programma in costruzione va scritto direttamente su disco a partire dal settore: 00,08,00,80
Di seguito vi propongo le istuzioni di tale codice che voi potete modificare a piacimento.

Partiamo con il codice del programma
          ;un promemoria per ricordarci dove dobbiamo prelevare o depositare eventuale codice
          ;disco-fisso
      ;00,01,00,00  elenco dei nomi 
      ;00,01,00,82  impostazioni di "avvio"
      ;00,03,00,00  definizioni di assembler
      ;00,08,00,00  segmento dati
      ;00,08,00,80  segmento codice
          ;memoria
      ;03:0000      elenco dei nomi
      ;04:0000      definizioni del testo
      ;04:0000      definizioni di assembler
      ;05:0000      codice compilato
      ;10:0000      impostazioni e archivi

      :0000 jmp 0400          ;la prima istruzione ad inizio segmento ci fa saltare ad inizio eseguibile

          ;qui scriviamo gli indirizzi a 6 bytes delle due tabelle a partire dalla locazione :0003
      *80 00 10 00 01 00        ;0003 tabella idt
      *18 00 90 00 01 00        ;0009 tabella gdt

          ;qui riportiamo la tabella "idt" a 8 bytes a partire dalla locaziome :0010
      *00 80 08 00 00 8f 00 00  ;0010 int 00
      *00 80 08 00 00 8f 00 00  ;int 01
      *00 80 08 00 00 8f 00 00  ;int 02
      *00 80 08 00 00 8f 00 00  ;int 03
      *00 80 08 00 00 8f 00 00  ;int 04
      *00 80 08 00 00 8f 00 00  ;int 05
      *00 80 08 00 00 8f 00 00  ;int 06
      *00 80 08 00 00 8f 00 00  ;int 07
      *30 80 08 00 00 8f 00 00  ;int 08
      *b0 80 08 00 00 8f 00 00  ;int 09
      *00 80 08 00 00 8f 00 00  ;int 0a
      *00 80 08 00 00 8f 00 00  ;int 0b
      *00 80 08 00 00 8f 00 00  ;int 0c
      *00 80 08 00 00 8f 00 00  ;int 0d
      *00 80 08 00 00 8f 00 00  ;int 0e
      *00 80 08 00 00 8f 00 00  ;int 0f

          ;qui riportiamo la tabella "gdt" a 8 bytes a partire dalla locazione :0090
      *00 00 00 00 00 00 00 00  ;0090 indice 00
      *00 00 00 00 01 9a 01 00  ;indice 08 (codice)
      *00 00 00 00 00 92 81 00  ;indice 10 (dati)

          ;qui registraiamo tutte le variabili che ci servono per il programma a parire dalla locazione :0100
      *00 00 00 00  ;0100 il tempo totale
      *00 00        ;0104 il tempo parziale
      *00 00 00 00  ;0106 la tastiera
      *00           ;010a fondo riga
      *00
      *00 00 00 00  ;010c numero da convertire
      *00000000 00000000  ;0110 numero convertito
      *88 88 88 88  ;0118 sfondo riga di comando
      *f5 88 01 88  ;011c colori riga di comando
      *00 00        ;0120 numero settori
      *00 00 00 00  ;0122 posizione su disco
      *00 00 00 00  ;0126 posizione in memoria
      *00 00        ;012a riduzione del video
      *c0 13 02 00  ;012c buffer della linea di comando
      *e0 11 07 00  ;0130 punto e pagina video della linea di comando
      *20 03 00 00  ;0134 orizzontale video
      *3d 02 00 00  ;0138 verticale video
      *00 00 00 03  ;013c memoria grafica
      *00 00 00 00  ;0140 fondo buffer archivi
      *54 02 00 00  ;0144 orizzontale pagina
      *3d 02 00 00  ;0148 verticale pagina
      *00 00        ;014c impaginazione sulla x
      *00 00        ;014e impaginazione sulla y
      *00 00 00 00  ;0150 primo punto
      *00 00 00 00  ;0154 punti per pagina
      *00 00 00 00  ;0158 dimensione del testo
      *00 00 40 00  ;015c memoria grafica
      *00 00 00 00  ;0160 spie della tastiera
      *00 e4 8f 03  ;0164 max settore del disco
      *00 00 06 00  ;0168 fondo codifica del salto
      *00000000000000000000000000000000  ;0180 numeri istruzione
      *00000000000000000000000000000000
      *00000000000000000000000000000000  ;01a0 testo istruzioni
      *00000000000000000000000000000000

          ;da qui parte il codice eseguibile del nostro programma dalla locazione :0400
           impostiamo il modo video grafico con risoluzione "800x600"
      :0400 mov ax,4F02
      :0403 mov bx,0103
      :0406 int 10
          ;impostiamo la linea "a0" per poter accedere a tutta la memoria del calcolatore
      :0408 cli
      :0409 call 8120
      :040C mov al,D1
      :040E out 64,al
      :0410 call 8120
      :0413 mov al,DF
      :0415 out 60,al
      :0417 call 8120
      :041A mov al,FF
      :041C out 64,al
      :041E sti
          ;impostiamo la memoria protetta
      :041F cli
      :0420 mov ax,1000
      :0423 mov ds,ax
      :0425 lgdt pbyte [00000009]
      :042D lidt pbyte [00000003]
      :0435 mov eax,00000013
      :043B mov CR0,eax
      :043E sti
          ;impostiamo i registri di segmento
      :043F cli
      :0440 mov ax,0010
      :0443 mov ds,ax
      :0445 mov es,ax
      :0447 mov fs,ax
      :0449 mov gs,ax
      :044B mov ss,ax
      :044D mov esp,0000FFFF
      :0453 mov ax,0002
      :0456 push ax
      :0457 popf
      :0458 sti
      :0459 jmp 0008:0460
          ;adesso andiamo ad inviare la nostra tabella dei colori al controller
      :0460 cli
      :0461 mov ah,20
      :0463 call 8150
      :0466 push ax
      :0467 lea esi,[00021000] ;deposito della nostra tabella
      :046F mov dx,03C8
      :0472 mov al,00
      :0474 out dx,al
      :0475 inc dx
      :0476 mov cx,0100        ;numero di colori da inviare
      :0479 mov al,[esi]
      :047C out dx,al
      :047D mov al,[esi+01]
      :0481 out dx,al
      :0482 mov al,[esi+02]
      :0486 out dx,al
      :0487 add si,0003
      :048A loopw 0479
      :048C pop ax
      :048D call 8150
      :0490 sti
          ;sfondo riga di comando
      :0491 call 83E0
          ;In fondo a sinistra andiamo ad impostare la scritta "Pagina:" che ci verrà utile per eventuali numerazioni
           delle pagine video sia di testo che di grafica
      :0494 lea esi,[000214E0]
      :049C lea edi,[00071168]
      :04A4 mov bx,[0001011C]
      :04AB mov cx,0007
      :04AE mov al,[esi]
      :04B1 call 8220
      :04B4 inc si
      :04B5 add di,0008
      :04B8 loopw 04AE
          ;In fondo a destra andiamo ad impostare la scritta "X:      Y:" che ci verrà utile per la numerazione dei
           punti video sia in orizzontale che in verticale dei nostri disegni di grafica
      :04BA lea esi,[000214E7]
      :04C2 lea edi,[000713F0]
      :04CA mov bx,[0001011C]
      :04D1 mov cx,000B
      :04D4 mov al,[esi]
      :04D7 call 8220
      :04DA inc si
      :04DB add di,0008
      :04DE loopw 04D4
          ;col seguente codice andiamo a caricare il settore delle impostazioni direttamente dal disco-fisso
           alle locazioni di memoria 10:0000, qui avremo così qualche dato per l'inpostazione della pagina grafica
      :04E0 mov ax,0001
      :04E3 mov [00010120],ax
      :04E9 mov eax,00010082
      :04EF mov [00010122],eax
      :04F6 mov eax,00100000
      :04FC mov [00010126],eax
      :0503 call 8430
          ;poi andiamo a caricare alle locazioni di memoria 03:0000 l'elenco dei nomi che in precedenza abbiamo
           provveduto a dicitare direttamente sul disco-fisso.
           La dicitura di tale codice è descritta alla pagina "Impostazioni"
      :0506 mov ax,0001
      :0509 mov [00010120],ax
      :050F mov eax,00010000
      :0515 mov [00010122],eax
      :051C mov eax,00030000
      :0522 mov [00010126],eax
      :0529 call 8430
          ;imposta il disegno
      :052C call 8740
          ;disegna il video
      :052F call 87B0
          ;ciclo riga di comando, con il codice seguente andiamo a generare un ciclo continuo sulla linea di comando
           che ci permette di inserire o cancellare caratteri e numeri che ci servono per comporre le parole dei
           vari comandi
      :0532 mov ax,[00010106]  ;la tastiera
      :0538 cmp al,00
      :053A jz 0532
      :053C mov word [00010106],0000
      :0545 cmp ax,E02A
      :0548 jz 0532
      :054A cmp al,0E
      :054C jz 058B
      :054E cmp al,1C
      :0550 jz 05C4
          ;disegna un carattere
      :0552 mov ebx,[0001012C] ;buffer linea di comando
      :055A cmp bx,1400        ;controllo sul fine riga
      :055E jz 0532
      :0560 add al,80          ;carattere maiuscolo
      :0562 mov [ebx],al
      :0565 inc bx
      :0566 mov [0001012C],bx
      :056D mov edi,[00010130] ;video linea di comando
      :0575 mov bx,[0001011E]  ;colore dei caratteri
      :057C call 8220          ;disegna il carattere
      :057F add di,0008
      :0582 mov [00010130],di
      :0589 jmp 0532
          ;cancella un carattere
      :058B mov ebx,[0001012C]
      :0593 cmp bx,13C0        ;controllo sull'inizio riga
      :0597 jz 0532
      :0599 dec bx
      :059A mov byte [ebx],00
      :059E mov [0001012C],bx
      :05A5 mov edi,[00010130]
      :05AD sub di,0008
      :05B0 mov bx,[0001011E]
      :05B7 call 8220          ;cancella il caratttere
      :05BA mov [00010130],di
      :05C1 jmp 0532
          ;FINE  dicitando questa stringa sulla linea di comando e premendo il tasto ritorno
                 si esce definitivamente dal nostro ambiente di programmazione
      :05C4 lea esi,[000214FB]
      :05CC call 8830
      :05CF jb 05D4
      :05D1 jmp 8300
          ;COMPILA  dicitando questa stringa sulla linea di comando si entra nella fase di editazione del
                    codice assembler, naturalmente il comando dovrà essere seguito dal nome del programma
                    che vogliamo editare e successivamente compilare
      :05D4 lea esi,[00021500]
      :05DC call 8830
      :05DF jb 0532
          ;avendo una riga di comando già funzionante possiamo impostare la funzione che andrà a controllare
           nell'elenco nomi se il comando digitato veramente esiste o non esiste affatto o è scritto male, quindi
           appena riscontrato l'esattezza del nome si potrà uscire dal ciclo.
      :05E3 lea edi,[00030000] ;elenco dei nomi
      :05EB lea ebp,[000213C8] ;posizione sulla linea di comando
      :05F3 mov al,[edi]
      :05F6 cmp al,00          ;il nome non si trova
      :05F8 jz 0532
      :05FC push bp
      :05FD mov ah,[ebp+00]
      :0601 mov al,[edi]
      :0604 cmp al,ah
      :0606 jz 061B
      :0608 cmp ax,00FF        ;trovato il nome
      :060B jz 061F
      :060D inc di
      :060E mov al,[edi]
      :0611 cmp al,FF
      :0613 jnz 060D
      :0615 add di,0005
      :0618 pop bp
      :0619 jmp 05F3
      :061B inc bp
      :061C inc di
      :061D jmp 05FD
      :061F pop bp
      :0620 inc di
          ;carica le impostazioni, a questo punto abbiamo individuato sia il comando che il nome del programma
           quindi non ci resta che caricare il primo archivio del programma in memoria (a partire dalla locazione
           10:0000) contenente le impostazioni iniziali e parte del codice in formato testo come descritto
           alla pagina "impostazioni"
      :0621 mov ax,0080        ;numero di settori da caricare
      :0624 mov [00010120],ax
      :062A mov eax,[edi]      ;posizione su disco del codice da caricare
      :062E mov [00010122],eax
      :0635 lea edi,[00100000] ;posizione in memoria
      :063D mov [00010126],edi
      :0645 call 8430
      :0648 lea esi,[00100100] ;elenco degli archivi facente parte del programma
      :0650 mov ecx,[edi]
      :0654 shr ecx,10
      :0658 sub cx,0010        ;numero di archivi da caricare
      :065B jz 0680            ;non ci sono altri archivi
          ;carica gli archivi, poi andiamo a caricare in memoria tutti gli altri archivi facente parte del programma
           in editazione
      :065D mov eax,[esi]      ;posizione su disco del codice
      :0661 mov [00010122],eax
      :0668 add edi,00010000   ;posizione in memoria
      :066F mov [00010126],edi
      :0677 call 8430
      :067A add si,0004
      :067D dec cx
      :067E jnz 065D           ;ciclo di rotazione
      :0680 mov eax,[00100000]
      :0687 mov [00010140],eax ;fondo buffer archivi
          ;carica il testo, dopo aver caricato l'intero programma che ci serve per l'editazione del codice non ci
           rimane che andare a caricare un tipo di testo che verrà usato per la definizione dei caratteri.
           Lo andiamo a caricare a partire dalla locazione 4:0000 della memoria
      :068E mov eax,00020000
      :0694 mov al,[0010001B]  ;numero di settori da caricare
      :069A mov [00010120],ax
      :06A0 mov ax,[00100018]  ;posizione del testo su disco
      :06A6 mov [00010122],eax
      :06AD mov eax,00040000   ;posizione in memoria
      :06B3 mov [00010126],eax
      :06BA call 8430
          ;impaginazione, di seguito andiamo a calcolare le impostazioni di base che verranno utilizzate
           per impostare la pagina video del nostro editor di testo
      :06BD mov ax,[00010144]  ;orizzontale del video
      :06C3 mov ch,[00040004]  ;dimensione del testo
      :06CA div ch
      :06CC mov [0001014C],ax  ;impaginazione sulla x
      :06D2 mov ax,[00010148]  ;verticale video
      :06D8 mov ch,[00040006]  ;dimensione del testo
      :06DF div ch
      :06E1 mov [0001014E],ax  ;impaginazione sulla y
          ;calcola la pagina, qui andiamo a calcolare a che numero di pagina ci troviamo così possiamo
           ripartire dalla pagina la quale si era concluso il programma la volta precedente
      :06E7 lea edi,[00102001] ;buffer degli archivi
      :06EF mov ax,[00100006]  ;numero di pagina
      :06F5 dec ax
      :06F6 xor cx,cx
      :06F8 mov cl,[0001014E]
      :06FF mul cx
      :0701 mov cx,ax          ;numero di righe
      :0703 cmp cx,0000
      :0706 jz 0718
      :0708 mov al,[edi]
      :070B cmp al,1C          ;fondo riga
      :070D jz 0713
      :070F inc edi
      :0711 jmp 0708
      :0713 inc edi
      :0715 dec cx
      :0716 jmp 0703           ;ciclo di rotazione
          ;imposta la pagina
      :0718 call 8610
          ;primo punto, calcoliamo il primo punto video da dove avrà inizio l'iserimento dei caratteri
      :071B mov esi,[0001015C] ;memoria grafica
      :0723 xor eax,eax
      :0726 mov al,[0001014D]
      :072C shr al,1
      :072E add esi,eax
      :0731 mov al,[0001014F]
      :0737 shr al,1
      :0739 mov cx,[00010144]
      :0740 mul cx
      :0742 add esi,eax
      :0745 mov [00010150],esi ;primo punto pagina video
          ;imposta il fondo riga
      :074D mov dh,01
      :074F cmp edi,[00010140]
      :0757 jz 076A
      :0759 push edi
      :075B mov al,[edi]
      :075E cmp al,1C
      :0760 jz 0768
      :0762 inc edi
      :0764 inc dh
      :0766 jmp 075B
      :0768 pop edi
      :076A mov [0001010A],dh
          ;imposta le coordinate, le seguenti call ci serviranno per impostare, disegnare e farci vedere
           sul video la pagina corrente del nostro editor di testo
      :0771 mov dx,0101
          ;calcola i punti della pagina
      :0774 call 8880
          ;cancella la pagina
      :0777 call 8900
          ;disegna i caratteri
      :077A call 8A00
          ;disegna la croce
      :077D call 8AD0
          ;disegna il video
      :0780 call 8950
          ;ciclo tastiera, il ciclo tastiera ci permette di coordinare i principali movimenti del nostro editor
           di testo, a questi se ne possono aggiungere altri a piacimento. Ogni comando è abinato ad un tasto
           della tastiera e relativo codice per l'esecuzione di una specifica funzione
      :0783 mov ax,[00010106] ;la tastiera
      :0789 cmp al,00
      :078B jz 0783
      :078D mov word [00010106],0000
      :0796 cmp ax,E02A
      :0799 jz 0783
      :079B cmp ax,E04B
      :079E jz 08E1
      :07A2 cmp ax,E04D
      :07A5 jz 0905
      :07A9 cmp ax,E050
      :07AC jz 092B
      :07B0 cmp ax,E048
      :07B3 jz 0999
      :07B7 cmp ax,E051
      :07BA jz 09E8
      :07BE cmp ax,E049
      :07C1 jz 0A58
      :07C5 cmp al,3A
      :07C7 jz 0A89
      :07CB cmp al,0E
      :07CD jz 0AB0
      :07D1 cmp al,1C
      :07D3 jz 0B8C
      :07D7 cmp al,0F
      :07D9 jz 0BF5
      :07DD cmp al,3B
      :07DF jz 0C83
      :07E3 cmp al,01
      :07E5 jz 0E00
          ;carattere, con il seguente codice andiamo ad inserire un singolo carattere nella precisa posizione
           indicata dalla croce, il carattere può essere minuscolo o maiuscolo e di colore pari ai caratteri
           già disegnati dopo di che la croce sarà spostata sulla destra e il video rigenerato
      :07E9 mov cl,[0001010A]  ;fondo riga
      :07F0 cmp cl,[0001014C]  ;test di fondo riga
      :07F7 jz 0783
      :07F9 mov ecx,[00010140] ;fondo buffer archivi
      :0801 cmp ecx,[0001015C] ;test di buffer archivi pieno
      :0809 jz 0783
      :080D mov bl,[00010162]  ;tasto: caps lock
      :0814 cmp bl,00          ;test su carattere minuscolo o maiuscolo
      :0817 jz 081B
      :0819 add al,80
      :081B push edi
      :081D inc ecx
      :081F mov ah,[edi]       ;sposta i caratteri
      :0822 mov [edi],al
      :0825 mov al,ah
      :0827 inc edi
      :0829 cmp edi,ecx
      :082C jb 081F
      :082E mov [edi],al
      :0831 mov [00010140],ecx
      :0839 pop edi
      :083B call 8AD0          ;toglie la croce
      :083E push esi           ;disegna i caratteri
      :0840 push edi
      :0842 push dx
      :0843 mov dh,[0010001A]  ;colore del carattere
      :084A mov dl,[00100010]  ;colore dello sfondo
      :0851 push esi
      :0853 mov eax,00040000   ;inizio ciclo carattere
      :0859 mov al,[edi]
      :085C cmp al,1C
      :085E jz 08C3
      :0860 nop
      :0861 nop
      :0862 mov ch,[0004000A]
      :0869 mul ch
      :086B add ax,0000
      :086E mov ebx,eax        ;maschera
      :0871 push esi
      :0873 mov ah,00
      :0875 mov cx,[00040006]  ;ciclo in verticale
      :087C push esi
      :087E push cx
      :087F mov cx,[00040004]  ;ciclo in orizzontale
      :0886 cmp ah,00
      :0889 jnz 0891
      :088B mov ah,80
      :088D mov al,[ebx]
      :0890 inc bx
      :0891 test al,ah
      :0893 jz 089A
      :0895 mov [esi],dh
      :0898 jmp 089D
      :089A mov [esi],dl
      :089D inc esi
      :089F shr ah,1
      :08A1 loopw 0886
      :08A3 pop cx
      :08A4 pop esi
      :08A6 add esi,[00010144] ;orizzontale pagina
      :08AE loopw 087C
      :08B0 pop esi
      :08B2 xor ecx,ecx
      :08B5 mov cx,[00040004]  ;ciclo sulla riga
      :08BC add esi,ecx
      :08BF inc edi
      :08C1 jmp 0853
      :08C3 pop esi
      :08C5 pop dx
      :08C6 pop edi
      :08C8 pop esi
      :08CA add esi,ecx
      :08CD inc edi
      :08CF inc dh
      :08D1 inc byte [0001010A]
      :08D8 call 8AD0           ;disegna la croce
      :08DB call 8950           ;disegna il video
      :08DE jmp 0783
          ;croce a sinistra, col tasto "freccia a sinistra" andiamo a spostare la croce sulla sinistra di un
           carattere fin tanto che non si arriva ad inizio riga
      :08E1 cmp dh,01
      :08E4 jz 0783
      :08E8 call 8AD0
      :08EB xor ecx,ecx
      :08EE mov cx,[00040004]
      :08F5 sub esi,ecx
      :08F8 dec edi
      :08FA dec dh
      :08FC call 8AD0
      :08FF call 8950
      :0902 jmp 0783
          ;croce a destra, col tasto "freccia a destra" andiamo a spostare la croce sulla destra di un
           carattere fin tanto che non si arriva al fondo riga
      :0905 mov al,[edi]
      :0908 cmp al,1C
      :090A jz 0783
      :090E call 8AD0
      :0911 xor ecx,ecx
      :0914 mov cx,[00040004]
      :091B add esi,ecx
      :091E inc edi
      :0920 inc dh
      :0922 call 8AD0
      :0925 call 8950
      :0928 jmp 0783
          ;croce in basso, col tasto "freccia in basso" andiamo a spostare la croce all'inizio della
           prossima riga fin tanto che non si arriva a fondo pagina
      :092B cmp dl,[0001014E]  ;test di fondo pagina
      :0932 jz 0783
      :0936 push edi
      :0938 mov al,[edi]
      :093B cmp al,1C
      :093D jz 0943
      :093F inc edi
      :0941 jmp 0938
      :0943 mov eax,edi
      :0946 pop edi
      :0948 cmp eax,[00010140] ;test di fondo buffer
      :0950 jz 0783
      :0954 mov edi,eax
      :0957 inc edi
      :0959 call 8AD0
      :095C push edi
      :095E mov dh,01
      :0960 mov al,[edi]
      :0963 cmp al,1C
      :0965 jz 096D
      :0967 inc edi
      :0969 inc dh
      :096B jmp 0960
      :096D pop edi
      :096F mov [0001010A],dh  ;imposta il fondo riga
      :0976 mov esi,[00010150] ;primo punto
      :097E xor cx,cx
      :0980 mov cl,dl
      :0982 add esi,[00010158] ;dimensione del testo
      :098A loopw 0982
      :098C mov dh,01
      :098E inc dl
      :0990 call 8AD0
      :0993 call 8950
      :0996 jmp 0783
          ;croce in alto, col tasto "freccia in alto" andiamo a spostare la croce all'inzio della riga
           superiore fin tanto che non si arriva ad inizio pagina
      :0999 cmp dl,01          ;test di inizio pagina
      :099C jz 0783
      :09A0 dec edi
      :09A2 mov al,[edi]
      :09A5 cmp al,1C
      :09A7 jnz 09A0
      :09A9 call 8AD0
      :09AC mov dh,00
      :09AE dec edi
      :09B0 inc dh
      :09B2 mov al,[edi]
      :09B5 cmp al,1C
      :09B7 jnz 09AE
      :09B9 inc edi
      :09BB mov [0001010A],dh  ;imposta il fondo riga
      :09C2 dec dl
      :09C4 mov esi,[00010150] ;primo punto
      :09CC xor cx,cx
      :09CE mov cl,dl
      :09D0 dec cx
      :09D1 jz 09DD
      :09D3 add esi,[00010158] ;dimensione del testo
      :09DB jmp 09D0
      :09DD mov dh,01
      :09DF call 8AD0
      :09E2 call 8950
      :09E5 jmp 0783
          ;pagina in basso, col tasto "pag in basso" ci spostiamo di un'intera pagina del nostro archivio
           in elaborazione fin tanto che non arriviamo al fondo archivio
      :09E8 push edi
      :09EA push dx
      :09EB mov al,[edi]
      :09EE cmp al,1C
      :09F0 jz 09F6
      :09F2 inc edi
      :09F4 jmp 09EB
      :09F6 cmp edi,[00010140] ;test di fondo archivio
      :09FE jnz 0A06
      :0A00 pop dx
      :0A01 pop edi
      :0A03 jmp 0783
      :0A06 cmp dl,[0001014E]  ;test di fondo pagina
      :0A0D jz 0A15
      :0A0F inc edi
      :0A11 inc dl
      :0A13 jmp 09EB
      :0A15 pop dx
      :0A16 pop eax
      :0A18 inc edi
      :0A1A inc word [00100006]
      :0A21 call 8610          ;imposta la pagina
      :0A24 mov esi,[00010150] ;primo punto
      :0A2C mov dh,01
      :0A2E push edi
      :0A30 mov al,[edi]
      :0A33 cmp al,1C
      :0A35 jz 0A3D
      :0A37 inc edi
      :0A39 inc dh
      :0A3B jmp 0A30
      :0A3D pop edi
      :0A3F mov [0001010A],dh  ;imposta il fondo riga
      :0A46 mov dx,0101        ;imposta le coordinate
      :0A49 call 8900          ;cancella la pagina
      :0A4C call 8A00          ;disegna i caratteri
      :0A4F call 8AD0          ;disegna la croce
      :0A52 call 8950          ;disegna il video
      :0A55 jmp 0783
          ;pagina in alto, col tasto "pag in alto" ci spostiamo di un'intera pagina nel nostro archivio
           in elaborazione fin tanto che non arriviamo all'inizio archivio
      :0A58 mov ax,[00100006] ;numero di pagina
      :0A5E cmp ax,0001       ;test su inizio archivio
      :0A61 jz 0783
      :0A65 add dl,[0001014E]
      :0A6C dec edi
      :0A6E mov al,[edi]
      :0A71 cmp al,1C
      :0A73 jnz 0A6C
      :0A75 cmp dl,01
      :0A78 jz 0A7E
      :0A7A dec dl
      :0A7C jmp 0A6C
      :0A7E inc edi
      :0A80 dec word [00100006]
      :0A87 jmp 0A21
          ;minuscole e maiuscole, col tasto "caps lock" possiamo distinguere tra caratteri minuscoli o maiuscoli
           la spia accesa ci indica che abbiamo inserito le maiuscole
      :0A89 xor byte [00010162],01
      :0A91 cli
      :0A92 call 8120
      :0A95 mov al,ED
      :0A97 out 60,al
      :0A99 call 8120
      :0A9C mov al,[00010160]
      :0AA2 xor al,04
      :0AA4 out 60,al
      :0AA6 sti
      :0AA7 mov [00010160],al
      :0AAD jmp 0783
          ;cancella un carattere, col tasto "cancella" abbiamo la possibilità di cancellare il carattere
           che stà a sinistra della croce e tutti gli altri caratteri verranno spostati di una posizione
      :0AB0 cmp dh,01          ;test sull'inizio riga
      :0AB3 jz 0783
      :0AB7 mov ecx,[00010140] ;fondo buffer archivi
      :0ABF dec edi
      :0AC1 push edi
      :0AC3 mov al,[edi+01]    ;sposta i caratteri
      :0AC7 mov [edi],al
      :0ACA inc edi
      :0ACC cmp edi,ecx
      :0ACF jb 0AC3
      :0AD1 dec ecx
      :0AD3 mov [00010140],ecx
      :0ADB pop edi
      :0ADD call 8AD0          ;toglie la croce
      :0AE0 xor ecx,ecx
      :0AE3 mov cx,[00040004]
      :0AEA sub esi,ecx
      :0AED push esi           ;disegna i caratteri
      :0AEF push edi
      :0AF1 push dx
      :0AF2 mov dh,[0010001A]  ;colore del carattere
      :0AF9 mov dl,[00100010]  ;colore dello sfondo
      :0B00 push esi
      :0B02 mov eax,00040000   ;ciclo carattere
      :0B08 mov al,[edi]
      :0B0B mov ch,[0004000A]
      :0B12 mul ch
      :0B14 add ax,0000
      :0B17 mov ebx,eax        ;maschera
      :0B1A push esi           ;disegna un carattere
      :0B1C mov ah,00
      :0B1E mov cx,[00040006]  ;ciclo in verticale
      :0B25 push esi
      :0B27 push cx
      :0B28 mov cx,[00040004]  ;ciclo in orizzontale
      :0B2F cmp ah,00
      :0B32 jnz 0B3A
      :0B34 mov ah,80
      :0B36 mov al,[ebx]
      :0B39 inc bx
      :0B3A test al,ah
      :0B3C jz 0B43
      :0B3E mov [esi],dh
      :0B41 jmp 0B46
      :0B43 mov [esi],dl
      :0B46 inc esi
      :0B48 shr ah,1
      :0B4A loopw 0B2F
      :0B4C pop cx
      :0B4D pop esi
      :0B4F add esi,[00010144] ;orizzontale video pagina
      :0B57 loopw 0B25
      :0B59 pop esi
      :0B5B mov al,[edi]
      :0B5E cmp al,1C
      :0B60 jz 0B73
      :0B62 xor ecx,ecx
      :0B65 mov cx,[00040004]  ;ciclo sulla riga
      :0B6C add esi,ecx
      :0B6F inc edi
      :0B71 jmp 0B02
      :0B73 pop esi
      :0B75 pop dx
      :0B76 pop edi
      :0B78 pop esi
      :0B7A dec dh
      :0B7C dec byte [0001010A] ;fondo riga
      :0B83 call 8AD0           ;disegna la croce
      :0B86 call 8950           ;disegna il video
      :0B89 jmp 0783
          ;va a capo, il tasto "invio" ci permette di andare a capo e inserire una riga vuota pronta per
           l'editazione di nuovo testo, la croce sarà posizionata all'inizio della nuova riga
      :0B8C cmp dl,[0001014E]  ;test di fondo pagina
      :0B93 jz 0783
      :0B97 mov ecx,[00010140] ;fondo buffer archivi
      :0B9F cmp ecx,[0001015C] ;test di buffer pieno
      :0BA7 jz 0783
      :0BAB mov al,[edi]
      :0BAE cmp al,1C
      :0BB0 jz 0BB6
      :0BB2 inc edi
      :0BB4 jmp 0BAB
      :0BB6 inc edi
      :0BB8 push edi
      :0BBA inc ecx
      :0BBC mov ah,[edi]       ;sposta i caratteri
      :0BBF mov [edi],al
      :0BC2 mov al,ah
      :0BC4 inc edi
      :0BC6 cmp edi,ecx
      :0BC9 jb 0BBC
      :0BCB mov [edi],al
      :0BCE mov [00010140],ecx ;nuovo fondo buffer
      :0BD6 pop edi
      :0BD8 call 8AD0          ;toglie la croce
      :0BDB call 8B40          ;cancella i caratteri
      :0BDE mov dh,01
      :0BE0 mov [0001010A],dh  ;imposta il fondo riga
      :0BE7 inc dl
      :0BE9 call 8A00          ;disegna i caratteri
      :0BEC call 8AD0          ;disegna la croce
      :0BEF call 8950          ;disegna il video
      :0BF2 jmp 0783
          ;cancella una riga, il tasto "tab" ci cancella un'intera riga di testo e ci posiziona la croce
           sulla sinistra del nostro video
      :0BF5 push esi
      :0BF7 mov ecx,[00010140] ;fondo buffer archivi
      :0BFF dec edi
      :0C01 mov al,[edi]
      :0C04 cmp al,1C
      :0C06 jnz 0BFF
      :0C08 xor eax,eax
      :0C0B mov al,[0001010A]  ;fondo riga
      :0C11 mov esi,edi
      :0C14 add esi,eax
      :0C17 push edi
      :0C19 mov al,[esi]       ;sposta i caratteri
      :0C1C mov [edi],al
      :0C1F cmp esi,ecx
      :0C22 jz 0C2A
      :0C24 inc esi
      :0C26 inc edi
      :0C28 jmp 0C19
      :0C2A mov [00010140],edi ;imposta il fondo buffer
      :0C32 mov eax,edi
      :0C35 pop edi
      :0C37 cmp eax,edi        ;test di fine buffer
      :0C3A jnz 0C4D
      :0C3C inc edi
      :0C3E mov al,1C
      :0C40 mov [edi],al
      :0C43 mov [00010140],edi
      :0C4B dec edi
      :0C4D inc edi
      :0C4F pop esi
      :0C51 call 8AD0          ;toglie la croce
      :0C54 mov dh,01
      :0C56 push edi
      :0C58 mov al,[edi]
      :0C5B cmp al,1C
      :0C5D jz 0C65
      :0C5F inc edi
      :0C61 inc dh
      :0C63 jmp 0C58
      :0C65 mov [0001010A],dh  ;imposta il fondo riga
      :0C6C pop edi
      :0C6E dec dl
      :0C70 call 8B40          ;cancella i caratteri
      :0C73 inc dl
      :0C75 mov dh,01
      :0C77 call 8A00          ;disegna i caratteri
      :0C7A call 8AD0          ;disegna la croce
      :0C7D call 8950          ;disegna il video
      :0C80 jmp 0783
          ;termina senza compilazione, col tasto "F1" si può terminare il programma di editazione evitando la
           compilazione del codice. Tutte la modifiche e aggiunte del testo andranno naturalmente perse, così
           ci resterà la vecchia copia del codice compilato funzionante senza varianti
      :0C83 mov ax,0001
      :0C86 mov [00010120],ax
      :0C8C mov eax,[0010001C]
      :0C93 mov [00010122],eax
      :0C9A mov eax,00100000
      :0CA0 mov [00010126],eax
      :0CA7 call 8BB0          ;salva il segmento delle impostazioni
      :0CAA jmp 8300
      
Così abbiamo concluso la prima parte del programma "Avvio" definendo le impostazioni della macchina e poi impostando il nostro editor di testo che ci permette di digitare il codice dei futuri programmi, l'ultima funzione che abbiamo scritto ci permette di uscire dall'editor senza un nulla di fatto ma se vogliamo dare vita al nostro codice di testo dobbiamo procedere alla compilazione dello stesso ed andarlo a registrare nelle locazioni del disco-fisso pronto per essere testato e usato.
Col tasto "esc" diamo il via alla compilazione

Partiamo con il codice della compilazione
      :0E00 mov eax,[0010001C]
      :0E07 cmp eax,00080400   ;limite di compilazione
      :0E0D ja 8300
      :0E11 mov ax,0080
      :0E14 mov [00010120],ax
      :0E1A mov eax,00030000
      :0E20 mov [00010122],eax
      :0E27 mov eax,00040000
      :0E2D mov [00010126],eax
      :0E34 call 8430          ;carica le definizioni di assembler
      :0E37 lea edi,[00102000] ;buffer del testo
      :0E3F lea ebp,[00100200] ;etichette di salto
      :0E47 lea edx,[00050000] ;codice compilato
          ;ciclo istruzioni, qui possiamo smistare i vari tipi dei caratteri di controllo e far eseguire la
           realtiva porzione di codice
      :0E4F cmp edi,[00010140] ;fondo buffer archivi
      :0E57 jz 1020
      :0E5B inc edi
      :0E5D mov al,[edi]
      :0E60 cmp al,1C
      :0E62 jz 0E4F
      :0E64 cmp al,39
      :0E66 jz 0E5B
      :0E68 cmp al,B9
      :0E6A jz 0E5B
      :0E6C cmp al,33
      :0E6E jz 0E7A
      :0E70 cmp al,34
      :0E72 jz 0E85
      :0E74 cmp al,37
      :0E76 jz 0E9E
      :0E78 jmp 0ECC
          ;commento, il carattere ; ci indica l'inzio di un commento
      :0E7A inc edi
      :0E7C mov al,[edi]
      :0E7F cmp al,1C
      :0E81 jz 0E4F
      :0E83 jmp 0E7A
          ;etichetta, il carattere : ci indica che dobbiamo decodificare u'etichetta di salto
      :0E85 inc edi
      :0E87 mov eax,[edi]
      :0E8B call 8C50
      :0E8E shl ax,1
      :0E90 push bp
      :0E91 add bp,ax
      :0E93 mov [ebp+00],dx
      :0E97 pop bp
      :0E98 add edi,00000004
      :0E9C jmp 0E5D
          ;zona dati, il carattere * ci indica che stiamo entrando in una zona dati e registrare il codice seguente 
      :0E9E cmp dx,FFF0
      :0EA2 jb 0EA7
      :0EA4 jmp 8300           ;errore!! segmento codice pieno
      :0EA7 inc edi
      :0EA9 mov al,[edi]
      :0EAC cmp al,1C
      :0EAE jz 0E4F
      :0EB0 cmp al,33
      :0EB2 jz 0E7A
      :0EB4 cmp al,39
      :0EB6 jz 0EA7
      :0EB8 cmp al,B9
      :0EBA jz 0EA7
      :0EBC mov ax,[edi]
      :0EBF call 8CC0
      :0EC2 mov [edx],al
      :0EC5 inc dx
      :0EC6 add edi,00000002
      :0ECA jmp 0EA9
         ;istruzione, da qui passano tutte le istruzioni che verranno decodificate e registrate nel segmento codice
      :0ECC cmp dx,FFF0
      :0ED0 jb 0ED5
      :0ED2 jmp 8300           ;errore!! segmento codice pieno
      :0ED5 lea ebx,[00010180] ;buffer dei numeri
      :0EDD lea esi,[000101A0] ;buffer del testo
      :0EE5 jmp 0EE9
      :0EE7 inc edi
      :0EE9 mov al,[edi]
      :0EEC cmp al,1C
      :0EEE jz 0F0C
      :0EF0 cmp al,33
      :0EF2 jz 0F0C
      :0EF4 cmp al,39
      :0EF6 jz 0EE7
      :0EF8 cmp al,B9
      :0EFA jz 0EE7
      :0EFC cmp al,80
      :0EFE jb 0F06
      :0F00 mov [ebx],al       ;copia il numero
      :0F03 inc bx
      :0F04 jmp 0EE7
      :0F06 mov [esi],al       ;copia il carattere
      :0F09 inc si
      :0F0A jmp 0EE7
          ;test istruzione, l'istruzione viene confrontata con le definizioni di assembler
      :0F0C mov byte [esi],FF
      :0F10 push edi
      :0F12 lea edi,[00040000] ;definizioni di assembler
      :0F1A push di
      :0F1B lea si,[01A0]
      :0F1F mov al,[esi]
      :0F22 mov ah,[edi]
      :0F25 cmp al,ah
      :0F27 jnz 0F2D
      :0F29 inc si
      :0F2A inc di
      :0F2B jmp 0F1F
      :0F2D pop di
      :0F2E cmp ax,00FF
      :0F31 jz 0F74
      :0F33 cmp ah,FF
      :0F36 jz 0F3D
      :0F38 add di,0020
      :0F3B jmp 0F1A
          ;istruzione non trovata, l'istruzione non esiste quindi non si può procedere nella compilazione
      :0F3D pop edi
      :0F3F call 84D0          ;cancella la linea di comando
      :0F42 mov esi,edi
      :0F45 lea edi,[000711E0]
      :0F4D mov bx,[0001011C]
      :0F54 dec esi
      :0F56 mov al,[esi]
      :0F59 cmp al,1C
      :0F5B jnz 0F54
      :0F5D inc esi
      :0F5F mov al,[esi]
      :0F62 cmp al,1C
      :0F64 jz 0F6E
      :0F66 call 8220          ;stampa l'istruzione mancante
      :0F69 add di,0008
      :0F6C jmp 0F5D
      :0F6E call 8DD0          ;salva l'archivio con le modifiche
      :0F71 jmp 8300
          ;istruzione trovata, il confronto ha dato esito positivo quindi possiamo passare alla decodifica
      :0F74 add di,0010
      :0F77 mov ah,[edi]       ;copia del codice istruzione
      :0F7A inc di
      :0F7B mov al,[edi]
      :0F7E mov [edx],al
      :0F81 inc dx
      :0F82 dec ah
      :0F84 jnz 0F7A
      :0F86 lea esi,[00010180] ;buffer dei numeri
      :0F8E xor cx,cx
      :0F90 inc di
      :0F91 mov cl,[edi]
      :0F94 cmp cl,00
      :0F97 jz 0F9E
      :0F99 call 8E80
      :0F9C jmp 0F90
      :0F9E inc di
      :0F9F mov al,[edi]
      :0FA2 cmp al,00          ;decodifica istruzione completata
      :0FA4 jz 0FCB
      :0FA6 cmp al,01          ;un salto indietro da decodificare
      :0FA8 jz 0FD0
      :0FAA mov ebx,[00010168] ;fondo codifica del salto
      :0FB2 mov [ebx],al       ;un salto da decodificare
      :0FB5 inc bx
      :0FB6 mov [ebx],dx
      :0FB9 add bx,0002
      :0FBC mov al,[edx-02]
      :0FC0 mov [ebx],al
      :0FC3 inc bx
      :0FC4 mov [00010168],bx
      :0FCB pop edi            ;prossima istruzione
      :0FCD jmp 0E5D
      :0FD0 push bp            ;un salto corto indietro da decodificare
      :0FD1 lea ebx,[00010180] ;buffer dei numeri
      :0FD9 mov eax,[ebx]
      :0FDD call 8C50
      :0FE0 shl ax,1
      :0FE2 add bp,ax
      :0FE4 mov ax,[ebp+00]
      :0FE8 sub ax,dx
      :0FEA cmp ax,FF80
      :0FED ja 0FF3
      :0FEF pop bp             ;errore!! loop troppo lunga
      :0FF0 jmp 0F3D
      :0FF3 mov [edx-01],al
      :0FF7 pop bp             ;prossima istruzione
      :0FF8 pop edi
      :0FFA jmp 0E5D
          ;fine compilazione, siamo così giunti quasi al termine del nostro primo programma non ci rimane
           che calcolare la distanza di ogni salto e salvare il tutto
          ;carica le etichette di avvio programma
      :1020 mov eax,[0010001C]
      :1027 cmp eax,00080100
      :102D jz 1057
      :102F mov ax,0010
      :1032 mov [00010120],ax
      :1038 mov eax,00080100
      :103E mov [00010122],eax
      :1045 mov eax,00070000
      :104B mov [00010126],eax
      :1052 call 8430
      :1055 jmp 1071
      :1057 lea esi,[00100000]
      :105F lea edi,[00070000]
      :1067 mov ecx,00000800
      :106D repz movsd
          ;carica le etichette delle call
      :1071 mov eax,[0010001C]
      :1078 cmp eax,00080300
      :107E jz 10A8
      :1080 mov ax,0010
      :1083 mov [00010120],ax
      :1089 mov eax,00080300
      :108F mov [00010122],eax
      :1096 mov eax,00072000
      :109C mov [00010126],eax
      :10A3 call 8430
      :10A6 jmp 10C2
      :10A8 lea esi,[00100000]
      :10B0 lea edi,[00072000]
      :10B8 mov ecx,00000800
      :10BE repz movsd
      :10C2 mov ebx,[00010168]
      :10CA mov si,bx
      :10CC mov bx,0000
      :10CF cmp bx,si
      :10D1 jz 113A
      :10D3 mov eax,[ebx]
      :10D7 cmp al,02
      :10D9 jz 10DF
      :10DB cmp al,03
      :10DD jz 1101
          ;salto lungo
      :10DF push bp
      :10E0 shr eax,08
      :10E4 mov cx,ax
      :10E6 sub ax,0002
      :10E9 mov dx,ax
      :10EB mov ax,[edx]
      :10EE shl ax,1
      :10F0 add bp,ax
      :10F2 mov ax,[ebp+00]
      :10F6 sub ax,cx
      :10F8 mov [edx],ax
      :10FB pop bp
      :10FC add bx,0004
      :10FF jmp 10CF
          ;salto fuori segmento
      :1101 push ebp
      :1103 shr eax,08
      :1107 sub ax,0004
      :110A mov dx,ax
      :110C shr eax,10
      :1110 lea ebp,[00070200]
      :1118 cmp al,08
      :111A jz 1124
      :111C lea ebp,[00072200]
      :1124 mov eax,[edx]
      :1128 shl ax,1
      :112A add bp,ax
      :112C mov ax,[ebp+00]
      :1130 mov [edx],ax
      :1133 pop ebp
      :1135 add bx,0004
      :1138 jmp 10CF
          ;salva il segmento del codice
      :113A mov ax,0080
      :113D mov [00010120],ax
      :1143 mov eax,[00100014]
      :114A mov [00010122],eax
      :1151 mov eax,00050000
      :1157 mov [00010126],eax
      :115E call 8BB0
          ;salva l'archivio
      :1161 call 8DD0
          ;conclude il programma
      :1164 jmp 8300
      

*********************************************************************************************************************
Il nostro programma di avvio lo dividiamo in due parti di dimensione uguale, nella prima parte ci scriviamo il codice principale del programma, mentre a partire da metà segmento ci mettiamo tutte le "call" che ci servono e che verranno richiamate all'occorrenza.

Partiamo con il codice delle "call"
          ;int 00  Questa interruzione si genera quando l'esecuzione del programma incontra un "grave errore"
                   quindi il programma termina e ci restituisce la posizione dell'errore
      :8000 mov eax,FFFFFFFF
      :8006 pop ebx
      :8008 pop ecx
      :800A pop edx
      :800C jmp 800C
          ;int 08   questa interruzione ci serve per registrare lo scandire del tempo che in forma automatica
                    viene gestita direttamente dalla "cpu" e ci permette di eseguire eventuali funzioni basate
                    sul trascorrere del tempo.
      :8030 push ax
      :8031 cli
      :8032 inc dword [00010100] ;in queste locazioni registriamo lo scandire del tempo totale
      :803A inc word [00010104]  ;qui incece andiamo a registrare un tempo parziale
      :8041 mov al,20
      :8043 out 20,al            ;segnaliamo alla "cpu" il termine di esecuzione dell'interruzione
      :8045 sti
      :8046 pop ax
      :8047 iretd                ;la iretd è indispensabile il codice-macchina è "66 cf"
          ;call 8080  la prima call la usiamo per leggere un tasto della tastiera
                      in "al" ci restituisce il tasto che abbiamo premuto
      :8080 push cx
      :8081 xor cx,cx
      :8083 cli
      :8084 in al,64             ;si controlla che la porta sia in stato di lettura
      :8086 jmp 8088
      :8088 jmp 808A
      :808A jmp 808C
      :808C jmp 808E
      :808E test al,02
      :8090 loopnzw 8084
      :8092 in al,60             ;tramite al porta "60" possiamo leggere il tasto
      :8094 sti
      :8095 pop cx
      :8096 ret
          ;int 09   questa interruzione ci permette la lettura della tastiera, tutte le volte che si preme un
                    tasto viene registrato da queta funzione e in seguito è possibile la relativa decodifica.
                    Nei miei programmi non userò conversioni di caratteri, operazioni completamente inutili, ma
                    farò uso direttamente dei codici inviati dal controller della tastiera
      :80B0 push ax
      :80B1 call 8080
      :80B4 cmp al,E0            ;"al" ci restituisce il tasto appena premuto
      :80B6 jnz 80C8
      :80B8 mov byte [00010106],00 
      :80C0 mov [00010107],al    ;lo andiamo a registrare nella locazzione :0107 se "al=e0"
      :80C6 jmp 80DB
      :80C8 mov [00010106],al    ;altrimenti lo registriamo nella sua locazione :0106
      :80CE cmp al,80
      :80D0 jb 80DB
      :80D2 mov word [00010106],0000 ;qui mettiamo a "0" le due locazioni se "al>80"
      :80DB cli
      :80DC mov al,20
      :80DE out 20,al
      :80E0 sti
      :80E1 pop ax
      :80E2 iretd
          ;call 8120   questa call la usiamo per impostare la porta "64" con la quale dobbiamo comunicare
                       e la useremo tutte le volte che dobbiamo inviare un comando al controller
      :8120 push cx
      :8121 xor cx,cx
      :8123 cli
      :8124 in al,64
      :8126 jmp 8128
      :8128 jmp 812A
      :812A jmp 812C
      :812C jmp 812E
      :812E test al,02
      :8130 loopnzw 8124        ;ciclo di attesa che la porta sia pronta per ricevere i comandi
      :8132 pop cx
      :8133 ret
          ;call 8150   la seguente call verrà usata per impostare la modalità con la quale
                       andremo a scrivere i colori nel controller 
      :8150 push dx
      :8151 mov dx,03C4
      :8154 mov al,01
      :8156 out dx,al
      :8157 inc dx
      :8158 in al,dx
      :8159 mov dh,al
      :815B and ax,20DF
      :815E or al,ah
      :8160 mov ah,dh
      :8162 mov dh,03
      :8164 out dx,al
      :8165 pop dx
      :8166 ret
          ;call 8180   questa call la useremo tutte le volte che si dovrà stampare un numero e quindi si dovrà
                       convertire il numero esadecimale in carattere
                       eax = numero da convertire lo mettiamo nel registro
                       [00010110] = numero convertito ce lo restituisce nella locazione
      :8180 push esi
      :8182 push edi
      :8184 push ebx
      :8186 push cx
      :8187 lea edi,[00010110]
      :818F lea esi,[0001010F]
      :8197 mov [0001010C],eax
      :819E mov ebx,00021400   ;buffer dei codici di conversione
      :81A4 mov cx,0004
      :81A7 mov bl,[esi]
      :81AA rol bl,04
      :81AD and bl,0F
      :81B0 mov bl,[ebx]
      :81B3 mov [edi],bl
      :81B6 inc di
      :81B7 mov bl,[esi]
      :81BA and bl,0F
      :81BD mov bl,[ebx]
      :81C0 mov [edi],bl
      :81C3 inc di
      :81c4 dec si
      :81C5 loopw 81A7         ;ciclo di rotazione per 4 numeri
      :81C7 pop cx
      :81C8 pop ebx
      :81CA pop edi
      :81CC pop esi
      :81CE ret
          ;call 81f0   questa call ci permette di impostare la pagina video sulla quale andremo ad inserire i punti
                       del nostro disegno, tenere in considerazione che tutto il programma è concepito per la
                       gestione di un video a colori con risoluzione 800x600.
                       La seguente call può variare in relazione alla scheda video che si fa uso, quindi bisogna
                       fare i dovuti controlli sul funzionamento ed evetualmente apportare qualche modifica
                       edi = pagina video
      :81F0 push eax
      :81F2 push dx
      :81F3 mov dx,03DE
      :81F6 mov eax,edi
      :81F9 shr eax,08
      :81FD mov al,04
      :81FF cli
      :8200 out dx,ax
      :8201 sti
      :8202 pop dx
      :8203 pop eax
      :8205 ret
          ;call 8220    la seguente call ci permette di scrivere un carattere direttamente nella pagina video,
                        gli argomenti che utilizza sono il numero della pagina video, il colore, lo sfondo e il
                        carattere da stampare, il carattere avrà una dimensione di 8x16 punti e verrà piazzato nel
                        punto voluto del video.
                        al = carattere da stampare
                        bx = sfondo e colore del carattere
                        edi = pagina video e punto di inserimento del carattere
      :8220 push cx
      :8221 push esi
      :8223 push edi
      :8225 push ebp
      :8227 call 81F0           ;impostiamo la pagina iniziale
      :822A lea esi,[00020000]  ;buffer della machera del carattere
      :8232 lea ebp,[000A0000]  ;memoria grafica del video
      :823A mov bp,di
      :823C mov ah,00
      :823E shl ax,04
      :8241 add si,ax
      :8243 mov cx,0010         ;punti in verticale
      :8246 mov ah,80
      :8248 mov al,[esi]
      :824B push cx
      :824C mov cx,0008         ;punti in orizzontale
      :824F mov [ebp+00],bh
      :8253 test al,ah
      :8255 jz 825B
      :8257 mov [ebp+00],bl
      :825B inc bp
      :825C jnz 8268
      :825E add edi,00010000
      :8265 call 81F0           ;se è il caso si cambia pagina
      :8268 shr ah,1
      :826A loopw 824F          ;ciclo in orizzontale
      :826C add bp,0318
      :8270 ja 827C
      :8272 add edi,00010000
      :8279 call 81F0           ;se è il caso si cambia pagina
      :827C inc si
      :827D pop cx
      :827E loopw 8246          ;ciclo in verticale
      :8280 pop ebp
      :8282 pop edi
      :8284 pop esi
      :8286 pop cx
      :8287 ret
          ;call 8300    questa piccola call è la più preziosa di ogni programmatore, infatti richiamandola in un
                        qualsiasi momento essa ci riporta la situazione esatta dei registri del nostro programma.
                        Quindi ci permette di controllare la situazione dell'ultimo codice che abbiamo dicitato,
                        senza questa call sarebbe impossibile dicitare il codice in quanto non sasebbe possibile
                        testarlo andando a controllare l'effettivo valore dei vari registri in quel preciso momento.
                        Quindi vediamo di scivere questa call nel modo miglione e poi di usarla il più sovente
                        possibile, essa ci aiuterà nel proseguimento del nostro codice dandoci tutti quei test che
                        ci permetteranno di correggere il nostro codice.
      :8300 push esp
      :8302 push edi
      :8304 push esi           ;salviamo nello stack tutti i registri da stampare
      :8306 push ebp
      :8308 push edx
      :830A push ecx
      :830C push ebx
      :830E push eax
      :8310 pushfd
      :8312 push cs
      :8313 push gs
      :8315 push fs
      :8317 push ss
      :8318 push es
      :8319 push ds
      :831A mov bx,081A        ;sfondo e colore dei caratteri
      :831D lea esi,[000214A0] ;buffer di stampa dei vari registri
      :8325 lea edi,[00020000] ;punto di inserimento della tabella registri di segmento
      :832D mov cx,0006        ;numero di registri da stampare
      :8330 pop ax
      :8331 call 8180
      :8334 mov eax,[00010114]
      :833B mov [esi+05],eax
      :8340 push cx
      :8341 mov cx,0009        ;numero di caratteri da stampare per riga
      :8344 mov al,[esi]
      :8347 call 8220
      :834A inc si
      :834B add edi,00000008
      :834F loopw 8344         ;cilo di rotazione sulla riga
      :8351 add edi,000031B8
      :8358 pop cx
      :8359 loopw 8330         ;ciclo di rotazione registri
      :835B lea esi,[00021410]
      :8363 lea edi,[00033200] ;punto di inserimento della tabella registri a 32 bit
      :836B mov cx,0009
      :836E pop eax
      :8370 call 8180
      :8373 mov eax,[00010110]
      :837A mov [esi+08],eax
      :837F mov eax,[00010114]
      :8386 mov [esi+0C],eax
      :838B push cx
      :838C mov cx,0010
      :838F mov al,[esi]
      :8392 call 8220
      :8395 inc si
      :8396 add edi,00000008
      :839A loopw 838F
      :839C add edi,00003180
      :83A3 pop cx
      :83A4 loopw 836E
      :83A6 mov al,[00010106] ;ciclo di attesa per il controllo dei valori dei registri,
      :83AC cmp al,00         ;premendo un tasto qualsiasi si riavvia il calcolatore
      :83AE jz 83A6
      :83B0 mov al,FE
      :83B2 out 64,al
          ;call 83e0  sfondo riga di comando, con questa call andiamo a colorare una striscia nella parte bassa
                      del video dalla quale sarà possibile dicitare i vari comandi di esecuzione
      :83E0 push ecx
      :83E2 push edi
      :83E4 push dx
      :83E5 lea edi,[000A01C0] ;punto di inserimento della striascia di colore
      :83ED mov dx,03DE
      :83F0 mov ax,0704
      :83F3 cli
      :83F4 out dx,ax          ;impostiamo la pagina video
      :83F5 sti
      :83F6 mov eax,[00010118] ;colore dello sfondo
      :83FD mov ecx,00001450   ;numero di punti
      :8403 repz stosd         ;inseriamo i punti (codice = f3,67,66,ab)
      :8407 pop dx
      :8408 pop edi
      :840A pop ecx
      :840C ret
          ;call 8430  legge settori del disco, altra call molto importante ci serve per leggere uno o più
                      settori del disco fisso e di portarli direttamente in memoria alle locazioni volute.
                      Penso che la call funzioni correttamente su una gran quantità di dischi fissi, usa il
                      "modo-pio" nel trasferimento dei dati e può leggere un totale di "fffffff" settori,
                      tradotto in decimale = 268.435.455 settori
      :8430 push edi
      :8432 push cx
      :8433 push dx
      :8434 mov cx,[00010120]  ;numero settori da leggere
      :843B mov edi,[00010126] ;posizione in memoria dove saranno trasferiti
      :8443 cmp cx,0000        ;ciclo di rotazione settori
      :8446 jz 84A2
      :8448 cli
      :8449 mov dx,01F2        ;porta di invio comandi controller del disco-fisso
      :844C mov al,01
      :844E out dx,al
      :844F inc dx
      :8450 mov al,[00010122]  ;posizione del settore in lettura su disco
      :8456 out dx,al
      :8457 inc dx
      :8458 mov al,[00010123]
      :845E out dx,al
      :845F inc dx
      :8460 mov al,[00010124]
      :8466 out dx,al
      :8467 inc dx
      :8468 mov al,[00010125]
      :846E add al,E0          ;modo di lettura = "lba"
      :8470 out dx,al
      :8471 inc dx
      :8472 mov al,20          ;comando di lettura
      :8474 out dx,al
      :8475 in al,dx
      :8476 test al,08         ;test di termine del comando di lettura
      :8478 jz 8475
      :847A push cx
      :847B cld
      :847C mov cx,0080
      :847F mov dx,01F0        ;porta di trasferimento dati
      :8482 in eax,dx
      :8484 mov [edi],eax      ;spostiamo i dati letti in memoria
      :8488 add edi,00000004
      :848C loopw 8482         ;ciclo per spostare un settore
      :848E mov dx,01F7
      :8491 in al,dx
      :8492 test al,88         ;test di termine spostamento
      :8494 jnz 8491
      :8496 inc dword [00010122] ;prossimo settore che andremo a leggere
      :849E pop cx
      :849F dec cx
      :84A0 jmp 8443
      :84A2 sti
      :84A3 and eax,000000FF   ;la call ritorna "50 in al" se tutto è andato a buon fine
      :84A9 pop dx
      :84AA pop cx
      :84AB pop edi
      :84AD ret
          ;call 84d0 cancella la linea di comando, la call si utilizza per ripulire la riga di comando quando
                     una scritta o un comando ha finito il suo corso e la si deve sostituire con un'altra
                     scritta
      :84D0 push ecx
      :84D2 push edi
      :84D4 push dx
      :84D5 lea edi,[000213C0] ;buffer della linea di comando
      :84DD mov [0001012C],di
      :84E4 xor eax,eax
      :84E7 mov ecx,00000010
      :84ED repz stosd         ;cancella il buffer (codice = f3,67,66,ab)
      :84F1 cli
      :84F2 mov dx,03DE
      :84F5 mov ax,0704
      :84F8 out dx,ax          ;imposta la pagina video (risoluzione 800*600)
      :84F9 sti
      :84FA lea edi,[000A11E0] ;punto di inizio nella linea di comando
      :8502 mov [00010130],di
      :8509 mov eax,[00010118] ;colore
      :8510 mov cx,0010
      :8513 push cx
      :8514 mov cx,0080
      :8517 repz stosd         ;cancella il video
      :851B add di,0120
      :851F pop cx
      :8520 loopw 8513         ;ciclo di rotazione
      :8522 pop dx
      :8523 pop edi
      :8525 pop ecx
      :8527 ret
          ;call 8550  Attesa... La call seguente verrà usata per impostare sulla riga di comando al scritta "Attesa"
                      Anche se i fanatici della tecnologia sostengono che i calcolatori moderni siano delle macchine
                      super veloci; nella realtà proprio così non è...
                      Qindi ho pensato di scrivere questa call che verrà usata quando si prevede un certo carico di
                      operazioni che richiedono un po di tempo, almeno si avvisa che la macchina è in fase di calcolo.
      :8550 push bx
      :8551 push cx
      :8552 push esi
      :8554 push edi
      :8556 call 84D0          ;cancella la linea di comando
      :8559 lea esi,[000214F2] ;buffer del testo
      :8561 lea edi,[000711E0] ;punto video
      :8569 mov bx,[0001011C]  ;colore del testo
      :8570 mov cx,0009
      :8573 mov al,[esi]
      :8576 call 8220          ;disegna i caratteri
      :8579 inc si
      :857A add di,0008
      :857D loopw 8573
      :857F pop edi
      :8581 pop esi
      :8583 pop cx
      :8584 pop bx
      :8585 ret
          ;call 85b0  conversione esadecimale in carattere decimale, la call ci converte un numero
                      esadecimale in un decimale stampabile
                      eax = numero da convertire
                      la call ci ritorna la posizione del numero convertito nel registro "edi"
      :85B0 push ebx
      :85B2 push ecx
      :85B4 push edx
      :85B6 lea edi,[00010117] ;buffer del numero convertito
      :85BE mov ebx,00021400   ;tabella di conversione
      :85C4 mov ecx,0000000A
      :85CA cmp eax,00000000
      :85CE jz 85E1
      :85D0 xor edx,edx
      :85D3 div ecx
      :85D6 mov bl,dl
      :85D8 mov dl,[ebx]
      :85DB mov [edi],dl
      :85DE dec di
      :85DF jmp 85CA
      :85E1 cmp di,0117
      :85E5 jnz 85EC
      :85E7 mov byte [edi],52
      :85EB dec di
      :85EC pop edx
      :85EE pop ecx
      :85F0 pop ebx
      :85F2 ret
          ;call 8610  imposta la pagina, la seguente call la useremo per impostare il numero di pagina nella
                      linea di comando quindi spostandoci a destra-sinista o in alto-basso abbiamo sempre un
                      riferimento al numero di pagina corrente
      :8610 push bx
      :8611 push cx
      :8612 push esi
      :8614 push edi
      :8616 xor eax,eax
      :8619 mov ax,[00100006]  ;numero di pagina
      :861F call 85B0
      :8622 mov esi,edi
      :8625 lea edi,[000711A0] ;punto video
      :862D mov bx,[0001011E]  ;colore del testo
      :8634 mov cx,0003        ;numero caratteri
      :8637 inc si
      :8638 mov al,[esi]
      :863B call 8220          ;disegna il numero
      :863E add di,0008
      :8641 dec cx
      :8642 cmp si,0117
      :8646 jnz 8637
      :8648 mov al,39
      :864A cmp cx,0000
      :864D jnz 863B
      :864F pop edi
      :8651 pop esi
      :8653 pop cx
      :8654 pop bx
      :8655 ret
          ;call 8670  imposta la orizzontale, la call ci imposta la coordinata "x" del nostro disegno quindi
                      abbiamo un riferimento sulla linea di comando che ci indica il numero del punto-video dove
                      ci troviamo.
                      Si tenga presente che il punto in alto a sinistra corrisponde a 0000:0000 (x,y)
      :8670 push bx
      :8671 push cx
      :8672 push esi
      :8674 push edi
      :8676 xor eax,eax
      :8679 mov ax,[00100008]  ;numero in orizzontale
      :867F call 85B0
      :8682 mov esi,edi
      :8685 lea edi,[00071400] ;punto video
      :868D mov bx,[0001011E]  ;colore del testo
      :8694 mov cx,0005        ;numero di caratteri
      :8697 inc si
      :8698 mov al,[esi]
      :869B call 8220          ;disegna il numero
      :869E add di,0008
      :86A1 dec cx
      :86A2 cmp si,0117
      :86A6 jnz 8697
      :86A8 mov al,39
      :86AA cmp cx,0000
      :86AD jnz 869B
      :86AF pop edi
      :86B1 pop esi
      :86B3 pop cx
      :86B4 pop bx
      :86B5 ret
          ;call 86d0  imposta la verticale, la call è come la precedente e ci imposta la coordinata "y"
      :86D0 push bx
      :86D1 push cx
      :86D2 push esi
      :86D4 push edi
      :86D6 xor eax,eax
      :86D9 mov ax,[0010000C]  ;numero in verticale
      :86DF call 85B0
      :86E2 mov esi,edi
      :86E5 lea edi,[00071448] ;punto video
      :86ED mov bx,[0001011E]  ;colore del testo
      :86F4 mov cx,0005        ;numero di caratteri
      :86F7 inc si
      :86F8 mov al,[esi]
      :86FB call 8220          ;disegna il numero
      :86FE add di,0008
      :8701 dec cx
      :8702 cmp si,0117
      :8706 jnz 86F7
      :8708 mov al,39
      :870A cmp cx,0000
      :870D jnz 86FB
      :870F pop edi
      :8711 pop esi
      :8713 pop cx
      :8714 pop bx
      :8715 ret
          ;call 8740  imposta il disegno, la call si occupa di impostare una pagina grafica del nostro disegno
                      definendo il colore di sfondo e impostando il testo utile sulla riga di comando.
                      La risoluzione considerata sarà di 800*600, risoluzione ottimale per disegni di grafica del
                      punto, risoluzioni maggiori si possono pure impostare però diventa poi più difficile la lettura
                      del testo e di maggiore difficoltà il controllo del singolo punto.
      :8740 push edi
      :8742 push ecx
      :8744 push edx
      :8746 mov eax,[00010134] ;orizzontale video
      :874D mov ecx,[00010138] ;verticale video
      :8755 mul ecx
      :8758 mov ecx,eax        ;numero totale di punti
      :875B shr ecx,02
      :875F mov edi,[0001013C] ;inizio della memoria grafica
      :8767 mov eax,[00100010] ;colore di sfondo
      :876E repz stosd         ;coloriamo la pagina video (codice = f3,67,66,ab)
      :8772 call 8610
      :8775 call 8670
      :8778 call 86D0
      :877B pop edx
      :877D pop ecx
      :877F pop edi
      :8781 ret
          ;call 87b0  disegna il video, la call provvede a trasferire l'intera memoria grafica sul video, al momento
                      ne faremo uso raramente avendo una sola pagina video ma continuando con la programmazione le
                      pagine video aumenteranno e quindi la call verrà usata molto sovente.
                      Questo tipo di grafica imposta una certa quantità di memoria permanente per registrare il colore
                      di ogni punto, più grande sarà il disegno e maggiore sarà la quantità di memoria riservata,
                      quindi nella fase di calcolo ed esecuzione del programma i singoli punti saranno piazzati
                      unicamente in questa memoria grafica e solo al termine del programma i colori di una pagina
                      grafica grande quanto è l'intero video saranno trasferiti sul video e visibili.
                      Il metodo gode di una grande velocità in fatto di rigenerazione del video, spostando unicamente
                      i colori da una memoria all'altra; ben lontani da questo metodo sono i vari programmi di grafica
                      gestiti da un sistema operativo che provvede a spezzettare tutta la memoria e quindi poi ogni
                      volta che si deve rigenerare il video dovrà provvedere a ricalcolare punto per punto creando
                      lentaggini non da poco.
      :87B0 push esi
      :87B2 push edi
      :87B4 push bx
      :87B5 push cx
      :87B6 push dx
      :87B7 mov esi,[0001013C] ;inizio della memoria grafica
      :87BF lea edi,[000A0000] ;memoria video
      :87C7 cli
      :87C8 mov ax,0004
      :87CB mov dx,03DE
      :87CE out dx,ax          ;impostiamo la pagina video iniziale
      :87CF sti
      :87D0 mov bx,0004
      :87D3 mov cx,[00010138]  ;ciclo in verticale
      :87DA push esi
      :87DC push cx
      :87DD mov cx,[00010134]  ;ciclo in orizzontale
      :87E4 mov al,[esi]
      :87E7 mov [edi],al       ;spostiamo il colore
      :87EA inc esi
      :87EC inc di
      :87ED jnz 87F6
      :87EF cli
      :87F0 inc bh
      :87F2 mov ax,bx
      :87F4 out dx,ax          ;cambiamo la pagina video
      :87F5 sti
      :87F6 loopw 87E4
      :87F8 pop cx
      :87F9 pop esi
      :87FB add esi,[00010134] ;avvanzamento di una riga intera
      :8803 loopw 87DA
      :8805 pop dx
      :8806 pop cx
      :8807 pop bx
      :8808 pop edi
      :880A pop esi
      :880C ret
          ;call 8830  confronta nome di comando, la call controlla quello che abbiamo dicitato sulla linea di
                      comando se il nome corrisponde ad un comando ci ritorna "vero" altrimenti ci ritorna "falso"
                      esi = posizione del testo per il confronto
      :8830 push ebx
      :8832 push si
      :8833 lea ebx,[000213C0] ;buffer della linea di comando
      :883B mov ah,[ebx]
      :883E mov al,[esi]
      :8841 cmp ax,0000
      :8844 jz 8856
      :8846 cmp ax,B900
      :8849 jz 8856
      :884B inc bx
      :884C inc si
      :884D cmp al,ah
      :884F jz 883B
      :8851 stc                ;comando inesistente ritorna "falso"
      :8852 pop si
      :8853 pop ebx
      :8855 ret
      :8856 clc                ;comando valido ritorna "vero"
      :8857 pop si
      :8858 pop ebx
      :885A ret
          ;call 8880  calcola i punti della pagina, qui impostiamo alcune operazioni di base che ci serviranno
                      di volta in volta per disegnare la pagina video del nostro editor di testo
      :8880 push ecx
      :8882 push edx
      :8884 mov eax,[00010144] ;orizzontale pagina
      :888B mov ecx,[00010148] ;verticale pagina
      :8893 mul ecx
      :8896 shr eax,02
      :889A mov [00010154],eax ;numero punti per pagina
      :88A1 mov ax,[00010134]  ;orizzontale video
      :88A7 sub ax,[00010144]
      :88AE mov [0001012A],ax  ;riduzione del video
      :88B4 mov eax,[00010144]
      :88BB mov cx,[00040006]
      :88C2 mul ecx
      :88C5 mov [00010158],eax ;dimensione in punti di una intera riga di testo
      :88CC pop edx
      :88CE pop ecx
      :88D0 ret
          ;call 8900  cancella la pagina, la call serve per ripulire la pagina video
      :8900 push edi
      :8902 push ecx
      :8904 mov eax,[00100010] ;colore di sfondo
      :890B mov edi,[0001015C] ;memoria grafica
      :8913 mov ecx,[00010154] ;totale punti
      :891B repz stosd
      :891F pop ecx
      :8921 pop edi
      :8923 ret
          ;call 8950  disegna il video, la call ci rigenera il video tutte le volte che si sono verificate
                      delle modifiche nella parte testo o nello scorrimento delle pagine.
                      La seguente call dovrà essere pensata e codificata nel modo migliore, in quanto è
                      esenziale per ottenere una buona velocità di esecuzione per evitare inutili attese
                      durante la modifica del testo, la call verrà richiamata in continuazione ad ogni
                      esigenza di cambiamento disegnandoci una nuova istantanea del nostro lavoro
      :8950 push bx
      :8951 push cx
      :8952 push dx
      :8953 push esi
      :8955 push edi
      :8957 mov esi,[0001015C] ;memoria grafica
      :895F lea edi,[000A0000] ;memoria video
      :8967 cli
      :8968 mov ax,0004
      :896B mov dx,03DE
      :896E out dx,ax          ;imposta la pagina video
      :896F sti
      :8970 mov bx,0004
      :8973 mov cx,[00010148]  ;ciclo in verticale
      :897A push cx
      :897B mov cx,[00010144]  ;ciclo in orizzontale
      :8982 shr cx,02
      :8985 mov eax,[esi]
      :8989 mov [edi],eax
      :898D add esi,00000004
      :8991 add di,0004
      :8994 jnz 899D
      :8996 cli
      :8997 inc bh
      :8999 mov ax,bx
      :899B out dx,ax          ;cambia pagina video
      :899C sti
      :899D loopw 8985
      :899F add di,[0001012A]  ;riduzione del video
      :89A6 ja 89AF
      :89A8 cli
      :89A9 inc bh
      :89AB mov ax,bx
      :89AD out dx,ax          ;cambia pagina video
      :89AE sti
      :89AF pop cx
      :89B0 loopw 897A
      :89B2 pop edi
      :89B4 pop esi
      :89B6 pop dx
      :89B7 pop cx
      :89B8 pop bx
      :89B9 ret
          ;call 8a00  disegna i caratteri,la call ci disegna uno ad uno tutti i caratteri di una pagina; sono
                      miglia di punti da calcolare ed andare ad inserire nelle posizioni appropriate della memoria
                      grafica quindi il seguente codice deve essere ben disposto per riuscire ad ottenere una buona
                      efficienza in velocità di esecuzione.
                      La call verrà utilizzata molto sovente e ci ritornerà molto utile per avere un rapido scorrimento
                      delle pagine sul nostro video
      :8A00 push esi
      :8A02 push edi
      :8A04 push ecx
      :8A06 push edx
      :8A08 mov dh,[0010001A]  ;colore del carattere
      :8A0F push esi
      :8A11 mov eax,00040000   ;definizioni del testo
      :8A17 mov al,[edi]
      :8A1A cmp al,1C          ;ritorno a capo
      :8A1C jnz 8A41
      :8A1E pop esi
      :8A20 cmp edi,[00010140] ;fondo archivio
      :8A28 jz 8A9E
      :8A2A cmp dl,[0001014E]  ;fondo pagina
      :8A31 jz 8A9E
      :8A33 add esi,[00010158] ;prossima riga
      :8A3B inc edi
      :8A3D inc dl
      :8A3F jmp 8A0F
      :8A41 mov ch,[0004000A]  ;disegna il carattere
      :8A48 mul ch
      :8A4A add ax,0000
      :8A4D mov ebx,eax
      :8A50 push esi
      :8A52 mov ah,00
      :8A54 mov cx,[00040006]  ;ciclo in verticale
      :8A5B push esi
      :8A5D push cx
      :8A5E mov cx,[00040004]  ;ciclo in orizzontale
      :8A65 cmp ah,00
      :8A68 jnz 8A70
      :8A6A mov ah,80
      :8A6C mov al,[ebx]
      :8A6F inc bx
      :8A70 test al,ah
      :8A72 jz 8A77
      :8A74 mov [esi],dh       ;disegna il punto
      :8A77 inc esi
      :8A79 shr ah,1
      :8A7B loopw 8A65
      :8A7D pop cx
      :8A7E pop esi
      :8A80 add esi,[00010144] ;orizzontale pagina
      :8A88 loopw 8A5B
      :8A8A pop esi
      :8A8C xor ecx,ecx
      :8A8F mov cx,[00040004]
      :8A96 add esi,ecx        ;prossimo carattere
      :8A99 inc edi
      :8A9B jmp 8A11           ;rotazione caratteri
      :8A9E pop edx
      :8AA0 pop ecx
      :8AA2 pop edi
      :8AA4 pop esi
      :8AA6 ret
          ;call 8ad0  disegna la croce, che ci evidenzia su di un video in formato testo l'esatta posizione dove
                      andremo ad inserire o correggere ogni singolo carattere. Tramire un ciclo tastiera avremo
                      la possibilità di spostare al croce nelle quattro direzioni
      :8AD0 push esi           ;punto di inserimento del carattere
      :8AD2 mov cx,0008
      :8AD5 inc esi            ;ciclo sulla destra
      :8AD7 xor byte [esi],04  ;cambia il colore del punto
      :8ADB loopw 8AD5
      :8ADD pop esi
      :8ADF cmp dh,01
      :8AE2 jz 8AF3
      :8AE4 push esi
      :8AE6 mov cx,0008
      :8AE9 dec esi            ;ciclo a sinistra
      :8AEB xor byte [esi],04
      :8AEF loopw 8AE9
      :8AF1 pop esi
      :8AF3 push esi
      :8AF5 mov cx,0008
      :8AF8 add esi,[00010144] ;ciclo in basso
      :8B00 xor byte [esi],04
      :8B04 loopw 8AF8
      :8B06 pop esi
      :8B08 push esi
      :8B0A mov cx,0008
      :8B0D sub esi,[00010144] ;ciclo in alto
      :8B15 xor byte [esi],04
      :8B19 loopw 8B0D
      :8B1B pop esi
      :8B1D ret
          ;call 8b40  cancella i caratteri, la call si utilizza per inserire una riga vuota nel nostro
                      editor del testo e ci cancella tutti i caratteri che si devono spostare
      :8B40 push edi
      :8B42 push ecx
      :8B44 push dx
      :8B45 mov esi,[00010150] ;primo punto
      :8B4D xor ecx,ecx
      :8B50 mov cl,dl
      :8B52 cmp cx,0000
      :8B55 jz 8B61
      :8B57 add esi,[00010158] ;imposta il punto di inizio testo
      :8B5F loopw 8B57
      :8B61 add ecx,[00010158] ;imposta il numero di punti da cancellare
      :8B69 inc dl
      :8B6B cmp dl,[0001014E]  ;impaginazione sulla y:
      :8B72 jnz 8B61
      :8B74 shr ecx,02
      :8B78 mov edi,esi
      :8B7B mov eax,[00100010] ;colore si sfondo
      :8B82 repz stosd
      :8B86 pop dx
      :8B87 pop ecx
      :8B89 pop edi
      :8B8B ret
          ;call 8bb0  scrive settori del disco, la call ci permette di scrivre uno o più settori del disco-fisso
                      trasferimento dati in "modo-pio" e numerazione dei settori in formato "lba"
      :8BB0 push esi
      :8BB2 push cx
      :8BB3 push dx
      :8BB4 mov cx,[00010120]  ;numero settori da scrivere
      :8BBB mov esi,[00010126] ;posizione in memoria dei dati da scrivere
      :8BC3 cmp cx,0000        ;ciclo settori
      :8BC6 jz 8C23
      :8BC8 cli
      :8BC9 mov dx,01F2
      :8BCC mov al,01
      :8BCE out dx,al
      :8BCF inc dx
      :8BD0 mov al,[00010122]  ;settore del disco-fisso
      :8BD6 out dx,al
      :8BD7 inc dx
      :8BD8 mov al,[00010123]
      :8BDE out dx,al
      :8BDF inc dx
      :8BE0 mov al,[00010124]
      :8BE6 out dx,al
      :8BE7 inc dx
      :8BE8 mov al,[00010125]
      :8BEE add al,E0
      :8BF0 out dx,al
      :8BF1 inc dx
      :8BF2 mov al,30
      :8BF4 out dx,al          ;modo scrittura
      :8BF5 in al,dx
      :8BF6 test al,08         ;test di fine impostazione controller
      :8BF8 jz 8BF5
      :8BFA push cx
      :8BFB cld
      :8BFC mov cx,0080        ;trasferimento dati
      :8BFF mov dx,01F0
      :8C02 mov eax,[esi]
      :8C06 out dx,eax
      :8C08 add esi,00000004
      :8C0C loopw 8C02
      :8C0E mov dx,01F7
      :8C11 in al,dx
      :8C12 test al,88         ;test di fine trasferimento
      :8C14 jnz 8C11
      :8C16 sti
      :8C17 inc dword [00010122] ;prossimo settore
      :8C1F pop cx
      :8C20 dec cx
      :8C21 jmp 8BC3
      :8C23 and eax,000000FF   ;ritorna al=50 (altrimenti errore di scrittura)
      :8C29 pop dx
      :8C2A pop cx
      :8C2B pop esi
      :8C2D ret
          ;call 8c50  conversione da carattere a numero, la call ci converte i caratteri stampabili in un numero
                      esadecimale a 4 cifre. In eax ci mettiamo i caratteri da convertire
      :8C50 push ebx
      :8C52 mov [0001010C],eax
      :8C59 lea ebx,[00021600] ;buffer di conversione
      :8C61 mov bl,[0001010C]
      :8C68 mov ah,[ebx]
      :8C6B shl ah,04
      :8C6E mov bl,[0001010D]
      :8C75 mov al,[ebx]
      :8C78 add ah,al
      :8C7A mov bl,[0001010E]
      :8C81 mov al,[ebx]
      :8C84 shl al,04
      :8C87 mov bl,[0001010F]
      :8C8E mov bl,[ebx]
      :8C91 add al,bl          ;ci ritorna in ax il numero convertito
      :8C93 pop ebx
      :8C95 ret
          ;call 8cc0  conversione da carattere a numero, ax = caratteri da convertire
      :8CC0 push ebx
      :8CC2 mov [0001010C],ax
      :8CC8 lea ebx,[00021600]
      :8CD0 mov bl,[0001010C]
      :8CD7 mov al,[ebx]
      :8CDA shl al,04
      :8CDD mov bl,[0001010D]
      :8CE4 mov ah,[ebx]
      :8CE7 add al,ah          ;ritorna al = numero
      :8CE9 pop ebx
      :8CEB ret
          ;call 8d10  nuovo archivio lavori, la call provvede alle dovute registrazioni quando manca il segmento
           di archivio lavori, ne imposta uno nuovo e poi ritorna
      :8D10 push edi
      :8D12 mov ax,0001
      :8D15 mov [00010120],ax
      :8D1B mov eax,00010083
      :8D21 mov [00010122],eax
      :8D28 mov eax,00001200
      :8D2E mov [00010126],eax
      :8D35 call 8430          ;carica il settore dei dati variabili
      :8D38 mov eax,[1200]
      :8D3C add eax,00000080
      :8D42 cmp eax,[00010164] ;max settore del disco
      :8D4A jb 8D4F
      :8D4C jmp 8300           ;errore!! il disco è pieno
      :8D4F lea edi,[00100100] ;buffer degli archivi
      :8D57 mov eax,[edi]
      :8D5B cmp eax,00000000
      :8D5F jz 8D6D
      :8D61 add di,0004
      :8D64 cmp di,0200
      :8D68 jnz 8D57
      :8D6A jmp 8300           ;errore!! il buffer degli archivi è pieno
      :8D6D mov eax,[1200]
      :8D71 mov [edi],eax
      :8D75 add eax,00000080
      :8D7B mov [1200],eax
      :8D7F mov eax,00010083
      :8D85 mov [00010122],eax
      :8D8C call 8BB0          ;salva il settore dei dati variabili
      :8D8F mov eax,[0010001C]
      :8D96 mov [00010122],eax
      :8D9D mov eax,00100000
      :8DA3 mov [00010126],eax
      :8DAA call 8BB0          ;salva il settore di intestazione archivio
      :8DAD pop edi
      :8DAF ret
          ;call 8dd0  salva l'archivio, la call a fine lavoro ci salva l'intero archivio registrando tutte le modifiche
           apportate durante la fase di editazione del testo
      :8DD0 push esi
      :8DD2 push edi
      :8DD4 push ecx
      :8DD6 mov eax,[00010140]
      :8DDD mov [00100000],eax ;fondo archivio
      :8DE4 lea edi,[00100000]
      :8DEC lea esi,[00100100]
      :8DF4 mov ax,0080
      :8DF7 mov [00010120],ax
      :8DFD mov eax,[0010001C]
      :8E04 mov [00010122],eax
      :8E0B mov [00010126],edi
      :8E13 call 8BB0          ;salva il segmento impostazioni
      :8E16 mov ecx,[edi]
      :8E1A shr ecx,10
      :8E1E sub cx,0010
      :8E21 jz 8E5A
      :8E23 mov eax,[esi]
      :8E27 cmp eax,00000000
      :8E2B jnz 8E3B
      :8E2D call 8D10          ;nuovo archivio lavori
      :8E30 mov ax,0080
      :8E33 mov [00010120],ax
      :8E39 jmp 8E23
      :8E3B mov [00010122],eax
      :8E42 add edi,00010000
      :8E49 mov [00010126],edi
      :8E51 call 8BB0          ,salva tutti gli archivi
      :8E54 add si,0004
      :8E57 dec cx
      :8E58 jnz 8E23
      :8E5A pop ecx
      :8E5C pop edi
      :8E5E pop esi
      :8E60 ret
          ;call 8e80  conversione da carattere a numero
           esi = posizione del numero da convertire
           edx = posizione del numero convertito
           cx  = numero di cifre
      :8E80 push ebx
      :8E82 add dx,cx
      :8E84 push dx
      :8E85 lea ebx,[00021600]
      :8E8D mov bl,[esi]
      :8E90 mov ah,[ebx]
      :8E93 shl ah,04
      :8E96 mov bl,[esi+01]
      :8E9A mov al,[ebx]
      :8E9D add ah,al
      :8E9F dec dx
      :8EA0 mov [edx],ah
      :8EA3 add si,0002
      :8EA6 loopw 8E8D
      :8EA8 pop dx
      :8EA9 pop ebx
      :8EAB ret
      
Introduzione alla programmazione in "Assembler"
invia E-mail