;******************************************************************************
; 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