;****************************************************************************** ; INT60 per Videobank VSX500 ; Author Roberto Gaspari, RVM Genova / Ciakware ; ; Rel 1.128: 22 Jan 1991 ; Rel 1.129: 28 Jan 1991 ; Rel 1.130: 06 Feb 1991 ; Rel 1.131: 11 Mar 1991 ; Rel 1.132: 25 Mar 1991 ; Rel 1.133: 17 Dec 1992 ; Rel 1.134: 05 Apr 1993 ; Rel 1.135: 06 Apr 1993 ; Rel 1.136: 14 Sep 1994 (copia per GAMMA srl, Abano) ; Rel 1.137: 16 Oct 1998 (copia per Buster24 per adeguare il nuovo robot Buster) ; ; (c)1991-1998 Roberto Gaspari ; porzioni di codice rielaborate da un progetto originale di Ing. Pietro Rotoloni (Videobank 500) ; ; TASM ; ;****************************************************************************** _CODE SEGMENT ASSUME cs:_CODE,ds:_CODE,es:_CODE ORG 100h start: jmp installa SNSPNC EQU 0 ; tipo sensore pinza (1=switch,0=prossimetro) DOORBCKGRD EQU 1 ; chiusura porta in background (1=abilitata,0=disabilitata) BARGP EQU 0 ; barriere gruppo pinza (1=presenti,0=assenti) VERPNZ EQU 1 ; verifica apertura pinza (1=abilitata,0=disabilitata) INT8 EQU 1 ; timer (1=tramite int 8,0=tramite int 1c) sign DB 13,10,'VIDEOBANK VSX500 ',13,10,'$' filler DB 128 DUP(?) ;****************************************************************************** ; ; gestione delle porte di output mappate fra 300h e 31fh ; ; input: dx = indirizzo ; al = maschera ; ;****************************************************************************** port DB 32 DUP (0) ; copia dei valori delle porte resetbit PROC NEAR ; resetta il bit not al mov bx,dx and [port+bx-300h],al mov al,[port+bx-300h] out dx,al ret ENDP setbit PROC NEAR ; setta il bit mov bx,dx or [port+bx-300h],al mov al,[port+bx-300h] out dx,al ret ENDP reversebit PROC NEAR ; inverte il bit mov bx,dx xor [port+bx-300h],al mov al,[port+bx-300h] out dx,al ret ENDP ;****************************************************************************** ; ; gestione degli elettromagneti ; ; input: ds:si = puntatore ai parametri del magnete ; ; output: zero-flag = stato del sensore ; ;****************************************************************************** ; parametri magnete MGN EQU [si] ; indirizzo magnete MGN_BIT EQU [si+2] ; bit magnete MSNS EQU [si+3] ; indirizzo sensore MSNS_BIT EQU [si+5] ; bit sensore WAIT_MGN EQU 3 ; tempo attesa lettura sensore magneteoff PROC NEAR ; disattiva il magnete mov dx,MGN mov al,MGN_BIT call setbit jmp SHORT magnete magneteon: mov dx,MGN ; attiva il magnete mov al,MGN_BIT call resetbit magnete: mov bx,WAIT_MGN ; attende mgn1: xor cx,cx loop $ dec bx jnz mgn1 mov dx,MSNS ; legge sensore in al,dx test al,MSNS_BIT ret ENDP ;****************************************************************************** ; ; gestione dei motori passo-passo ; ; input: ds:di = puntatore ai parametri fissi del motore ; ;****************************************************************************** ; segnali motore EN EQU [di] ; indirizzo abilitazione EN_BIT EQU [di+2] ; bit abilitazione DIR EQU [di+3] ; indirizzo direzione DIR_BIT EQU [di+5] ; bit direzione CK EQU [di+6] ; indirizzo clock CK_BIT EQU [di+8] ; bit clock ; parametri rampa velocit… START_VEL EQU [di+9] ; velocit… di partenza STEPS_ACC EQU [di+11] ; passi per accelerazione ACC EQU [di+13] ; accelerazione STEPS_DECC EQU [di+15] ; passi per deccelerazione DECC EQU [di+17] ; deccelerazione ; parametri traiettoria SNS EQU [si] ; indirizzo sensore SNS_BIT EQU [si+2] ; bit sensore SNS_STAT EQU [si+3] ; stato sensore per arresto MAX_STEPS EQU [si+4] ; passi massimi prima del sensore STEPS_SNS EQU [si+6] ; passi dopo il sensore WAIT_SNS EQU 2000 ; tempo attesa verifica sensore steps DW ? ; contatore passi vel DW ? ; velocit… attuale motoreoff PROC NEAR ; disattiva il motore mov dx,EN mov al,EN_BIT call setbit ret ENDP motoreon PROC NEAR ; attiva il motore: questa non funziona quasi mai a "freddo" mov dx,EN ; al limite ci butto un loop mov al,EN_BIT call resetbit ret ENDP ; muove il motore fino al sensore nella direzione specificata ; ; input: ds:si = puntatore ai parametri della traiettoria ; ; output: carry-flag = reset se tutto ha funzionato a dovere ; carry-flag = set se non Š stato raggiunto il sensore step PROC NEAR ; muove il motore di un passo mov dx,CK ; tick mov al,CK_BIT call reversebit mov cx,vel ; velocit… loop $ ret ENDP motore0 PROC NEAR ; direzione 0 mov dx,DIR mov al,DIR_BIT call resetbit jmp SHORT motorego motore1: mov dx,DIR ; direzione 1 mov al,DIR_BIT call setbit motorego: call motoreon ; abilita il motore mov ax,START_VEL ; velocit… di partenza mov vel,ax mov ax,STEPS_ACC ; passi per accelerazione mov steps,ax mt1: call step mov ax,ACC ; accellera sub vel,ax dec steps jnz mt1 mtt1: mov ax,MAX_STEPS ; passi massimi prima del sensore mov steps,ax mt2: call step mov dx,SNS ; controlla sensore in al,dx and al,SNS_BIT xor al,SNS_STAT jnz mt3 ; sensore non raggiunto mov cx,WAIT_SNS ; attende stabilit… segnale loop $ in al,dx ; verifica sensore and al,SNS_BIT xor al,SNS_STAT jz mt4 ; sensore raggiunto mt3: dec steps jnz mt2 ; continua stc ; TROPPI PASSI !!! ret mt4: mov ax,STEPS_SNS ; passi dopo il sensore mov steps,ax mt5: call step dec steps jnz mt5 mov dx,SNS ; verifica stato fine-corsa in al,dx and al,SNS_BIT xor al,SNS_STAT jnz mtt1 ; sensore non raggiunto mov ax,STEPS_DECC ; passi per deccelerazione mov steps,ax mt6: call step mov ax,DECC ; deccellera add vel,ax dec steps jnz mt6 clc ; tutto ok ret ENDP ;****************************************************************************** ; ; gestione del tappeto del posto operatore ; ;****************************************************************************** ESC_KEY EQU 011bh F9_KEY EQU 4300h TEN EQU 0310h ; segnali motore TEN_BIT EQU 00001000b TDIR EQU 031ch TDIR_BIT EQU 10000000b ; 0 -> verso l'esterno TCK EQU 0312h TCK_BIT EQU 00100000b SNS_EST EQU 0318h ; sensore esterno SNS_EST_BIT EQU 00000001b SNS_CNT EQU 0318h ; sensore centrale SNS_CNT_BIT EQU 00000010b SNS_INT EQU 0318h ; sensore interno SNS_INT_BIT EQU 00000100b MGN_TAPP EQU 0318h ; magnete blocco cassetta e micro relativo MGN_TAPP_BIT EQU 00000100b MSNS_TAPP EQU 0318h MSNS_TAPP_BIT EQU 10000000b PBOX EQU 0318h ; sensore presenza box PBOX_BIT EQU 00001000b PBOK EQU 0310h ; sensore presenza box ok PBOK_BIT EQU 00000010b MAX_STEPS_CNT0 EQU 10000 ; passi massimi prima del sensore cnt. MAX_STEPS_CNT1 EQU 7000 ; passi massimi durante il sensore cnt. MAX_STEPS_EST EQU 10000 ; passi massimi espulsione cassetta STEPS_EST EQU 400 ; passi extra espulsione cassetta VEL_REG DW 1300 ; velocita' tappeto a regime STEPS_INT DW 200 ; passi extra dopo sensore centrale ex DW 0 ; riporta lo stato attuale del tappeto dedotto dalla lettura dei sensori ; ; output: ah = 00000XXXb ; ³³³ ; ³³ÀÄÄÄ = stato sensore esterno ; ³ÀÄÄÄÄ = stato sensore centrale ; ÀÄÄÄÄÄ = stato sensore interno tappstatus PROC NEAR xor ah,ah mov dx,SNS_EST ; controlla sensore esterno in al,dx test al,SNS_EST_BIT jz ts1 ; sensore a 0 or ah,00000001b ; sensore ad 1 ts1: mov dx,SNS_CNT ; controlla sensore centrale in al,dx test al,SNS_CNT_BIT jz ts2 ; sensore a 0 or ah,00000010b ; sensore ad 1 ts2: mov dx,SNS_INT ; controlla sensore interno in al,dx test al,SNS_INT_BIT jz ts3 ; sensore a 0 or ah,00000100b ; sensore ad 1 ts3: ret ENDP ; muove di un passo il motore del tappeto tstep PROC NEAR mov dx,TCK ; tick mov al,TCK_BIT call reversebit mov cx,vel ; pausa loop $ ret ENDP ; porta la cassetta davanti il tappeto ; ; output: param = '0' se tutto ha funzionato a dovere ; param = 'P' se ancora prima di aver raggiunto il sensore centrale, ; si Š eccitato un sensore della pinza ; param = '1' se ancora prima di aver raggiunto il sensore centrale, ; e' stato premuto il tasto Esc ; param = '2' se ancora prima di aver raggiunto il sensore centrale ; e' stato premuto il tasto F9 ; param = 'A' se non Š mai stato raggiunto il sensore centrale ; param = 'p' se dopo aver raggiunto il sensore centrale, si Š eccitato ; un sensore della pinza ; param = 'B' se non Š mai stato superato il sensore centrale ; param = 'Q' se dopo aver superato il sensore centrale, questo si Š ; eccitato di nuovo ; param = 'q' se dopo aver superato il sensore centrale, si Š eccitato ; un sensore della pinza __vbtapp PROC NEAR mov dx,TDIR ; fissa direzione 1 mov al,TDIR_BIT call setbit mov dx,TEN ; attiva motore mov al,TEN_BIT call resetbit mov ax,VEL_REG ; velocit… di regime mov vel,ax mov dx,SNS_INT ; controlla sensore interno in al,dx test al,SNS_INT_BIT jz tapp4 ; sensore eccitato ; cassetta davanti sensore centrale mov steps,MAX_STEPS_CNT0 ; massima attesa cassetta tapp1: call tstep ; un passo mov dx,SNS_CNT ; controlla sensore centrale in al,dx test al,SNS_CNT_BIT jnz tapp2 ; sensore non eccitato mov cx,WAIT_SNS ; attende stabilit… segnale loop $ in al,dx ; verifica sensore test al,SNS_CNT_BIT jz tapp4 ; sensore eccitato tapp2: mov dx,BAR_ANT ; controlla sensori pinza in al,dx test al,BAR_ANT_BIT jnz lp ; sensori non eccitati mov cx,WAIT_SNS ; attende stabilit… segnale loop $ in al,dx ; verifica sensori test al,BAR_ANT_BIT jnz lp ; sensori non eccitati mov al,'P' jmp tappret ; sensori eccitati lp: mov ah,01h ; lettura tastiera al volo int 16h jz tapp3 ; nessun tasto xor ah,ah ; scarica il buffer int 16h cmp ax,ESC_KEY jne tapp31 mov al,'1' jmp tappret ; ESC tapp31: cmp ax,F9_KEY jne tapp3 mov al,'2' jmp tappret ; F9 tapp3: dec steps ; controlla passi totali jnz tapp1 ; pochi: continua mov al,'A' ; time-out jmp tappret ; cassetta dopo sensore centrale tapp4: mov steps,MAX_STEPS_CNT1 ; massima attesa cassetta tapp5: call tstep ; un passo mov dx,SNS_CNT ; controlla sensore centrale in al,dx test al,SNS_CNT_BIT jz tapp6 ; sensore eccitato mov cx,WAIT_SNS ; attende stabilit… segnale loop $ in al,dx ; verifica sensore test al,SNS_CNT_BIT jz tapp6 ; sensore eccitato mov dx,SNS_INT ; controlla barriera interna in al,dx test al,SNS_INT_BIT jz tapp7 ; barriera interrotta tapp6: mov dx,BAR_ANT ; controlla sensori pinza in al,dx test al,BAR_ANT_BIT jnz lp1 ; sensori non eccitati mov cx,WAIT_SNS ; attende stabilit… segnale loop $ in al,dx ; verifica sensori test al,BAR_ANT_BIT jnz lp1 ; sensori non eccitati mov al,'p' jmp tappret ; sensori eccitati lp1: mov dx,SNS_EST ; controlla barriera esterna in al,dx test al,SNS_EST_BIT jnz lp11 ; barriera non interrotta mov dx,SNS_INT ; controlla barriera interna in al,dx test al,SNS_INT_BIT jnz lp11 ; barriera non interrotta mov al,'Q' jmp tappret ; 3 barriere interrotte lp11: dec steps ; controlla passi totali jnz tapp5 ; pochi: continua mov al,'B' ; time-out jmp tappret ; passi extra tapp7: mov ax,STEPS_INT ; passi dopo sensore mov steps,ax tapp8: call tstep ; un passo mov dx,SNS_CNT ; controlla sensore centrale in al,dx test al,SNS_CNT_BIT jnz lp2 ; sensore non eccitato mov cx,WAIT_SNS ; attesa stabilta' segnale loop $ in al,dx ; verifica sensore test al,SNS_CNT_BIT jnz lp2 ; sensore non eccitato mov al,'Q' jmp tappret ; sensore eccitato lp2: mov dx,BAR_ANT ; controlla sensori pinza in al,dx test al,BAR_ANT_BIT jnz lp3 ; sensori non eccitati mov cx,WAIT_SNS ; attesa stabilita' segnale loop $ in al,dx ; verifica sensori test al,BAR_ANT_BIT jnz lp3 ; sensori non eccitati mov al,'q' jmp tappret ; sensori eccitati lp3: dec steps ; controlla passi fatti jnz tapp8 ; pochi: continua mov al,'0' ; tutto ok tappret: push ax ; salva esito mov dx,TEN ; disattiva motore mov al,TEN_BIT call setbit pop ax ; ripristina esito ret ENDP ; espelle la cassetta ; ; output: param = '0' se tutto ha funzionato a dovere ; param = 'B' se time-out esp_stat DB ? ; stato da raggiungere esp_max DW ? ; passi massimi esp_ex DW ? ; passi extra ___vbesp PROC NEAR mov dx,TDIR ; fissa direzione 0 mov al,TDIR_BIT call resetbit mov dx,TEN ; attiva motore mov al,TEN_BIT call resetbit mov ax,VEL_REG ; velocit… di regime mov vel,ax mov steps,0 ; passi totali esp1: mov ex,0 ; passi extra esp2: call tstep ; un passo inc steps call tappstatus ; controlla sensori cmp ah,esp_stat jne esp3 ; sensori non ok inc ex ; controlla passi extra mov ax,ex cmp ax,esp_ex jb esp2 ; continua mov al,'0' ; tutto ok jmp espret esp3: mov ax,steps cmp ax,esp_max ; controlla passi totali jb esp1 ; pochi: continua mov al,'B' ; time-out espret: push ax ; salva esito mov dx,TEN ; disattiva motore mov al,TEN_BIT call setbit pop ax ; ripristina esito ret ENDP __vbesp PROC NEAR ; espulsione totale mov esp_stat,111b mov esp_max,MAX_STEPS_EST mov esp_ex,STEPS_EST jmp ___vbesp ENDP __vbespp PROC NEAR ; espulsione parziale, utente batman mov esp_stat,100b mov esp_max,MAX_STEPS_EST mov esp_ex,30 jmp ___vbesp ENDP COMMENT ~ ; porta la cassetta davanti il tappeto __vbtapp PROC NEAR mov dx,TEN ; abilitazione mov al,TEN_BIT call resetbit mov dx,TDIR ; direzione mov al,TDIR_BIT call setbit __tapp1: mov dx,TCK ; clock mov al,TCK_BIT call reversebit mov cx,VEL_REG ; velocita' loop $ mov dx,SNS_CNT ; controlla barriera centrale in al,dx test al,SNS_CNT_BIT jnz __tapp1 ; barriera non interrotta __tapp2: mov dx,TCK ; clock mov al,TCK_BIT call reversebit mov cx,VEL_REG ; velocita' loop $ mov dx,SNS_CNT ; controlla barriera interna in al,dx test al,SNS_CNT_BIT jz __tapp2 ; barriera interrotta mov dx,TEN ; disabilitazione mov al,TEN_BIT call setbit mov al,'0' ; ok ret ENDP ; espelle la cassetta __vbespp LABEL NEAR __vbesp PROC NEAR mov dx,TEN ; abilitazione mov al,TEN_BIT call resetbit mov dx,TDIR ; direzione mov al,TDIR_BIT call resetbit __esp1: mov dx,TCK ; clock mov al,TCK_BIT call reversebit mov cx,VEL_REG ; velocita' loop $ mov dx,SNS_EST ; controlla barriera esterna in al,dx test al,SNS_EST_BIT jnz __esp1 ; barriera non interrotta mov dx,TEN ; disabilitazione mov al,TEN_BIT call setbit mov al,'0' ; ok ret ENDP ~ ;****************************************************************************** ; ; gestione della porta del posto operatore ; ;****************************************************************************** APERTA EQU 00000010b ; porta aperta CHIUSA EQU 00000001b ; porta chiusa pen DW 0310h ; segnali motore pen_bit DB 00000100b pdir DW 031ch pdir_bit DB 01000000b ; 0 -> verso chiusura pck DW 0312h pck_bit DB 00010000b pstart_vel DW 1200 ; parametri rampa velocit… psteps_acc DW 1 pacc DW 0 psteps_decc DW 1 pdecc DW 0 sns_inf DW 0318h ; dati per chiusura porta sns_inf_bit DB 00100000b sns_inf_stat DB 00000000b max_steps_down DW 6000 steps_sns_down DW 20 sns_sup DW 0318h ; dati per apertura porta sns_sup_bit DB 00010000b sns_sup_stat DB 00000000b max_steps_up DW 6000 steps_sns_up DW 40 mgn_blc DW 0318h ; magnete blocco porta mgn_blc_bit DB 00001000b msns_blc DW 0318h msns_blc_bit DB 01000000b status DB 0 ; stato teorico porta (0=aperta, 1=chiusa, 2=incastrata in chiusura) time1 DW ? ; istante chiusura completata se plexiglas e finecorsa sani ; riporta lo stato attuale della porta dedotto dalla lettura dei sensori ; ; output: ah = 000000XXb ; ³ÀÄÄÄ = stato sensore superiore ; ÀÄÄÄÄ = stato sensore inferiore portastatus PROC NEAR xor ah,ah mov dx,sns_inf ; controlla sensore inferiore in al,dx test al,sns_inf_bit jz ps1 ; sensore a 0 or ah,00000010b ; sensore ad 1 ps1: mov dx,sns_sup ; controlla sensore superiore in al,dx test al,sns_sup_bit jz ps2 ; sensore a 0 or ah,00000001b ; sensore ad 1 ps2: ret ENDP ; chiude la porta ; ; output: param = '0' se tutto ha funzionato a dovere ; param = 'B' se la porta non si Š chiusa nel tempo stabilito ; param = 'D' se dopo la chiusura la porta non risultava chiusa __vbdown PROC NEAR mov status,0 ; imposta porta aperta mov di,OFFSET pen ; chiude mov si,OFFSET sns_inf call motore0 mov al,'B' jc downret ; CHIUSURA NON AVVENUTA !!! IF INT8 EQ 0 ; se non c'e' chiusura in background call motoreoff ; resetta motore (in background) ENDIF call portastatus ; controlla stato porta cmp ah,CHIUSA mov al,'D' jne downret ; PORTA NON CHIUSA !!! mov al,'0' ; tutto ok cli mov status,1 ; imposta porta chiusa mov time1,0 ; registra istante attuale sti ret downret: push ax ; salva esito call motoreoff ; disabilita motore pop ax ; recupera esito mov status,2 ; imposta porta incastrata ret ENDP ; apre la porta ; ; output: param = '0' se tutto ha funzionato a dovere ; param = 'C' se la porta non si Š aperta nel tempo stabilito ; param = 'D' se dopo l'apertura la porta non risultava aperta __vbup PROC NEAR mov status,0 ; imposta porta aperta mov di,OFFSET pen ; apre mov si,OFFSET sns_sup call motore1 mov al,'C' jc upret ; APERTURA NON AVVENUTA !!! call portastatus ; controlla stato porta cmp ah,APERTA mov al,'D' jne upret ; PORTA NON APERTA !!! mov al,'0' ; tutto ok upret: ret ENDP ;****************************************************************************** ; ; gestione del gruppo pinza ; ;****************************************************************************** MT0 EQU ; direzione 0 MT1 EQU ; direzione 1 MAG EQU ; pinza davanti magazzino RIP EQU ; pinza a riposo RIP_MCR EQU RIP_MCR_BIT EQU RIP_MCR_STAT EQU RIP_MAX EQU RIP_EX EQU TIN EQU ; cassetta dentro tappeto TOUT EQU ; cassetta su bordo tappeto FBR EQU ; indirizzo fibra FBR_BIT EQU ; maschera fibra BAR EQU ; indirizzo barriera BAR_BIT EQU ; maschera barriera MGN EQU ; magnete pinza VICINO EQU ; passi vicino magazzino OTHER EQU ; puntatore all'altro magazzino TNT_PNZ EQU 3 TNT_PMAG EQU 15 TNT_INS EQU 10 TNT_OUT EQU 10 EX_FIBRA EQU 100 MCR_ANT EQU 0310h MCR_ANT_BIT EQU 00010000b MCR_POS EQU 0316h MCR_POS_BIT EQU 00000001b MCR_CNT EQU 0310h MCR_CNT_BIT EQU 00100000b IF BARGP EQ 1 ; se ci sono le barriere BAR_ANT EQU 0316h ; le associo ai loro indirizzi BAR_ANT_BIT EQU 00100000b BAR_POS EQU 0316h BAR_POS_BIT EQU 01000000b ELSE ; se non ci sono le barriere BAR_ANT EQU FBR_ANT ; le associo alle fibre BAR_ANT_BIT EQU FBR_ANT_BIT BAR_POS EQU FBR_POS BAR_POS_BIT EQU FBR_POS_BIT ENDIF FBR_ANT EQU 031ah FBR_ANT_BIT EQU 01000000b FBR_POS EQU 031ah FBR_POS_BIT EQU 10000000b MMCR_ANT EQU 0316h MMCR_ANT_BIT EQU 00001000b MMCR_POS EQU 0316h MMCR_POS_BIT EQU 00010000b ppvel DW 1400 ttvel DW 1400 ; motore trasporto pinza ppen DW 0310h ; segnali motore ppen_bit DB 00100000b ppdir DW 0314h ppdir_bit DB 00001000b ; 0 -> verso anteriore ppck DW 0312h ppck_bit DB 10000000b ppstart_vel DW 1400 ; parametri rampa velocit… ppsteps_acc DW 1 ppacc DW 0 ppsteps_decc DW 1 ppdecc DW 0 ; motore tappeto pinza tten DW 0310h ; segnali motore tten_bit DB 00010000b ttdir DW 0314h ttdir_bit DB 00000100b ; 0 -> verso posteriore ttck DW 0312h ttck_bit DB 01000000b ttstart_vel DW 1400 ; parametri rampa velocit… ttsteps_acc DW 1 ttacc DW 0 ttsteps_decc DW 1 ttdecc DW 0 ; parametri per azioni su magazzino anteriore mt0_ant DW OFFSET motore1 ; direzione motori mt1_ant DW OFFSET motore0 mcr_cnta DW MCR_CNT ; dati per trasporto pinza davanti mcr_cnta_bit DB MCR_CNT_BIT ; magazzino da posizione di riposo mcr_cnta_stat DB MCR_CNT_BIT max_steps_ravt DW 1000 steps_sns_ravt DW 10 mcr_ant DW MCR_POS ; dati per trasporto pinza in posizione mcr_ant_bit DB MCR_POS_BIT ; di riposo da magazzino mcr_ant_stat DB MCR_POS_BIT max_steps_ind DW 1000 steps_sns_ind DW 10 IF BARGP EQ 1 bar_pos0 DW BAR_POS ; dati per trasporto cassetta in bar_pos0_bit DB BAR_POS_BIT ; centro tappeto da bordo esterno bar_pos0_stat DB 00000000b ELSE bar_pos0 DW FBR_ANT ; idem in caso di assenza barriere bar_pos0_bit DB FBR_ANT_BIT bar_pos0_stat DB FBR_ANT_BIT ENDIF max_steps_aind DW 3000 steps_sns_aind DW 10 bar_ant1 DW BAR_ANT ; dati per trasporto cassetta bar_ant1_bit DB BAR_ANT_BIT+BAR_POS_BIT ; da centro tappeto a bordo bar_ant1_stat DB BAR_ANT_BIT+BAR_POS_BIT ; esterno max_steps_cavt DW 3000 steps_sns_cavt DW 10 fbr_ant DW FBR_ANT ; fibra fbr_ant_bit DB FBR_ANT_BIT bar_ant DW BAR_ANT ; barriera bar_ant_bit DB BAR_ANT_BIT mgn_ant DW 0318h ; magnete pinza mgn_ant_bit DB 00100000b mmcr_ant DW MMCR_ANT mmcr_ant_bit DB MMCR_ANT_BIT vicino_ant DW 100 ; passi vicino magazzino othera DW OFFSET mt0_pos ; parametri per azioni su magazzino posteriore mt0_pos DW OFFSET motore0 ; direzione motori mt1_pos DW OFFSET motore1 mcr_cntp DW MCR_CNT ; dati per trasporto pinza davanti mcr_cntp_bit DB MCR_CNT_BIT ; magazzino da posizione di riposo mcr_cntp_stat DB MCR_CNT_BIT max_steps_rind DW 1000 steps_sns_rind DW 10 mcr_pos DW MCR_ANT ; dati per trasporto pinza in posizione mcr_pos_bit DB MCR_ANT_BIT ; di riposo da magazzino mcr_pos_stat DB MCR_ANT_BIT max_steps_avt DW 1000 steps_sns_avt DW 10 IF BARGP EQ 1 bar_ant0 DW BAR_ANT ; dati per trasporto cassetta in bar_ant0_bit DB BAR_ANT_BIT ; centro tappeto da bordo esterno bar_ant0_stat DB 00000000b ELSE bar_ant0 DW FBR_POS ; idem in caso di assenza barriere bar_ant0_bit DB FBR_POS_BIT bar_ant0_stat DB FBR_POS_BIT ENDIF max_steps_pavt DW 3000 steps_sns_pavt DW 10 bar_pos1 DW BAR_POS ; dati per trasporto cassetta bar_pos1_bit DB BAR_POS_BIT+BAR_ANT_BIT ; da centro tappeto a bordo bar_pos1_stat DB BAR_POS_BIT+BAR_ANT_BIT ; esterno max_steps_cind DW 3000 steps_sns_cind DW 10 fbr_pos DW FBR_POS ; fibra fbr_pos_bit DB FBR_POS_BIT bar_pos DW BAR_POS ; barriera bar_pos_bit DB BAR_POS_BIT mgn_pos DW 0318h ; magnete pinza mgn_pos_bit DB 00010000b mmcr_pos DW MMCR_POS mmcr_pos_bit DB MMCR_POS_BIT vicino_pos DW 100 ; passi vicino magazzino otherp DW OFFSET mt0_ant IF BARGP EQ 0 ; se non ci sono le barriere tout0 DW ? ; in trasporto cassetta da centro tout0_bit DB ? ; a bordo tappeto e' necessario prima tout0_stat DB 00000000b ; eccitare una fibra tout0_max DW 1000 tout0_ex DW 50 ENDIF t DW ? ; riporta in AX la variazione di velocita' del trasporto pinza ppvelvar PROC NEAR mov ax,ppvel shr ax,1 ret ENDP ; abbassa la velocita' del trasporto ppslow PROC NEAR call ppvelvar add ppstart_vel,ax ret ENDP ; aumenta la velocita' del trasporto ppfast PROC NEAR call ppvelvar sub ppstart_vel,ax ret ENDP ; riporta in AX la variazione di velocita' del tappeto pinza ttvelvar PROC NEAR mov ax,ttvel shr ax,1 ret ENDP ; abbassa la velocita' del tappeto ttslow PROC NEAR call ttvelvar add ttstart_vel,ax ret ENDP ; aumenta la velocita' del tappeto ttfast PROC NEAR call ttvelvar sub ttstart_vel,ax ret ENDP ; riporta in AH lo stato delle barriere ; ; out: bit0 = stato barriera anteriore ; bit1 = stato barriera posteriore barstat PROC NEAR xor ah,ah ; inizializza stato mov dx,BAR_ANT ; controlla barriera anteriore in al,dx test al,BAR_ANT_BIT jz brs1 ; barriera interrotta or ah,01b ; barriera non interrotta brs1: mov dx,BAR_POS ; controlla barriera posteriore in al,dx test al,BAR_POS_BIT jz brs2 ; barriera interrotta or ah,10b ; barriera non interrotta brs2: ret ; fine ENDP ; riporta in AH lo stato dei micro ; ; out: bit0 = stato micro anteriore ; bit1 = stato micro centrale ; bit2 = stato micro posteriore mcrstat PROC NEAR xor ah,ah ; inizializza stato mov dx,MCR_ANT ; controlla micro anteriore in al,dx test al,MCR_ANT_BIT jz mrs1 ; micro premuto or ah,001b ; micro rilasciato mrs1: mov dx,MCR_CNT ; controlla micro centrale in al,dx test al,MCR_CNT_BIT jz mrs2 ; micro premuto or ah,010b ; micro rilasciato mrs2: mov dx,MCR_POS ; controlla micro posteriore in al,dx test al,MCR_POS_BIT jz mrs3 ; micro premuto or ah,100b ; micro rilasciato mrs3: ret ; fine ENDP ; cerca di portare il tappeto in posizione di riposo ; ; out: cf = esito (set = negativo, reset = positivo) taprip PROC NEAR mov di,OFFSET tten ; tappeto pinza call ttslow ; bassa velocita' call barstat ; legge stato barriere cmp ah,10b je tprpa ; cassetta verso anteriore cmp ah,01b je tprpp ; cassetta verso posteriore tprpok: call ttfast ; alta velocita' clc ; ok ret tprpa: mov si,OFFSET bar_pos0 ; cassetta in centro da ant. call motore0 call barstat ; legge stato barriere IF BARGP EQ 1 cmp ah,00b ELSE cmp ah,11b ENDIF je tprpok ; cassetta in centro cmp ah,01b je tprpok ; cassetta verso posteriore jmp tprperr ; ERRORE !!! tprpp: mov si,OFFSET bar_ant0 ; cassetta in centro da pos. call motore1 call barstat ; legge stato barriere IF BARGP EQ 1 cmp ah,00b ELSE cmp ah,11b ENDIF je tprpok ; cassetta in centro cmp ah,10b je tprpok ; cassetta verso anteriore tprperr: call ttfast ; alta velocita' stc ; ERRORE !!! ret ENDP ; cerca di portare la pinza in posizione di riposo ; ; out: cf = esito (set = negativo, reset = positivo) pnzrip PROC NEAR mov di,OFFSET ppen ; trasporto pinza call ppslow ; bassa velocita' call mcrstat ; legge stato micro cmp ah,100b je pzrpp ; pinza un po' indietro cmp ah,110b je pzrpp ; pinza tutta indietro cmp ah,001b je pzrpa ; pinza un po' avanti cmp ah,011b je pzrpa ; pinza tutta avanti cmp ah,101b je pzrpok ; pinza a riposo pzrperr: call ppfast ; alta velocita' stc ; ERRORE !!! ret pzrpp: mov si,OFFSET mcr_pos ; pinza a riposo da pos. call motore0 call mcrstat ; legge stato micro cmp ah,001b je pzrpok ; pinza un po' avanti cmp ah,101b je pzrpok ; pinza a riposo jmp pzrperr ; ERRORE !!! pzrpa: mov si,OFFSET mcr_ant ; pinza a riposo da ant. call motore1 call mcrstat ; legge stato micro cmp ah,100b je pzrpok ; pinza un po' indietro cmp ah,101b je pzrpok ; pinza a riposo jmp pzrperr ; ERRORE !!! pzrpok: call ppfast ; alta velocita' clc ; ok ret ENDP ; cerca di portare la pinza in uno stato stabile e ne riporta l'esito ; ; output: cf = esito (set = negativo, reset = positivo) ; zf = stato in caso di presenza barriere ; (set = con cassetta, reset = senza cassetta) statopinza PROC NEAR call pnzrip ; pinza a riposo jc statoret ; ERRORE !!! call taprip ; tappeto a riposo jc statoret ; ERRORE !!! IF BARGP EQ 1 ; se ci sono le barriere call barstat ; controlla presenza cassetta test ah,01b jz statook ; cassetta presente test ah,10b ENDIF statook: clc ; ok statoret: ret ENDP ; chiusura pinza pnz_on PROC NEAR lea si,MGN ; magnete pinza mov cx,TNT_PNZ ; # tentativi jmp SHORT po2 po1: push cx call magneteoff ; apre pop cx po2: push cx call magneteon ; chiude pop cx IF SNSPNC EQ 1 ; se i magneti hanno i micro jnz po3 ; pinza chiusa ELSE ; altrimenti ci sono i prossimetri jz po3 ; pinza chiusa ENDIF loop po1 po3: ret ENDP ; apertura pinza ver_pnz DB ? ; flag di verifica apertura pinza ; (1=pinza aperta,0=pinza chiusa) pnz_off PROC NEAR lea si,MGN ; magnete pinza call magneteoff ; apre mov ver_pnz,1 ; imposta apertura avvenuta IF SNSPNC EQ 1 ; se i magneti hanno i micro jz pnzor ; pinza aperta ELSE ; altrimenti ci sono i prossimetri jnz pnzor ; pinza aperta ENDIF mov ver_pnz,0 ; imposta apertura fallita pnzor: ret ENDP ; pinzata da magazzino ; ; output: zf = stato della barriera pinzata_mag PROC NEAR mov di,OFFSET ppen ; pinza davanti magazzino lea si,MAG call MT1 call pnz_on ; chiusura pinza mov dx,ttdir ; dir. tapp. (verso mag. opposto) mov al,ttdir_bit call setbit ; verso anteriore cmp word ptr MT1,OFFSET motore1 je pm1 mov dx,ttdir mov al,ttdir_bit call resetbit ; verso posteriore pm1: mov al,ttck_bit ; pinza a riposo con rotazione tappeto or ppck_bit,al lea si,RIP call MT0 mov al,ttck_bit not al and ppck_bit,al call pnz_off ; apertura pinza mov dx,BAR ; controllo barriera in al,dx test al,BAR_BIT ret ENDP ; pinzata da tappeto ; ; output: zf = esito (set -> ok, reset -> si richiede ulteriore pinzata) fibra DW ? totrip DW ? exrip DW ? ind DB ? ; flag di indietreggiamento: ; 0 -> non indietreggiare, 1 -> indietreggiare STEPSIND DW 30 ; passi indietro dopo apertura pinza e prima ; di controllare la fibra su magazzino pinzata_tap PROC NEAR call pnz_on ; chiusura pinza mov dx,ttdir ; dir. tapp. (verso mag.) mov al,ttdir_bit call setbit ; verso anteriore cmp word ptr MT0,OFFSET motore1 je _pt1 mov dx,ttdir mov al,ttdir_bit call resetbit ; verso posteriore _pt1: mov al,ttck_bit ; pinza su mag. con rotazione tappeto or ppck_bit,al mov di,OFFSET ppen lea si,MAG call MT1 mov al,ttck_bit not al and ppck_bit,al cmp ind,5 ; controlla indietreggiamento jb no_ind ; indietreggiamento non attivo mov ax,2 ; attende un po' __pt1: xor cx,cx loop $ dec ax jnz __pt1 call pnz_off ; apertura pinza ; pinza un po' indietro lentamente mov dx,ppdir ; inverte direzione mov al,ppdir_bit call reversebit call ppslow ; bassa velocita' mov cx,STEPSIND ; passi da fare call stepss ; muove call ppfast ; alta velocita' mov ax,2 ; attende un po' ___pt1: xor cx,cx loop $ dec ax jnz ___pt1 mov fibra,0 ; imposta fibra diseccitata mov dx,FBR ; controlla fibra in al,dx test al,FBR_BIT jnz _pt2 ; fibra diseccitata mov fibra,1 ; imposta fibra eccitata jmp _pt2 no_ind: mov fibra,0 ; imposta fibra diseccitata mov dx,FBR ; controlla fibra in al,dx test al,FBR_BIT jnz __pt2 ; fibra diseccitata mov fibra,1 ; imposta fibra eccitata __pt2: call pnz_off ; apertura pinza mov dx,ppdir ; inverte direzione trasporto pinza mov al,ppdir_bit call reversebit ; riporta la pinza in posizione di riposo _pt2: mov totrip,0 ; passi totali mov exrip,0 ; passi extra _pt3: mov dx,ppck ; un passo mov al,ppck_bit call reversebit mov cx,ppstart_vel loop $ inc totrip mov dx,RIP_MCR ; controlla stato di riposo in al,dx and al,RIP_MCR_BIT xor al,RIP_MCR_STAT jnz _pt4 ; stato non raggiunto inc exrip ; controlla passi extra mov ax,exrip cmp ax,RIP_EX jbe _pt5 ; pochi: continua mov cx,WAIT_SNS ; attende stabilita' segnale loop $ in al,dx ; verifica stato di riposo and al,RIP_MCR_BIT xor al,RIP_MCR_STAT jz _ptret ; stato raggiunto _pt4: mov exrip,0 mov ax,totrip ; controlla passi totali cmp ax,RIP_MAX jae _ptret ; troppi: time-out !!! _pt5: mov dx,FBR ; controlla fibra in al,dx test al,FBR_BIT jnz _pt6 ; fibra non eccitata mov fibra,1 ; imposta fibra eccitata jmp _pt3 ; continua _pt6: cmp fibra,0 ; controlla storico fibra je _pt3 ; fibra non eccitata: continua inc fibra ; fibra diseccitata cmp fibra,EX_FIBRA ; da quanto ? jb _pt3 ; da poco: continua _ptret: cmp fibra,0 ; imposta valore di ritorno ret ENDP ; verifica la presenza della cassetta in magazzino ; ; out: cf = esito (set -> negativo, reset -> positivo) STEPSVER EQU 150 STEPSVER1 EQU 300 verifica PROC NEAR mov di,OFFSET ppen ; pinza davanti magazzino lea si,MAG call MT1 call pnz_on ; chiusura pinza ; pinza un po' indietro mov dx,ppdir ; inverte direzione mov al,ppdir_bit call reversebit mov cx,STEPSVER ; passi da fare call stepss ; muove call pnz_off ; apertura pinza mov di,OFFSET ppen ; pinza davanti magazzino lea si,MAG call MT1 and fibra,110b ; imposta fibra eccitata mov dx,FBR ; controlla fibra in al,dx test al,FBR_BIT jz ver0 ; fibra eccitata or fibra,001b ; imposta fibra non eccitata ver0: and fibra,011b ; azzera tentativi ; riporta la pinza un po' indietro ver1: mov dx,ppdir ; inverte direzione mov al,ppdir_bit call reversebit mov cx,STEPSVER1 ; passi da fare call stepss ; muove call pnz_on ; chiusura pinza mov di,OFFSET ppen ; pinza davanti magazzino lea si,MAG call MT1 and fibra,101b ; imposta fibra diseccitata mov dx,FBR ; controlla fibra in al,dx test al,FBR_BIT jnz ver2 ; fibra non eccitata or fibra,010b ; imposta fibra eccitata xor fibra,100b ; incrementa tentativi ver2: call pnz_off ; apertura pinza test fibra,010b ; testa stato fibra jz ver3 ; fibra non eccitata test fibra,100b ; controlla tentativi fatti jnz ver1 ; pochi: riprova stc ; ERRORE: FIBRA ECCITATA !!! jmp verret ver3: test fibra,001b ; testa stato fibra precedente stc jnz verret ; ERRORE: FIBRA NON ECCITATA !!! clc ; ok verret: pushf ; salva esito mov di,OFFSET ppen ; pinza a riposo lea si,RIP call MT0 popf ; recupera esito ret ENDP ; prelievo cassetta da bordo tappeto ; ; output: cf = esito (set = negativo, reset = positivo) inside PROC NEAR mov cx,TNT_INS ; # tentativi jmp SHORT in2 in1: push cx ; pinzata da magazzino call pinzata_mag pop cx in2: push cx ; cassetta in centro tappeto mov di,OFFSET tten lea si,TIN call MT1 pop cx jnc insret ; cassetta in centro loop in1 ; riprova stc ; time-out insret: ret ENDP ; deposito cassetta da bordo tappeto ; ; output: cf = esito (set = time-out, reset = ok) outside PROC NEAR mov cx,TNT_OUT ; contatore tentativi mov ind,0 ; disattiva indietreggiamento _out00: inc ind ; imposta riprova per fibra eccitata _out0: push cx ; salva contatore call pinzata_tap ; pinzata da tappeto pop cx ; recupera contatote mov ah,0 ; imposta esito pinzata positivo jz _out1 ; esito positivo or ah,00000001b ; imposta esito pinzata negativo _out1: mov dx,BAR_ANT ; controlla barriera anteriore in al,dx test al,BAR_ANT_BIT jnz _out2 ; barriera non interrotta or ah,00000010b ; barriera interrotta _out2: mov dx,BAR_POS ; controlla barriera posteriore in al,dx test al,BAR_POS_BIT jnz _out3 ; barriera non interrotta or ah,00000010b ; barriera interrotta _out3: or ah,ah ; controlla esito generale jz _outok dec cx ; controlla tentativi stc jz _outret ; troppi: time-out !!! test ah,00000010b ; controlla stato barriere jz _out00 ; non interrotte: continua push cx ; salva contatore mov di,OFFSET tten ; motore tappeto IF BARGP EQ 0 ; se non ci sono le barriere, mov ax,FBR ; prima eccita una fibra mov tout0,ax mov al,FBR_BIT mov tout0_bit,al mov si,OFFSET tout0 call MT0 ENDIF lea si,TOUT ; tappeto verso esterno call MT0 pop cx ; recupera contatore jmp _out0 ; continua _outok: IF VERPNZ EQ 1 cmp ver_pnz,1 ; controlla pinza aperta clc je _outret ; tutto ok call verifica ; verifica pinza in magazzino ELSE clc ; tutto ok ENDIF _outret: ret ENDP ; preleva la cassetta dal magazzino ; ; output: AL = '0' = tutto ok ; 'G' = cassetta assente o presa fallita ; 'F' = stato errato dopo constatazione cassetta assente ; 'J' = prelievo e deposito falliti ; 'K' = prelievo fallito ma deposito riuscito ; 'I' = stato errato dopo prelievo o deposito riusciti pop PROC NEAR call pinzata_mag ; avvicina la cassetta mov cx,TNT_PMAG ; numero tentativi pop1: push cx call pinzata_mag ; pinza la cassetta pop cx jz pop3 ; barriera eccitata loop pop1 ; riprova call statopinza ; controlla stato gruppo pinza mov al,'F' jc pop2 ; STATO ERRATO !!! IF BARGP EQ 1 jz pop2 ; STATO ERRATO !!! ENDIF mov al,'G' ; CASSETTA ASSENTE !!! pop2: ret pop3: call inside ; porta la cassetta al centro jnc pop5 ; ok call outside ; deposita la cassetta mov al,'J' jc pop4 ; DEPOSITO E PRELIEVO FALLITI !!! call statopinza ; controlla stato pinza mov al,'I' jc pop4 ; STATO ERRATO !!! IF BARGP EQ 1 jz pop4 ; STATO ERRATO !!! ENDIF mov al,'K' ; prelievo fallito ma deposito ok pop4: ret pop5: call statopinza ; controlla stato pinza mov al,'I' jc pop6 ; STATO ERRATO !!! IF BARGP EQ 1 jnz pop6 ; STATO ERRATO !!! ENDIF mov al,'0' ; tutto ok pop6: ret ENDP ; deposita la cassetta in magazzino ; ; output: AL = '0' = tutto ok ; 'S' = stato errato dopo deposito o prelievo riuscito ; 'V' = deposito e prelievo falliti ; 'U' = deposito fallito ma prelievo riuscito push PROC NEAR mov di,OFFSET tten ; motore tappeto IF BARGP EQ 0 ; se non ci sono le barriere, mov ax,FBR ; prima eccita una fibra mov tout0,ax mov al,FBR_BIT mov tout0_bit,al mov si,OFFSET tout0 call MT0 ENDIF lea si,TOUT ; cassetta su bordo tappeto call MT0 call outside ; tenta deposito jc push2 ; deposito non riuscito call statopinza ; controlla stato gruppo pinza mov al,'S' jc push1 ; STATO ERRATO !!! IF BARGP EQ 1 jz push1 ; STATO ERRATO !!! ENDIF mov al,'0' ; tutto ok push1: ret push2: mov cx,TNT_PMAG push22: mov dx,BAR ; controlla barriera in al,dx test al,BAR_BIT jz push222 ; barriera eccitata dec cx ; controlla tentativi mov al,'V' jz push3 ; troppi: DEPOSITO E PRELIEVO FALLITI push cx ; salva contatore call pinzata_mag ; pinzata da magazzino pop cx ; recupera contatore jmp push22 ; ricontrolla push222: call inside ; tenta prelievo mov al,'V' jc push3 ; DEPOSITO E PRELIEVO FALLITI !!! call statopinza ; controlla stato pinza mov al,'S' jc push3 ; STATO ERRATO !!! IF BARGP EQ 1 jnz push3 ; STATO ERRATO !!! ENDIF mov al,'U' ; deposito fallito ma prelievo ok push3: ret ENDP ; preleva/restituisce la cassetta dal/nel magazzino specificato ; ; input: param = 'A' se prelievo/restituzione dal/nel magazzino anteriore ; param = 'P' se prelievo/restituzione dal/nel magazzino posteriore ; ; output: param = codice di errore __vbpick PROC NEAR mov bx,OFFSET pop jmp SHORT prgo __vbplace LABEL NEAR mov bx,OFFSET push prgo: push bp mov bp,OFFSET mt0_ant ; dal/nel magazzino anteriore cmp al,'A' je prg1 mov bp,OFFSET mt0_pos ; dal/nel magazzino posteriore prg1: push bx mov di,OFFSET tten ; abilita motori call motoreon mov di,OFFSET ppen call motoreon pop bx call bx ; preleva/restituisce xor cx,cx ; attesa loop $ push ax ; salva esito mov di,OFFSET ppen ; disattiva motori call motoreoff mov di,OFFSET tten call motoreoff pop ax ; recupera esito pop bp ret ENDP STEPS_ANT DW 200 ; passi in deposito su tappeto STEPST DW 70 ; passi pinza da riposo a tappeto STEPSP DW 70 ; passi pinza da riposo a posteriore MAX_TNT EQU 10 ; tentativi pinzate su tappeto tttstep PROC NEAR ; muove di un passo i tappeti mov dx,ttck ; tick mov al,01100000b call reversebit mov cx,vel ; velocit… loop $ ret ENDP dir0 PROC NEAR ; direzione verso tappeto mov dx,ppdir mov al,ppdir_bit call resetbit ret ENDP dir1 PROC NEAR ; direzione verso posteriore mov dx,ppdir mov al,ppdir_bit call setbit ret ENDP cktton PROC NEAR ; abilita rotazione tappeti con pinza mov al,TCK_BIT or al,ttck_bit or ppck_bit,al ret ENDP ckttoff PROC NEAR ; disabilita tappeti con pinza mov al,TCK_BIT or al,ttck_bit not al and ppck_bit,al ret ENDP stepss PROC NEAR ; cx passi su trasporto mov dx,ppck ; tick mov al,ppck_bit call reversebit push cx ; delay mov cx,ppstart_vel loop $ pop cx loop stepss ; prossimo ret ENDP pnzon PROC NEAR ; chiusura pinza anteriore push bp mov bp,OFFSET mt0_ant call pnz_on pop bp ret ENDP pnzoff PROC NEAR ; apertura pinza anteriore push bp mov bp,OFFSET mt0_ant call pnz_off pop bp ret ENDP pick PROC NEAR ; presa cassetta call dir0 ; direzione verso tappeto mov cx,STEPST ; pinza su tappeto call stepss call pnzon ; chiusura pinza call dir1 ; direzione verso posteriore call cktton ; associa tappeti mov cx,STEPST ; pinza su posteriore add cx,STEPSP call stepss call ckttoff ; dissocia tappeti call pnzoff ; apertura pinza mov di,OFFSET ppen ; pinza a riposo mov si,OFFSET mcr_pos call motore0 ret ENDP place PROC NEAR ; deposito cassetta call dir1 ; direzione verso posteriore mov cx,STEPSP ; pinza su posteriore call stepss call pnzon ; chiusura pinza call dir0 ; direzione verso tappeto call cktton ; associa tappeti mov cx,STEPSP ; pinza su tappeto add cx,STEPST call stepss call ckttoff ; dissocia tappeti call pnzoff ; apertura pinza mov di,OFFSET ppen ; pinza a riposo mov si,OFFSET mcr_ant call motore1 ret ENDP ; preleva la cassetta dal tappeto (casella 0) ; ; output: AL = '0' -> tutto ok ; 'B' -> time-out ; 'I' -> barriera centrale interrotta prima di quella anteriore ; 'i' -> barriera cnt. int. assieme a quella anteriore IF BARGP EQ 0 fbr_stat DB ? ENDIF __vbpicktp PROC NEAR mov di,OFFSET ppen ; abilita tappeti e pinza call motoreon mov dx,TEN mov al,TEN_BIT call resetbit mov di,OFFSET tten call motoreon mov dx,TDIR ; direzione 1 per tappeto p.o. mov al,TDIR_BIT call setbit mov dx,ttdir ; direzione 0 per tappeto pinza mov al,ttdir_bit call resetbit mov ax,VEL_REG ; velocit… di regime mov vel,ax mov t,0 ; # tentativi IF BARGP EQ 0 mov fbr_stat,0 ; attende fibra eccitata ENDIF pt1: mov steps,0 ; passi totali pt2: mov ex,0 ; passi extra pt3: call tttstep ; un passo inc steps mov dx,SNS_CNT ; controllo barriera centrale in al,dx test al,SNS_CNT_BIT jnz pt4 ; barriera non interrotta mov dx,SNS_EST ; controllo barriera esterna in al,dx test al,SNS_EST_BIT jnz pt4 ; barriera non interrotta mov cx,WAIT_SNS ; attende stabilita' loop $ mov dx,SNS_CNT ; verifica barriera centrale in al,dx test al,SNS_CNT_BIT jnz pt4 ; barriera non interrotta mov dx,SNS_EST ; verifica barriera esterna in al,dx test al,SNS_EST_BIT jnz pt4 ; barriera non interrotta mov dx,BAR_ANT ; controllo barriera anteriore in al,dx test al,BAR_ANT_BIT mov al,'I' ; non interrotta jnz ptret mov al,'i' ; interrotta jmp ptret pt4: IF BARGP EQ 1 mov dx,BAR_POS ; controllo barriera posteriore in al,dx test al,BAR_POS_BIT jnz pt5 ; barriera non eccitata ; mov dx,BAR_ANT ; controlla barriera anteriore ; in al,dx ; test al,BAR_ANT_BIT ; jnz pt5 ; barriera non eccitata ELSE mov dx,FBR_ANT ; controlla barriera interna in al,dx and al,FBR_ANT_BIT xor al,fbr_stat jnz pt5 ; barriera non raggiunta ENDIF inc ex ; controllo passi extra mov ax,ex cmp ax,steps_sns_aind jb pt3 ; continua mov cx,WAIT_SNS ; attende stabilita' loop $ IF BARGP EQ 1 mov dx,BAR_POS ; verifica barriera posteriore in al,dx test al,BAR_POS_BIT jnz pt5 ; barriera non eccitata ; mov dx,BAR_ANT ; verifica barriera anteriore ; in al,dx ; test al,BAR_ANT_BIT ; jnz pt5 ; barriera non eccitata ELSE mov dx,FBR_ANT ; verifica barriera interna in al,dx and al,FBR_ANT_BIT xor al,fbr_stat jnz pt5 ; barriera non raggiunta xor fbr_stat,FBR_ANT_BIT ; inverte stato da raggiungere jnz pt1 ; continua ENDIF mov al,'0' ; tutto ok jmp ptret pt5: mov ax,steps cmp ax,max_steps_aind ; controllo passi totali jb pt2 ; continua cmp t,MAX_TNT ; controlla tentativi mov al,'B' jae ptret ; time-out call pick ; pinzata inc t jmp pt1 ; riprova ptret: push ax ; salva esito mov dx,ppen ; disabilita tappeti e pinza mov al,ppen_bit call setbit mov dx,TEN mov al,TEN_BIT call setbit mov di,OFFSET tten call motoreoff pop ax ; recupera esito ret ENDP ; pone la cassetta sul tappeto (casella 0) ; ; output: AL = '0' -> tutto ok ; 'A' -> time-out ; 'B' -> cassetta in tappeto ma ancora visibile da pinza ; 'C' -> cassetta non vista da pinza e neanche in tappeto presente DB ? ; flag di rilevazione passaggio cassetta stato DB ? ; stato attuale barriere ex_pnz DW ? ; passi extra barriere pinza diseccitate ex_cnt DW ? ; passi extra barriera centrale eccitata __vbpltp PROC NEAR mov di,OFFSET ppen ; abilita tappeti e pinza call motoreon mov dx,TEN mov al,TEN_BIT call resetbit mov di,OFFSET tten call motoreon mov dx,TDIR ; direzione 0 per tappeto p.o. mov al,TDIR_BIT call resetbit mov dx,ttdir ; direzione 1 per tappeto pinza mov al,ttdir_bit call setbit mov ax,VEL_REG ; velocit… di regime mov vel,ax mov t,0 ; # tentativi mov presente,000b ; imposta cassetta non vista pl1: mov steps,0 ; passi totali mov ex_pnz,0 ; passi extra mov ex_cnt,0 pl3: call tttstep ; un passo inc steps ; incrementa contatore passi totali ; mov dx,BAR_POS ; controlla barriera posteriore ; in al,dx ; test al,BAR_POS_BIT ; jz pl4 ; barriera interrotta mov dx,BAR_ANT ; controlla barriera anteriore in al,dx test al,BAR_ANT_BIT jz pl4 ; barriera interrotta or stato,001b ; impone: barriere pinza = non interr. inc ex_pnz ; incrementa contatore passi extra ... cmp ex_pnz,500 ; ... limitando l'overflow jbe pl5 dec ex_pnz jmp pl5 pl4: or presente,001b ; impone: cassetta vista da barr. pnz. and stato,110b ; impone: barriere pinza = interr. mov ex_pnz,0 ; azzera contatore passi extra pl5: mov dx,SNS_INT ; controlla barriera interna in al,dx test al,SNS_INT_BIT jz pl6 ; barriera interrotta or stato,010b ; impone: barriera interna = non int. jmp pl7 pl6: or presente,010b ; impone: cassetta vista da barr. int. and stato,101b ; impone: barriera interna interrotta pl7: mov dx,SNS_CNT ; controlla barriera centrale in al,dx test al,SNS_CNT_BIT jz pl8 ; barriera interrotta or stato,100b ; impone: barriera centrale = non int. mov ex_cnt,0 ; azzera contatore passi extra jmp pl9 pl8: or presente,100b ; impone: cassetta vista da barr. cnt. and stato,011b ; impone: barriera centrale = int. inc ex_cnt ; incrementa contatore passi extra ... cmp ex_cnt,20 ; ... evitando l'overflow jbe pl9 dec ex_cnt pl9: test stato,001b ; ceck barriere pinza jnz pl12 ; barriere non interrotte test stato,010b ; ceck barriera interna jz pl10 ; barriera interrotta test presente,010b ; cassetta vista su barr. interna ? jz pl10 ; no: continua test stato,100b ; ceck barriere centrale jnz pl10 ; barriera non interrotta mov al,'B' ; CASSETTA VISIBILE DA TAPP. E PNZ. !! jmp plret pl10: cmp steps,2000 ; controlla passi totali jae pl33 ; troppi jmp pl3 ; pochi: continua pl33: cmp t,MAX_TNT ; controlla tentativi pinzata jb pl11 ; pochi: continua mov al,'A' ; TIME-OUT !!! jmp plret pl11: call place ; pinzata inc t jmp pl1 ; riprova pl12: cmp ex_pnz,500 ; da quanto bar. pnz. non interr. ? jae pl333 ; da molto jmp pl3 ; da poco: continua pl333: test stato,010b ; ceck barriera interna jnz pl13 ; barriera non interrotta test stato,100b ; ceck barriera centrale jnz pl10 ; barriera non interrotta cmp ex_cnt,20 ; da quanto bar. cnt. interrotta ? jae pl13 ; da molto jmp pl3 ; da poco: coninua pl13: IF BARGP EQ 0 ; verifica deposito avvenuto test presente,001b ; cassetta vista su barriere pinza ? jz pl14 ; no: verifica jmp plok ; si: fine pl14: call dir1 ; pinza su mag. post. mov cx,STEPSP call stepss mov ax,3 ; piccola attesa llll1: xor cx,cx loop $ dec ax jnz llll1 mov dx,FBR_ANT ; controlla fibra anteriore in al,dx test al,FBR_ANT_BIT jnz __pl1 ; fibra non eccitata cmp t,MAX_TNT ; controlla tentativi jb __pl0 ; pochi mov di,OFFSET ppen ; pinza a riposo mov si,OFFSET mcr_pos call motore0 mov al,'A' ; time-out !!! jmp plret __pl0: call pnzon ; chiusura pinza call dir0 ; direzione verso tappeto call cktton ; associa tappeti mov cx,STEPSP ; pinza su tappeto add cx,STEPST call stepss call ckttoff ; dissocia tappeti call pnzoff ; apertura pinza mov di,OFFSET ppen ; pinza a riposo mov si,OFFSET mcr_ant call motore1 inc t jmp pl1 ; riprova __pl1: call dir0 ; pinza su tappeto p.o. mov cx,STEPSP add cx,STEPST call stepss mov ax,3 ; piccola attesa llll2: xor cx,cx loop $ dec ax jnz llll2 mov dx,FBR_POS ; controlla fibra posteriore in al,dx test al,FBR_POS_BIT jnz __pl2 ; fibra non eccitata cmp t,MAX_TNT ; controlla tentativi jb __pl00 ; pochi mov di,OFFSET ppen ; pinza a riposo mov si,OFFSET mcr_ant call motore1 mov al,'A' ; time-out !!! jmp plret __pl00: mov di,OFFSET ppen ; pinza a riposo mov si,OFFSET mcr_ant call motore1 call place ; pinzata inc t jmp pl1 ; riprova __pl2: mov di,OFFSET ppen ; pinza a riposo mov si,OFFSET mcr_ant call motore1 test presente,010b ; cassetta vista su barriera interna ? jnz plok ; si: ok cmp t,5 ; controlla tentativi pinzata jb __pl3 mov al,'C' ; CASSETTA ASSENTE O MAI VISTA !!! jmp plret __pl3: call place ; pinzata inc t jmp pl1 ; riprova ENDIF plok: mov al,'0' ; tutto ok plret: push ax ; salva esito mov dx,ppen ; disabilita tappeti e pinza mov al,ppen_bit call setbit mov dx,TEN mov al,TEN_BIT call setbit mov di,OFFSET tten call motoreoff pop ax ; recupera esito ret ENDP COMMENT ~ ; pone la cassetta sul tappeto (casella 0) ; ; output: AL = '0' -> tutto ok ; 'A' -> time-out __vbpltp PROC NEAR mov di,OFFSET ppen ; abilita tappeti e pinza call motoreon mov dx,TEN mov al,TEN_BIT call resetbit mov di,OFFSET tten call motoreon mov dx,TDIR ; direzione 0 per tappeto p.o. mov al,TDIR_BIT call resetbit mov dx,ttdir ; direzione 1 per tappeto pinza mov al,ttdir_bit call setbit mov ax,VEL_REG ; velocit… di regime mov vel,ax mov t,0 ; # tentativi IF BARGP EQ 0 mov fbr_stat,0 ; attesa fibra eccitata mov dx,SNS_INT ; controlla barriera interna in al,dx test al,SNS_INT_BIT jnz pl1 ; barriera non interrotta mov fbr_stat,FBR_ANT_BIT ; barriera interrotta -> attesa fibra diseccitata ENDIF pl1: mov steps,0 ; passi totali pl2: mov ex,0 ; passi extra pl3: call tttstep ; un passo inc steps IF BARGP EQ 1 mov dx,BAR_POS ; controllo bar. pos. in al,dx test al,BAR_POS_BIT jz pl4 ; bar. interrotta mov dx,BAR_ANT ; controllo bar. ant. in al,dx test al,BAR_ANT_BIT jz pl4 ; bar. interrotta ELSE mov dx,FBR_ANT ; controlla fibra anteriore in al,dx and al,FBR_ANT_BIT xor al,fbr_stat jnz pl4 ; fibra non raggiunta cmp fbr_stat,FBR_ANT_BIT ; che stato ? ... je pl44 ; ... fibra diseccitata mov fbr_stat,FBR_ANT_BIT ; attesa fibra diseccitata jmp pl1 ; continua ENDIF pl44: mov dx,SNS_INT ; controlla barriera interna in al,dx test al,SNS_INT_BIT jnz pl4 ; barriera non interrotta mov dx,SNS_CNT ; controlla barriera centrale in al,dx test al,SNS_CNT_BIT jnz pl4 ; barriera non interrotta inc ex ; controllo passi extra mov ax,ex cmp ax,20 ; cmp ax,STEPS_ANT jb pl3 ; continua mov al,'0' ; tutto ok jmp plret pl4: mov ax,steps cmp ax,max_steps_cavt ; controllo passi totali jb pl2 ; continua cmp t,MAX_TNT ; controlla tentativi mov al,'A' jae plret ; time-out call place ; pinzata inc t jmp pl1 ; riprova plret: push ax ; salva esito mov dx,ppen ; disabilita tappeti e pinza mov al,ppen_bit call setbit mov dx,TEN mov al,TEN_BIT call setbit mov di,OFFSET tten call motoreoff pop ax ; recupera esito ret ENDP ~ ;****************************************************************************** ; ; gestione degli LM628 ; ; input: dx = command-port ; ;****************************************************************************** ; LM628 user command set RESET EQU 00h ; reset LM628 PORT8 EQU 05h ; select 8-bit output PORT12 EQU 06h ; select 12-bit output DFH EQU 02h ; define home SIP EQU 03h ; set index position LPEI EQU 1bh ; interrupt on error LPES EQU 1ah ; stop on eror SBPA EQU 20h ; set breakpoint, absolute SBPR EQU 21h ; set breakpoint, relative MSKI EQU 1ch ; mask interrupts RSTI EQU 1dh ; reset interrupts LFIL EQU 1eh ; load filter parameters UDF EQU 04h ; update filter LTRJ EQU 1fh ; load trajectory STT EQU 01h ; start motion RDSIGS EQU 0ch ; read signals register RDIP EQU 09h ; read index position RDDP EQU 08h ; read desired position RDRP EQU 0ah ; read real position RDDV EQU 07h ; read desired velocity RDRV EQU 0bh ; read real velocity RDSUM EQU 0dh ; read integration sum ALL_INT EQU 0000000001111110b ; mask for all interrupts LALL_FIL EQU 00001111b ; loading kp,ki,kd and il data ; trajectory control word bit allocation FWRD EQU 0001000000000000b ; forward direction VMODE EQU 0000100000000000b ; velocity mode STOP EQU 0000010000000000b ; stop smoothly BREAK EQU 0000001000000000b ; stop abruptly OFF EQU 0000000100000000b ; turn off motor LACC EQU 0000000000100000b ; loading acceleration data LVEL EQU 0000000000001000b ; loading velocity data LPOS EQU 0000000000000010b ; loading position data ; status byte bit allocation MT_OFF EQU 10000000b ; motor off BREAKPOINT EQU 01000000b ; breakpoint reached [interrupt] EX_POS_ERR EQU 00100000b ; excessive position error [interrupt] WRAPAROUND EQU 00010000b ; wraparound occurred [interrupt] INDEX_PULSE EQU 00001000b ; index pulse observed [interrupt] TRJ_COMP EQU 00000100b ; trajectory complete [interrupt] CMD_ERROR EQU 00000010b ; command error [interrupt] BUSY_BIT EQU 00000001b ; busy bit ; invia un comando all'LM628 ; ; input: al = comando wrcmd PROC NEAR push ax busy1: in al,dx ; attende che l'LM628 sia disponible test al,BUSY_BIT jnz busy1 inc dx ; prima uno zero sulla data-port xor al,al out dx,al dec dx ; e poi il comando sulla command-port pop ax out dx,al ret ENDP ; invia una word all'LM628 ; ; input: ax = valore wrword PROC NEAR push ax busy2: in al,dx ; attende che l'LM628 sia disponibile test al,BUSY_BIT jnz busy2 inc dx ; data-port pop ax ; prima il byte pi— significativo xchg al,ah out dx,al xchg al,ah ; e poi quello meno significativo out dx,al dec dx ; command-port ret ENDP ; legge una word dall'LM628 ; ; output: ax = valore rdword PROC NEAR in al,dx ; attende che l'LM628 sia disponibile test al,BUSY_BIT jnz rdword inc dx ; data-port in al,dx ; prima il byte pi— significativo mov ah,al in al,dx ; e poi quello meno significativo dec dx ; command-port ret ENDP ; resetta tutte le interruzzioni rsti PROC NEAR mov al,RSTI ; prima il comando di reset call wrcmd mov ax,NOT ALL_INT ; e poi la parola di controllo call wrword ret ENDP ; inizializza l'LM628 ; ; input: ds:di+13 = puntatore ai parametri del filtro DSI EQU [di+14] ; derivative sampling interval KP EQU [di+15] ; proportional term KI EQU [di+17] ; integration term KD EQU [di+19] ; derivative term IL EQU [di+21] ; integration limit WAIT_RESET EQU 0 ; tempo attesa reset MAX_PEI EQU 7fffh ; max. errore di posizione senza stop init628 PROC NEAR ; resetta l'LM628 xor ax,ax ; prima due zeri sulla data-port call wrword mov al,RESET ; poi il comando di reset call wrcmd mov cx,WAIT_RESET ; e quindi attesa loop $ mov al,PORT12 ; seleziona l'output a 12 bits call wrcmd ; massimizza il massimo errore senza stop mov al,LPEI ; prima il comando di caricamento call wrcmd mov ax,MAX_PEI ; e poi il valore effettivo call wrword ; inizializza i parametri del filtro mov al,LFIL ; prima il comando di caricamento call wrcmd mov ah,DSI ; poi la parola di controllo con dsi mov al,LALL_FIL call wrword mov ax,KP ; quindi il dato per kp call wrword mov ax,KI ; quello per ki call wrword mov ax,KD ; quello per kd call wrword mov ax,IL ; e quello per il call wrword mov al,UDF ; ed infine il comando call wrcmd ; di aggiornamento effettivo ; azzera i parametri della traiettoria mov al,LTRJ ; prima il comando di caricamento call wrcmd mov ax,LACC OR LVEL OR LPOS ; poi la parola di controllo call wrword mov cx,6 ; quindi i dati per acc=vel=pos=0 xor ax,ax ini1: call wrword loop ini1 mov al,DFH ; poi il comando per fissare l'origine call wrcmd mov al,STT ; ed infine il comando call wrcmd ; di aggiornamento effettivo ; disabilita tutte le interruzzioni mov al,MSKI ; prima il comando di mascheramento call wrcmd mov ax,NOT ALL_INT ; e poi la parola di controllo call wrword call rsti ; resetta tutte le interruzzini ret ENDP ;****************************************************************************** ; ; gestione degli assi ; ; input: ds:di = puntatore ai parametri dell'asse ; ;****************************************************************************** CMD_PORT EQU [di+0] ; command-port ENABLE EQU [di+2] ; abilitazione asse ENABLE_BIT EQU [di+4] VER_AB EQU [di+5] ; verifica abilitazione VER_AB_BIT EQU [di+7] SNS_1 EQU [di+8] ; sensore 1 SNS_1_BIT EQU [di+10] SNS_2 EQU [di+11] ; sensore 2 SNS_2_BIT EQU [di+13] FILTER EQU [di+14] ; parametri filtro ACC_LOW EQU [di+23] ; accelerazione ACC_HIGH EQU [di+25] SSLOW_LOW EQU [di+27] ; velocit… bassissima SSLOW_HIGH EQU [di+29] SLOW_LOW EQU [di+31] ; bassa velocit… SLOW_HIGH EQU [di+33] FAST_LOW EQU [di+35] ; alta velocit… FAST_HIGH EQU [di+37] POS_LOW EQU [di+39] ; posizione POS_HIGH EQU [di+41] WAIT_1 EQU [di+43] ; attesa raggiunta 1 per origine WAIT_ARR EQU 12 ; tempo attesa arresto effettivo asse ; parametri asse x xport DW 0300h ; command-port xenable DW 0310h ; abilitazione xenable_bit DB 10000000b xab DW 0316h ; verifica abilitazione xab_bit DB 00000010b xsns_1 DW 031Ah ; sensore 1 xsns_1_bit DB 00100000b xsns_2 DW 031Ah ; sensore 2 xsns_2_bit DB 00010000b xdsi DB 0 ; parametri filtro xkp DW 8 xki DW 5 xkd DW 20 xil DW 0 xacc DD 700 ; accelerazione xsslow DD 1000 ; bassissima velocit… xslow DD 20000 ; bassa velocit… xfast DD 150000 ; alta velocit… xpos DW 0,0 ; posizione xwait_1 DW 546 ; attesa raggiunta 1 per origine ; parametri asse z zport DW 0304h ; command-port zenable DW 0310h ; abilitazione zenable_bit DB 01000000b zab DW 0316h ; verifica abilitazione zab_bit DB 00000100b zsns_1 DW 031Ah ; sensore 1 zsns_1_bit DB 00000100b zsns_2 DW 031Ah ; sensore 2 zsns_2_bit DB 00000010b zdsi DB 0 ; parametri filtro zkp DW 8 zki DW 5 zkd DW 20 zil DW 0 zacc DD 120 ; accelerazione zsslow DD 3000 ; bassissima velocit… zslow DD 90000 ; bassa velocit… zfast DD 2750000 ; alta velocit… zpos DW 0,0 ; posizione zwait_1 DW 728 ; attesa raggiunta 1 per origine ; riporta lo stato dell'asse dedotto dalla lettura dei sensori ; ; output: ah = 00000XX0b ; ³³ ; ³ÀÄÄÄ not stato sensore 1 ; ÀÄÄÄÄ not stato sensore 2 assestatus PROC NEAR xor ah,ah mov dx,SNS_1 ; controlla sensore 1 in al,dx test al,SNS_1_BIT jnz as1 ; sensore rilasciato or ah,00000010b ; SENSORE PREMUTO !!! as1: mov dx,SNS_2 ; controlla sensore 2 in al,dx test al,SNS_2_BIT jnz as2 ; sensore rilasciato or ah,00000100b ; SENSORE PREMUTO !!! as2: ret ENDP ; sposta l'asse in modo posizione position PROC NEAR mov dx,CMD_PORT ; command-port mov al,LTRJ ; carica la traiettoria call wrcmd mov ax,LVEL OR LPOS call wrword mov ax,FAST_HIGH ; velocit… call wrword mov ax,FAST_LOW call wrword mov ax,POS_HIGH ; posizione call wrword mov ax,POS_LOW call wrword call rsti ; resetta le interruzzioni mov al,STT ; inizia lo spostamento call wrcmd ret ENDP ; sposta l'asse in modo velocit… forward PROC NEAR ; direzione indietro/basso mov ah,(VMODE OR FWRD) SHR 8 jmp SHORT velocity backward: mov ah,VMODE SHR 8 ; direzione avanti/alto velocity: mov dx,CMD_PORT ; command-port mov al,LTRJ ; carica la traiettoria call wrcmd mov al,LVEL call wrword mov ax,SLOW_HIGH call wrword mov ax,SLOW_LOW call wrword call rsti ; resetta le interruzzioni mov al,STT ; inizia lo spostamento call wrcmd ret ENDP ; attende l'arresto effettivo dell'asse waitarr PROC NEAR mov bx,WAIT_ARR ; attesa arresto wa1: xor cx,cx loop $ dec bx jnz wa1 ret ENDP ; arresta l'asse stop PROC NEAR ; deccelerazione programmata mov ah,STOP SHR 8 jmp SHORT arresto break: mov ah,BREAK SHR 8 ; massima deccelerazione jmp SHORT arresto off: mov ah,OFF SHR 8 ; blocco immediato arresto: mov dx,CMD_PORT ; command-port mov al,LTRJ ; carica la traiettoria call wrcmd xor al,al call wrword call rsti ; resetta le interruzzioni mov al,STT ; inizia arresto call wrcmd arr1: in al,dx ; attende arresto test al,TRJ_COMP jz arr1 call waitarr ; attende arresto effettivo ret ENDP ; resetta l'asse reset PROC NEAR in al,61h ; beep mov cx,500 ll11: xor al,00000010b out 61h,al push cx mov cx,200 loop $ pop cx loop ll11 mov dx,CMD_PORT ; command-port call init628 ; inizializza l'LM628 mov al,LTRJ ; fissa l'accelerazione call wrcmd mov ax,LACC call wrword mov ax,ACC_HIGH call wrword mov ax,ACC_LOW call wrword mov ax,STT call wrcmd call waitarr ; attende arresto asse call waitarr call waitarr ret ENDP ; sposta l'asse dai sensori 1 e 2 ; ; output: carry-flag = reset se tutto ha funzionato a dovere ; carry-flag = set se l'asse Š bloccato o si Š verificato un errore ttt DW ? tnt_nosns DW ? nosns PROC NEAR call assestatus ; legge stato micro ; controlla micro 1 test ah,00000010b ; controlla micro 1 jz ns4 ; micro 1 rilasciato ; sposta l'asse dal micro 1 mov tnt_nosns,0 ; # tentativi fatti ns1: call forward ; inizia spostamento mov ax,time ; registra istante attuale mov ttt,ax ns2: call assestatus ; legge stato micro test ah,00000100b ; controlla micro 2 jnz nsoff ; MICRO 2 PREMUTO !!! mov ax,time ; controlla tempo trascorso sub ax,ttt jnc ns3 neg ax ; evita l'overflow del timer ns3: cmp ax,54 jb ns2 ; tempo inferiore a 3 sec. call stop ; arresta l'asse call assestatus ; legge stato micro test ah,00000100b ; controlla micro 2 jnz nsoff ; MICRO 2 PREMUTO !!! test ah,00000010b ; controlla micro 1 jz nsok ; micro 1 rilasciato inc tnt_nosns ; controlla tentativi cmp tnt_nosns,3 jae nsoff ; troppi: ERRORE !!! call reset ; resetta l'asse jmp ns1 ; riprova ; controlla micro 2 ns4: test ah,00000100b ; controlla micro 2 jz nsok ; micro 2 rilasciato ; sposta l'asse dal micro 2 mov tnt_nosns,0 ; # tentativi fatti ns5: call backward ; inizia spostamento mov ax,time ; registra istante attuale mov ttt,ax ns6: call assestatus ; legge stato micro test ah,00000010b ; controlla micro 1 jnz nsoff ; MICRO 1 PREMUTO !!! mov ax,time ; controlla tempo trascorso sub ax,ttt jnc ns7 neg ax ; evita l'overflow del timer ns7: cmp ax,54 jb ns6 ; tempo inferiore a 3 sec. call stop ; arresta l'asse call assestatus ; legge stato micro test ah,00000010b ; controlla micro 1 jnz nsoff ; MICRO 1 PREMUTO !!! test ah,00000100b ; controlla micro 2 jz nsok ; micro 2 rilasciato inc tnt_nosns ; controlla tentativi cmp tnt_nosns,3 jae nsoff ; troppi: ERRORE !!! call reset ; resetta l'asse jmp ns5 ; riprova nsoff: mov dx,ENABLE ; disabilita l'asse mov al,ENABLE_BIT call setbit call off ; blocca l'asse stc ; ERRORE !!! ret nsok: clc ; tutto ok ret ENDP ; inizializza l'asse ; ; output: carry-flag = reset se tutto ha funzionato a dovere ; carry-flag = set se si Š verificato un errore tt DW ? tnt_init DW ? asseinit PROC NEAR mov dx,ENABLE ; abilita l'asse mov al,ENABLE_BIT call resetbit call reset ; resetta l'asse call nosns ; sposta l'asse dai sensori 1 e 2 jc aierr ; ERRORE !!! ; attende mcr_1 = 1 mov tnt_init,0 ; # tentativi aini1: call backward ; inizia spostamento mov ax,time ; registra istante attuale mov tt,ax aini2: call assestatus ; legge stato micro test ah,00000100b ; controlla micro 2 jnz aierr ; MICRO 2 PREMUTO !!! test ah,00000010b ; controlla micro 1 jnz aini4 ; micro 1 premuto mov ax,time ; controlla tempo trascorso sub ax,tt jnc aini3 neg ax ; evita l'overflow del timer aini3: cmp ax,WAIT_1 jb aini2 call stop ; arresta l'asse call assestatus ; legge stato micro test ah,00000100b ; controlla micro 2 jnz aierr ; MICRO 2 PREMUTO !!! inc tnt_init ; controlla tentativi cmp tnt_init,3 jae aierr ; troppi: ERRORE !!! call reset ; resetta l'asse jmp aini1 ; riprova aierr: mov dx,ENABLE ; toglie l'abilitazione mov al,ENABLE_BIT call setbit call off ; blocca l'asse stc ; ERRORE !!! ret ; attende mcr_1 = 0 aini4: call break ; arresta l'asse push SLOW_HIGH ; salva bassa velocit… push SLOW_LOW mov ax,SSLOW_HIGH ; imposta bassissima velocit… mov SLOW_HIGH,ax mov ax,SSLOW_LOW mov SLOW_LOW,ax mov tnt_init,0 ; # tentativi aini6: call forward ; inizia spostamento mov ax,time ; registra istante attuale mov tt,ax aini7: call assestatus ; legge stato micro test ah,00000100b ; controlla micro 2 jnz _aierr ; MICRO 2 PREMUTO !!! test ah,00000010b ; controlla micro 1 jnz aini8 ; micro 1 premuto mov cx,WAIT_SNS ; attende stabilit… segnale loop $ call assestatus ; legge stato micro test ah,00000100b ; controlla micro 2 jnz _aierr ; MICRO 2 PREMUTO !!! test ah,00000010b ; controlla micro 1 jz aini10 ; micro 1 rilasciato aini8: mov ax,time ; controlla tempo trascorso sub ax,tt jnc aini9 neg ax ; evita l'overflow del timer aini9: cmp ax,182 jb aini7 ; tempo inferiore a 10 sec. call stop ; arresta l'asse call assestatus ; legge stato micro test ah,00000100b ; controlla micro 2 jnz _aierr ; MICRO 2 PREMUTO !!! inc tnt_init ; controlla tentativi cmp tnt_init,3 jae _aierr ; troppi: ERRORE !!! call reset ; resetta l'asse jmp aini6 ; riprova aini10: mov dx,CMD_PORT ; fissa l'origine mov al,DFH call wrcmd pop SLOW_LOW ; recupera bassa velocit… pop SLOW_HIGH call stop ; arresta l'asse clc ; tutto ok ret _aierr: pop SLOW_LOW ; recupera bassa velocit… pop SLOW_HIGH jmp aierr ENDP ; trova la distanza fra i due micro fine-corsa dell'asse ; ; output: DX:AX = valore trovato (0 in caso di errore) assedist PROC NEAR call nosns ; sposta l'asse dai sensori 1 e 2 jc aderr ; ERRORE !!! ; attende mcr_2 = 1 mov tnt_init,0 ; # tentativi adis1: call forward ; inizia spostamento mov ax,time ; registra istante attuale mov tt,ax adis2: call assestatus ; legge stato micro test ah,00000010b ; controlla micro 1 jnz aderr ; MICRO 1 PREMUTO !!! test ah,00000100b ; controlla micro 2 jnz adis4 ; micro 2 premuto mov ax,time ; controlla tempo trascorso sub ax,tt jnc adis3 neg ax ; evita l'overflow del timer adis3: cmp ax,WAIT_1 jb adis2 call stop ; arresta l'asse call assestatus ; legge stato micro test ah,00000010b ; controlla micro 1 jnz aderr ; MICRO 1 PREMUTO !!! inc tnt_init ; controlla tentativi cmp tnt_init,3 jae aderr ; troppi: ERRORE !!! jmp adis1 ; riprova aderr: mov dx,ENABLE ; toglie l'abilitazione mov al,ENABLE_BIT call setbit call off ; blocca l'asse xor ax,ax ; ERRORE !!! xor dx,dx ret ; attende mcr_2 = 0 adis4: call break ; arresta l'asse push SLOW_HIGH ; salva bassa velocit… push SLOW_LOW mov ax,SSLOW_HIGH ; imposta bassissima velocit… mov SLOW_HIGH,ax mov ax,SSLOW_LOW mov SLOW_LOW,ax mov tnt_init,0 ; # tentativi adis6: call backward ; inizia spostamento mov ax,time ; registra istante attuale mov tt,ax adis7: call assestatus ; legge stato micro test ah,00000010b ; controlla micro 1 jnz _aderr ; MICRO 1 PREMUTO !!! test ah,00000100b ; controlla micro 2 jnz adis8 ; micro 2 premuto mov cx,WAIT_SNS ; attende stabilit… segnale loop $ call assestatus ; legge stato micro test ah,00000010b ; controlla micro 1 jnz _aderr ; MICRO 1 PREMUTO !!! test ah,00000100b ; controlla micro 2 jz adis10 ; micro 2 rilasciato adis8: mov ax,time ; controlla tempo trascorso sub ax,tt jnc adis9 neg ax ; evita l'overflow del timer adis9: cmp ax,182 jb adis7 ; tempo inferiore a 10 sec. call stop ; arresta l'asse call assestatus ; legge stato micro test ah,00000010b ; controlla micro 1 jnz _aderr ; MICRO 1 PREMUTO !!! inc tnt_init ; controlla tentativi cmp tnt_init,3 jae _aderr ; troppi: ERRORE !!! jmp adis6 ; riprova adis10: call stop ; arresta l'asse pop SLOW_LOW ; recupera bassa velocit… pop SLOW_HIGH mov dx,CMD_PORT ; legge la posizione attuale mov al,RDRP call wrcmd call rdword push ax call rdword pop dx ; dx = MSW , ax = LSW ret ; tutto ok _aderr: pop SLOW_LOW ; recupera bassa velocit… pop SLOW_HIGH jmp aderr ENDP ; inizializza l'asse X ; ; out: AL = esito ('0' -> ok, 'X' -> errore) __vbinitx PROC NEAR mov di,OFFSET xport ; inizializza call asseinit mov al,'X' ; ERRORE !!! jc ixret mov al,'0' ; ok ixret: ret ENDP ; inizializza l'asse Z ; ; out: AL = esito ('0' -> ok, 'Z' -> errore) __vbinitz PROC NEAR mov di,OFFSET zport ; inizializza call asseinit mov al,'Z' ; ERRORE !!! jc izret mov al,'0' ; ok izret: ret ENDP ; trova la distanza fra i due micro fine-corsa dell'asse X ; ; out: DX:AX = valore trovato (0 in caso di errore) __vbdisx PROC NEAR mov di,OFFSET xport ; imposta asse x call assedist ; trova distanza ret ENDP ; trova la distanza fra i due micro fine-corsa dell'asse Z ; ; out: DX:AX = valore trovato (0 in caso di errore) __vbdisz PROC NEAR mov di,OFFSET zport ; imposta asse z call assedist ; trova distanza ret ENDP ;***************************************************************************** ; ; gestione del posizionamento degli assi ; ; input: DATI.TXT = file con la posizione da raggiungere ; ; output: AL = '0' se tutto ok ; AL = 'I' se pinza in stato errato ; AL = 'F' se errore nel file ; AL = 'P' se errore nello spostamento ; ;****************************************************************************** posfile DB 'DATI.TXT',0 ; file con la posizione time DW ? ; contatori tempo old DW ? old1 DW ? tnt_goto DW ? __vbgotoxz PROC NEAR ; controllo stato pinza call statopinza jnc go1 ; pinza ok mov al,'I' ; PINZA IN STATO ERRATO !!! ret ; lettura posizione da raggiungere go1: mov ax,3d00h ; apertura file DATI.TXT mov dx,OFFSET posfile int 21h jc fileerrret ; APERTURA FALLITA !!! mov bx,ax ; lettura posizione x mov cx,4 mov dx,OFFSET xpos mov ah,3fh int 21h jc fileerr ; LETTURA FALLITA !!! cmp ax,4 jne fileerr ; LETTURA ERRATA !!! mov dx,OFFSET zpos ; lettura posizione z mov ah,3fh int 21h jc fileerr ; LETTURA FALLITA !!! cmp ax,4 jne fileerr ; LETTURA ERRATA !!! mov ah,3eh ; chiusura file int 21h jnc go2 ; chiusura ok fileerr: mov ah,3eh ; chiusura file int 21h fileerrret: mov al,'F' ; ERRORE NEL FILE !!! ret ; inizia traiettoria go2: mov di,OFFSET ppen ; attiva motori pinza call motoreon mov di,OFFSET tten call motoreon mov tnt_goto,0 ; # tentativi posizonamento _go2: mov di,OFFSET xport ; inizia spostamento call position mov di,OFFSET zport call position mov time,0 ; tempo trascorso mov old,0 ; istante ultima lettura posizione ; attende completamento traiettoria e controlla errori gonext: mov ax,time ; istante ultima constatazione assi mov old1,ax ; non in quota gonext1: cmp time,182 ; controlla tempo trascorso con 10 s. jb _gonext1 inc tnt_goto ; controlla tentativi fatti cmp tnt_goto,3 jae goerr ; TIME-OUT: 3 tentativi fatti !!! in al,61h ; beep mov cx,500 ll22: xor al,00000010b out 61h,al push cx mov cx,200 loop $ pop cx loop ll22 jmp _go2 ; riprova _gonext1: ; mov di,OFFSET xport ; controlla fine-corsa x ; call assestatus ; test ah,00000110b ; jz go3 ; fine-corsa rilasciati ; mov cx,8000h ; attende e ricontrolla fine-corsa x ; loop $ ; call assestatus ; test ah,00000110b ; jnz goerr ; FINE-CORSA PREMUTI !!! go3: ; mov di,OFFSET zport ; controlla fine-corsa z ; call assestatus ; test ah,00000110b ; jz go4 ; fine-corsa rilasciati ; mov cx,8000h ; attende e ricontrolla fine-corsa z ; loop $ ; call assestatus ; test ah,00000110b ; jnz goerr ; FINE-CORSA PREMUTI !!! go4: ; mov dx,xport ; controlla status byte LM628 x ; in al,dx ; test al,EX_POS_ERR ; jnz goerr ; EXCESSIVE POSITION ERROR !!! ; mov dx,zport ; controlla status byte LM628 z ; in al,dx ; test al,EX_POS_ERR ; jnz goerr ; EXCESSIVE POSITION ERROE !!! jmp SHORT go5 goerr: mov dx,xenable ; disabilita l'asse x mov al,xenable_bit call setbit mov dx,zenable ; disabilita l'asse z mov al,zenable_bit call setbit mov di,OFFSET xport ; blocca l'asse x call off mov di,OFFSET zport ; blocca l'asse z call off mov al,'P' ; POSIZIONE NON RAGGIUNTA !!! jmp goret go5: mov dx,xport ; controlla status byte LM628 x in al,dx test al,TRJ_COMP jz gonextr ; asse x in movimento mov di,zport ; controlla status byte LM628 z in al,dx test al,TRJ_COMP jz gonextr ; asse z in movimento mov ax,time ; intervalla le operazioni succesive sub ax,old ; di 0.1 secondi cmp ax,2 jb gonext1r mov ax,time ; istante ultima lettura posizione mov old,ax mov dx,xport ; legge posizione x attuale mov al,RDRP call wrcmd call rdword push ax call rdword pop dx ; dx = MSW , ax = LSW add ax,100 ; somma epsilon adc dx,0 cmp dx,xpos[2] ; controlla limite inferiore jl gonextr ; quota non raggiunta jg go6 cmp ax,xpos[0] jbe gonextr ; quota non raggiunta go6: add ax,-200 ; sottrae epsilon adc dx,-1 cmp dx,xpos[2] ; controlla limite superiore jg gonextr ; quota non raggiunta jl go7 ; quota x raggiunta cmp ax,xpos[0] jb go7 ; quota x raggiunta gonextr: jmp gonext gonext1r: jmp gonext1 go7: mov dx,zport ; legge la posizione z attuale mov al,RDRP call wrcmd call rdword push ax call rdword pop dx ; dx = MSW , ax = LSW add ax,400 ; somma epsilon adc dx,0 cmp dx,zpos[2] ; controlla limite inferiore jl gonextr ; quota non raggiunta jg go8 cmp ax,zpos[0] jbe gonextr ; quota non raggiunta go8: add ax,-800 ; sottrae epsilon adc dx,-1 cmp dx,zpos[2] ; controlla limte superiore jg gonextr ; quota non raggiunta jl go9 ; quota z raggiunta cmp ax,zpos[0] jae gonextr ; quota non raggiunta go9: mov ax,time ; controllo tempo assi in quota sub ax,old1 cmp ax,9 jb gonext1r ; tempo inferiore a 0.5 secondi mov al,'0' ; ok goret: push ax ; salva esito mov di,OFFSET ppen ; disattiva motori pinza call motoreoff mov di,OFFSET tten call motoreoff pop ax ; recupera esito ret ENDP ;****************************************************************************** ; ; inizializzazione VIDEOBANK ; ; output: param = '0' se tutto ha funzionato a dovere ; param = 'A' se si Š verificato un errore inizializzando la porta ; param = 'B' se si Š verificato un errore inizializzando la pinza ; param = 'C' se il tappeto Š in stato errato ; param = 'X' se si Š verificato un errore inizializzando l'asse x ; param = 'Z' se si Š verificato un errore inizializzando l'asse z ; ;****************************************************************************** __vbinit PROC NEAR mov dx,0310h ; setta tutte le porta di output mov al,11111111b call setbit mov dx,0312h mov al,11111101b ; (lo Z80 non deve essere resettato) call setbit mov dx,0314h mov al,11111111b call setbit mov dx,0318h mov al,11111111b call setbit mov dx,031Ch mov al,11111111b call setbit call tappstatus ; controlla stato tappeto cmp ah,00000111b je __i1 mov al,'C' ; TAPPETO NON OK !!! ret __i1: call __vbdown ; chiude porta cmp al,'0' je __i2 mov al,'A' ; PORTA NON OK !!! ret ; inizializza gruppo pinza __i2: IF BARGP EQ 0 ; se non ci sono le barriere mov di,OFFSET tten ; controlla presenza cassetta mov tout0,FBR_ANT mov tout0_bit,FBR_ANT_BIT mov si,OFFSET tout0 call motore1 jnc pnzerr ; cassetta presente ENDIF mov di,OFFSET ppen ; preme il micro posteriore mov si,OFFSET mcr_ant mov mcr_ant_stat,0 ; prova 1 volta call motore0 mov mcr_ant_stat,MCR_POS_BIT jnc _i1 ; ok mov mcr_ant_stat,0 ; prova 1 volta call motore0 mov mcr_ant_stat,MCR_POS_BIT jnc _i1 ; ok mov mcr_ant_stat,0 ; prova 1 volta call motore0 mov mcr_ant_stat,MCR_POS_BIT jnc _i1 ; ok pnzerr: mov al,'B' ; PINZA NON OK !!! ret _i1: call statopinza ; completa inizializzazione jc pnzerr ; PINZA NON OK !!! IF BARGP EQ 1 jz pnzerr ; PINZA NON OK !!! ENDIF mov dx,MCR_CNT ; controlla micro centrale in al,dx test al,MCR_CNT_BIT jnz pnzerr ; micro rilasciato mov dx,FBR_ANT ; controlla fibra anteriore in al,dx test al,FBR_ANT_BIT jz pnzerr ; fibra eccitata mov dx,FBR_POS ; controlla fibra posteriore in al,dx test al,FBR_POS_BIT jz pnzerr ; fibra eccitata mov di,OFFSET ppen ; abilita trasporto call motoreon mov di,OFFSET tten ; disattiva tappeto call motoreoff mov di,OFFSET zport ; inizializza asse z call asseinit mov al,'Z' jc initret ; ASSE Z NON OK !!! mov di,OFFSET xport ; inizializza asse x call asseinit mov al,'X' jc initret ; ASSE X NON OK !!! mov di,OFFSET ppen ; disattiva trasporto call motoreoff mov al,'0' ; tutto ok initret: ret ENDP ;****************************************************************************** ; ; VIDEOBANK in errore ; ; output: param = '0' se tutto ha funzionato a dovere ; param = 'A' se la porta non si Š chiusa ; ;****************************************************************************** __vbleave PROC NEAR mov dx,0310h ; setta tutte le porta di output mov al,11111111b call setbit mov dx,0312h mov al,11111101b ; (lo Z80 non deve essere resettato) call setbit mov dx,0314h mov al,11111111b call setbit mov dx,0318h mov al,11111111b call setbit mov dx,031Ch mov al,11111111b call setbit mov di,OFFSET xport ; blocca gli assi call off mov di,OFFSET zport call off call __vbdown ; chiude la porta cmp al,'0' je leaveret ; porta chiusa mov al,'A' ; porta non chiusa leaveret: ret ENDP ; carica i parametri dal file C:\VBL\PARAM.TXT param DB 'C:\VBL\PARAM.TXT',0 ; file con i parametri __lparam PROC NEAR mov ax,3d00h ; apre il file in lettura mov dx,OFFSET param int 21h mov bx,ax mov cx,2 mov ah,3fh mov dx,OFFSET VEL_REG int 21h mov ah,3fh mov dx,OFFSET STEPS_INT int 21h mov ah,3fh mov dx,OFFSET pstart_vel int 21h mov ah,3fh mov dx,OFFSET steps_sns_up int 21h mov ah,3fh mov dx,OFFSET steps_sns_down int 21h mov ah,3fh mov dx,OFFSET ppstart_vel int 21h mov ah,3fh mov dx,OFFSET ttstart_vel int 21h mov ah,3fh mov dx,OFFSET vicino_ant int 21h mov ah,3fh mov dx,OFFSET steps_sns_ravt int 21h mov ah,3fh mov dx,OFFSET steps_sns_ind int 21h mov ah,3fh mov dx,OFFSET steps_sns_aind int 21h mov ah,3fh mov dx,OFFSET steps_sns_cavt int 21h mov ah,3fh mov dx,OFFSET vicino_pos int 21h mov ah,3fh mov dx,OFFSET steps_sns_rind int 21h mov ah,3fh mov dx,OFFSET steps_sns_avt int 21h mov ah,3fh mov dx,OFFSET steps_sns_pavt int 21h mov ah,3fh mov dx,OFFSET steps_sns_cind int 21h mov ah,3fh mov dx,OFFSET STEPS_ANT int 21h mov ah,3fh mov dx,OFFSET STEPST int 21h mov ah,3fh mov dx,OFFSET STEPSP int 21h mov ah,3eh ; chiude il file int 21h mov ax,ppstart_vel mov ppvel,ax mov ax,ttstart_vel mov ttvel,ax ret ENDP ;****************************************************************************** ; ; gestione del lettore di banconote ; ; output: AL = 'G' -> lettore guasto ; 'T' -> time-out attendendo una banconota ; '1' -> tasto ESC premuto ; '2' -> tasto F9 premuto ; 'A' -> banconota da L. 10000 ; 'B' -> banconota da L. 5000 ; 'C' -> banconota da L. 50000 ; ;****************************************************************************** OOO EQU 0314h OOO_BIT EQU 01000000b LBUSY EQU 0314h LBUSY_BIT EQU 00100000b DATA_V EQU 0314h DATA_V_BIT EQU 00000010b DATA_1 EQU 0314h DATA_1_BIT EQU 00000100b DATA_2 EQU 0314h DATA_2_BIT EQU 00001000b DATA_3 EQU 0314h DATA_3_BIT EQU 00010000b BLOCK EQU 0314h BLOCK_BIT EQU 00000010b AUX1 EQU 0318h AUX1_BIT EQU 10000000b AUX2 EQU 0318h AUX2_BIT EQU 00000010b __vbrdban PROC NEAR mov dx,OOO ; controlla stato lettore in al,dx test al,OOO_BIT jnz ban0 ; lettore funzionante mov al,'G' jmp banret ; lettore guasto ban0: mov dx,BLOCK ; abilita ingresso banconote mov al,BLOCK_BIT call resetbit mov time,0 ; registra istante attuale ban1: mov dx,DATA_V ; banconota presente ? in al,dx test al,DATA_V_BIT jnz ban2 ; no: attendi mov cx,8000h ; si: attendi un po' e ... loop $ in al,dx ; verifica banconota presente test al,DATA_V_BIT jnz ban2 ; no: attendi mov dx,DATA_2 ; controlla se banconota da L. 5000 in al,dx test al,DATA_2_BIT mov al,'B' jz ban4 ; L. 5000 mov dx,DATA_3 ; controlla se banconota da L. 10000 in al,dx test al,DATA_3_BIT mov al,'A' jz ban4 ; L. 10000 mov dx,DATA_1 ; controlla se banconota da L. 50000 in al,dx test al,DATA_1_BIT mov al,'C' jz ban4 ; L. 50000 mov al,'G' ; lettore guasto jmp ban4 ban2: mov dx,LBUSY ; controlla busy in al,dx test al,LBUSY_BIT jz ban1 ; lettore occupato mov ah,01h ; controlla buffer tastiera int 16h jz ban3 ; buffer vuoto xor ah,ah ; legge tasto int 16h mov dx,ax cmp dx,ESC_KEY mov al,'1' je ban4 ; tasto ESC cmp dx,F9_KEY mov al,'2' je ban4 ; tasto F9 ban3: cmp time,182 ; controlla tempo trascorso jb ban1 ; continua mov al,'T' ; time-out ban4: push ax ; salva esito mov dx,BLOCK ; disabilita ingresso banconote mov al,BLOCK_BIT call setbit mov dx,LBUSY ; attesa arresto motore ban5: in al,dx test al,LBUSY_BIT jz ban5 ; motore in movimento pop ax ; recupera esito banret: ret ENDP ; riporta in AL lo stato del tunnel ; ; out: bit0 = stato barriera esterna ; bit1 = stato barriere interna e centrale (1->non interrotte,0->almeno 1 interrotta) ; bit2 = stato barriera anteriore ; bit3 = stato barriera posteriore __vbstatus PROC NEAR mov ah,1111b ; imposta barriere non interrotte mov dx,SNS_EST ; controlla barriere esterna in al,dx test al,SNS_EST_BIT jnz __vbst1 ; barriera non interrotta and ah,1110b ; barriera interrotta __vbst1: mov dx,SNS_CNT ; controlla barriere centrale in al,dx test al,SNS_CNT_BIT jnz __vbst2 ; barriera non interrotta and ah,1101b ; barriera interrotta __vbst2: mov dx,SNS_INT ; controlla barriere interna in al,dx test al,SNS_INT_BIT jnz __vbst3 ; barriera non interrotta and ah,1101b ; barriera interrotta __vbst3: mov dx,BAR_ANT ; controlla barriere anteriore in al,dx test al,BAR_ANT_BIT jnz __vbst4 ; barriera non interrotta and ah,1011b ; barriera interrotta __vbst4: mov dx,BAR_POS ; controlla barriere posteriore in al,dx test al,BAR_POS_BIT jnz __vbst5 ; barriera non interrotta and ah,0111b ; barriera interrotta __vbst5: mov al,ah ; ritorna il risultato in AL ret ENDP IF INT8 EQ 1 oldint8 DD ? inint8 DB 0 total DW ? extra DW ? j00: jmp j0 j11: jmp j1 j22: jmp j2 int8 PROC FAR ; push ds ; debug ; push bx ; mov bx,0b800h ; mov ds,bx ; xor bx,bx ; inc word ptr [bx] ; pop bx ; pop ds push ds ; salva DS push cs ; imposta DS=CS pop ds inc time ; aggiorna i contatori inc time1 pushf ; esegue il precedente handler call oldint8 cmp inint8,0 ; si Š gi… in questo handler ? ja j00 ; si: esci !!! ; push ds ; debug ; push bx ; mov bx,0b800h ; mov ds,bx ; mov bx,2 ; inc word ptr [bx] ; pop bx ; pop ds inc inint8 ; registra l'entrata sti ; interrupt ok cmp status,0 ; stato teorico porta ? je j11 ; aperta: esci push ax ; salva i registri usati push bx push cx push dx mov dx,318h ; stato micro inferiore ? in al,dx test al,00100000b jz j5 ; premuto: porta chiusa cmp status,2 ; stato teorico porta ? je j22 ; incastrata: esci IF DOORBCKGRD EQ 0 ; se non c'e' la chiusura in back-ground jmp j4 ; spegni il motore ENDIF mov dx,310h ; abilita motore mov al,00000100b call resetbit mov dx,31ch ; direzione chiusura mov al,01000000b call resetbit mov total,0 ; partenza mov extra,0 j7: mov dx,312h ; un passo mov al,00010000b call reversebit inc total mov cx,pstart_vel ; attesa per velocit… loop $ mov dx,318h ; stato micro inferiore ? in al,dx test al,00100000b jz j6 ; premuto mov extra,0 ; micro rilasciato mov ax,total ; passi fatti ? cmp ax,max_steps_down jb j7 ; pochi: ritenta mov status,2 ; time-out: porta incastrata jmp SHORT j4 ; disabilita ed esci j6: inc extra ; micro premuto mov ax,extra ; stato reale porta ? cmp ax,steps_sns_down jb j7 ; non chiusa: continua mov time1,0 ; porta appena chiusa jmp SHORT j2 ; esci j5: cmp status,2 ; stato teorico porta ? je j3 ; incastrata: sblocca IF DOORBCKGRD EQ 0 ; se non c'e' la chiusura in back-ground jmp j4 ; spegni il motore ENDIF cmp time1,364 ; tempo di disabilitare ? jb j2 ; no: esci dec time1 ; disabilita motore porta j4: mov dx,310h mov al,00000100b call setbit jmp SHORT j2 ; ed esci j3: mov status,1 ; sblocca ed esci mov time1,364 j2: pop dx ; recupera i registri salvati pop cx pop bx pop ax j1: dec inint8 ; registra l'uscita j0: pop ds ; recupera DS iret ENDP ELSE oldint1c DW 2 DUP (?) int1c PROC FAR inc cs:time push cs:[oldint1c+2] push cs:[oldint1c+0] retf ENDP ENDIF int60 PROC FAR sti push bx ; salva registri push cx push dx push si push di push bp push ds push es mov bx,cs mov ds,bx mov es,bx ah1: dec ah jnz ah2 call __vbtapp jmp SHORT intret ah2: dec ah jnz ah3 call __vbesp jmp SHORT intret ah3: dec ah jnz ah4 call __vbdown jmp SHORT intret ah4: dec ah jnz ah5 call __vbup jmp SHORT intret ah5: dec ah jnz ah6 call __vbpick jmp SHORT intret ah6: dec ah jnz ah7 call __vbplace jmp SHORT intret ah7: dec ah jnz ah8 call __vbpicktp jmp SHORT intret ah8: dec ah jnz ah9 call __vbpltp jmp SHORT intret ah9: dec ah jnz ah10 call __vbgotoxz jmp SHORT intret ah10: dec ah jnz ah11 call __vbinit jmp SHORT intret ah11: dec ah jnz ah12 call __vbleave jmp SHORT intret ah12: dec ah jnz ah13 call __lparam jmp SHORT intret ah13: dec ah jnz ah14 call __vbrdban jmp SHORT intret ah14: dec ah jnz ah15 call __vbinitx jmp SHORT intret ah15: dec ah jnz ah16 call __vbinitz intret: pop es ; recupera registri pop ds pop bp pop di pop si pop dx pop cx pop bx iret ah16: dec ah jnz ah17 call __vbdisx jmp SHORT disret ah17: dec ah jnz ah18 call __vbdisz jmp SHORT disret ah18: dec ah jnz ah19 call __vbespp jmp SHORT intret ah19: dec ah jnz ah20 call __vbstatus jmp SHORT intret ah20: disret: pop es ; recupera registri in caso di pop ds ; calcolo distanza micro fine-corsa pop bp ; asse pop di pop si pop cx ; non recupera DX pop cx pop bx iret ENDP fineparteres LABEL BYTE Z80 EQU 0312h ; reset Z80 Z80_BIT EQU 00000010b installa PROC NEAR mov dx,0310h ; setta tutte le porta di output mov al,11111111b call setbit mov dx,0312h mov al,11111101b ; (lo Z80 non deve essere resettato) call setbit mov dx,0314h mov al,11111111b call setbit mov dx,0318h mov al,11111111b call setbit mov dx,031Ch mov al,11111111b call setbit mov ah,9 ; scrive intestazione mov dx,OFFSET sign int 21h IF INT8 EQ 1 mov ax,3508h ; memorizza vecchio int 08h int 21h mov WORD PTR cs:[oldint8+0],bx mov WORD PTR cs:[oldint8+2],es mov ax,2508h ; installa nuovo int 08h push cs pop ds mov dx,OFFSET int8 int 21h ELSE mov ax,351ch ; memorizza vecchio int 1ch int 21h mov cs:[oldint1c+0],bx mov cs:[oldint1c+2],es mov ax,251ch ; installa nuovo int 1ch push cs pop ds mov dx,OFFSET int1c int 21h ENDIF mov ax,2560h ; installa l'interrupt 60h push cs pop ds mov dx,OFFSET int60 int 21h call __lparam ; carica la tabella mov dx,Z80 ; resetta lo Z80 mov al,Z80_BIT call setbit mov time,0 ; registra instante attuale inst1: mov ax,time cmp ax,9 ; tempo trascorso jb inst1 ; poco: attendi mov dx,Z80 ; riattiva lo Z80 mov al,Z80_BIT call resetbit call statopinza ; controlla stato pinza jc noinitassi ; errato ; sposta l'asse z dai micro mov di,OFFSET zport ; imposta asse z mov dx,ENABLE ; abilita mov al,ENABLE_BIT call resetbit call reset ; resetta call nosns ; sposta ; sposta l'asse x dai micro mov di,OFFSET xport ; imposta asse x mov dx,ENABLE ; abilita mov al,ENABLE_BIT call resetbit call reset ; resetta call nosns ; sposta noinitassi: mov di,OFFSET ppen ; spegne motori pinza call motoreoff mov di,OFFSET tten call motoreoff mov es,cs:[2ch] ; libera l'environment mov ah,49h int 21h lea dx,fineparteres ; esce e rimane in memoria int 27h ENDP ENDS END start