A2osX/SYS/PM.VEDRIVE.S.txt

858 lines
18 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
.LIST OFF
.OP 65C02
.OR $2000
* .TF sys/pm/pm.vedrive
.TF sys/pm.vedrive
*--------------------------------------
.INB inc/macros.i
.INB inc/io.i
.INB inc/monitor.i
.INB inc/mli.i
.INB inc/mli.e.i
.INB inc/nic.i
.INB inc/nic.8900a.i
.INB inc/nic.w5100.i
.INB inc/nic.91c96.i
.INB inc/eth.i
.INB inc/net.tcpip.i
.INB inc/net.dhcp.i
*--------------------------------------
ZPPtr1 .EQ $0
ZPPtr2 .EQ $2
len .EQ 4
idx .EQ 5
int .EQ 6
ZPBufPtr .EQ 8
ZPBufCnt .EQ 10
ZPnCnt .EQ 12
ZPCheckSum .EQ 14
timerS .EQ 16
timerC .EQ 17
bRemoteMac .EQ 18
Slotn0 .EQ 19
*--------------------------------------
ADT.CMD.VSD .EQ $C5 "E": Virtual Drive Command Envelope
ADT.CMD.PING .EQ $D9 "Y": PING
DRV.EntryPoint .EQ $BF41
DRV.NIC.START .EQ $D500
*--------------------------------------
CONF.FBUF .EQ $4000
CONF.LBUF .EQ $4400
CONF.FILEPATH .EQ $4500
FRAMEBUF .EQ $4600
*--------------------------------------
VEDRIVE.Init >LDYAI VEDRIVE.MSG0
jsr PrintFYA
jsr VEDRIVE.CheckDRV
bcc .1
>LDYAI VEDRIVE.DRVKO
jsr PrintFYA
rts
.1 jsr VEDRIVE.ReadConf
bcc .2
>LDYAI VEDRIVE.CONFINV
jsr PrintFYA
rts
.2 jsr VEDRIVE.CheckHW
bcc .3
>LDYAI VEDRIVE.NICKO
jsr PrintFYA
rts
.3 jsr VEDRIVE.MACInit
lda CONF.ADDRESS
bne .4
>LDYAI VEDRIVE.DHCP
jsr PrintFYA
jsr VEDRIVE.DHCPReq
bcc .4
>LDYAI VEDRIVE.DHCPKO
jsr PrintFYA
rts
.4 jsr VEDRIVE.IPInit
jsr VEDRIVE.ARPReq
bcc .5
>LDYAI VEDRIVE.IPKO
jsr PrintFYA
rts
.5 ldx #11
.6 lda CONF.ADDRESS,x
pha
dex
bpl .6
>LDYAI VEDRIVE.IPOK
jsr PrintFYA
jsr VEDRIVE.Ping
bcc .7
>LDYAI VEDRIVE.SRVKO
jsr PrintFYA
rts
.7 >LDYAI VEDRIVE.SRVOK
jsr PrintFYA
* jsr VEDRIVE.SetSlot
bcc .8
>LDYAI VEDRIVE.NOSLOT
jsr PrintFYA
rts
.8 pha Push slot
pha 2 times
>LDYAI VEDRIVE.DEVOK
jsr PrintFYA
jsr VEDRIVE.Install
bcc .9
>LDYAI VEDRIVE.DRVIKO
jsr PrintFYA
rts
.9 >LDYAI VEDRIVE.DRVIOK
jsr PrintFYA
rts
*--------------------------------------
VEDRIVE.CheckDRV
ldx #COPYRIGHT.LEN
sec
.1 lda DRV.EntryPoint-1,x
eor COPYRIGHT-1,x
bne .9
dex
bne .1
clc
.9 rts
*--------------------------------------
VEDRIVE.Ping lda CONF.PORT
sta ADT.REQ.UDP.DST
lda CONF.PORT+1
sta ADT.REQ.UDP.DST+1
>LDYAI ADT.REQ
>STYA ZPBufPtr
>LDYAI ADT.REQ.LEN
>STYA ZPBufCnt
jsr VEDRIVE.SendUDP
bcs .9
jsr VEDRIVE.InitTimer
.3 jsr VEDRIVE.READ
bcc .4
jsr VEDRIVE.Wait
bcc .3
rts
.4 jsr VEDRIVE.CheckADTRep
bcc .8
jsr VEDRIVE.CheckARPFrame
bra .3
.8
* clc
.9 rts
*--------------------------------------
VEDRIVE.CheckHW ldx CONF.NIC
jmp (.1,x)
.1 .DA GS.Init
.DA U1.Init
.DA U2.Init
*--------------------------------------
VEDRIVE.SendUDP jsr VEDRIVE.IPChecksum
jsr VEDRIVE.UDPChecksum
VEDRIVE.SendARP ldx CONF.NIC
jmp (.1,x)
.1 .DA U1.WRITE
.DA U1.WRITE
.DA U2.WRITE
*--------------------------------------
VEDRIVE.READ >LDYAI FRAMEBUF
>STYA ZPBufPtr
ldx CONF.NIC
jmp (.1,x)
.1 .DA U1.READ
.DA U1.READ
.DA U2.READ
*--------------------------------------
VEDRIVE.InitTimer
lda VBL
sta timerS
stz timerC
rts
*--------------------------------------
VEDRIVE.Wait lda VBL
tax
eor timerS
bpl .8
stx timerS
dec timerC
bne .8
sec
rts
.8 clc
rts
*--------------------------------------
* Find 2 free slots in DEVPTRS (D1 & D2)
*--------------------------------------
VEDRIVE.SetSlot ldx #2 Starts at Slot1
.1 lda DEVPTRS,x Drive1
cmp DEVPTRS pointing to S0D1 NODEV ?
bne .2
lda DEVPTRS+1,x
cmp DEVPTRS+1
bne .2
lda DEVPTRS+16,x Drive2
cmp DEVPTRS
bne .2
lda DEVPTRS+17,x
cmp DEVPTRS+1
bne .2
lda #DRV.EntryPoint
sta DEVPTRS,x
sta DEVPTRS+16,x
lda /DRV.EntryPoint
sta DEVPTRS+1,x
sta DEVPTRS+17,x
txa
asl
asl
asl
ora #$0D
ldy DEVCNT
iny
sta DEVLST,y add Drv1
ora #$80
iny
sta DEVLST,y add Drv2
sty DEVCNT
txa
lsr exit with A=SLOT
clc
rts
.2 inx
inx
cpx #16
bne .1
rts sec from CPX
*--------------------------------------
VEDRIVE.Install ldx #PATCH.SIZE
*.1 lda PATCH-1,x
* sta DRV.EntryPoint-1,x
* dex
* bne .1
bit RRAMWRAMBNK2
bit RRAMWRAMBNK2
ldy #DRV.SIZE-1
.2 lda DRV,y
sta DRV.START,y
dey
bne .2
lda Slotn0
sta DRV.START
ldy #DRV.IP.SIZE-1
.3 lda DRV.IP,y
sta DRV.IP.START,y
dey
bne .3
ldx CONF.NIC
lda .10,x
sta ZPPtr1
lda .10+1,x
sta ZPPtr1+1
lda .20,x
eor #$ff
sta ZPnCnt
lda .20+1,x
eor #$ff
sta ZPnCnt+1
lda #DRV.NIC.START
sta ZPPtr2
lda /DRV.NIC.START
sta ZPPtr2+1
ldy #0
.4 inc ZPnCnt
bne .5
inc ZPnCnt+1
beq .6
.5 lda (ZPPtr1),y
sta (ZPPtr2),y
iny
bne .4
inc ZPPtr1+1
inc ZPPtr2+1
bra .4
.6 ldy #S.UDP
.7 lda ADT.REQ-1,y
sta DRV.OutBuf-1,y
dey
bne .7
bit RROMBNK1
clc
rts
*--------------------------------------
.10 .DA DRV.U2
.DA DRV.U2
.DA DRV.U2
*--------------------------------------
.20 .DA DRV.U2.SIZE
.DA DRV.U2.SIZE
.DA DRV.U2.SIZE
*--------------------------------------
.INB usr/src/shared/x.printf.s
*--------------------------------------
* ProDOS $BE41->$BE4B Patch for switching to BANK2 (10 bytes)
*--------------------------------------
COPYRIGHT .AS "(C)APPLE "
COPYRIGHT.LEN .EQ *-COPYRIGHT
PATCH .PH DRV.EntryPoint
bit RRAMWRAMBNK2
jsr $D002
bit RRAMWRAMBNK1
rts
.EP
PATCH.SIZE .EQ *-PATCH
*--------------------------------------
* Drivers
*--------------------------------------
* OP = 2 : Write drv1
* OP = 3 : Read drv1
* OP = 4 : Write drv2
* OP = 5 : Read drv2
* CMD = $C5+OP+BLKLO+BLKHI+CHKSUM
* DO NOT trash DRV.COMMAND...DRV.BLKNUM as ProDOS
* reuses them after Block operation
* A1,A2 are used by Disk II Driver,
* so we use it safely as Tmp Ptr
*--------------------------------------
DRV.A1L .EQ $3C
DRV.A1H .EQ $3D
DRV.A2L .EQ $3E
DRV.A2H .EQ $3F
DRV.COMMAND .EQ $42
DRV.UNITNUM .EQ $43
DRV.BUFF .EQ $44
DRV.BLKNUM .EQ $46
*--------------------------------------
DRV.Write .EQ DRV.NIC.START
DRV.Read .EQ DRV.NIC.START+3
*--------------------------------------
DRV.OutBuf .EQ $D800-S.UDP-6 Frame Buffer = S.UDP+5+512+1 bytes
DRV.OutBuf.Env .EQ DRV.OutBuf+S.UDP
DRV.OutBuf.Cmd .EQ DRV.OutBuf+S.UDP+1
DRV.OutBuf.BlkL .EQ DRV.OutBuf+S.UDP+2
DRV.OutBuf.BlkH .EQ DRV.OutBuf+S.UDP+3
DRV.OutBuf.Sum .EQ DRV.OutBuf+S.UDP+4
DRV.OutBuf.Data .EQ DRV.OutBuf+S.UDP+5
*--------------------------------------
DRV.InBuf .EQ $DA00 Frame Buffer = 1536 bytes
*--------------------------------------
DRV .PH $D001 Main LC Bnk 2 $D001->$DFFF
DRV.START .BS 1 SELF MODIFIED slot 0n
lda DRV.COMMAND S=0,R=1,W=2,F=3
bne .1
ldx #$ff return Status
ldy #$ff
.8 lda #0
clc
rts
.1 cmp #3
beq .8 Format ....
bcs DRV.DO.CMD.ERR more....IO error
ora #2 W=2,R=3
ldy DRV.UNITNUM
bpl .2
adc #2 CC from bcs
.2 sta DRV.OutBuf.Cmd store cmd
eor #ADT.CMD.VSD
eor DRV.BLKNUM
eor DRV.BLKNUM+1
sta DRV.OutBuf.Sum Compute & store CheckSum
lda DRV.BLKNUM
sta DRV.OutBuf.BlkL
lda DRV.BLKNUM+1
sta DRV.OutBuf.BlkH
*--------------------------------------
lda DRV.COMMAND
dec 1-1=0 if read
bne DRV.DO.CMD.W go write
*--------------------------------------
* Read block
*--------------------------------------
DRV.DO.CMD.R ldy #S.UDP+5
lda /S.UDP+5
jsr DRV.Write
DRV.DO.CMD.ERR
lda #MLI.E.IO
sec
rts
*--------------------------------------
* Write Block
*--------------------------------------
DRV.DO.CMD.W lda #$B1 lda (),y
lda #MLI.E.IO
sec
rts
*--------------------------------------
DRV.RWBYTE bit RRAMWRAMBNK1
sta (DRV.BUFF),y
bit RRAMWRAMBNK2
rts
*--------------------------------------
.EP
*--------------------------------------
.LIST ON
DRV.SIZE .EQ *-DRV
.LIST OFF
*--------------------------------------
DRV.IP .PH $D400
DRV.IP.START ldy #S.IP.TOTAL.LENGTH+1
lda ZPBufCnt
sec
sbc #S.ETH.EII
sta (ZPBufPtr),y
dey
lda ZPBufCnt+1
sbc /S.ETH.EII
sta (ZPBufPtr),y
lda #0
ldy #S.IP.HDR.CHECKSUM
sta (ZPBufPtr),y
iny
sta (ZPBufPtr),y
stz ZPCheckSum RESET IP CHECKSUM
stz ZPCheckSum+1
clc
ldy #S.IP.V.IHL
ldx #10 10 words for IP Header
.1 lda (ZPBufPtr),y
adc ZPCheckSum
sta ZPCheckSum
iny
lda (ZPBufPtr),y
adc ZPCheckSum+1
sta ZPCheckSum+1
iny
dex
bne .1
ldy #S.IP.HDR.CHECKSUM
lda ZPCheckSum
adc #0
eor #$FF
sta (ZPBufPtr),y
iny
lda ZPCheckSum+1
adc #0
eor #$FF
sta (ZPBufPtr),y
rts
*--------------------------------------
clc
ldy #S.UDP.LENGTH+1
lda (ZPBufPtr),y
adc #S.IP.PROTOCOL.UDP
sta ZPCheckSum+1
dey
lda (ZPBufPtr),y
adc /S.IP.PROTOCOL.UDP (all zero)
sta ZPCheckSum
ldy #S.IP.SRC
ldx #4 4 words for SRC & DST IP
.2 lda (ZPBufPtr),y
adc ZPCheckSum
sta ZPCheckSum
iny
lda (ZPBufPtr),y
adc ZPCheckSum+1
sta ZPCheckSum+1
iny
dex
bne .2
ldy #S.UDP.LENGTH+1
lda (ZPBufPtr),y
eor #$ff
tax
dey
lda (ZPBufPtr),y
eor #$ff
ldy #S.UDP.CHECKSUM
phy Save Offset
pha Save !ByteCount.HI
lda #0 Reset Checksum
sta (ZPBufPtr),y
iny
sta (ZPBufPtr),y
>LDYA ZPBufPtr
>STYA ZPPtr1
ldy #S.IP
.3 inx
bne .4
pla
inc
beq .8
pha
.4 lda (ZPPtr1),y
adc ZPCheckSum
sta ZPCheckSum
iny
bne .5
inc ZPPtr1+1
.5 inx
bne .6
pla
inc
beq .7
pha
.6 lda (ZPPtr1),y
adc ZPCheckSum+1
sta ZPCheckSum+1
iny
bne .3
inc ZPPtr1+1
bra .3
.7 adc ZPCheckSum+1 A=0 from beq .7
sta ZPCheckSum+1
.8 ply
lda ZPCheckSum
adc #0 Don't forget to add last carry!!!
eor #$FF
sta (ZPBufPtr),y
iny
lda ZPCheckSum+1
adc #0 Don't forget to add last carry!!!
eor #$FF
sta (ZPBufPtr),y
rts
*--------------------------------------
.EP
*--------------------------------------
.LIST ON
DRV.IP.SIZE .EQ *-DRV.IP
.LIST OFF
*--------------------------------------
* CONTROL SECTION :
*--------------------------------------
.DO DRV.SIZE>255
ERROR:DRV.SIZE too big
.FIN
*--------------------------------------
*--------------------------------------
.INB usr/src/sys/pm.vedrive.s.cf
.INB usr/src/sys/pm.vedrive.s.ip
.INB usr/src/sys/pm.vedrive.s.u1
.INB usr/src/sys/pm.vedrive.s.u2
.INB usr/src/sys/pm.vedrive.s.gs
*--------------------------------------
VEDRIVE.MSG0 .AZ "VEDRIVE (ADTPro Virtual Ethernet HD) Driver\n"
VEDRIVE.DRVKO .AZ "VEDRIVE (Or other custom Driver) Already Installed.\n"
VEDRIVE.CONF .AZ "Checking %S...\n"
VEDRIVE.CONFKO .AZ "Error reading VEDRIVE.CONF file.\n"
VEDRIVE.CONFSYN .AZ "Syntax error in VEDRIVE.CONF file.\n"
VEDRIVE.CONFINV .AZ "Invalid VEDRIVE.CONF file.\n"
VEDRIVE.NICKO .AZ "Hardware not detected.\n"
VEDRIVE.NICOK .AZ "%S Rev. %d.%d Found At Slot %d.\n"
VEDRIVE.DHCP .AZ "Querying DHCP...\n"
VEDRIVE.DHCPKO .AZ "No response from DHCP.\n"
VEDRIVE.IPKO .AZ "Unable to setup IP configuration.\n"
VEDRIVE.IPOK .AZ "IP config : %d.%d.%d.%d/%d.%d.%d.%d GW=%d.%d.%d.%d\n"
VEDRIVE.SRV .AZ "Contacting ADTPro Server..."
VEDRIVE.SRVKO .AZ "No Response From ADTPro Server.\n"
VEDRIVE.SRVOK .AZ "ADTPro Server Is Online.\n"
VEDRIVE.NOSLOT .AZ "No ProDOS device slot available.\n"
VEDRIVE.DEVOK .AZ "VEDRIVE Installed 2 devices at S%d,D1 & S%d,D2.\n"
VEDRIVE.DRVIKO .AZ "Unable to install VEDRIVE.\n"
VEDRIVE.DRVIOK .AZ "VEDRIVE Successfully Installed.\n"
*--------------------------------------
CONF.FILENAME .AS "vedrive.conf"
CONF.FILENAME.L .EQ *-CONF.FILENAME
*--------------------------------------
CONF.KW >PSTR "nic"
>PSTR "slot"
>PSTR "address"
>PSTR "netmask"
>PSTR "gateway"
>PSTR "server"
>PSTR "port"
.HS 00
*--------------------------------------
CONF.KW.NIC >PSTR "lancegs"
>PSTR "uthernet"
>PSTR "uthernet2"
.HS 00
*--------------------------------------
CONF.NIC .HS FF
CONF.SLOT .HS 00
CONF.IPCFG .EQ *
CONF.SRCMAC .HS 000E3A123456
CONF.ADDRESS .HS 00000000
CONF.MASK .HS 00000000
CONF.GATEWAY .HS 00000000
CONF.SERVER .HS 00000000
CONF.PORT .DA /1977,#1977
*--------------------------------------
MLIGETPREFIX.P .DA #1
.DA CONF.FILEPATH
*--------------------------------------
MLIOPEN.P .DA #3
.DA CONF.FILEPATH
.DA CONF.FBUF
.BS 1 FILE#
*--------------------------------------
MLINEWLINE.P .DA #3
.BS 1
.DA #$7F
.DA #$0D
*--------------------------------------
MLIREAD.P .DA #4
.BS 1
.DA CONF.LBUF
.DA 255
.BS 2
*--------------------------------------
MLICLOSE.P .DA #1
.BS 1
*--------------------------------------
ARP.REQ .HS FFFFFFFFFFFF S.ETH.DSTMAC
ARP.REQ.SRCMAC .BS 6
ARP.REQ.ETYPE .DA /S.ETH.EII.TYPE.ARP
.DA #S.ETH.EII.TYPE.ARP
.HS 0001.0800.06.04
ARP.REQ.OP .DA /S.ARP.OPERATION.REQ
.DA #S.ARP.OPERATION.REQ
ARP.REQ.SHA .BS 6
ARP.REQ.SPA .BS 4
ARP.REQ.THA .BS 6
ARP.REQ.TPA .BS 4
*--------------------------------------
ARP.REP .EQ *
ARP.REP.DSTMAC .BS 6
ARP.REP.SRCMAC .BS 6
ARP.REP.ETYPE .DA /S.ETH.EII.TYPE.ARP
.DA #S.ETH.EII.TYPE.ARP
.HS 0001.0800.06.04
ARP.REP.OP .DA /S.ARP.OPERATION.REP
.DA #S.ARP.OPERATION.REP
ARP.REP.SHA .BS 6
ARP.REP.SPA .BS 4
ARP.REP.THA .BS 6
ARP.REP.TPA .BS 4
*--------------------------------------
DHCP.DISC .HS FFFFFFFFFFFF DST MAC
DHCP.DISC.SRCMAC .BS 6
.DA /S.ETH.EII.TYPE.IP
.DA #S.ETH.EII.TYPE.IP
DHCP.DISC.IP .HS 4500
.DA /DHCP.DISC.END-DHCP.DISC.IP,#DHCP.DISC.END-DHCP.DISC.IP
.HS 0000
.HS 0000
.DA #64 TTL
.DA #S.IP.PROTOCOL.UDP
.BS 2 IP CHECKSUM
.HS 00000000
.HS FFFFFFFF
*--------------------------------------
DHCP.DISC.UDP .DA #0,#UDP.PORT.DHCPC
.DA #0,#UDP.PORT.DHCPS
.DA /DHCP.DISC.END-DHCP.DISC.UDP,#DHCP.DISC.END-DHCP.DISC.UDP
.BS 2 UDP CHECKSUM
*--------------------------------------
.HS 01010600 OP,HTYPE,HLEN,HOPS
DHCP.DISC.XID .HS 54328574
.HS 0000 SECS
.DA S.DHCP.FLAGS.BRDCST
.HS 00000000 CIADDR
DHCP.DISC.YIADDR .HS 00000000
.HS 00000000 SIADDR
DHCP.DISC.GIADDR .HS 00000000
DHCP.DISC.CHADDR .HS 00000000.00000000.00000000.00000000
.BS 64 SNAME
.BS 128 FILE
.HS 63825363 COOKIE
.HS 3501 OPT
.DA #S.DHCP.OPTIONS.DHCPDiscover
.HS 37020103FF 37040103060FFF
DHCP.DISC.END .EQ *
DHCP.DISC.LEN .EQ *-DHCP.DISC
*--------------------------------------
DHCP.REQ .HS FFFFFFFFFFFF DST MAC
DHCP.REQ.SRCMAC .BS 6
.DA /S.ETH.EII.TYPE.IP
.DA #S.ETH.EII.TYPE.IP
DHCP.REQ.IP .HS 4500
.DA /DHCP.REQ.END-DHCP.REQ.IP,#DHCP.REQ.END-DHCP.REQ.IP
.HS 0000
.HS 0000
.DA #64 TTL
.DA #S.IP.PROTOCOL.UDP
.BS 2 IP CHECKSUM
.HS 00000000
.HS FFFFFFFF
*--------------------------------------
DHCP.REQ.UDP .DA #0,#UDP.PORT.DHCPC
.DA #0,#UDP.PORT.DHCPS
.DA /DHCP.REQ.END-DHCP.REQ.UDP,#DHCP.REQ.END-DHCP.REQ.UDP
.BS 2 UDP CHECKSUM
*--------------------------------------
.HS 01010600 OP,HTYPE,HLEN,HOPS
DHCP.REQ.XID .HS 54328574
.HS 0000 SECS
.DA S.DHCP.FLAGS.BRDCST
.HS 00000000 CIADDR
DHCP.REQ.YIADDR .HS 00000000
.HS 00000000 SIADDR
.HS 00000000 GIADDR
DHCP.REQ.CHADDR .HS 00000000.00000000.00000000.00000000
.BS 64 SNAME
.BS 128 FILE
.HS 63825363 COOKIE
.HS 3501 OPT
.DA #S.DHCP.OPTIONS.DHCPRequest
.HS 3204
DHCP.REQ.OPT.REQIP .BS 4
.HS 3604
DHCP.REQ.OPT.SVRIP .BS 4
.HS FF
DHCP.REQ.END .EQ *
DHCP.REQ.LEN .EQ *-DHCP.REQ
*--------------------------------------
ADT.REQ
ADT.REQ.DSTMAC .BS 6 DST MAC
ADT.REQ.SRCMAC .BS 6
.DA /S.ETH.EII.TYPE.IP
.DA #S.ETH.EII.TYPE.IP
ADT.REQ.IP .HS 4500
.DA /ADT.REQ.END-ADT.REQ.IP,#ADT.REQ.END-ADT.REQ.IP
.HS 0000
.HS 0000
.DA #64 TTL
.DA #S.IP.PROTOCOL.UDP
.BS 2 IP CHECKSUM
ADT.REQ.IP.SRC .BS 4 SRC IP
ADT.REQ.IP.DST .BS 4 DST IP
*--------------------------------------
ADT.REQ.UDP .DA #$C0,#$00 SRC PORT
ADT.REQ.UDP.DST .BS 2 DST PORT
.DA /ADT.REQ.END-ADT.REQ.UDP,#ADT.REQ.END-ADT.REQ.UDP
.BS 2 UDP CHECKSUM
*--------------------------------------
.DA #ADT.CMD.VSD
.HS 030000C6 READ D1, BLK 0
ADT.REQ.END .EQ *
ADT.REQ.LEN .EQ *-ADT.REQ
*--------------------------------------
MAN
SAVE usr/src/sys/pm.vedrive.s
ASM