diff --git a/FileServer/Binary Files/FS3-131 b/FileServer/Binary Files/FS3-131 new file mode 100644 index 0000000..9a54d2c Binary files /dev/null and b/FileServer/Binary Files/FS3-131 differ diff --git a/FileServer/Binary Files/FS3-131.inf b/FileServer/Binary Files/FS3-131.inf new file mode 100644 index 0000000..3770229 --- /dev/null +++ b/FileServer/Binary Files/FS3-131.inf @@ -0,0 +1 @@ +$.FS3-131 00000400 00000400 diff --git a/FileServer/Binary Files/FS3-131d b/FileServer/Binary Files/FS3-131d new file mode 100644 index 0000000..457492b Binary files /dev/null and b/FileServer/Binary Files/FS3-131d differ diff --git a/FileServer/Binary Files/FS3-131d.inf b/FileServer/Binary Files/FS3-131d.inf new file mode 100644 index 0000000..a073563 --- /dev/null +++ b/FileServer/Binary Files/FS3-131d.inf @@ -0,0 +1 @@ +$.FS3-131d 00000400 00000400 diff --git a/FileServer/Binary Files/FS3-131dp b/FileServer/Binary Files/FS3-131dp new file mode 100644 index 0000000..f651a38 Binary files /dev/null and b/FileServer/Binary Files/FS3-131dp differ diff --git a/FileServer/Binary Files/FS3-131dp.inf b/FileServer/Binary Files/FS3-131dp.inf new file mode 100644 index 0000000..2535c9f --- /dev/null +++ b/FileServer/Binary Files/FS3-131dp.inf @@ -0,0 +1 @@ +$.FS3-131dp 00000400 00000400 diff --git a/FileServer/Binary Files/FS3-131p b/FileServer/Binary Files/FS3-131p new file mode 100644 index 0000000..720f918 Binary files /dev/null and b/FileServer/Binary Files/FS3-131p differ diff --git a/FileServer/Binary Files/FS3-131p.inf b/FileServer/Binary Files/FS3-131p.inf new file mode 100644 index 0000000..4a172bb --- /dev/null +++ b/FileServer/Binary Files/FS3-131p.inf @@ -0,0 +1 @@ +$.FS3-131p 00000400 00000400 diff --git a/FileServer/Binary Files/FSR-131 b/FileServer/Binary Files/FSR-131 new file mode 100644 index 0000000..008c927 Binary files /dev/null and b/FileServer/Binary Files/FSR-131 differ diff --git a/FileServer/Binary Files/FSR-131p b/FileServer/Binary Files/FSR-131p new file mode 100644 index 0000000..7505561 Binary files /dev/null and b/FileServer/Binary Files/FSR-131p differ diff --git a/FileServer/SRC/!BOOT b/FileServer/SRC/!BOOT new file mode 100644 index 0000000..965dfa5 --- /dev/null +++ b/FileServer/SRC/!BOOT @@ -0,0 +1 @@ +MODE0 *DIR $ *LIB $.LIBRARY *CB CH."START" \ No newline at end of file diff --git a/FileServer/SRC/!BOOT.INF b/FileServer/SRC/!BOOT.INF new file mode 100644 index 0000000..1fd3d8a --- /dev/null +++ b/FileServer/SRC/!BOOT.INF @@ -0,0 +1 @@ +$.!BOOT 00000000 00000000 0000002B 19 A242 060E14 A155 2B1715 diff --git a/FileServer/SRC/FSASM b/FileServer/SRC/FSASM new file mode 100644 index 0000000..91fa0fe --- /dev/null +++ b/FileServer/SRC/FSASM @@ -0,0 +1 @@ +*|Assembly sequence for FileStore FS > FSAsm *|By Jes 3/9/84, Updated by Glenn 8/5/85 *|Updated by Mark Usher 7/4/21 *DIR $.FileServer *LIB $.LIBRARY *TurMasm *OPT 1 1 STOP ON ASM FileStore *CB CH."$.FSmake" \ No newline at end of file diff --git a/FileServer/SRC/FSASM.inf b/FileServer/SRC/FSASM.inf new file mode 100644 index 0000000..03fd71e --- /dev/null +++ b/FileServer/SRC/FSASM.inf @@ -0,0 +1 @@ +$.FSASM 00000000 00000000 000000D2 19 A548 101D0B A24D 331317 diff --git a/FileServer/SRC/FSmake b/FileServer/SRC/FSmake new file mode 100644 index 0000000..7651895 Binary files /dev/null and b/FileServer/SRC/FSmake differ diff --git a/FileServer/SRC/FSmake.inf b/FileServer/SRC/FSmake.inf new file mode 100644 index 0000000..b03e82e --- /dev/null +++ b/FileServer/SRC/FSmake.inf @@ -0,0 +1 @@ +$.FSmake 00000800 0000B823 00000674 33 A54C 193A12 A24D 331317 diff --git a/FileServer/SRC/FileServer/FileStore b/FileServer/SRC/FileServer/FileStore new file mode 100644 index 0000000..0f7840f --- /dev/null +++ b/FileServer/SRC/FileServer/FileStore @@ -0,0 +1,14 @@ + OPT 2 ;> .FileStore + TTL File server. Initial variable setup for FileStore variant. + + ORG &200 + + GBLL $Level3 + GBLL $CMOS + +$Level3 SETL 1=0 ; False +$CMOS SETL 1=1 ; True + + CPU 1 + + LNK Uade01 diff --git a/FileStore/SRC/FileStore/Form00.6502 b/FileServer/SRC/FileServer/Form00 similarity index 86% rename from FileStore/SRC/FileStore/Form00.6502 rename to FileServer/SRC/FileServer/Form00 index 79b757b..cf50d27 100644 --- a/FileStore/SRC/FileStore/Form00.6502 +++ b/FileServer/SRC/FileServer/Form00 @@ -1,6 +1,8 @@ OPT Form00 ;File > Form00 TTL File server file FORM00 + [ $CMOS ; whole file is Filestore only + ;********** ;* FORMAT * ;********** @@ -13,38 +15,17 @@ Fgpptr * Mpmbpt Fgprpt * Mapent FMform ROUT - JSR SPACES - CMPIM &34 ;First allowed disc number (one digit) + JSR NMdisr ;**22/5/88** read disc no & name + CMPIM 4 ;First allowed disc number (one digit) BCC #03 - CMPIM &36 - BCS #03 - ANDIM 7 STA Drivno ;Save for later LSRA ;Put drive number into dscb RORA RORA RORA STA Dsccb+Cmd+1 - -;v1.23 - INY - JSR RDTITL - BNE #04 - LDXIM &FF - LDAIM &D - -00 - INX - CMPAX TXTBUF - BNE #00 - CPXIM 0 - BEQ #03 - CPXIM &10 - BCS #03 - JSR FMackn -;v1.31 -; JSR FMackn ;reply to caller now, lest he time out + JSR FMackn ;reply to caller now, lest he time out LDAIM &0F ;Format command STA Dsccb+Cmd @@ -60,11 +41,9 @@ FMform ROUT BEQ #05 ;Br if Ok so far JMP #50 ;Else report error -03 LDAIM WOTERR ;Bad disc number +03 LDAIM Numerr ;Bad disc number JMP Error -;v1.23 -04 JMP COMRTS ; Now have the disc in the state where every sector looks like the bitmap ; for an empty track. Only the first sector of each cylinder is actually @@ -100,30 +79,12 @@ FMform ROUT STA FMdat1+1 STA FMdat2+1 STA FMdat3+1 -;v1.23 - LDXIM 0 - -;v1.31 -; LDXIM Dnamln-1 ;Now build disc names + LDXIM Dnamln-1 ;Now build disc names 06 LDAAX Txtbuf -;v1.23 - CMPIM &D - BEQ #07 STAAX FMdnm1 STAAX FMdnm2 - INX - BRA #06 - -07 CPXIM &10 - BCS #10 - LDAIM &20 - STAAX FMdnm1 - STAAX FMdnm2 - INX - BRA #07 - -08 JMP FMVok - + DEX + BPL #06 10 LDX Freptr ;get address of work buffer LDY Freptr+1 STX Fgpptr ;set up to build next sector group @@ -133,7 +94,7 @@ FMform ROUT STZ DSCCB+TRadd+2 STZ DSCCB+TRadd+3 JSR #95 ;get number of sectors - BEQ #08 ;go exit if all done + BEQ #24 ;go exit if all done STA DSCCB+CMD+4 ;else set sector count in DSCB 12 PHA LDXIM 0 @@ -171,6 +132,8 @@ FMform ROUT STA Fgprpt+1 BRA #22 +24 BRA FMvok ;done, go say OK + 25 JSR #95 ;copy string to sector image JSR #90 DEX @@ -200,12 +163,10 @@ FMform ROUT FMVerr 50 JSR Looker ;put error msg at MIDTX -55 LDA DRIVNO - JSR RDDATA - LDA CBstid ;copy caller station - STA Ccode +55 LDA CBstid ;copy caller station + STA Txbuf LDA CBstid+1 ;and net - STA RTcode + STA Txbuf+1 LDA TXbuf-1 ;borrow a byte PHA LDAIM 1 @@ -225,6 +186,8 @@ FMVok STA Midtx+1 LDAIM CR STA Midtx+2 + LDA Drivno ;seek disc to home + JSR Rddata ;(a good a way as any - ignore errors) BRA #55 ; Routine to store value in constructed image & step ptr @@ -281,18 +244,11 @@ FMmaps ROUT & 0 ;cylinder 0 sector 0 has first disc info ptr; also ADFS free map = 1, FDsecs*FDside ;ADFS free space - cylinder 1 = Szoff-1 ;offset - -;v1.23 - = 1, 2*FDside-2 ;first disc info sector -; = 1, FDsecs*FDside-2 ;first disc info sector - + = 1, FDsecs*FDside-2 ;first disc info sector = 5 ;offset to 252 = 1, FDsecs*FDside ;ADFS disc size (1 cylinder!) = 2 ;offset to checksum - -;v1.23 - = 1, &42 -; = 1, FDsecs*FDside+FDsecs*FDside-2+FDsecs*FDside ;checksum + = 1, FDsecs*FDside+FDsecs*FDside-2+FDsecs*FDside ;checksum = 0,0 ;end sector = 1 @@ -300,48 +256,37 @@ FMmaps ROUT [ FDside = 1 = 1,FDsecs-9 ;ADFS free length | -;v1.23 - = 1, 0 -; = 1,FDsecs-7 ;ADFS free length + = 1,FDsecs-7 ;ADFS free length ] = Szoff-1 ;offset - -;v1.23 - = 1, 2*FDside-1 ;second disc info sector -; = 1, FDsecs*FDside-1 ;second disc info sector + = 1, FDsecs*FDside-1 ;second disc info sector = 8 ;offset [ FDside = 1 = 1, FDsecs*FDside-9+FDsecs*FDside-1 ;checksum | -;v1.23 - = 1, 2*FDside-1 ;checksum ;checksum -; = 1, FDsecs*FDside-7+FDsecs*FDside-1 ;checksum + = 1, FDsecs*FDside-7+FDsecs*FDside-1 ;checksum ] = 0,0 ;end sector -; = 5 -; & 2 ;cylinder 0 sectors 2-6 have ADFS root directory -; = 5,0,"Hugo" ;Master sequence + dir id -; = 250,1,0 ;5-&FF -; = 255,1,0 ;&100-&1FF -; = 255,1,0 ;&200-&2FF -; = 255,1,0 ;&300-&3FF -; = &CC,2,"$",CR ;Directory name -; = 9,1,2 ;Parent pointer -; = 3,2,"$",CR ;Directory title -; = 32,4,"Hugo" ;Dir id -; = 0,0 ;end sectors + = 5 + & 2 ;cylinder 0 sectors 2-6 have ADFS root directory + = 5,0,"Hugo" ;Master sequence + dir id + = 250,1,0 ;5-&FF + = 255,1,0 ;&100-&1FF + = 255,1,0 ;&200-&2FF + = 255,1,0 ;&300-&3FF + = &CC,2,"$",CR ;Directory name + = 9,1,2 ;Parent pointer + = 3,2,"$",CR ;Directory title + = 32,4,"Hugo" ;Dir id + = 0,0 ;end sectors = 1 -;v1.23 - & 2*FDside-2 ;cylinder 0 sector last-2 has 1st disc info -; & FDsecs*FDside-2 ;cylinder 0 sector last-2 has 1st disc info + & FDsecs*FDside-2 ;cylinder 0 sector last-2 has 1st disc info = #20-#10 ;length of all next guff 10 = "AFS0" FMdnm1 = "Fileserver disc0" ;overwritten by users name & FDcyls ;cylinders per disc - -;v1.23 & FDsecs*FDside*FDcyls ;sectors per disc = 0 ;... continued = 1 ;number of discs @@ -357,9 +302,7 @@ FMdat1 & 0 ;overwritten by date of root 20 = 0,0 ;end sector = 1 -;v1.23 - & 2*FDside-1 ;cylinder 0 sector last-2 has 1st disc info -; & FDsecs*FDside-1 ;cylinder 0 sector last-1 has 2nd disc info + & FDsecs*FDside-1 ;cylinder 0 sector last-1 has 2nd disc info = #40-#30 ;length of all next guff 30 = "AFS0" FMdnm2 = "Fileserver disc0" ;overwritten by users name @@ -477,20 +420,19 @@ $Mbtot SETA $Mbtot-$Mbcnt ;; ;; This is the old source ;; -80 - = 0,2 ;first chain word - & 0 ;marks end of free list - = 24,2 ;offset and next chain word - & &11 - = 24,2 +;; 80 = 0,2 ;first chain word +;; & 0 ;marks end of free list +;; = 24,2 ;offset and next chain word +;; & &11 +;; = 24,2 ;; ;; This is the new source (matches the dumped ROMS) ;; -;; = &ff, &ff -;;80 -;; = 21, 2 -;; & &22 -;; = 27, 2 + = &ff, &ff +80 + = 21, 2 + & &22 + = 27, 2 ;; ;; And then the existing source continues ;; @@ -568,12 +510,7 @@ FMdat3 & 0 ;to be filled in VERIFY ROUT LDAIM &2F ;Winchester verify command code - BRA #00 - -CERTIFY - LDAIM &E2 - -00 STA Tempa ;preset command + STA Tempa ;preset command JSR Spaces ;find arguments CMPIM "0" ;first is disc number (one digit) BCC #20 @@ -678,12 +615,26 @@ CERTIFY 80 DEC Brega+2 BRA #60 + ] ; end of filestore only + FNSH LEFT * FRESTR-. ;get free store - [ LEFT > 0 ;must not overflow workspace + [ LEFT >= 0 ;must not overflow workspace | ! 0,"FRESTR incorrect" ] + [ $CMOS +; The original ROM has some junk at the end. +; but don't add if Psuedo = Yes + [ Pseudods = No + = &87, &D0, &02, &E6, &88, &C6 + = &89, &80, &CB, &D0, &02, &E6, &88, &C6 + = &89, &80, &CB, &80, &CB, &90, &03, &EE + = &60, &81, &E6, &87, &D0, &02, &E6, &88 + = &C6, &89, &80, &CB, &14, &3F, &A5, &B4 + ] + ] + ;** T H E E N D *** END diff --git a/FileServer/SRC/FileServer/Level3 b/FileServer/SRC/FileServer/Level3 new file mode 100644 index 0000000..4ad57ae --- /dev/null +++ b/FileServer/SRC/FileServer/Level3 @@ -0,0 +1 @@ + OPT 2 ;> .Level3 TTL File server. Initial variable setup for Level 3 variant. File => Level3 ORG &400 GBLL $Level3 GBLL $CMOS $Level3 SETL 1=1 ; True $CMOS SETL 1=0 ; False CPU 0 LNK Uade01 \ No newline at end of file diff --git a/FileServer/SRC/FileServer/Mbbmcm b/FileServer/SRC/FileServer/Mbbmcm new file mode 100644 index 0000000..0168298 --- /dev/null +++ b/FileServer/SRC/FileServer/Mbbmcm @@ -0,0 +1,1055 @@ + OPT MBBMCM ;> Mbbmcm + TTL File server file MBBMCM + +; +; MAP BLOCK AND BIT MAP MANAGEMENT +; +; +; INITIALISE THE MAP BLOCKS +; +; ALLOCATES CONTROL BLOCKS FOR THE BIT MAP CACHE +; AND THE MAP BLOCK CACHE +; +; USES MPTMPE,MPTMPD +; +INBKMN ROUT + LDYIM :LSB:SZMBCB + LDXIM :MSB:SZMBCB + JSR GETVEC ;GET SPACE FOR MAP BLOCK CHACHE DESCRIPTORS + STY MBCBPT ;SAVE POINTER TO AREA + STX MBCBPT+1 + LDYIM :LSB:SZBMCB + LDXIM :MSB:SZBMCB + JSR GETVEC ;GET SPACE FOR BIT MAP CACHE DESCRIPTORS + STY BMCBPT + STX BMCBPT+1 ;SAVE THIS POINTER + LDAIM :LSB:SZBMAR ;SIZE OF MEMORY AREA FOR THESE BLOCKS + STA MPTMPE + LDAIM :MSB:SZBMAR + STA MPTMPE+1 + JSR SETBM ;**25/12/86** + JSR SETCBS ;INITIALISE CONTROL BLOCKS + LDAIM :LSB:SZMBAR ;SIZE OF MAP BLOCK AREA + STA MPTMPE + LDAIM :MSB:SZMBAR + STA MPTMPE+1 + JSR SETMB + JSR SETCBS +00 RTS +; +; SETUP MAP BLOCK OR BIT MAP CONTROL BLOCKS +; +; ON ENTRY +; GNCBPT POINTS TO CONTROL BLOCK +; MPTMPE HOLDS SIZE OF DISC BLOCK CACHE +; NCBDB HOLDS NUMBER OF DISC BLOCK ENTRIES +; +SETCBS LDY MPTMPE + LDX MPTMPE+1 ;GET SIZE OF CACHE + JSR GETVEC ;GET THE SPACE + STY MPTMPE + STX MPTMPE+1 ; SAVE THE AREA + LDX NCBDB ;GET NUMBER OF ENTRIES +10 LDYIM CAFLG + LDAIM 0 + STAIY GNCBPT ;ZERO ALL FLAGS + LDYIM CBSA + LDA MPTMPE + STAIY GNCBPT ;SAVE ADDRESS OF STORE + INY + LDA MPTMPE+1 + STAIY GNCBPT + DEX + BEQ #00 ; FINISH + CLC + LDA MPTMPE ;Increment to next block of store + ADCIM :LSB:BTINBK + STA MPTMPE + LDA MPTMPE+1 + ADCIM :MSB:BTINBK + STA MPTMPE+1 + JSR ADGNCB ;POINT TO NEXT CONTROL BLOCK + [ $CMOS + BRA #10 ;TRY NEXT + | + JMP #10 ;TRY NEXT + ] + +; +; GET BLOCK TO STORE +; +; ON ENTRY +; CBSIN HOLDS THE DISC ADDRESS +; GNCBPT POINTS TO RELEVANT CACHE DESCRIPTORS +; NCBDB HOLDS NUMBER OF CONTROL BLOCK ENTRIES +; MPDRVE HOLDS DRIVE NUMBER +; +; ON EXIT +; CBSTA HOLDS STORE ADDRESS OF BLOCK +; +GTBTS ROUT + LDA GNCBPT ;SAVE POINTER TO CONTROL BLOCKS + PHA + LDA GNCBPT+1 + PHA + JSR FNDBLK + BCC #30 +10 LDYIM CBSA ;IN STORE SO JUST GET ADDRESS + LDAIY GNCBPT + STA CBSTA + INY + LDAIY GNCBPT + STA CBSTA+1 + LDYIM CBAGE + LDAIM 0 + STAIY GNCBPT + PLA ;RESTORE POINTER + STA GNCBPT+1 + PLA + STA GNCBPT + JSR CAAGE ;AGE ALL ENTRIES + LDAIM 0 + RTS + + [ $CMOS +30 PLX ;NEED TO START AT BEGINNING AGAIN + | +30 PLA ;NEED TO START AT BEGINNING AGAIN + TAX + ] + PLA + STA GNCBPT + PHA + STX GNCBPT+1 + [ $CMOS + PHX ;KEEP POINTER IN CORRECT ORDER ON STACK + | + TXA + PHA ;KEEP POINTER IN CORRECT ORDER ON STACK + ] + JSR GETFR ;GET A FREE POSITION + BNE #50 ;IF FAILED + LDYIM CBDA + LDA CBSIN + STAIY GNCBPT + INY + LDA CBSIN+1 + STAIY GNCBPT + INY + LDA CBSIN+2 + STAIY GNCBPT + LDYIM CBDR + LDA MPDRVE + STAIY GNCBPT + JSR RDBLK ;READ IN THE NEW BLOCK + BEQ #40 + LDAIM 2 ;READ ERROR + [ $CMOS + TSB ERRTYP + | + ORA ERRTYP + STA ERRTYP + ] +40 LDYIM CAFLG + LDAIY GNCBPT + ORAIM 1 ;FLAG IN STORE + STAIY GNCBPT + [ $CMOS + BRA #10 + | + BNE #10 + ] + +50 TAX ; ** 13/12/85 ** + PLA + STA GNCBPT+1 + PLA ;Balance stack + STA GNCBPT + TXA + RTS + +; +; FIND A SPECIFIED DISC BLOCK IN STORE +; +; CBSIN HOLDS DISC ADDRESS +; MPDRVE HOLDS DRIVE NUMBER +; +; C SET IF FOUND +FNDBLK ROUT + LDA GNCBPT + PHA + LDA GNCBPT+1 + PHA + LDX NCBDB ;CHECK IF ALREADY IN STORE +10 LDYIM CBDA + LDAIY GNCBPT + CMP CBSIN + BNE #20 + INY + LDAIY GNCBPT + CMP CBSIN+1 + BNE #20 + INY + LDAIY GNCBPT + CMP CBSIN+2 + BNE #20 + LDYIM CBDR + LDAIY GNCBPT + CMP MPDRVE + BEQ #30 +20 DEX + BEQ #40 + JSR ADGNCB + [ $CMOS + BRA #10 + | + JMP #10 + ] + +30 LDYIM CAFLG ;CHECK IF IN STORE + LDAIY GNCBPT + ANDIM 1 + BEQ #20 + PLA + PLA + SEC + RTS + +40 PLA + STA GNCBPT+1 + PLA + STA GNCBPT + CLC + RTS +; +; READ/WRITE A BLOCK INTO STORE +; +; ON ENTRY +; GNCBPT POINTS TO ENTRY IN CACHE DESCRIPTOR +; + + [ $Level3 + [ WINCH=0 +RDBLK ROUT + LDAIM &08 + BNE #00 +WRBLK LDAIM &0A +00 STA SAVCOM + LDYIM CBDR + LDAIY GNCBPT + STA DRIVNO + LDYIM CBDA + LDAIY GNCBPT + STA RBDA ; SAVE DISC ADDRESS + INY + LDAIY GNCBPT + STA RBDA+1 + INY + LDAIY GNCBPT + STA RBDA+2 +10 LDYIM MPSECS + LDA RBDA + CMPIY MAPPTR + INY + LDA RBDA+1 + SBCIY MAPPTR + INY + LDA RBDA+2 + SBCIY MAPPTR + BCC #20 + LDYIM MPADFT + CLC + LDA DRIVNO + ADCIY MAPPTR + STA DRIVNO + SEC + LDYIM MPSECS + LDA RBDA + SBCIY MAPPTR + STA RBDA + INY + LDA RBDA+1 + SBCIY MAPPTR + STA RBDA+1 + INY + LDA RBDA+2 + SBCIY MAPPTR + STA RBDA+2 + JMP #10 + +20 LDYIM CBSA + LDAIY GNCBPT + STA DCSTAD + INY + LDAIY GNCBPT + STA DCSTAD+1 + LDA DSCCB+TRADD+2 + PHA + LDAIM 0 + STA DSCCB+TRADD+2 + STA DSCCB+TRADD+3 + LDYIM CAFLG ;MARK NOT WRITTEN + LDAIY GNCBPT + ANDIM 3 + STAIY GNCBPT + LDA RBDA + ORA RBDA+1 + ORA RBDA+2 ;IF SECTOR ZERO CALCULATE CHECKSUM + BNE #40 + LDA GNCBPT + PHA + LDA GNCBPT+1 + PHA + LDA DCSTAD + STA GNCBPT + LDA DCSTAD+1 + STA GNCBPT+1 + LDYIM &FF + TYA + STAIY GNCBPT + LDAIM 0 + CLC +30 ADCIY GNCBPT + DEY + BNE #30 + ADCIY GNCBPT + DEY + STAIY GNCBPT + PLA + STA GNCBPT+1 + PLA + STA GNCBPT +40 JSR XFER ;Transfer block + TAX + PLA + STA DSCCB+TRADD+2 + STA DSCCB+TRADD+3 + TXA + RTS + | +RDBLK ROUT + LDAIM &53 ;VALUE FOR READ + BNE #10 + +WRBLK LDAIM &4B ;VALUE FOR WRITE +10 STA SAVCOM ;SAVE VALUE + LDYIM CBDR + LDAIY GNCBPT ;GET DRIVE NUMBER + STA DRIVNO + LDAIM 0 + STA CTRACK ;PREPARE TO CALCULATE TRACK AND SECTOR + STA CSECTR + LDYIM CBDA + LDAIY GNCBPT + STA RBDA ; SAVE DISC ADDRESS + INY + LDAIY GNCBPT + STA RBDA+1 + INY + LDAIY GNCBPT + STA RBDA+2 +20 LDYIM MPSECS + LDA RBDA + CMPIY MAPPTR + INY + LDA RBDA+1 + SBCIY MAPPTR + INY + LDA RBDA+2 + SBCIY MAPPTR + BCC #30 + LDYIM MPADFT + CLC + LDA DRIVNO + ADCIY MAPPTR + STA DRIVNO + SEC + LDYIM MPSECS + LDA RBDA + SBCIY MAPPTR + STA RBDA + INY + LDA RBDA+1 + SBCIY MAPPTR + STA RBDA+1 + INY + LDA RBDA+2 + SBCIY MAPPTR + STA RBDA+2 + JMP #20 + +30 LDYIM MPSPCY + LDA RBDA + CMPIY MAPPTR ; CHECK IF END REACHED + INY + LDA RBDA+1 + SBCIY MAPPTR + LDA RBDA+2 + SBCIM 0 + BCC #40 ;BRANCH WHEN CORRECT PLACE + INC CTRACK + LDYIM MPSPCY + SEC + LDA RBDA + SBCIY MAPPTR ; KEEP DECREMENTING + STA RBDA + INY + LDA RBDA+1 + SBCIY MAPPTR + STA RBDA+1 + LDA RBDA+2 + SBCIM 0 + STA RBDA+2 + JMP #30 + +40 LDA RBDA + STA CSECTR ; SAVE SECTOR + LDYIM CBSA + LDAIY GNCBPT + STA DCSTAD + INY + LDAIY GNCBPT + STA DCSTAD+1 + LDAIM 0 + STA DSCCB+TRADD+2 + STA DSCCB+TRADD+3 + LDYIM CAFLG ;MARK NOT WRITTEN + LDAIY GNCBPT + ANDIM 3 + STAIY GNCBPT + JMP XFER ;TRANSFER THE BLOCK + ] + + | ; not level3, filestore code + +RDBLK ROUT + LDAIM &08 + [ $CMOS + BRA #00 + | + BNE #00 + ] +WRBLK LDAIM &0A +00 STA SAVCOM + LDYIM CBDR + LDAIY GNCBPT + STA DRIVNO + LDYIM CBDA + LDAIY GNCBPT + STA RBDA ; SAVE DISC ADDRESS + INY + LDAIY GNCBPT + STA RBDA+1 + INY + LDAIY GNCBPT + STA RBDA+2 + [ 1=0 ; not needed, no disc overflow **16/1/86** +10 LDYIM MPSECS + LDA RBDA + CMPIY MAPPTR + INY + LDA RBDA+1 + SBCIY MAPPTR + INY + LDA RBDA+2 + SBCIY MAPPTR + BCC #20 + LDYIM MPADFT + CLC + LDA DRIVNO + ADCIY MAPPTR + STA DRIVNO + SEC + LDYIM MPSECS + LDA RBDA + SBCIY MAPPTR + STA RBDA + INY + LDA RBDA+1 + SBCIY MAPPTR + STA RBDA+1 + INY + LDA RBDA+2 + SBCIY MAPPTR + STA RBDA+2 + +20 + ] + LDYIM CBSA + LDAIY GNCBPT + STA DCSTAD + INY + LDAIY GNCBPT + STA DCSTAD+1 + STZ DSCCB+TRADD+2 + STZ DSCCB+TRADD+3 + LDYIM CAFLG ;MARK NOT WRITTEN + LDAIY GNCBPT + ANDIM 3 + STAIY GNCBPT + [ 1=0 ;**23/1/87** never use sector zero this way + LDA RBDA + ORA RBDA+1 + ORA RBDA+2 ;IF SECTOR ZERO CALCULATE CHECKSUM + BNE #40 + LDA GNCBPT + PHA + LDA GNCBPT+1 + PHA + LDA DCSTAD + STA GNCBPT + LDA DCSTAD+1 + STA GNCBPT+1 + LDYIM &FF + TYA + STAIY GNCBPT + LDAIM 0 + CLC +30 ADCIY GNCBPT + DEY + BNE #30 + ADCIY GNCBPT + DEY + STAIY GNCBPT + PLA + STA GNCBPT+1 + PLA + STA GNCBPT + ] +40 JMP XFER ;Transfer block, exit cc still set + + ] +; +; AGE ALL CHAIN ENTRIES +; +; ON ENTRY +; GNCBPT POINTS TO RELEVANT CACHE DESCRIPTOR +; NCBDB HOLDS NUMBER OF ENTRIES +; +CAAGE ROUT + LDA GNCBPT + PHA ; SAVE THE POINTER + LDA GNCBPT+1 + PHA + LDX NCBDB +10 LDYIM CBAGE ; GET CURRENT AGE + LDAIY GNCBPT + [ $CMOS + INCA ;INCREMENT + | + ADCIM 1 ;INCREMENT + ] + STAIY GNCBPT + DEX + BEQ #20 ;CHECK FOR END + JSR ADGNCB + [ $CMOS + BRA #10 ;LOOK AT NEXT + | + JMP #10 ;LOOK AT NEXT + ] + +20 PLA ;GET POINTER BACK + STA GNCBPT+1 + PLA + STA GNCBPT + RTS +; +; GET A FREE SPACE FOR A BLOCK +; +; ON ENTRY +; GNCBPT POINTS TO START OF CONTROL BLOCK +; NCBDB HOLDS NUMBER OF CONTROL BLOCK ENTRIES +; +; ON EXIT +; GNCBPT POINTS TO VACANT ENTRY +; +; USES CBSTA,CBTPPT +; +GETFR ROUT + LDA GNCBPT + PHA + LDA GNCBPT+1 + PHA + LDX NCBDB + LDAIM &FF + STA CBSTA ;CURRENT YOUNGEST + [ $CMOS + STZ CBTPPT ;CURRENT POINTER TO YOUNGEST + STZ CBTPPT+1 + | + LDAIM 0 + STA CBTPPT ;CURRENT POINTER TO YOUNGEST + STA CBTPPT+1 + ] +10 LDYIM CAFLG + LDAIY GNCBPT + [ $CMOS + BITIM 4 ;**25/12/86** check if written + BEQ #20 + BITIM 2 ;**25/12/86** check if locked + | + ANDIM 4 ;check if written + BEQ #20 + LDAIY GNCBPT + ANDIM 2 ;check if locked + ] + BNE #20 + LDYIM CBAGE + LDAIY GNCBPT + CMP CBSTA + BCS #20 + STA CBSTA + LDA GNCBPT + STA CBTPPT + LDA GNCBPT+1 + STA CBTPPT+1 +20 JSR ADGNCB + DEX + BNE #10 + LDA CBTPPT + STA GNCBPT + ORA CBTPPT+1 + BEQ #30 + LDA CBTPPT+1 + STA GNCBPT+1 + JSR WRBLK + BEQ #30 + LDAIM 1 + [ $CMOS + TSB ERRTYP + | + ORA ERRTYP + STA ERRTYP + ] +30 PLA + STA GNCBPT+1 + PLA + STA GNCBPT + LDX NCBDB ;NUMBER OF ENTRIES + [ $CMOS + STZ CBSTA ;CURRENT OLDEST + STZ CBTPPT ;CURRENT POINTER TO OLDEST + STZ CBTPPT+1 + | + LDAIM 0 + STA CBSTA ;CURRENT OLDEST + STA CBTPPT ;CURRENT POINTER TO OLDEST + STA CBTPPT+1 + ] +40 LDYIM CAFLG + LDAIY GNCBPT + RORA ;Test bit 0 + BCS #50 + LDXIM 1 ;FREE AREA SO FOOL INTO THINKING ITS END + [ $CMOS + BRA #60 + | + BNE #60 + ] + +50 RORA + BCS #70 + LDYIM CBAGE + LDAIY GNCBPT + CMP CBSTA + BCC #70 + STA CBSTA +60 LDA GNCBPT + STA CBTPPT + LDA GNCBPT+1 + STA CBTPPT+1 +70 DEX + BEQ #80 + JSR ADGNCB ;LOOK AT NEXT ENTRY + [ $CMOS + BRA #40 + | + JMP #40 + ] + +80 LDA CBTPPT ;CHECK IF ANYTHING FOUND + ORA CBTPPT+1 + BEQ #95 + LDA CBTPPT ;SAVE ADDRESS + STA GNCBPT + LDA CBTPPT+1 + STA GNCBPT+1 + LDYIM CAFLG ;CHECK IF ALLOCATED + LDAIY GNCBPT + RORA + BCC #90 + RORA + RORA ;CHECK IF IT HAS BEEN WRITTEN TO + BCC #90 + JSR WRBLK + BEQ #90 + LDAIM 1 + [ $CMOS + TSB ERRTYP + | + ORA ERRTYP + STA ERRTYP + ] +90 LDAIM 0 + LDYIM CAFLG + STAIY GNCBPT + RTS + +95 LDAIM MPERRM ;FLAG ERROR + RTS +; +; SET THE WRITTEN BIT IN THE GIVEN CACHE DESCRIPTOR +; THE STORE ADDRESS IS GIVEN +; +; ON ENTRY +; GNCBPT POINTS TO RELEVANT CACHE DESCRIPTORS +; NCBDB HOLDS NUMBER OF DESCRIPTORS +; CBSTA HOLDS STORE ADDRESS OF BLOCK +; +; ON EXIT +; Z NON-ZERO IF FAILED +; +; +CASTWB ROUT + LDX NCBDB ;GET NUMBER OF DESCRIPTORS +10 LDYIM CBSA ;CHECK ADDRESS + LDAIY GNCBPT + CMP CBSTA + BNE #20 ;GO TO CHECK NEXT + INY + LDAIY GNCBPT + CMP CBSTA+1 + BEQ #30 +20 DEX ;CHECK FOR END + BEQ #40 + JSR ADGNCB + [ $CMOS + BRA #10 + | + JMP #10 + ] + +30 LDYIM CAFLG + LDAIY GNCBPT ;SET WRITTEN BIT + ORAIM 4 ;WRITTEN BIT + STAIY GNCBPT + LDYIM CBAGE + LDAIM 0 + STAIY GNCBPT + RTS ;Exit A=0, success + +40 LDAIM 1 + RTS ;NOT FOUND +; +; ENSURE ALL CACHED BLOCKS +; +; ON ENTRY +; GNCBPT POINTS TO CACHE DESCRIPTORS +; NCBDB HOLDS NUMBER OF DECRIPTORS +; +ENSBKS ROUT + LDX NCBDB ;NUMBER +10 LDYIM CAFLG + LDAIY GNCBPT + ANDIM 4 ;WRITTEN FLAG + BEQ #40 ;DON'T WRITE OUT IF NOT WRITTEN + [ $CMOS + PHX + | + TXA + PHA + ] + LDYIM CBSA + LDAIY GNCBPT + STA GENPTR + INY + LDAIY GNCBPT + STA GENPTR+1 + LDYIM 16 +20 LDAIY GENPTR ;SAVE SOME OF BLOCK + STAAY DATARA + DEY + BPL #20 + JSR WRBLK + BEQ #30 + LDAIM 1 + [ $CMOS + TSB ERRTYP + BRA #35 ;**26/2/87** Return now if any error + | + ORA ERRTYP + STA ERRTYP + BNE #35 ;**26/2/87** Return now if any error + ] + +30 JSR CHECKB + [ $CMOS +35 PLX + | +35 PLA + TAX + ] +40 JSR ADGNCB + DEX + BNE #10 + RTS +; +; CHECK BLOCK JUST WRITTEN FOR VALIDITY +; +CHECKB ROUT + JSR RDBLK + BNE #30 + LDYIM CBSA + LDAIY GNCBPT + STA GENPTR + INY + LDAIY GNCBPT + STA GENPTR+1 + LDYIM 16 +10 LDAIY GENPTR + CMPAY DATARA + BNE #20 + DEY + BPL #10 + RTS + +20 LDAIM &F8 + JSR INTERR +30 CLC + RTS +; +; MAKE GNCBPT POINT TO NEXT ENTRY +; +ADGNCB ROUT + CLC + LDA GNCBPT + ADCIM CBSZ + STA GNCBPT + BCC #10 + INC GNCBPT+1 +10 RTS +; +; MARK WRITTEN BIT IN SPECIFIED CACHE DESCRIPTOR +; +; ON ENTRY +; CBSTA POINTS TO ADDRESS IN MEMORY +; +MBMWT ROUT + LDA BMCBPT ;GET POINTERS TO BIT MAP + STA GNCBPT + LDA BMCBPT+1 + STA GNCBPT+1 + LDAIM NOBTMP + STA NCBDB + JSR CASTWB + BEQ #10 + LDAIM &F5 + JSR INTERR +10 RTS +; +; MARK WRITTEN BIT IN SPECIFIED MAP BLOCK +; +; ON ENTRY +; CBSTA POINTS TO MAP BLOCK +; +; +MMBWT ROUT + LDA CBSTA + STA GNCBPT + LDA CBSTA+1 + STA GNCBPT+1 + LDYIM MBSQNO + [ $CMOS + LDAIY GNCBPT + INCA + STAIY GNCBPT + | + CLC + LDAIY GNCBPT + ADCIM 1 + STAIY GNCBPT + ] + CLC + LDA GNCBPT + ADCIM :LSB:LSTSQ + STA GNCBPT + LDA GNCBPT+1 + ADCIM :MSB:LSTSQ + STA GNCBPT+1 + [ $CMOS + LDAI GNCBPT + INCA + STAI GNCBPT + | + LDYIM 0 + CLC + LDAIY GNCBPT + ADCIM 1 + STAIY GNCBPT + ] + JSR SETMB + JMP CASTWB + +; +; ENSURE BIT MAPS +; +ENSBM ROUT + LDA BMCBPT + STA GNCBPT + LDA BMCBPT+1 + STA GNCBPT+1 + LDAIM NOBTMP + STA NCBDB + JMP ENSBKS + +; +; ENSURE MAP BLOCKS +; +ENSMB ROUT + JSR SETMB + JMP ENSBKS + +; +; FIND THE SPECIFIED MAP BLOCK +; +; CBSIN HOLDS THE SIN +; +; C SET IF FOUND +; +FNDMB ROUT + LDA MBCBPT + STA GNCBPT + LDA MBCBPT+1 + STA GNCBPT+1 + LDAIM NOMPBK + STA NCBDB + JMP FNDBLK + +; +; LOCK IN STORE +; +; BLOCK WHOSE STORE ADDRESS IS IN CBSTA +; GNCBPT POINTS TO CACHE BLOCKS +; NCBDB NUMBER OF DESCRIPTORS +; +; NON-ZERO IF NOT FOUND +; +LOCKIS ROUT + LDX NCBDB +10 LDYIM CBSA + LDAIY GNCBPT + CMP CBSTA + BNE #20 + INY + LDAIY GNCBPT + CMP CBSTA+1 + BEQ #30 +20 JSR ADGNCB + DEX + BNE #10 + LDAIM 1 + RTS + +30 LDYIM CAFLG + LDAIY GNCBPT + ORAIM 2 ;LOCK IN STORE + STAIY GNCBPT + LDAIM 0 + RTS +; +; UNLOCK ALL BLOCKS +; +; NCBDB HOLDS NUMBER OF BLOCKS +; GNCBPT POINTS TO LIST +; +UNLKBS ROUT + LDX NCBDB + LDYIM CAFLG +10 LDAIY GNCBPT + ANDIM &FD ;UNLOCK BLOCK + STAIY GNCBPT + JSR ADGNCB + DEX + BNE #10 + RTS +; +; +; MARK MAP BLOCK LOCKED +; +; MPMBPT HOLDS STORE ADDRESS OF MAP BLOCK +; NON-ZERO IF FAILED +; +MMBLKD ROUT + JSR SETMB + LDA MPMBPT + STA CBSTA + LDA MPMBPT+1 + STA CBSTA+1 + [ $CMOS + BRA LOCKIS + | + JMP LOCKIS + ] + ; +; MARK BIT MAP LOCKED +; +; MPscor POINTS TO BIT MAP +; +; +MBMLKD ROUT + JSR SETBM + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + [ $CMOS + BRA LOCKIS + | + JMP LOCKIS + ] + ; +; UNLOCK ALL MAP BLOCKS +; +ULMB ROUT + JSR SETMB + [ $CMOS + BRA UNLKBS + | + JMP UNLKBS + ] + ; +; UNLOCK ALL BIT MAPS +; +ULBM ROUT + JSR SETBM + [ $CMOS + BRA UNLKBS + | + JMP UNLKBS + ] + ; +; SET VALUES FOR BIT MAP +; +SETBM ROUT + LDA BMCBPT + STA GNCBPT + LDA BMCBPT+1 + STA GNCBPT+1 + LDAIM NOBTMP + STA NCBDB + RTS +; +; SET VALUES FOR MAP BLOCKS +; +SETMB ROUT + LDA MBCBPT + STA GNCBPT + LDA MBCBPT+1 + STA GNCBPT+1 + LDAIM NOMPBK + STA NCBDB + RTS + + + LNK UADE14 diff --git a/FileServer/SRC/FileServer/Print0 b/FileServer/SRC/FileServer/Print0 new file mode 100644 index 0000000..349b6a2 --- /dev/null +++ b/FileServer/SRC/FileServer/Print0 @@ -0,0 +1,528 @@ + OPT PRINT0 ;FILE > Print0 + TTL Print server file Print0 + +; PRWAIT macro enables the printer server to exit to the fileserver +; when it wishes to wait or loop. The fileserver returns to the point +; after the call of PRWAIT when it next has nothing to do. + + MACRO +$label PRWAIT $last="0" + [ :MSB:$last = :MSB:(.+5) ; short form if same page +$label LDAIM :LSB:(.+5) + JMP PRwat1 + | +$label LDAIM :LSB:(.+7) + LDYIM :MSB:(.+5) + JMP PRwait + ] + MEND + + [ $CMOS ; whole file is Filestore only + +; Initial entry from fileserver setup. No variables yet initialized, +; All printserver exits (except initial) are to COMRTS in the command section; +; all subsequent calls on the print server are via JMI PRJUMP. + + +Prtime * Cozero ;Timer work CB + +Pstart ROUT + STZ Pstate ;Mark not busy + STZ Lastin ;No previous station + STZ Lastch ;No previous char to printer + STZ Prpoll ;No POLLPS RECEIVE CB current + STZ Prxcb ;No printer RECEIVE CB current + + LDXIM Praddr ;Read any preset printserver name +00 JSR OSrdad ;from non-volatile memory + STAAX Printn-Praddr + INX + CPXIM Praddr+6 + BCC #00 + LDXIM PRnoFF ;**8/2/88** read trailer banner suppress state + JSR OSrdad + STA PRnotb + LDAIM :LSB:#10 ;prime initial entry from commutator + STA Prjump + LDAIM :MSB:#10 + STA Prjump+1 + RTS ;finished init + +05 JSR Prxcbi ;Issue receive for printer rxcb + STA Prxcb ;Save CB number +10 + PRWAIT 0 + LDA Prxcb ;check if rxcb queued + BEQ #05 + LDAIM &33 + LDX Prxcb + JSR OSbyte ;See if receive satisfied + TXA + BMI #20 ;and br if so to process + + BIT Pstate ;else see if busy + BPL #10 ;br if not + LDXIM :LSB:Prtime + LDYIM :MSB:Prtime + LDAIM 3 + JSR OSword ;read interval timer + LDA Prtime+1 ;in centiseconds + CMPIM :MSB:(Prtimo*100) ;approx check (range 3-655 secs) + BCC #10 + STZ Pstate ;mark not busy if timed out + BRA #10 + +20 LDAIM &11 + LDXIM :LSB:Prxcb + LDYIM :MSB:Prxcb + JSR OSword ;Read receive control block + STZ Prxcb ;Mark CB not queued + LDA Printn ;**23/1/87** Test if printer disabled + BEQ #05 ;**23/1/87** and ignore block if so + LDA Pstate + BEQ #25 ;Br if idle + JSR Prchks ;Check if current station sent this + BNE #05 ;Ignore block if not + JSR Prstrt ;Check if start print block + BEQ #65 ; #30 to print pkt data +22 LDA Prxcb+1 ;Else check sequence bit + EOR Lastct + RORA + BCS #40 ;Different, go print text + BRA #65 ;Same, ignore probable repeat + +25 LDAIM PRbusy ;Mark printer busy from idle + TSB Pstate + JSR Prstrt ;Check if start print block + BEQ #64 ;**1/6/87** + JSR Prchks ;Check if from last active station + BEQ #22 ;Yes, just continue print + STZ Pstate ;**1/6/87** idle again if wrong station + +30 + PRWAIT #10 + JSR PRspac ; read free buffer space + BEQ #30 +; LDAIM &0C ;printer header (more complicated later!) +; JSR PRasci + +40 LDA Prxcb+5 ;check if more data to print + CMP Prxcb+9 + BNE #45 + LDA Prxcb+6 + CMP Prxcb+10 + BEQ #65 ;br if no more +45 JSR PRspac ;Read print buffer space + BNE #55 +50 + PRWAIT #10 + BRA #45 + +55 LDAI Prxcb+5 ;get next character + JSR PRasci +60 INC Prxcb+5 + BNE #40 + INC Prxcb+6 + BRA #40 + +64 LDA Lastin ;**1/6/87** if previous station unterminated + BEQ #65 + JSR PRfoot ;**1/6/87** print footer now +65 LDA Prxcb+5 ;Prepare to return CB as acknowledge + CLC + ADCIM 1 + STA Prxcb+9 + LDA Prxcb+6 + ADCIM 0 + STA Prxcb+10 ;Make one byte length + LDAIM 0 + STAI Prxcb+5 ;and send one zero byte + LDA Prxcb+1 ;save control byte + STA Lastct + STZ Pretry ;zero retry count +75 LDA Lastct + STA Prxcb+1 + LDXIM :LSB:(Prxcb+1) + LDYIM :MSB:(Prxcb+1) + LDAIM &10 + JSR OSword ;Transmit CB +80 + PRWAIT 0 + LDA Prxcb+1 ;Check transmitting + BEQ #75 + +85 + PRWAIT #80 + LDAIM &32 ;Check transmit before proceeding + JSR OSbyte + TXA + BMI #85 + BEQ #86 ;br if transmit ok + DEC Pretry ;else retry some times + BNE #75 ;before giving up + +86 LDA Prxcb+3 ;Save station as last + STA Lastin + LDA Prxcb+4 + STA Lastin+1 + LDA Prxcb+1 ;**20/5/87** + ANDIM MCtask + STA Lastin+2 + JSR Pconnt ;refresh timeout + JSR Prxcbi ;Then reissue receive + STA Prxcb ;save CB number (or zero) + LDA Lastct ;See if this was end print buffer + BITIM &04 + BEQ #87 + JSR PRfoot ;**1/6/87** page footer and ... + STZ Lastin ;**1/6/87** no station active and ... + STZ Pstate ;Go idle if so +87 JMP #10 + + +Pollps ROUT ;here every main idle cycle + LDX Prpoll ;see if POLLPS action needed + BNE #15 ;br unless no RECEIVE issued + LDXIM 1 ;set up rxcb in fours + LDYIM &7F + LDAIM Prpolp + JSR Prxcbs ;zeros for wildcard station, net + LDYIM :LSB:Prwork + LDAIM :MSB:Prwork + JSR Prxcbs + LDYIM :LSB:(Prwork+8) + LDAIM :MSB:(Prwork+8) + JSR Prxcbs + JSR Prxcbj ;send off RECEIVE CB + STA Prpoll ;save CB number or zero +10 RTS ;exit for now + +15 LDAIM &33 ;poll POLLPS CB + JSR OSbyte + TXA + BPL #10 ;br if still pending + + LDA Rxcbn ;save main cb number + PHA + LDA Prpoll + STA Rxcbn + STZ Prpoll ;no block queued after this + LDAIM &11 + LDXIM :LSB:Rxcbn + LDYIM :MSB:Rxcbn + JSR OSword ;read RECEIVE cb + PLA + STA Rxcbn ;restore CB number + + LDA Printn ;**23/1/87** check if printer disabled + BEQ #10 ;**23/1/87** and ignore packet if so + + LDAIM :LSB:(Prwork+8) + CMP CBbufe ;check exactly 8 bytes received + BNE #10 ;error if not + + LDA Prwork+6 ;check request code + CMPIM 1 ;poll printserver? + BEQ #94 + CMPIM 2 ;poll & connect (as poll)? + BEQ #94 + CMPIM 6 ;read alternate name? + BNE #10 ;ignore all others pro tem + + LDXIM 5 ;set up to reply alternate name + LDYIM :LSB:Printn + LDAIM :MSB:Printn + JSR Prxcbs + LDYIM :LSB:(Printn+6) + LDAIM :MSB:(Printn+6) +92 JSR Prxcbs + LDAIM Prpolr + STA CBport ;set reply port + LDY Qptr ;use main SEND routine + JMP Send ;which does it all for us + +94 LDXIM :LSB:Pollpn + LDYIM :MSB:Pollpn + JSR #97 ;try to match main name + BEQ #95 + LDXIM :LSB:Printn + LDYIM :MSB:Printn + JSR #97 ;try to match user-defined name + BNE #10 ;failed, ignore +95 STZ Prwork ;set up reply in work store + STZ Prwork+1 + STZ Prwork+2 + STZ Prwork+3 + LDA Pstate ;see if busy + BNE #89 + JSR PRspac ;idle, test if jammed + BNE #88 ;br if not + LDAIM 2 ;jammed code + STA Prwork + BRA #96 + +88 LDA Prwork+6 ;Poll & connect? + CMPIM 2 + BNE #96 + LDA CBstid ;Yes, save station as last + STA Lastin + LDA CBstid+1 + STA Lastin+1 + LDA CBflg ;**20/5/87** + ANDIM MCtask + STA Lastin+2 + JSR Pconnt ;refresh timer + LDAIM Prbusy ;and mark busy + TSB Pstate + BRA #96 + +89 INC Prwork ;mark reply if so + LDA Lastin + STA Prwork+1 + LDA Lastin+1 + STA Prwork+2 + LDA Lastin+2 + STA Prwork+3 +96 LDXIM 9 + LDYIM :LSB:(Prwork+3) + LDAIM :MSB:(Prwork+3) + BRA #92 ;go send reply + +97 STX Cozero ;compare X,Y against Prwork + STY Cozero+1 ;in either case + LDYIM 5 +98 LDAAY Prwork + EORIY Cozero + ANDIM &DF + BNE #99 + DEY + BPL #98 + TAY ;set Z if match +99 RTS + +Pollpn = "PRINT",0 + +; Refresh timer + +Pconnt ROUT + LDXIM 4 +82 STZAX Prtime ;reset interval timer to zero + DEX + BPL #82 + LDXIM :LSB:Prtime + LDYIM :MSB:Prtime + LDAIM 4 + JMP OSword + +; Print page footer + +PRfoot ROUT + LDA PRnotb ;**8/2/88** See if trailer suppressed + BNE #10 + LDAIM &0C ;and send formfeed FOOTER (may get worse) + CMP Lastch ;unless already done in data stream + BEQ #10 + JSR PRasci +10 RTS + +; Issue Receive CB for printer + +Prxcbi ROUT + LDXIM 1 + LDYIM &7F + LDAIM Prport ;Receive on this port + JSR Prxcbs ;Wildcard station (any) + LDYIM :LSB:Prdata + LDAIM :MSB:Prdata + JSR Prxcbs + LDYIM :LSB:(Prdata+Prlong) + LDAIM :MSB:(Prdata+Prlong) + JSR Prxcbs +Prxcbj LDA Rxcbn ;save main CB number + PHA + STZ Rxcbn ;for CB number + LDXIM :LSB:Rxcbn + LDYIM :MSB:Rxcbn + LDAIM &11 + JSR OSword ;there it goes + PLX + LDA Rxcbn ;get new CB number or zero + STX Rxcbn ;restore main CB number + RTS + +Prxcbs PHA ;store Y,A,0,0 at Rxcbn+X... + TYA + STAAX Rxcbn + PLA + INX ;and increment X + STAAX Rxcbn + INX + STZAX Rxcbn ;high order address zero + INX + STZAX Rxcbn + INX + RTS + +; PRspac tests free space and returns Z set if none + +PRspac ROUT + LDAIM 128 ;Read print buffer space + LDXIM 252 + JSR OSbyte + TXA + RTS + + [ 1=0 +; The fileserver can request a printserver shutdown by calling the PRstop +; entry. This cancels any pending RECEIVE blocks (but does nothing more +; orderly than that at present). + +; PRstop - shuts down print server + +PRstop ROUT + LDX Prxcb ;any RECEIVE block queued? + BEQ #10 + JSR #20 ;yes, cancel it +10 LDX Prpoll ;any RECEIVE block for POLLPS? + BEQ #30 + STZ Prpoll ;mark none now +20 LDAIM &34 ;cancel CB + JSR OSbyte +30 RTS + ] + +; Send char A to printer + +PRasci ROUT + STA Lastch + JMP OSwrch + +; Record next printserver entry point and return to fileserver + +PRwait STY Prjump+1 ;both bytes if entered here +PRwat1 STA Prjump ;lsb only if entered here + JMP Comrts ;return to fileserver + +; Check if new buffer from previously active station +; Returns with Z set appropriately + +Prchks ROUT + LDA Prxcb+3 ;new station + CMP Lastin + BNE #10 + LDA Prxcb+4 + CMP Lastin+1 + BNE #10 ;**20/5/87** + LDA Prxcb+1 + ANDIM MCtask + CMP Lastin+2 +10 RTS + +; Check if new buffer is a "start print" buffer. Returns Z set if so. + +Prstrt ROUT + LDA Prxcb+1 ;get control byte + BITIM &02 ;is it a control buffer at all + BEQ #10 + BITIM &04 ;yes, is it "end print" + BEQ #20 ;no, so IS start print + LDA Prxcb+9 ;endprint, remove trailing CTRL-C + BNE #00 + DEC Prxcb+10 +00 DEC Prxcb+9 + LDAI Prxcb+9 + CMPIM &03 ;check CTRL-C + BEQ #10 ;removed now + INC Prxcb+9 ;not CTRL-C, better restore + BNE #10 + INC Prxcb+10 +10 LDAIM &FF ;clear Z +20 RTS + +; PRNAME - enables an authorised used to set a 6-char printer alias. +; for entry and exit details see COMRTS + +Prerrm = "Bad printer name",CR +Prerrn * .-Prerrm + +Prname ROUT + STZ Txtbuf+7 ;Terminator and length check + JSR Buftxt ;Read name into TXTBUF + BNE #70 + JSR Comend + BNE #70 + LDA Txtbuf+7 ;Check length + BEQ #10 + LDAIM Prerrl + STA RTcode ; error if too long + LDXIM 0 +00 INX + LDAAX Prerrm-1 + STAAX Midtx-1 + CMPIM CR + BNE #00 + LDAIM Prerrn+Txhdr ; length + STZ Ccode + JSR Reply + BRA #70 + +10 JSR Getuse ;Get user CB + BNE #70 + LDYIM Utpriv ;Check privilege + LDAIY Ustptr + ANDIM Systpv + BNE #20 +15 LDAIM Aterrd + JMP Error + +20 LDXIM Praddr ;Set printserver name +30 LDAAX Txtbuf-Praddr ;Copy name + BEQ #50 + CMPIM CR ;Up to null or CR + BNE #50 + LDAIM 0 +50 STAAX Printn-Praddr ;and instore copy + JSR OSwrad ;Write alternate memory + INX + CPXIM Praddr+6 + BCS #60 + TAY ;propagate end if found + BEQ #50 + BRA #30 ;else continue copy + +60 LDAIM 0 + JSR Rcode ;Null reply +70 JMP Comrts + +; PRPAGE Y/N permits or suppresses the trailer banner +; which is currently a single FF + +PRPAGE ;**8/2/88** command added + BIT Cmndsw ;Maintenance mode is ok + BMI #80 + STY Bptr + JSR Getuse ;get user details + BNE #70 + LDYIM Utpriv + LDAIY Ustptr ;this guy better be privileged + ANDIM Systpv + BEQ #15 ;else reject command + LDY Bptr +80 JSR Spaces ;find argument + ANDIM &DF + CMPIM "N" + BEQ #90 + CMPIM "Y" + BNE #95 + LDAIM 0 +90 STA PRnotb ;set local flag + LDXIM PRnoFF ;and stash in non-volatile storage + JSR OSwrad + BRA #60 + +95 LDAIM Woterr ;argument not Y or N + JMP Error + + ]; whole file is Filestore only + + LNK FORM00 diff --git a/FileServer/SRC/FileServer/Rman01 b/FileServer/SRC/FileServer/Rman01 new file mode 100644 index 0000000..e33f370 --- /dev/null +++ b/FileServer/SRC/FileServer/Rman01 @@ -0,0 +1,702 @@ + OPT RMAN01 ; > .Rman01 + TTL File server file RMAN01 + +RMNORG + + ORG RMNORG + +;Set up ORG address so second pass gets +;addresses right when doing 2nd pass only + +;Second pass also needs source and object +;drives correctly set. + + +;********************************* +;* R N D M A N * +;********************************* + + + +;RNDMAN: THE RANDOM ACCESS MANAGER IS RESPONSIBLE +;FOR MAINTAINING A LIST OF OPENED OBJECTS +;(HANDTB) & FOR KEEPING VARIOUS DETAILS +;ABOUT OPENED FILES (RANDTB). +;RNDMAN PROVIDES THE FOLLOWING FUNCTIONS:- + +;1) OPEN OBJECT (GIVE HANDLE) +;2) INFO (INDICATE WHETHER OPEN) +;3) CLOSE OBJECT +;4) RESTART +;5) CREATE A HANDLE FOR AN OBJECT WITH SPECD HANDLE +;6) DELETE ALL HANDLES FOR A GIVEN M/C +;7) READ BYTE FROM FILE +;8) WRITE BYTE TO FILE +;9) GETBYTES +;10) PUTBYTES +;11) Read args of open file +;12) Set args of open file +;13) Close all files for machine +;14) Set up for PUTBYTES/GETBYTES calls + + + +;THE HANDTB CONTAINS THE FOLLOWING +;INFO:- +;0) HANDLE +;1) MC/NO +;2) TYPE AND ACCESS +;3) DISC NUMBER +;4) SIN +;5) MODE - MULTIPLE READER/SINGLE WRITER +;6) RANDTB OFFSET + + + +;********* MAIN ROUTINE *********** + + + +RNDMAN ROUT + LDXIM &F ;RNDMAN HAS 15 ENTRY POINTS + LDAIM MODRND ;A:=NAME OF THIS MODULE + JSR ENTRY + + [ $CMOS + LDAIM &F + JSR SETFS ;SET FRAME SIZE + JMIX RDRTNS + | + LDAAX RDRTNS + STA RDJUMP+1 + LDAAX RDRTNS+1 + STA RDJUMP+2 + LDAIM &F + JSR SETFS ;SET FRAME SIZE +RDJUMP JMP RDJUMP + ] +RDRTNS + & RDOPEN ;1 => OPEN OBJECT (ISSUE A HANDLE) + & RDINFO ;2 => INFO (INDICATE WHETHER OBJECT IS OPEN) + & RDCLOS ;3 => CLOSE OBJECT (INVALIDATE HANDLE) + & RDREST ;4 => RESTART + & RDCOPY ;5 => GENERATE ANOTHER HANDLE FOR AN OBJECT + & RDCLAL ;6 => DELETE ALL HANDLES FOR A USER + & RDRDCH ;7 => READCH + & RDWRCH ;8 => WRITECH + & RDGBTS ;9 => GETBYTES FROM FILE + & RDPBTS ;10 => PUTBYTES TO FILE + & RDRDAR ;11 => Read args of file + & RDSTAR ;12 => Set args of file + & RDCLAF ;13 => Close all files for machine + & RDSUBO ;14 => Set up for bytes operation + & RDEOF ;15 => Read "end of file" status + +RDEXIT JMP PREXIT + + + +;************ RDOPEN ************ + + +;RDOPEN: OPEN AN OBJECT & RETURN A HANDLE FOR IT. + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD = MODE(HOW OBJECT SHOULD BE OPENED) +;ARGE = TYPE & ACCESS ALLOWED TO OBJECT +;ARGF-G PTR TO OBJECT DETAILS + +;NOTE:- ARGD (MODE) +;BIT 0 => READ ACCESS NEEDED +;BIT 1 => WRITE ACCESS NEEDED +;BIT 7 => FILE JUST CREATED +;RNDMAN INFORCES MULTIPLE READER - SINGLE WRITER +;INTERLOCKS. + +;EXIT : ARGA = RC +;ARGB = HANDLE + +;FUNCTION: MAKE HANDTB ENTRY +;IF TYPE OF OBJECT = TYPFIL +;THEN MAKE NEW RANDTB ENTRY +;FI + + +RDOPEN ROUT + JSR INITRD ;INITIALISE MCNUMB,&GETPTR:=USERINFO,RNDPTR + +;SEE IF THIS MACHINE CAN OPEN ANOTHER FILE +;AND SEE WHETHER THERE IS ANY ROOM IN THE HANDTB + + JSR GETHND ;HNDPTR:=PTR TO A FREE HANDTB ENTRY + BNE #60 + LDYIM ARGE + LDAIY ARGPTR ;TYPE & ACCESS + ANDIM TYPDIR + BNE #50 + +;ITS A FILE SO SEE IF THERE IS ROOM IN RANDTB + +;The object is a file: must check that it can be opened +;for the requested access. (A file may be held open by +;a single writer, or by multiple readers). +;If it may be opened, then find a slot in RANDTB and +;fill it in. A pointer to the entry in RANDTB is +;put in HANDTB (stored in 2 bytes). + + JSR RDCKAC ;Check access allowed (corrupts HNDPTR) + BNE #60 ;not ok + JSR GETHND ;HNDPTR := free HANDTB entry + BNE #60 ;Didn't get one + JSR GETRND ;RTEPTR := free RANDTB entry + BNE #60 ;not got one + + LDA RTEPTR ;Store RANDTB entry ptr in HANDTB entry + LDYIM HTRPTR + STAIY HNDPTR + INY + LDA RTEPTR+1 + STAIY HNDPTR + +;Fill in new RANDTB entry (currently all zero) + + LDAIM &80 ;"In use" flag + seq num zero + LDYIM RTINUS + STAIY RTEPTR ;Mark entry "in use" + +;Current and old sequential file pointers +;already set to zero. +;High water mark and size both set from +;file size in object details. + + LDAIM RTFSZE + JSR #80 ;Little block move routine + +;High water mark used only if the object is open for +;update. If the file is new, then leave zero, otherwise +;set to file size. + + LDYIM ARGD ;Get mode byte + LDAIY ARGPTR + ANDIM FILEJC ;Test file just created + BNE #40 ;Jump if new file + +;File existed before: set HWM to size + + LDAIM RTHWM + JSR #80 + +40 +;Leave address of cache descriptor (hint) to +;be filled in on first read/write operation +;** END OF FILE CODE ** + + +;FIRST MARK HANDLE IN USE (IN USERTB ENTRY) + +50 JSR MHINUS ;MARK HANDLE IN USE - IN USERTB ENTRY + +;NOW COPY DETAILS (HANDLE,DISC NO,SIN, ETC.) +;INTO THE HANDTB (HNDPTR WAS SET BY GETHND) + + LDYIM HTHAND + LDA RNDTMP + STAIY HNDPTR ;HANDLE + + LDYIM HTMCNO + LDA MCNUMB + STAIY HNDPTR + INY + LDA MCNUMB+1 + STAIY HNDPTR + INY + LDA MCNUMB+2 ;**25/12/86** + STAIY HNDPTR ;MACHINE NUMBER + + LDYIM ARGE + LDAIY ARGPTR + LDYIM HTACC + STAIY HNDPTR ;TYPE & ACCESS + + LDXIM INFDIS + LDYIM HTDISC + LDAIM 2 + JSR #70 + + LDXIM INFSIN + LDYIM HTSIN + LDAIM 3 + JSR #70 + + LDYIM ARGD + LDAIY ARGPTR + LDYIM HTMODE + STAIY HNDPTR ;MODE + + LDAIM 0 ;RC := 0 + +60 PHA + LDA RNDTMP ;A:=HANDLE + LDYIM ARGB + STAIY ARGPTR + PLA + JMP RDEXIT + + +70 STX OFF1 + STY OFF2 + LDXIM RNDPTR ;Move stuff from RNDPTR + LDYIM HNDPTR ;To HNDPTR + JMP MOVBLK + + +80 STA OFF2 + LDAIM INFSZE ;Move size from + STA OFF1 ;RNDPTR to RTEPTR (offset already set) + LDXIM RNDPTR + LDYIM RTEPTR + LDAIM 3 + JMP MOVBLK + + +;************ RDINFO ************ + + +;RDINFO: SEARCH THE HANDTB TO DETERMINE WHETHER +;A PARTICULAR OBJECT IS OPEN. + +;ENTRY: ARGB = LS(DISC NO) +;ARGC = MS(DISC NO) +;ARGD = LS(SIN) +;ARGE = CS(SIN) +;ARGF = MS(SIN) + +;EXIT : ARGA = RC (0 => OBJECT OPEN) +; : ARGB = MODE OF ACCESS (**28/4/83**) + + +RDINFO ROUT + JSR INITHD ;HNDPTR:=HANDTB,X:=HTENTS + CLC + LDA ARGPTR + ADCIM ARGB + STA MOVFRM + LDA ARGPTR+1 + ADCIM 0 + STA MOVFRM+1 ;MOVFRM := ARGPTR + ARGB + +10 LDYIM HTHAND + LDAIY HNDPTR + BEQ #20 ;ENTRY IN USE ?? + CLC + LDA HNDPTR + ADCIM HTDISC + STA MOVTO + LDA HNDPTR+1 + ADCIM 0 + STA MOVTO+1 ;MOVTO := HNDPTR + HTDISC + + [ $CMOS + PHX + LDXIM 5 ;COMPARE DISC & SIN + JSR COMPAR + PLX + TAY + | + TXA + PHA + LDXIM 5 ;COMPARE DISC & SIN + JSR COMPAR + TAY + PLA + TAX + TYA + ] + BEQ #30 + +20 JSR INCHND + BNE #10 + LDAIM RDERRE ;OBJECT NOT OPEN + +30 PHA ;save A + BNE #40 + + LDYIM HTMODE + LDAIY HNDPTR ;get mode from table + LDYIM ARGB + STAIY ARGPTR ;for return + JSR RDopat ;**20/5/87** set 'open at' details + +40 PLA + JMP RDEXIT + + + +;************ RDCLOS ************ + + +;RDCLOS: CLOSE - INVALIDATE A HANDLE + +;ENTRY: ARGB = LS(PTR TO USER INFO) +;ARGC = MS(PTR TO USER INFO) +;ARGD = HANDLE + +;EXIT : ARGA = RC + + +RDCLOS ROUT + JSR INITRD ;SETUP GENPTR & MCNUMB + LDYIM ARGD + LDAIY ARGPTR ;A := HANDLE + BNE #10 + LDAIM RDERRB ;BAD HANDLE + [ $CMOS + BRA #20 + | + BNE #20 + ] + +10 STA RNDTMP ;RNDTMP := HANDLE + JSR FNDHND ;SEARCH HANDTB FOR THE HANDLE + BNE #20 + + +;NOW CLEAR HANDTB (RANDTB) ENTRY +;and mark handle free in USERTB + + JSR CLRHTE + +20 JMP RDEXIT + + + +;************ RDREST ************ + + +;RDREST: RESTART +;CREATE BOTH HANDTB & RANDTB. +;THE VARIABLES HANDTB & RANDTB ARE INITIALISED +;TO POINT TO THE FIRST ENTRY OF BOTH +;TABLES. + +;NOTE - HANDLE TABLE HAS 6*USERS ENTRIES, +;AND RAND TABLE 5*USERS ENTRIES. + + +RDREST ROUT + LDA USERS ;First create handle table + LDXIM 5 + CLC +30 ADC USERS + BCS #40 + DEX + BNE #30 + [ $CMOS + BRA #10 + | + BEQ #10 + ] + +40 LDAIM &FF +10 CMPIM 9 + BCS #20 + LDAIM 9 +20 PHA + STA HTENTS + TAX + LDYIM HTENSZ + JSR SETTAB ;SET HANDLE TABLE + STY HANDTB + STX HANDTB+1 + + PLA + SEC + SBC USERS + STA RTNENT ;Store no. of RT entries + TAX + LDYIM RTENSZ + JSR SETTAB + STY RANDTB + STX RANDTB+1 + LDAIM 0 + JMP RDEXIT + + + +;************ RDCOPY ************ + + +;RDCOPY: CREATE ANOTHER HANDLE FOR AN OBJECT +;(OOF TYPE DIR). N.B. RNDMAN.RDCOPY IS +;USED BY USRMAN WHEN SELECTING A USER'S UFD. + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;AFGC = MS(PTR TO USERINFO) +;ARGD = HANDLE (FOR A DIR) + +;EXIT : ARGA = RC +;ARGE = NEW HANDLE + + +RDCOPY ROUT + JSR INITRD ;SETUP GENPTR & MCNUMB + LDYIM ARGD + LDAIY ARGPTR + JSR FNDHND + BNE #20 + LDA HNDPTR + STA MOVFRM + LDA HNDPTR+1 + STA MOVFRM+1 ;MOVFRM := PTR TO HANDTB ENTRY + LDYIM HTACC + LDAIY HNDPTR + [ $CMOS + BITIM TYPDIR ;IS HANDLE FOR A DIR? + | + ANDIM TYPDIR ;IS HANDLE FOR A DIR? + ] + BNE #10 + LDAIM RDERRF ;RDCOPY ONLY AVAILABLE FOR DIRECTORIES + JSR INTERR +10 JSR GETHND ;HNDPTR:=PTR TO FREE HANDTB ENTRY + BNE #20 + JSR MHINUS ;MARK THE HANDLE IN USE IN USERTB + LDA HNDPTR + STA MOVTO + LDA HNDPTR+1 + STA MOVTO+1 + LDXIM HTENSZ + JSR MOVE ;COPY OBJECT DETAILS INTO NEW USERTB ENTRY + LDYIM ARGE + LDA RNDTMP ;A := HANDLE TO BE USED (SETBY GETHND) + STAIY ARGPTR + LDYIM HTHAND + STAIY HNDPTR ;PUT NEW HANDLE IN HANDTB ENTRY + LDAIM 0 ;RC:=0 +20 JMP RDEXIT + + + + +;************ RDCLEAR ALL ************* + + +;RDCLAL: DELETE ALL HANDLES BELONGING +;TO A MACHINE. + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) + +;EXIT: ARGA = RETURN CODE + + +RDCLAL ROUT + JSR INITRD ;SET GENPTR/MCNUMB/RDUPTR + JSR INITHD ;SET HNDPTR + +10 LDYIM HTMCNO ;M/C NUMBER + LDAIY HNDPTR + CMP MCNUMB + BNE #30 + INY + LDAIY HNDPTR + CMP MCNUMB+1 + BNE #30 + INY + LDAIY HNDPTR + CMP MCNUMB+2 ;**25/12/86** + BNE #30 + +;FOUND, SO DELETE + + LDA RDUPTR + STA GENPTR + LDA RDUPTR+1 + STA GENPTR+1 ;Ensure GENPTR pointing to right place + + [ $CMOS + PHX + | + TXA + PHA + ] + JSR CLRHTE ;CLEAR TABLE ENTRY + [ $CMOS + PLX ;tidy up stack + TAX + | + TAX + PLA ;tidy up stack + TXA + ] + BNE #40 +30 JSR INCHND ;INC. PTR + BNE #10 ;(X DEC'D IN INCHND) + + LDAIM 0 +40 + JMP RDEXIT + + + + +;GETHND: CHOOSE A HANDLE & A SLOT IN THE HANDTB +;WHICH ARE FREE. +;NOTE THAT EACH MACHINE CAN HAVE UPTO 8 HANDLES. +;THE HANDLES CURRENTLY BEING USED BY A +;PARTICULAR MACHINE ARE RECORDED IN THE USERTB. + +;ENTRY: GENPTR = PTR TO USER INFO + +;EXIT : A = RC +;HNDPTR = POINTER TO A FREE HANDTB ENTRY +;RNDTMP = HANDLE TO BE USED + + +GETHND ROUT + LDYIM UTHNDB ;HANDLE BYTE HELD IN USERTB + LDAIY GENPTR + +;FIRST SEE IF THIS MACHINE HAS A FREE HANDLE + + CMPIM &FF + BNE #10 + LDAIM RDERRC ;HANDLE QUOTA EXHAUSTED + RTS + +10 LDYIM 1 + STY RNDTMP +20 LSRA + BCC #30 ;FOUND A FREE HANDLE + ASL RNDTMP + [ $CMOS + BRA #20 + | + JMP #20 + ] + +;NOW SEE IF THERE IS A FREE SLOT IN HANDTB + +30 JSR INITHD ;HNDPTR := HANDTB + LDYIM HTHAND +40 LDAIY HNDPTR + BEQ #50 + JSR INCHND + BNE #40 + LDAIM RDERRD ;HANDTB FULL +50 RTS + + +INITRD ROUT + LDYIM ARGB ;INIT GENPTR,MCNUMB,RNDPTR + LDAIY ARGPTR + STA GENPTR + STA RDUPTR ;Store extra copy of user pointer INY + INY + LDAIY ARGPTR ;(used by RDCLAL and RDCLAF) + STA GENPTR+1 ;GENPTR := PTR TO USERINFO + STA RDUPTR+1 ;Extra copy high byte + + LDYIM UTMCNO + LDAIY GENPTR + STA MCNUMB + INY + LDAIY GENPTR + STA MCNUMB+1 + INY + LDAIY GENPTR + STA MCNUMB+2 ;MCNUMB initialised **25/12/86** + + LDYIM ARGF + LDAIY ARGPTR + STA RNDPTR + INY + LDAIY ARGPTR + STA RNDPTR+1 ;RNDPTR := PTR TO OBJECT INFO(SEE DIRMAN.RETR) + RTS + + +MHINUS ROUT + LDYIM UTHNDB ;MARK A HANDLE IN USE IN USERTB + LDA RNDTMP ;A:=HANDLE (SEE GETHND) + ORAIY GENPTR + STAIY GENPTR + RTS + + +;Mark handle free in USERTB +;GENPTR points at USERTB entry +;A contains handle + +MHFREE ROUT + LDYIM UTHNDB ;Mark handle free in USERTB + EORIM &FF ;Invert handle in A + ANDIY GENPTR ;Clear handle bit + STAIY GENPTR ;Put back in USERTB + RTS + + + +CLRHTE ROUT ;CLRHTE + +;CLEAR HANDLE TABLE ENTRY POINTED TO +;BY HNDPTR. IF ENTRY IS FOR A FILE, +;CLEAR CORRESPONDING RANDOM TABLE ENTRY. +;The handle bit in the USERTB entry +;(pointed to by GENPTR) is cleared. + + LDYIM HTHAND ;Get handle in A + LDAIY HNDPTR + JSR MHFREE ;Mark handle free in USERTB + + LDYIM HTACC + LDAIY HNDPTR + ANDIM TYPE + CMPIM TYPDIR + BEQ #10 + JSR RDFLSH ;Flush object from cache + BNE #30 ;**** 17/3/83 **** + JSR RDSFSZ ;Set size from HWM + JSR CLRRTE ;Clear RANDTB entry + +10 LDYIM HTENSZ-1 ;Y := SIZE OF HANDTB ENTRY + LDAIM 0 +20 STAIY HNDPTR + DEY + BPL #20 ;A zero already + TAY +30 RTS + + + +;*** RDSFSZ *** + +;If the file is open for update, then set +;its size to the HWM recorded in RANDTB. + +;Entry: HNDPTR points to HANDTB entry for file + +;Exit: RC in A + +RDSFSZ + LDYIM HTMODE ;Get mode in which open + LDAIY HNDPTR + ANDIM WRITAC ;Open for writing ? + BEQ #30 ;Yes, exit A=0 and Z set + + JSR SETRPT ;Set RTEPTR + LDYIM RTHWM + LDAIY RTEPTR ;HWM LS + STA NEWFSZ + INY + LDAIY RTEPTR ;HWM CS + STA NEWFSZ+1 + INY + LDAIY RTEPTR ;HWM MS + STA NEWFSZ+2 + + JMP RDCHSZ ;Change size and exit + + + LNK Rman02 diff --git a/FileServer/SRC/FileServer/Rman02 b/FileServer/SRC/FileServer/Rman02 new file mode 100644 index 0000000..b8a5fbd --- /dev/null +++ b/FileServer/SRC/FileServer/Rman02 @@ -0,0 +1,478 @@ + OPT RMAN02 ; > .Rman02 + TTL File server file RMAN02 + +;**************** RDRDCH **************** + +;RDRDCH: read one byte from an open file + +;Entry: ARGB = (LS) ptr to user info +;ARGC = (MS) ptr to user info +;ARGD = file handle +;ARGE = sequence no. (in LS bit) + +;Exit: ARGA = return code +;ARGB = byte read +;ARGC = end-of-file flag +;normally zero, +;#X80 if this is the last byte in file +;#XC0 if this is byte after end of file + +;1) Get HANDTB entry from handle +;2) Check that object is a file +;3) Get RANDTB entry +;4) Compare sequence no. in ARGD with that in RANDTB entry. +;Same => old seq. file ptr := current SFP +;increment sequence no. in RANDTB entry +;Different => repeat of last read; +;current SFP := old SFP +;5) Check sequential file pointer against file size +;SFP = size => return $FE and EOFFLG = $C0 +;SFP > size => end of file; return RC +;SFP < size => OK +;6) Work out disc address of block containing +;required byte, and offset of byte in block. +;7) Find / get required block in cache (STRMAN) +;8) Fetch required byte and return it +;Increment current SFP in RANDTB + +RDRDCH ROUT + JSR INITRD ;GENPTR := user info; MCNUMB := machine no. +;[RNDPTR := rubbish] + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #30 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #30 ;Not found (object not file) + + LDYIM HTMODE + LDAIY HNDPTR ;check that file is open for input + ANDIM READAC + BNE #10 + LDAIM RDERRO ;file not open for input ** 15/11/84 ** + [ $CMOS + BRA #30 + | + BNE #30 + ] + +10 JSR RDCSEQ ;Compare sequence numbers +;and choose file ptr; if equal +;then increment seq no. + JSR RDCKEX ;Check SFP against file length + BNE #30 ;End of file + LDAIM &FE ;Byte after last + BIT EOFFLG + BVS #20 ;Reading byte after last +;so return $FE + + JSR RDGBLK ;Get required block into cache +;GENPTR := store address + BNE #30 ;error + +;*** Assuming blocksize is 256 bytes *** +;Offset of required byte in block is given +;by LS byte of seq. file pointer. + + LDYIM RTCSFP + LDAIY RTEPTR ;LS byte of SFP + TAY + LDAIY GENPTR ;Get required byte +20 LDYIM ARGB + STAIY ARGPTR ;Return byte read + INY + LDA EOFFLG + STAIY ARGPTR ;Return end-of-file flag + + JSR RDISFP ;Increment Current SFP + + LDAIM 0 +30 JMP RDEXIT ;Exit: Rc in A + + +;**************** RDWRCH **************** + +;RDWRCH: write one byte to an open file + +;Entry: ARGB = (LS) ptr to user info +;ARGC = (MS) ptr to user info +;ARGD = file handle +;ARGE = sequence no. (in LS bit) +;ARGF = byte to be written + +;Exit: ARGA = return code + +;1) Get HANDTB entry from handle +;2) Check that object is a file +;3) Check file open for update +;4) Get RANDTB entry +;5) Compare sequence no. in ARGD with that +;in RANDTB entry. +;Same => old seq. file ptr := current SFP +;increment sequence no. in RANDTB entry +;Different => repeat of last read; +;current SFP := old SFP +;6) Check sequential file pointer against file size +;SFP >= size => end of file; extend file +;SFP < size => OK +;7) Work out disc address of block containing +;required byte, and offset of byte in block. +;8) Find / get required block in cache (STRMAN) +;9) Write byte to cache; mark cache buffer dirty +;(but do not cause it to be written to disc: this will +;happen when the cache space is needed for +;something else, or when the file is closed. +;The cache buffer is left unlocked between +;calls of RDWRCH). +;10) IF SFP > HWM THEN HWM := SFP +;11) Increment current SFP + +RDWRCH ROUT + JSR INITRD ;GENPTR := user info; MCNUMB := machine no. +;[RNDPTR := rubbish] + + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #40 ;Not found - exit + + LDYIM HTMODE ;Check file open for update + LDAIY HNDPTR ;Get mode + ANDIM WRITAC ;Extract write access bit + BNE #10 ;OK to write + + LDAIM RDERRN ;"File not open for update" + [ $CMOS + BRA #40 + | + BNE #40 + ] + +10 JSR SETRPT ;RTEPTR := RANDTB entry + BNE #40 ;Not found (object not file) + + JSR RDCSEQ ;Compare sequence numbers +;and choose file ptr; if equal +;then increment seq no. + JSR RDCKSP ;Check SFP against file length + BIT EOFFLG ;If PTR = EXT, need to extend + BVS #20 ;V set => PTR = EXT => extend + BEQ #30 ;Otherwise, Z set if inside file +;so don't extend + +;Must extend file +;Allocate another block (1K bytes) + +20 LDAIM 1 ;Ls byte of new size + STA NEWFSZ ;**29/4/88** central subroutine + [ $CMOS + STZ NEWFSZ+1 + | + LDAIM 0 + STA NEWFSZ+1 + ] + JSR RDEXSZ ;**29/4/** Change file size + BNE #40 ;Error + +30 JSR RDGBLK ;Get required block into cache +;GENPTR := store address + BNE #40 ;error + +;*** Assuming blocksize is 256 bytes *** +;Offset of required byte in block is given +;by LS byte of seq. file pointer. + + LDYIM ARGF + LDAIY ARGPTR ;Byte to be written + TAX ;Save it + LDYIM RTCSFP + LDAIY RTEPTR ;LS byte of file pointer + TAY + TXA + STAIY GENPTR ;Write byte to cache + + JSR MRKDRT ;Mark buffer dirty (addr in GENPTR) + JSR RDISFP ;Increment Current SFP + JSR RDSHWM ;Set high water mark + + LDAIM 0 ;Success +40 JMP RDEXIT ;Return - RC in A + + +;****** RDRDAR ****** + +;RDRDAR: read RANDTB info on open file + +;Entry: ARGB (LS) ptr to user info +;ARGC (MS) ptr to user info +;ARGD = file handle + +;Exit: ARGA = return code +;ARGB = (LS) Seq file ptr +;ARGC = (CS) " " " +;ARGD = (MS " " " +;ARGE = (LS) File high water mark +;ARGF = (CS) " " " +;ARGG = (MS) " " " +;ARGH = (LS) File size +;ARGI = (CS) " " +;ARGJ = (MS) " " + +;The file handle is used to find the HANDTB +;entry, which points to the RANDTB entry +;from which the info is extracted. + +RDRDAR ROUT + JSR INITRD ;GENPTR:=ptr to user info + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #40 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #40 ;Not found + +;Return current seq file ptr + + LDYIM RTCSFP + LDAIY RTEPTR ;LS byte of SFP + LDYIM ARGB + STAIY ARGPTR + LDYIM RTCSFP+1 + LDAIY RTEPTR ;CS byte + LDYIM ARGC + STAIY ARGPTR + LDYIM RTCSFP+2 + LDAIY RTEPTR ;MS + LDYIM ARGD + STAIY ARGPTR + +;Copy 6 bytes from RANDTB entry to ARGPTR +;stack. (The 2 fields are in the same +;order in each place). + + LDXIM 6 ;Loop count + LDAIM ARGE ;1st stack offset + STA RNDTMP ;Temp workspace + LDYIM RTHWM ;Offset in RANDTB entry + +10 LDAIY RTEPTR ;Get data from RANDTB + STY RNDTMP+1 ;Save RANDTB entry offset + LDY RNDTMP ;Get stack offset + STAIY ARGPTR ;Put data on stack + INY + STY RNDTMP ;Save next stack offset + LDY RNDTMP+1 ;Restore entry offset + INY + DEX ;Loop count + BNE #10 ;Loop if not zero + JSR RDCKSP ;check for EOF ** 26/5/83 ** + BEQ #30 ;skip except on error + + LDYIM ARGJ + STY RNDTMP + LDYIM ARGD + LDXIM 2 ;copy size to pointer area +20 STY RNDTMP+1 + LDY RNDTMP + LDAIY ARGPTR ;move the data + LDY RNDTMP+1 + STAIY ARGPTR + DEC RNDTMP + DEY + DEX + BPL #20 ;three bytes + +30 LDAIM 0 ;All copied - set RC +40 JMP RDEXIT ;Return - RC in A + + +;****** RDSTAR ****** + +;RDSTAR: set sequential file ptr + +;Entry: ARGB = (LS) ptr to user info +;ARGC = (MS) " " " " +;ARGD = file handle +;ARGE = arg saying what to set +;0: SFP +;1: HWM ** 5/9/84 ** +;ARGF = (LS) New value to set +;ARGG = (CS) " " " " +;ARGH = (MS) " " " " +;ARGI = 4th byte if any + +;Exit: ARGA = return code + +;The file handle is used to find the RANDTB entry. +;The arg in ARGE is inspected to find +;out what is being set. + +RDSTAR ROUT + JSR INITRD ;GENPTR -> user info + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HANDPTR := HANDTB entry + BNE #10 ;error + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #10 ;Not found + +;Inspect arg in ARGE + + LDYIM ARGE + LDAIY ARGPTR + LSRA + BEQ #20 ;0 => set SFP + ;1 => set HWM + + LDAIM RDERRM ;"Bad arg to RDSTAR" +10 JMP #40 + +;Set seq file ptr + +;IF newSFP < size THEN oldSFP = newSFP +;ELIF openforwriting THEN resize file: HWM = newSFP: oldSFP = newSFP +;ELSE IF newSFP <> size THEN error ELSE oldSFP = newSFP + +20 BCS #50 ;A = 1 => set extent of file + SEC + LDYIM ARGF + LDAIY ARGPTR + LDYIM RTFSZE + SBCIY RTEPTR ;Do RNDTMP := SFP - size + STA RNDTMP + LDYIM ARGG + LDAIY ARGPTR + LDYIM RTFSZE+1 + SBCIY RTEPTR + STA RNDTMP+1 + LDYIM ARGH + LDAIY ARGPTR + LDYIM RTFSZE+2 + SBCIY RTEPTR + ORA RNDTMP + ORA RNDTMP+1 + BCC #35 ;Set SFP = new SFP as size > SFP + +;Here SFP >= size, so attempt to point +;outside file. If open for update, resize +;else if SFP <> size then error else set SFP = new SFP + +25 PHP ;Push Z flag indicating SFP = size + LDYIM HTMODE + LDAIY HNDPTR ;Mode handle opened for + ANDIM WRITAC ;Check if open for writing + BNE #30 ;Yes, so resize + + PLP ;Not open for writing, so check if SFP=size + BEQ #35 ;Yes, so set SFP + LDAIM RDERRL ;No => "attempt to point outside file" + [ $CMOS + BRA #40 ;Error exit + | + BNE #40 + ] + +30 PLP ;Restore stack, and resize file + LDYIM ARGH + LDAIY ARGPTR ;Set NEWFSZ to seq. ptr. + STA NEWFSZ+2 + DEY + LDAIY ARGPTR + STA NEWFSZ+1 + DEY + LDAIY ARGPTR + STA NEWFSZ + JSR RDCHSZ ;Change size of file + BNE #40 ;Error => exit + +;Copy SFP into RANDTB + +35 LDAIM ARGF + STA OFF1 + LDAIM RTCSFP + JSR #90 ;Set current seq. ptr. + LDAIM RTOSFP ;Set old seq. ptr. as well + JSR #90 + JSR RDSHWM ;**1/6/88** set HWM if SFP > old HWM +37 LDAIM 0 ;Return code +40 JMP RDEXIT ;Return - RC in A + +50 LDYIM HTMODE + LDAIY HNDPTR + ANDIM WRITAC + BNE #55 ;open for update + LDAIM RDERRN ;not open for update + [ $CMOS + BRA #40 ;Error exit + | + BNE #40 + ] + +55 LDYIM ARGF + LDXIM :LSB:-3 +60 LDAIY ARGPTR + STAAX NEWFSZ-:LSB:(-3) + INY + INX + BNE #60 + + LDYIM RTHWM+2 + LDXIM 2 +65 LDAIY RTEPTR + CMPAX NEWFSZ + BNE #70 + DEY + DEX + BPL #65 + [ $CMOS + BRA #80 ;All ok + | + BMI #80 + ] + +;exactly the same size so NOP here + +70 LDYIM RTHWM + LDAIY RTEPTR + STA TEMPA ;save current extent + ROLA + STA TEMPB ;save carry as well + +;C=0 => extending the file + + RORA + BCC #75 + +;if decreasing file then must flush all blocks +;else cache may be left with antiquated data + + LDAIM 5 + JSR SETRTN + JSR RDDSIN + JSR STRMAN ;flush all blocks + BNE #40 + +75 JSR RDCHSZ ;call changesize + BNE #40 + +80 JSR #88 ;Having resized file, set HWM to ptr. value + [ $CMOS + BRA #37 + | + JMP #37 + ] + +;Little space-saving routine + +88 LDAIM ARGF + STA OFF1 + LDAIM RTHWM +90 STA OFF2 + LDXIM ARGPTR + LDYIM RTEPTR + LDAIM 3 + JMP MOVBLK + + LNK Rman02A diff --git a/FileServer/SRC/FileServer/Rman02A b/FileServer/SRC/FileServer/Rman02A new file mode 100644 index 0000000..77826fc --- /dev/null +++ b/FileServer/SRC/FileServer/Rman02A @@ -0,0 +1,405 @@ + OPT RMAN02 ; > .Rman02A + TTL File server file RMAN02A + +;*** RDCHSZ *** + +;Change the size of a file to the 3-byte value +;in NEWFSZ. HNDPTR points at its HANDTB entry, +;and RTEPTR at the RANDTB entry. + +;MAPMAN.CHANGESIZE is called, and the new +;size is recorded in the RANDTB entry. + +;RC in A on exit. + + +RDCHSZ ROUT + JSR RDDSIN ;Put disc and SIN on stack + +;Put new size on stack + + LDA NEWFSZ ;LS byte + LDYIM ARGG + STAIY NEWARG + LDA NEWFSZ+1 + INY + STAIY NEWARG ;CS byte + LDA NEWFSZ+2 + INY + STAIY NEWARG ;MS byte + + JSR JUSINF ;** 3/10/84 ** + + LDAIM 3 ;MAPMAN.CHANGESIZE + JSR SETRTN + JSR MAPMAN + BNE #10 ;Failed, return code + +;zero the new area if needed + + JSR RDDSIN ;** 20/9/84 ** + + LDYIM RTFSZE + LDAIY RTEPTR + LDYIM ARGG + STAIY NEWARG + + LDYIM RTFSZE+1 + LDAIY RTEPTR + LDYIM ARGH + STAIY NEWARG + + LDYIM RTFSZE+2 + LDAIY RTEPTR + LDYIM ARGI + STAIY NEWARG + + LDAIM 13 + JSR SETRTN + JSR MAPMAN + BNE #10 ;failed, return code + +;Size changed: record in RANDTB + + LDAIM 6 + JSR SETRTN ;Ensure map on disc + JSR MAPMAN ;Note assumes disc no. still on stack + BNE #10 ;Error -> leave + + LDYIM RTFSZE + LDA NEWFSZ + STAIY RTEPTR ;LS byte + LDA NEWFSZ+1 + INY + STAIY RTEPTR ;CS byte + LDA NEWFSZ+2 + INY + STAIY RTEPTR ;MS byte + + LDAIM 0 ;RC +10 RTS + + +;*** SETRPT *** + +;Set RTEPTR to point to RANDTB entry + +;Entry: HNDPTR points at HANDTB entry + +;Exit: A = return code +;RTEPTR points to corresponding RANDTB entry + + +SETRPT ROUT + LDYIM HTACC + LDAIY HNDPTR ;A := type of object (& access) + ANDIM TYPE ;Mask type + CMPIM TYPFIL ;Is it a file? + BEQ #10 ;Jump if file + + LDAIM RDERRI ;"Object not a file" + RTS ;Return + +10 LDYIM HTRPTR + LDAIY HNDPTR ;LS byte + STA RTEPTR ;LS byte + INY + LDAIY HNDPTR + STA RTEPTR+1 ;MS byte + + LDAIM 0 ;return code + RTS + + +;*** RDDSIN *** + +;Put disc number and SIN on NEWARG +;stack from ARGB - ARGF. + +RDDSIN ROUT + LDAIM HTDISC ;"Move from" offset + STA OFF1 + LDAIM ARGB ;"move to" offset + STA OFF2 + LDXIM HNDPTR ;Move from + LDYIM NEWARG ;Move to + LDAIM 5 ;Size of disc no. + SIN + JMP MOVBLK ;Note -> assumes DISC/SIN contiguous + + +;*** RDCKEX *** + +;Check SFP against HWM (For read operation) + +RDCKEX ROUT + LDYIM RTHWM + [ $CMOS + BRA #10 ;share code with RDCKSP + | + BNE #10 + ] + + +;*** RDCKSP *** + +;Check sequential file pointer against file size + +;Entry: RTEPTR points to RANDTB entry + +;Exit: A = return code: 0 => OK, SFP < size +;EOFFLG = 0 normally +;= #X80 if this is last byte of file +;= $C0 If byte after last + +RDCKSP LDYIM RTFSZE +10 STY RNDTMP+2 + [ $CMOS + STZ EOFFLG ;First set EOFFLG to zero + | + LDAIM 0 + STA EOFFLG + ] + SEC + LDY RNDTMP+2 ;Subtract SFP from file size + INC RNDTMP+2 + LDAIY RTEPTR ;LS byte of file size + LDYIM RTCSFP + SBCIY RTEPTR ;Subtract LS bytes + STA RNDTMP ;Use RNDTMP as workspace + LDY RNDTMP+2 + INC RNDTMP+2 + LDAIY RTEPTR + LDYIM RTCSFP+1 + SBCIY RTEPTR ;CS bytes + STA RNDTMP+1 + LDY RNDTMP+2 + INC RNDTMP+2 + LDAIY RTEPTR + LDYIM RTCSFP+2 + SBCIY RTEPTR ;Sets carry if SFP <= size + + TAX ;Save MS byte for EOFFLG test + ORA RNDTMP ;OR all 3 bytes of result + ORA RNDTMP+1 ;for zero test + BEQ #30 ;Jump if SFP = file size + BCC #40 ;Jump if SFP > file size + +;OK: SFP < file size | HWM +;Set EOFFLG to #X80 if this is the last +;byte of the file (size - SFP = 1) + + CMPIM 1 ;Is OR of all bytes 1? + BNE #20 ;No + TXA ;OR MS two bytes + ORA RNDTMP+1 ;CS byte + BNE #20 ;MS 2 bytes not both 0 + + LDAIM &80 ;(size - SFP)=1 so set + STA EOFFLG ;end-of-file flag + +20 LDAIM 0 ;OK: SFP <= file size + RTS + +;SFP = file size +;Set end of file marker to indicate +;reading/writing byte AFTER end of file. + +30 LDAIM &C0 ;Last AND one after last + STA EOFFLG + [ $CMOS + BRA #20 ;Exit, Z set, A=0 + | + BNE #20 + ] + +40 LDAIM RDERRJ ;"End of file" + RTS + + + +;*** RDCSEQ *** + +;Compare sequence number received with that recorded +;in RANDTB. If they are equal, then increment +;the sequence number in RANDTB and set +;old SFP := current SFP +;Otherwise, this is a repetition of the +;last operation, so don't change the sequence number +;and set current SFP := old SFP + +;Entry: RTEPTR points to RANDTB entry +;ARGE on ARGPTR stack holds received +;seq no (in LS bit) + +;Exit: Sequence number +;in RANDTB entry incremented if and only if +;sequence numbers matched. + +RDCSEQ ROUT + LDYIM ARGE + LDAIY ARGPTR ;A := received seq no. + LDYIM RTINUS ;Seq no. byte of RANDTB entry + EORIY RTEPTR ;A := XOR of seq nos. + ANDIM 1 ;Mask out "in use" bit + BEQ #20 ;Jump if seq nos. equal + +;Seq nos different, so back up SFP: +;current SFP := old SFP + +RDBACK LDYIM RTOSFP ;** 5/8/83 ** + LDAIY RTEPTR + LDYIM RTCSFP + STAIY RTEPTR + LDYIM RTOSFP+1 + LDAIY RTEPTR + LDYIM RTCSFP+1 + STAIY RTEPTR + LDYIM RTOSFP+2 + LDAIY RTEPTR + LDYIM RTCSFP+2 + STAIY RTEPTR + RTS ;Seq nos. different; return + +20 LDAIY RTEPTR ;Get seq. no. + EORIM 1 ;Flip seq no., leaving "in use" flag + STAIY RTEPTR + +;old SFP := current SFP + + LDYIM RTCSFP + LDAIY RTEPTR + LDYIM RTOSFP + STAIY RTEPTR + LDYIM RTCSFP+1 + LDAIY RTEPTR + LDYIM RTOSFP+1 + STAIY RTEPTR + LDYIM RTCSFP+2 + LDAIY RTEPTR + LDYIM RTOSFP+2 + STAIY RTEPTR + RTS ;Return + + +;*** RDISFP *** + +;Increment sequential file ptr (3 bytes) + +RDISFP ROUT + CLC + LDAIM 1 + LDYIM RTCSFP + ADCIY RTEPTR + STAIY RTEPTR ;LS byte + INY + LDAIY RTEPTR + ADCIM 0 + STAIY RTEPTR ;CS byte + INY + LDAIY RTEPTR + ADCIM 0 + STAIY RTEPTR ;MS byte + + RTS ;Return + + +;*** RDGBLK *** + +;Gets the required block into the cache. +;In order to speed up the operation, a means +;is provided of usually avoiding a call of STRMAN. +;Each entry in RANDTB contains a hint - in the form +;of a pointer to the cache descriptor for the block +;last used. STRMAN guarantees that this will +;continue to point to SOME cache descriptor, but if +;there has been a store crisis in the cache, then +;it may not still point to the block we want. +;Therefore the hint is carefully checked for validity +;before use. +;If the hint is no good, then the required block +;is read from disc by calling STRMAN.DISC ADDRESS-> +;STORE ADDRESS. The address of the cache descriptor +;is put in the RANDTB entry as the next hint. + +;Entry: HNDPTR points to handle table entry +;RTEPTR points to RANDTB entry + +;Exit: A = RC +;GENPTR contains store address of cache buffer. +;Hint field of RANDTB entry points to cache +;descriptor (or is zero). + +RDGBLK ROUT + JSR RDCHNT ;Check hint; set GENPTR if OK + BEQ #40 ;HINT OK, GO RETURN + JSR RDDSIN ;Put disc and SIN on stack + +;Logical block number of the block containing the +;current byte is given by the top 2 bytes of the +;sequential file pointer. +;*** This firmly assumes that the blocksize is +;*** 256 bytes (as does DIVIDE in MAPMAN). + + LDYIM RTCSFP+1 + LDAIY RTEPTR ;Seq file ptr (CS) + LDYIM ARGG + STAIY NEWARG ;Logical block no. (LS) + LDYIM RTCSFP+2 + LDAIY RTEPTR ;Seq file ptr (MS) + LDYIM ARGH + STAIY NEWARG ;Logical block no. (MS) + +;Ask for one block only. This simplifies the +;arithmetic elsewhere. +;(Would using units of > 1 block give a +;significant speed improvement?) + + LDAIM 0 + LDYIM ARGJ + STAIY NEWARG + [ $CMOS + INCA ; A=1 + | + LDAIM 1 ; A=1 + ] + DEY + STAIY NEWARG + + JSR SETRTN ; A=1 STRMAN: Disc address -> store address + + JSR STRMAN ;*** STRMAN.DISC -> STORE ADDRESS ** + BNE #40 ;Failed, go return + LDYIM ARGB ;GENPTR := store address + LDAIY NEWARG + STA GENPTR ;(LS) + INY + LDAIY NEWARG + STA GENPTR+1 ;(MS) + + INY ;Store cache desc. addr. in RANDTB entry + LDAIY NEWARG ;LS byte + LDYIM RTDESC + STAIY RTEPTR + LDYIM ARGE + LDAIY NEWARG ;MS byte + LDYIM RTDESC+1 + STAIY RTEPTR + +;Must unlock cache window, so that it is not +;locked between byte transfers. Note that if +;parallelism is ever introduced into the file +;server, care must be taken that RNDMAN does +;not relinquish control between deciding that +;it has found a block in the cache and using it. + +;Very conveniently, STRMAN has left the buffer +;address in the right place on the stack. + + LDAIM 3 ;STRMAN.UNLOCKWINDOW + JSR SETRTN + + JSR STRMAN ;*** STRMAN.UNLOCKWINDOW ** + +40 RTS ;exit + + LNK Rman03 diff --git a/FileServer/SRC/FileServer/Rman03 b/FileServer/SRC/FileServer/Rman03 new file mode 100644 index 0000000..a451c96 --- /dev/null +++ b/FileServer/SRC/FileServer/Rman03 @@ -0,0 +1,275 @@ + OPT RMAN03 ; > .Rman03 + TTL File server file RMAN03 + +;*** RDCHNT *** + +;Checks the cache descriptor hint in a +;RANDTB entry. + +;Entry: HNDPTR points to HANDTB entry +;RTEPTR points to RANDTB entry + +;Exit: A = RC: zero => hint used, GENPTR set +;non-zero=> must call STRMAN instead +;GENPTR points to cache buffer (iff RC=0) + +RDCHNT ROUT + LDYIM RTDESC ;GENPTR := Cache descriptor hint + LDAIY RTEPTR ;from RANDTB entry + STA GENPTR + INY + LDAIY RTEPTR + STA GENPTR+1 + +;Hint is invalid if it is zero (as it +;is when file first opened) + + ORA GENPTR ;OR both bytes of hint + BEQ #40 ;Hint no good (zero) + +;Must now check that the hint still points +;to the cache descriptor we want. (If it +;is not zero, it will always point to +;SOME cache descriptor). +;The descriptor is valid only if it has the +;right disc number and SIN, and if its start +;block is the one we want. + +;*** Assumptions: +;*** 1) Blocksize = 256 bytes (=> easy +;*** calculation of block number +;*** 2) Cache buffers contain only one +;*** disc block + +;Compare SINs first (more likely to +;be different than disc number). + + LDYIM HTSIN + LDAIY HNDPTR + LDYIM CESIN + CMPIY GENPTR ;Compare LS bytes + BNE #40 ;Different + LDYIM HTSIN+1 + LDAIY HNDPTR + LDYIM CESIN+1 + CMPIY GENPTR ;Compare CS bytes + BNE #40 ;Different + LDYIM HTSIN+2 + LDAIY HNDPTR + LDYIM CESIN+2 + CMPIY GENPTR ;Compare MS bytes + BNE #40 ;Different + +;SIN OK - check disc no. + + LDYIM HTDISC ;Compar disc nos. + LDAIY HNDPTR + LDYIM CEDISC + CMPIY GENPTR ;Compare LS bytes + BNE #40 ;Different - hint no good + LDYIM HTDISC+1 + LDAIY HNDPTR + LDYIM CEDISC+1 + CMPIY GENPTR ;Compare MS bytes + BNE #40 ;Different + +;Disc no. OK - Check block no. +;(should be equal to top 2 bytes of +;sequential file pointer). + + LDYIM CEBKNO + LDAIY GENPTR ;LS byte of block no. + LDYIM RTCSFP+1 + CMPIY RTEPTR ;Comp with CS byte of SFP + BNE #40 ;Different + LDYIM CEBKNO+1 + LDAIY GENPTR ;MS byte of block no. + LDYIM RTCSFP+2 + CMPIY RTEPTR ;Comp with MS byte of SFP + BNE #40 ;Different + +;The hint is OK. +;Copy buffer address to GENPTR (which +;currently points to cache descriptor). + + LDYIM CESTA + LDAIY GENPTR ;LS byte of buff addr + PHA ;Save for now + INY + LDAIY GENPTR ;MS byte of buff addr + STA GENPTR+1 ;GENPTR := buff addr + PLA + STA GENPTR ;LS byte + + LDAIM 0 ;Success - hint used + RTS + +40 LDAIM &FF ;Hint no good + RTS + + + +;************ RDCLAF ************ + + +;RDCLAF: Close all files for the calling machine + +;Entry: ARGB = Ptr to user info (LS) +;ARGC = Ptr to user info (MS) + +;Exit: ARGA = Return code + + +RDCLAF ROUT + JSR INITRD ;Set GENPTR & MCNUMB & RDUPTR (extra copy of user ptr.) + JSR INITHD ;Set HNDPTR and X + +10 LDYIM HTMCNO + LDAIY HNDPTR ;Get mc no. from HANDTB entry + CMP MCNUMB ;Same as client machine? + BNE #30 ;LS bytes differ + INY + LDAIY HNDPTR ;CS byte + CMP MCNUMB+1 + BNE #30 ;CS bytes differ + INY + LDAIY HNDPTR ;MS byte + CMP MCNUMB+2 + BNE #30 ;MS bytes differ **25/12/86** + +;Entry is for this machine. +;See if the object is a file. + + LDYIM HTACC + LDAIY HNDPTR ;Object type & access + ANDIM TYPE + CMPIM TYPDIR ;Is it a directory? + BEQ #30 ;Jump if yes + +;Entry is for a file for this mc. + + LDA RDUPTR + STA GENPTR + LDA RDUPTR+1 + STA GENPTR+1 ;Set pointer to user info (corrupted over CLRHTE) + + [ $CMOS + PHX + | + TXA + PHA + ] + JSR CLRHTE ;Close the file + [ $CMOS + PLX + TAY + | + TAX + PLA + TXA + ] + BNE #40 +30 JSR INCHND ;Inc pointer + BNE #10 ;Look at next entry + + LDAIM 0 ;Return code +40 JMP RDEXIT ;Return + + +;************ RDSUBO ************ + +;RDSUBO: Set up for PUTBYTES/GETBYTES operation + +;Entry: ARGB = LS ptr to user info +;ARGC = MS " " " " +;ARGD = file handle +;ARGE = Seq. no. received +;ARGF = Flag: 0 => use given offset +;NOT 0 => use SFP in RANDTB +;ARGG = LS total no. of bytes +;ARGH = CS " " " " +;ARGI = MS " " " " +;ARGJ = LS Offset in file +;ARGK = CS (only if flag=0) +;ARGL = MS " +; +;Exit: ARGA=RC +;ARGB = mode if access of file +; +; Side effect: +; OLDSZE is set to old HWM +; OLDSZE+3 is zero if area of disc has +; to be zeroed on a write +; +RDSUBO ROUT + LDAIM 1 + STA OLDSZE+3 + JSR INITRD + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #30 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #30 ;Not found + + JSR RDCSEQ ;Check seq no and set SFP accordingly + + LDYIM ARGF + LDAIY ARGPTR ;A := flag + BNE #20 ;Offset not supplied + +;Offset supplied : set SFP to offset + + LDYIM RTHWM ;GET CURRENT HWM + LDAIY RTEPTR + STA OLDSZE + INY + LDAIY RTEPTR + STA OLDSZE+1 + INY + LDAIY RTEPTR + STA OLDSZE+2 + [ $CMOS + STZ OLDSZE+3 ;Zero flag + | + LDAIM 0 + STA OLDSZE + 3 + ] + LDYIM ARGJ ;CHECK IF NEW SIZE LARGER THAN OLD + LDA OLDSZE + CMPIY ARGPTR + INY + LDA OLDSZE+1 + SBCIY ARGPTR + INY + LDA OLDSZE+2 + SBCIY ARGPTR + BCC #10 + INC OLDSZE+3 +10 LDYIM ARGJ + LDAIY ARGPTR ;Offset (LS) + LDYIM RTCSFP + STAIY RTEPTR ;LS byte + LDYIM ARGK + LDAIY ARGPTR + LDYIM RTCSFP+1 + STAIY RTEPTR ;CS byte + LDYIM ARGL + LDAIY ARGPTR + LDYIM RTCSFP+2 + STAIY RTEPTR ;MS byte + +20 LDYIM HTMODE ;**23/3/88** return access mode + LDAIY HNDPTR + LDYIM ARGB + STAIY ARGPTR + + JSR RDCKSP ;Check SFP inside file + BEQ #30 ;SFP inside file + PHA + JSR RDBACK ;restore SFP to old SFP + PLA +30 JMP RDEXIT + + LNK Rman04 diff --git a/FileServer/SRC/FileServer/Rman04 b/FileServer/SRC/FileServer/Rman04 new file mode 100644 index 0000000..ddeb3ab --- /dev/null +++ b/FileServer/SRC/FileServer/Rman04 @@ -0,0 +1,712 @@ + OPT RMAN04 ; > .Rman04 + TTL File server file RMAN04 + +;************ RDGBTS ************ + + +;RDGBTS: Get bytes from file + +;Entry: ARGA = func code (9) +;ARGB) = ptr to user info (LS) +;ARGC) = " " " " (MS) +;ARGD = file handle +;ARGE) = buffer address (LS) +;ARGF) = " " (MS) +;ARGG) = no. of bytes (LS) +;ARGH) to be read (MS) + +;Exit: ARGA = rc +;ARGB) = no. of bytes actually read (LS) +;ARGC) (MS) +;ARGD = flag: normally zero +;$80 if this read includes +;the last byte OR if it is +;completely outside the file. + +;The read is done starting at the current SFP. +;A call of RNDMAN.RDSUBO must be done at the start of each +;external GETBYTES operation, followed by one or more calls +;of RDGBTS. + +;*** N.B. Attempting a read partially or +;completely outside the file is not an error +;here. Transfer completely outside file +;will have been deletected in RDSUBO. + +;1) Get HANDTB entry from handle +;2) Get RANDTB entry +;3) BTSLFT := file size - SFP (bytes left) +;4) EOFFLG := 0 (end of file flag) +;5) IF transfer size < BTSLFT +;THEN BTSLFT := transfer size +;ELSE EOFFLG := $80 (end-of-file) +;6) BTSXFD := BTSLFT (bytes transferred) +;7) The transfer is done in 3 parts (any of which +;may be null). +;If the start address is not badly aligned on +;a disc block boundary, then STRMAN is called to +;get the required disc block into the cache. +;(It may still be there from the last GETBYTES call). +;The relevant bytes are copied into the buffer. +;We are now aligned to a disc block boundary, so +;can do a direct read by calling DSCMAN, provided +;at least 256 bytes remain to be read. +;The final partial block (if any) is read through +;the cache. + +RDGBTS ROUT + JSR INITRD ;GENPTR := user info; MCNUMB := machine no. + + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #20 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #20 ;Not found (object not file) + + LDYIM HTMODE + LDAIY HNDPTR ;check that file open for reading + ANDIM READAC + BNE #10 + LDAIM RDERRO + [ $CMOS + BRA #20 + | + BNE #20 + ] + +10 CLC ;CHECK CORRECT LIMIT + JSR RDBLFT ;BTSXFD := BTSLFT := +;min(transfer size, bytes left in file) +;Also sets EOFFLG + + JSR RDSBFA ;Set RDBFAD + + JSR RDGBT1 ;Read first partial disc block + BNE #20 ;Failed + + JSR RDGBT2 ;Read complete disc blocks in middle + BNE #20 ;Failed + + JSR RDGBT3 ;Read final partial disc block + ;BNE #20 + +;Reading worked OK + + ;LDAIM 0 + +;Exit: error code in A +;Bytes transferred in BTSXFD + +20 PHA ;Save error code + + LDYIM ARGB ;Return bytes tranferred + LDA BTSXFD + STAIY ARGPTR ;LS byte + INY + LDA BTSXFD+1 + STAIY ARGPTR ;MS byte + + INY + LDA EOFFLG ;Return EOF flag + STAIY ARGPTR + + PLA ;Restore error code + JMP RDEXIT ;Exit: RC in A + + + +;************ RDPBTS ************ + + +;RDPBTS: Put bytes to file + +;Entry: ARGA = func code (10) +;ARGB) = (LS) ptr to user info +;ARGC) = (MS) +;ARGD = file handle +;ARGE) = (LS) buffer address +;ARGF) = (MS) +;ARGG) = (LS) number of bytes to be written +;ARGH) = (MS) + +;Exit: ARGA = RC + +;The write is done starting from the current SFP. +;The file is extended if necessary. +;A call of RNDMAN.RDSUBO must be done at the +;start of each external PUTBYTES operation, +;followed by one or more calls of RDPBTS. + +;1) Get HANDTB entry from handle +;2) Get RANDTB entry +;3) Check open for writing +;4) (abolished) +;5) BTSLFT := file size - SFP (bytes left) +;6) IF transfer size > BTSLFT +;THEN extend file +;BTSLFT := transfer size +;7) BTSXFD := BTSLFT (bytes transferred) +;8) The write is done in 3 parts +;(any of which may be null). +;They are (a) via the cache, +;(b) directly to disc, and +;(c) via the cache, as for RDGBTS (q.v.). +;9) Adjust file HWM + +RDPBTS ROUT + JSR INITRD ;GENPTR := user info; MCNUMB:=machine no. + + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #10 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #10 ;Not found - exit + + LDYIM HTMODE ;Check file open for update + LDAIY HNDPTR ;Get mode + ANDIM WRITAC ;Write access + BNE #20 ;OK to write + + LDAIM RDERRN ;"Not open for update" +10 + [ $CMOS + BRA #40 + | + BNE #40 + ] + +20 SEC ;CHECK CORRECT LIMIT + JSR RDBLFT ;BTSXFD := BTSLFT := +;min(transfer size, bytes left in file) + + LDA EOFFLG ;Get end-of-file flag + BEQ #30 ;Not end of file + +;Must call MAPMAN to extend file + + LDYIM ARGG ;**29/4/88** + LDAIY ARGPTR + STA NEWFSZ + INY + LDAIY ARGPTR + STA NEWFSZ+1 + JSR RDEXSZ ;**29/4/88** Extend file + BNE #40 ;Failed + +30 LDYIM ARGG ;BTSLFT := xfer size + LDAIY ARGPTR + STA BTSLFT + INY + LDAIY ARGPTR + STA BTSLFT+1 + + JSR RDSBFA ;Set RDBFAD + + JSR RDPBT1 ;Write 1st partial block + BNE #40 ;Failed + + JSR RDPBT2 ;Write complete disc blocks + BNE #40 ;Failed + + JSR RDPBT3 ;Write final partial block + BNE #40 ;Failed + +;Writing worked OK + + JSR RDSHWM ;Adjust file HWM + LDAIM 0 ;=> successful return +40 JMP RDEXIT ;EXIT: RC IN A + +; Routine to extend file. Called with amount required +; in NEWFSZ, NEWFSZ+1. Adds 4K to round up. +; Exit Z set if OK, else error code in A. + +RDEXSZ ROUT ;**29/4/88** + CLC + LDYIM RTCSFP ;NEWFSZ := SFP + xfer size + LDAIY RTEPTR ;SFP LS byte + ADC NEWFSZ ;xfer size (LS) + STA NEWFSZ + INY + LDAIY RTEPTR + ADC NEWFSZ+1 + STA NEWFSZ+1 ;CS + INY + LDAIY RTEPTR + ADCIM 0 + STA NEWFSZ+2 ;MS + LDAIM &8A + BCS #40 ;**29/4/88** Error if overflowed + + LDAIM &FF ;Add 255 to round up + CMP NEWFSZ+2 ;**29/4/88** Unless reaching 24 bits + BEQ #50 + CLC + ADC NEWFSZ ;Don't want LS byte + LDAIM 4 ;Add extra 1K + ADC NEWFSZ+1 + STA NEWFSZ+1 + BCC #25 + INC NEWFSZ+2 +25 + [ $CMOS + STZ NEWFSZ ;Clear LS byte + | + LDAIM 0 + STA NEWFSZ + ] +30 JSR RDCHSZ ;**29/4/88** call change size routine +40 RTS + +50 STA NEWFSZ ;**29/4/88** getting near max, + STA NEWFSZ+1 ;**29/4/88** round up now to max + [ $CMOS + BRA #30 + | + BNE #30 + ] + + + +;*** RDBLFT *** + +;Initialize BTSLFT, BTSXFD & EOFFLG +;for PUTBYTES/GETBYTES. +;Carry is used as entry condition ** 24/1/84 ** + +RDBLFT ROUT + [ $CMOS + STZ EOFFLG ;EOFFLG=0 + | + LDAIM 0 + STA EOFFLG ;EOFFLG=0 + ] + LDYIM RTFSZE ;BTSLFT := filesize - SFP + BCS #10 ;C=1 -> use filesize, use HWM + LDYIM RTHWM + SEC + +10 LDAIY RTEPTR ;** 24/1/84 ** + INY + STY RNDTMP + LDYIM RTCSFP + SBCIY RTEPTR + STA BTSLFT ;LS byte + LDY RNDTMP ;** 24/1/84 ** + LDAIY RTEPTR + LDYIM RTCSFP+1 + SBCIY RTEPTR + STA BTSLFT+1 ;CS Byte + INC RNDTMP ;** 24/1/84 ** + LDY RNDTMP ;next byte + LDAIY RTEPTR + LDYIM RTCSFP+2 + SBCIY RTEPTR ;MS byte left in A + + BCS #20 ;Size >= SFP + +;If filesize < SFP set BTSLFT to 0 + + LDAIM 0 ;BTSLFT := 0 + STA BTSLFT + STA BTSLFT+1 + +;Test xfer size > bytes left +;> if A non-zero (MS byte) +;or if xfer size > BTSLFT + +20 BNE #30 ;A not 0 + + SEC ;BTSLFT - xfer size + LDA BTSLFT + LDYIM ARGG + SBCIY ARGPTR + STA RNDTMP ;Store LS byte + LDA BTSLFT+1 + INY + SBCIY ARGPTR + ORA RNDTMP ;for zero test + BEQ #40 ;BTSLFT = xfer size + BCC #40 ;BTSLFT < xfer size + +;BTSLFT > xfer size: transfer OK +;Set BTSLFT := xfer size + +30 LDYIM ARGG + LDAIY ARGPTR + STA BTSLFT + INY + LDAIY ARGPTR + STA BTSLFT+1 + [ $CMOS + BRA #50 + | + JMP #50 + ] + +;BTSLFT < xfer size: transfer too long +;or outside file +;Set EOFFLG to $80 + +40 LDAIM &80 + STA EOFFLG + +;BTSLFT now says how many bytes can be +;transferred: set BTSXFD to this. + +50 LDA BTSLFT + STA BTSXFD + LDA BTSLFT+1 + STA BTSXFD+1 + + RTS + + +;*** RDSBFA *** + +;Set RDBFAD from call stack + +RDSBFA ROUT + LDYIM ARGE + LDAIY ARGPTR + STA RDBFAD + INY + LDAIY ARGPTR + STA RDBFAD+1 + RTS + + +;*** RDGBT1 *** + +;Read the first partial block of a GETBYTES +;transfer, taking the SFP to a disc block +;boundary. + +RDGBT1 ROUT + JSR RDSZE1 ;Get no. of bytes in A + CMPIM 0 + BEQ #10 ;Exit if empty partial block + STA RNDTMP ;Save no. of bytes + + JSR RDGBLK ;Get required block in cache + BNE #20 ;Failed + +;Copy from cache buffer to user buffer + + LDA RDBFAD ;MOVETO := RDBFAD + STA MOVTO + LDA RDBFAD+1 + STA MOVTO+1 + + LDYIM RTCSFP ;Offset in cache blk + LDAIY RTEPTR ;given by LS byte of SFP + CLC + ADC GENPTR + STA MOVFRM + LDA GENPTR+1 + ADCIM 0 + STA MOVFRM+1 + + LDX RNDTMP ;No. of bytes to copy + JSR MOVE ;Copy + JSR RDADJ1 ;Adjust BTSLFT, RDBFAD, SFP +10 LDAIM 0 ;Return +20 RTS + + +;*** RDPBT1 *** + +;Write the first partial block of a PUTBYTES +;transfer, taking the SFP to a disc block +;boundary. + +RDPBT1 ROUT + JSR RDSZE1 ;Get no. of bytes in A + CMPIM 0 + BEQ #10 ; Exit if empty partial block + STA RNDTMP ;Save no. of bytes + + JSR RDGBLK ;Get required block in cache + BNE #20 ;Failed + +;Copy from user buffer to cache buffer + + LDA RDBFAD ;MOVFRM := RDBFAD + STA MOVFRM + LDA RDBFAD+1 + STA MOVFRM+1 + + LDYIM RTCSFP ;Offset in cache blk + LDAIY RTEPTR ;given by LS byte of SFP + CLC + ADC GENPTR + STA MOVTO + LDA GENPTR+1 + ADCIM 0 + STA MOVTO+1 + + LDX RNDTMP ;No. of bytes to copy + JSR MOVE ;Copy + JSR MRKDRT ;Mark cache buffer dirty + JSR RDADJ1 ;Adjust BTSLFT, RDBFAD, SFP +10 LDAIM 0 ; Return +20 RTS + +;*** RDSZE1 *** + +;Return size of 1st partial block in A. +;size1 := (0 - LS byte of SFP) mod 256 +;size := min(size1, BTSLFT) + +RDSZE1 ROUT + LDAIM 0 + SEC + LDYIM RTCSFP + SBCIY RTEPTR ;0 - LS(SFP) + + LDX BTSLFT+1 ;Is BTSLFT > 256 + BNE #10 ; Yes + CMP BTSLFT + BCC #10 ;A < BTSLFT + LDA BTSLFT ;A > BTSLFT +10 RTS + + +;*** RDADJ1 *** + +;Adjust BTSLFT, RDBFAD, SFP by RNDTMP + +RDADJ1 ROUT + SEC ;BTSLFT -:= RNDTMP + LDA BTSLFT + SBC RNDTMP + STA BTSLFT + BCS #10 + DEC BTSLFT+1 +10 CLC ;RDBFAD +:= RNDTMP + LDA RDBFAD + ADC RNDTMP + STA RDBFAD + BCC RDADJ3 + INC RDBFAD+1 + +;RDADJ3 entry adjusts SFP only + +RDADJ3 CLC ;SFP +:= RNDTMP + LDYIM RTCSFP + LDAIY RTEPTR + ADC RNDTMP + STAIY RTEPTR + INY + LDAIY RTEPTR + ADCIM 0 + STAIY RTEPTR + INY + LDAIY RTEPTR + ADCIM 0 + STAIY RTEPTR + RTS + + +;*** RDGBT2 *** and *** RDPBT2 *** + +;Do middle part of GETBYTES or PUTBYTES transfer +;i.e. that part consisting of whole disc blocks. + +;The code is identical apart from the disc action. + +RDGBT2 ROUT + LDAIM 1 ;DSCMAN.READ + [ $CMOS + BRA #10 + | + BNE #10 + ] + +RDPBT2 LDAIM 2 ;DSCMAN.WRITE - PUTBYTES entry +10 STA RNDTMP ;Store disc action for later +;Determine how many whole blocks there +;are to be transferred. +;*** Assumes blocksize = 256 bytes *** + + LDA BTSLFT+1 ;Blocks = ms byte of bytes left + BEQ #20 ;Nothing to do + +;Must flush all blocks of object from +;cache before doing direct transfer. + + JSR RDFALL ;Leaves DISC & SIN on NEWARG stack + BNE #30 ;Failed + +;Call DSCMAN to READ/WRITE directly from/to +;caller's buffer. + +;Start block no. is given by MS +;two bytes of SFP. + + LDYIM RTCSFP+1 + LDAIY RTEPTR ;SFP (CS) + LDYIM ARGG + STAIY NEWARG ;Block no. (LS) + LDYIM RTCSFP+2 + LDAIY RTEPTR ;SFP (MS) + LDYIM ARGH + STAIY NEWARG ;Block no. (MS) + +;Number of blocks is given by MS +;byte of BTSLFT. + + LDA BTSLFT+1 + INY + STAIY NEWARG + LDAIM 0 ;MS byte of block count + INY ;always zero (in 64K machine) + STAIY NEWARG + + LDA RDBFAD ;Put buffer address on stack + INY + STAIY NEWARG + LDA RDBFAD+1 + INY + STAIY NEWARG + +;Operation code was placed in RNDTMP +;on entry to this routine. + + LDA RNDTMP + JSR SETRTN + JSR DSCMAN ;*** DSCMAN.READ or DSCMAN.WRITE ** + BNE #30 ;Failed + +;Must adjust SFP in RANDTB, RDBFAD, and BTSLFT +;*** Assumes blocksize 256 bytes *** + + LDA BTSLFT+1 ;No. of blocks + LDYIM RTCSFP+1 ;Add to CS byte of SFP + CLC + ADCIY RTEPTR + STAIY RTEPTR ;Put back + INY + LDAIM 0 + ADCIY RTEPTR ;Carry to MS byte of SFP + STAIY RTEPTR ;Put back + +;Adjust MS byte of RDBFAD by no. of blocks + + LDA BTSLFT+1 ;No. of blocks + ADC RDBFAD+1 ;MS byte of buffer addr + STA RDBFAD+1 ;Put back + +;Only a partial block remains, so MS +;byte of BTSLFT is now zero + + [ $CMOS + STZ BTSLFT+1 + | + LDAIM 0 + STA BTSLFT + 1 + ] + +20 LDAIM 0 ; Return +30 RTS + +;*** RDGBT3 *** + +;Read the last partial block of a GETBYTES +;transfer + +RDGBT3 ROUT + LDA BTSLFT ;Get no. of bytes in A + BEQ #10 ;Nothing to do + JSR RDGBLK ;Get required block in cache + BNE #20 ;Failed + +;Copy from cache buffer to user buffer + + LDA RDBFAD ;MOVTO := RDBFAD + STA MOVTO + LDA RDBFAD+1 + STA MOVTO+1 + + LDA GENPTR ;MOVFRM := GENPTR + STA MOVFRM + LDA GENPTR+1 + STA MOVFRM+1 + + LDX BTSLFT ;No. of bytes to copy + STX RNDTMP ;Store for RDADJ3 below + JSR MOVE ;Copy + JSR RDADJ3 ;Adjust SFP +10 LDAIM 0 +20 RTS + +;*** RDPBT3 *** + +;Write the last partial block of a PUTBYTES +;transfer + +RDPBT3 ROUT + LDA BTSLFT ;Get no. of bytes in A + BEQ #10 ;Nothing to do + JSR RDGBLK ;Get required block in cache + BNE #20 ;Failed + +;Copy from user buffer to cache buffer + + LDA RDBFAD ;MOVFRM := RDBFAD + STA MOVFRM + LDA RDBFAD+1 + STA MOVFRM+1 + + LDA GENPTR ;MOVTO := GENPTR + STA MOVTO + LDA GENPTR+1 + STA MOVTO+1 + + LDX BTSLFT ;No. of bytes to copy + STX RNDTMP ;For RDADJ3 call below + JSR MOVE ;Copy + JSR MRKDRT ;Mark cache buffer dirty + JSR RDADJ3 ;Adjust SFP +10 LDAIM 0 +20 RTS + +;********* RDEOF ***************** + +;RDEOF: read "end of file" condition + +;Entry: ARGA = fn. code (#0F) +;ARGB = ptr. to user info (LS) +;ARGC = ptr. to user info (MS) +;ARGD = handle + +;Exit : ARGA = RC +;ARGB = zero if SFP <= HWM +;#FF if SFP => HWM + +RDEOF ROUT + JSR INITRD + LDYIM ARGD + LDAIY ARGPTR + JSR FNDHND ;Check handle/machine pair + BNE #30 ;Error -> exit + JSR SETRPT ;Set Random table ptr. (& check is file) + BNE #30 ;Not a file -> exit + + JSR CMPHWP ;Compare HWM with PTR + BEQ #10 ;Ptr = HWM -> exit w/$FF + LDAIM 0 + BCS #20 ;Ptr < HWM -> exit w/zero + +10 LDAIM &FF + +20 LDYIM ARGB + STAIY ARGPTR ;Set result + LDAIM 0 ;Set return code +30 JMP RDEXIT ;Return + + LNK Rman05 diff --git a/FileServer/SRC/FileServer/Rman05 b/FileServer/SRC/FileServer/Rman05 new file mode 100644 index 0000000..400505a --- /dev/null +++ b/FileServer/SRC/FileServer/Rman05 @@ -0,0 +1,248 @@ + OPT RMAN05 ; > .Rman05 + TTL File server file RMAN05 + + +;** RNDMAN UTILS ** + +;*** GETRND *** + +;Get free slot in RANDTB. + +;Exit: A = RC +;RTEPTR = Ptr to free RANDTB entry + +GETRND ROUT + LDA RANDTB ;RTEPTR := RANDTB + STA RTEPTR + LDA RANDTB+1 + STA RTEPTR+1 + + LDX RTNENT ;X := no. of entries in RANDTB + LDYIM RTINUS ;Y := offset of "in use" byte in entry + +10 LDAIY RTEPTR ;Get an "in use" byte + BEQ #20 ;Free entry found - exit A=0, Z set + + CLC ;RTEPTR +:= entry size + LDAIM RTENSZ + ADC RTEPTR ;LS byte + STA RTEPTR + BCC #15 + INC RTEPTR+1 ;MS byte +15 DEX ;Any entries left? + BNE #10 ;Jump if yes + +;No entries left + + LDAIM RDERRG ;"RANDTB full" +20 RTS + + +;*** RDCKAC *** + +;Check that the requested access to a file is allowed. +;Check first that the access is allowed in +;the directory entry, and secondly that it can +;be granted within a multiple reader / single +;writer regime (by scanning HANDTB). + +;Entry: ARGD (on ARGPTR) = requested access +;ARGE = allowed access (from directory entry) +;RNDPTR points to object details + +;Exit: A = RC +;HNDPTR is corrupted + +RDCKAC ROUT + LDYIM ARGD + LDAIY ARGPTR ;Get requested access + ANDIM RDWRAC ;Mask out type bit + STA RNDTMP ;Keep masked copy + INY + ANDIY ARGPTR ;AND with allowed access + CMP RNDTMP ;Should equal requested access + BEQ #10 ;Access allowed + LDAIM RDERRK ;"Access not allowed" + RTS + +10 JSR INITHD ;HNDPTR := HANDTB; X := no. of entries + +20 LDYIM HTHAND + LDAIY HNDPTR ;Is this an empty entry? + BEQ #30 ;Skip if empty + +;A used HANDTB entry: check disc no. and SIN +;against those of file we want to open. + + LDYIM INFDIS ;Compare disc numbers + LDAIY RNDPTR + LDYIM HTDISC + CMPIY HNDPTR + BNE #30 ;LS bytes differ + LDYIM INFDIS+1 + LDAIY RNDPTR + LDYIM HTDISC+1 + CMPIY HNDPTR + BNE #30 ;MS bytes differ + + LDYIM INFSIN ;Compare SINs + LDAIY RNDPTR ;A := LS byte of SIN for OPEN + LDYIM HTSIN + CMPIY HNDPTR + BNE #30 ;LS bytes differ + LDYIM INFSIN+1 + LDAIY RNDPTR + LDYIM HTSIN+1 + CMPIY HNDPTR + BNE #30 ;CS bytes differ + LDYIM INFSIN+2 + LDAIY RNDPTR + LDYIM HTSIN+2 + CMPIY HNDPTR + BNE #30 ;MS bytes differ + +;Have found an existing HANDTB entry for the SIN +;we want to open. +;Open can be permitted only if it is for reading, +;and the file is not already open for writing. + + LDYIM HTMODE + LDAIY HNDPTR ;A := mode in which already open + LDYIM ARGD + ORAIY ARGPTR ;OR requested access with that already granted + ANDIM WRITAC ;Look at write access bit + BEQ #30 ;Both for reading - proceed with search + +;The file is already open, and: +;either the request includes write access, or the +;file is already open with write access. + + JSR RDopat ;record 'open at' details + LDAIM RDERRH ;"File in use" + RTS + +;Have not yet found a reason to disallow the +;OPEN. Keep looking! + +30 JSR INCHND ;Point HNDPTR at next entry; X -:= 1 + BNE #20 ;back to start of loop + +;Have searched all of HANDTB - open may proceed + + LDAIM 0 ;set RC + RTS + + + +;*** RDopat *** + +;Record details of station at which a file is open (for use in error +; messages). HNDPTR points to the handle table entry for the object. + +RDopat ROUT ;**20/5/87** + LDYIM HTMCNO + LDAIY HNDPTR + STA MCopat + INY + LDAIY HNDPTR + STA MCopat+1 + INY + LDAIY HNDPTR + STA MCopat+2 + RTS + + +;*** CLRRTE *** + +;Clear entry in RANDTB pointed to by HANDTB entry +;whose address is in HNDPTR. + +CLRRTE ROUT + JSR SETRPT ;RTEPTR := address of RANDTB entry + + LDYIM RTENSZ-1 ;Y := size of RANDTB entry + LDAIM 0 +10 STAIY RTEPTR ;Clear whole entry to zero + DEY + BPL #10 ;Loop if more to do + RTS ;No result + + + +;*** RDFLSH *** + +;Flush all blocks of an object from cache. +;Called from CLRHTE when closing a file. + +;Entry: HNDPTR contains address of HANDTB entry + +RDFALL ROUT + LDAIM 5 ;STRMAN.remove all blocks + [ $CMOS + BRA #10 + | + BNE #10 + ] +;** 5/8/83 ** +RDFLSH LDAIM 9 ;STRMAN.REMOVEALLDIRTYWONDOWS +10 JSR SETRTN + JSR RDDSIN ;Put disc and SIN on stack + + JMP STRMAN ;*** Call STRMAN ** + + +;*** RDSHWM *** + +;IF seq file ptr > high water mark +;THEN high water mark := seq file ptr + +;Entry: RTEPTR points to RANDTB entry + +RDSHWM ROUT + JSR CMPHWP + BCS #10 ;SFP <= HWM, return + + LDYIM RTCSFP ;SFP > HWM, so copy + LDAIY RTEPTR ;SFP to HWM field + LDYIM RTHWM + STAIY RTEPTR ;LS byte + LDYIM RTCSFP+1 + LDAIY RTEPTR + LDYIM RTHWM+1 + STAIY RTEPTR ;CS byte + LDYIM RTCSFP+2 + LDAIY RTEPTR + LDYIM RTHWM+2 + STAIY RTEPTR ;MS byte +10 RTS + + + +;Compare High Water Mark with Seq. file +;ptr. and return CC if SFP>HWM, CS if +;SFP<=HWM. +;Also returns Z flag indicating EQ or not. + +;NOTE - corrupts RNDTMP + +CMPHWP ROUT + SEC + LDYIM RTHWM ;Subtract SFP from HWM + LDAIY RTEPTR ;LS byte of HWM + LDYIM RTCSFP + SBCIY RTEPTR ;Subtract LS bytes + STA RNDTMP + LDYIM RTHWM+1 + LDAIY RTEPTR + LDYIM RTCSFP+1 + SBCIY RTEPTR ;Subtract CS bytes + STA RNDTMP+1 + LDYIM RTHWM+2 + LDAIY RTEPTR + LDYIM RTCSFP+2 + SBCIY RTEPTR ;Sets carry if SFP <= HWM + ORA RNDTMP + ORA RNDTMP+1 ;Return Z flag indicating EQ or not + RTS + + LNK Uade0A diff --git a/FileServer/SRC/FileServer/Uade01 b/FileServer/SRC/FileServer/Uade01 new file mode 100644 index 0000000..3729ae0 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade01 @@ -0,0 +1,477 @@ + OPT 2 ; > .Uade01 + TTL File server file UADE01 + +;************************* +;printing on/off per file +;************************* + +ON * 4+1 ;printer on, new page +OFF * 2 ;printer off + +UADE01 * Off +UADE02 * Off +UADE03 * Off +UADE04 * Off +UADE05 * Off +UADE06 * Off +RMAN01 * Off +RMAN02 * Off +RMAN03 * Off +RMAN04 * Off +RMAN05 * Off +UADE0A * Off +UADE0B * Off +UADE0C * Off +UADE0D * Off +UADE0E * Off +UADE0F * Off +UADE10 * Off +UADE11 * Off +UADE12 * Off +UADE13 * Off +UADE14 * Off +MBBMCM * Off +UADE15 * Off +UADE16 * Off +UADE17 * Off +UADE18 * Off +UADE19 * Off +UADE20 * Off +PRINT0 * Off +FORM00 * Off + + OPT UADE01 ;select allotted printer option + +;********************************* +;* H E A D E R F I L E 1 * +;********************************* + +; Supported languages + +English * 0 +Italian * 1 ; **18/2/87** + +BBC * &00 +Winch * &00 ;If Winchester discs +Sys * &FF ;flags to indicate which type of FS +Ztime * &FF +FS * &FF +Dongle * 0 ;Real Time Clock present(=0) absent(=1) + +Debug * 0 ;Make this +ve for debug letters + + [ $Level3 +Verla * "3" ;Version number & level +Verlb * "1" ;Range 0-99 20/7/88 + | +Verla * 1 ;Version number & level +Verlb * 31 ;Range 0-99 20/7/88 + ] + +Lang * English +Mask * &3F ;protection state (&3F for service system) +Yes * 0 +No * &FFFF +Cachesw * No ; Disable big-buffer caching (ware use of BBUF for replies) + [ $Level3 +Pseudods * No ; **18/2/88** Pseudo directory (%, &, @) switch + | +Pseudods * No ; + ] + +;*** MODULE CODE NAMES *** + +;* NOTE WHENEVER A MODULE IS ENTERED * +;* IT PLACES ITS NAME ON THE ARGUMENT * +;* STACK (THIS IS DONE BY THE ENTER RTN) * + + +MODUSR * &10 ;=> USRMAN (THE USERTB MANAGER) +MODAUT * &20 ;=> AUTMAN (THE AUTHENTICATOR) +MODSTR * &30 ;=> STRMAN (THE STORE MANAGER) +MODDIR * &40 ;=> DIRMAN (THE DIRECTORY MANAGER) +MODMAP * &50 ;=> MAPMAN (THE MAP MANAGER) +MODRND * &60 ;=> RNDMAN (THE RANDOM ACCESS MANAGER) +MODDSC * &70 ;=> DSCMAN (THE DISC MANAGER) +MODCOM * &80 ;=> CMND. PROCESSOR PSEUDO NAME + +EXTER0 * &C0 ;=> external (BBC Machine) number + +;USRMAN RETURN CODES + +URERRA * EXTER0-1 ;MACHINE NUMBER NOT IN USERTB +URERRB * EXTER0-8 ;USERTB FULL +URERRD * MODUSR+4 ;OBJECT NOT A DIRECTORY +URERRE * EXTER0-&12 ;USER NOT LOGGED ON +URERRF * MODUSR+6 ;M/C NUMBER EQUALS ZERO + +;STRMAN RETURN CODES + +STERRB * MODSTR+2 ;SIN = 0 +STERRD * MODSTR+4 ;REF COUNT = $00 +STERRE * MODSTR+5 ;SIZE TOO BIG OR SIZE=0 ! +STERRF * MODSTR+6 ;INVALID WINDOW ADDRESS +STERRG * MODSTR+7 ;NO FREE CACHE DESCRIPTORS +STERRH * MODSTR+8 ;WINDOW REF COUNT > 0 +STERRK * MODSTR+&0B ;REF COUNT = $FF +STERRL * MODSTR+&0C ;STORE DEADLOCK !! +STERRM * MODSTR+&0D ;ARITH OVERFLOW IN TSTGAP + +;DIRMAN RETURN CODES + +DRERRA * &CC ;INVALID SEPARATOR IN FILE TITLE +DRERRB * MODDIR+2 ;BROKEN DIRECTORY +DRERRC * &D6 ;OBJECT NOT FOUND +DRERRD * EXTER0-2 ;OBJECT NOT A DIRECTORY +DRERRE * EXTER0-3 ;INSUFFICIENT ACCESS +DRERRF * MODDIR+6 ;WRONG ARG TO SET/READ OBJECT ATTRIBUTES +DRERRG * &C3 ;DIR ENTRY LOCKED +DRERRI * &C2 ;OBJECT IN USE (I.E. OPEN) +DRERRJ * EXTER0-&C ;DIR NOT EMPTY +DRERRK * EXTER0-&11 ;TYPES DON'T MATCH +DRERRL * MODDIR+12 ;NO WRITE ACCESS +DRERRM * EXTER0-&D ;MAX DIR SIZE REACHED +DRERRN * MODDIR+14 ;CLIENT ASKS FOR TOO MANY ENTRIES +DRERRO * MODDIR+15 ;BAD ARG. TO EXAMINE +DRERRP * MODDIR+1 ;cdir too big + +;AUTMAN RETURN CODES + +ATERRA * MODAUT+1 ;CANNOT FIND PASSWORD FILE +ATERRB * EXTER0- 4 ;USERID NOT FOUND IN PW FILE +ATERRC * EXTER0- 5 ;INCORRECT PASSWORD +ATERRD * EXTER0- 6 ;INSUFFICIENT PRIVILEGE +ATERRE * EXTER0- 7 ;SYNTAX ERROR IN PASSWORD +ATERRF * EXTER0-&F ;USERID ALREADY IN PASSWORD FILE +ATERRG * &AC ;bad user name in PW file**13/4/83** +ATERRH * EXTER0-&E ;PASSWORD FILE FULL UP +ATERRI * MODAUT+9 ;OBJECT '$.PASSWORDS' HAS WRONG TYPE + + +;RNDMAN RETURN CODES + +RDERRA * MODRND+1 ;RNDMAN.RESTART CALLED TWICE +RDERRB * &DE ;INVALID HANDLE +RDERRC * &C0 ;HANDLE QUOTA EXHAUSTED +RDERRD * MODRND+4 ;HANDTB FULL +RDERRE * RDERRA ;OBJECT NOT OPEN +RDERRF * MODRND+6 ;RNDMAN.COPY NOT FOR FILE OBJECTS +RDERRG * MODRND+7 ;RANDTB FULL +RDERRH * &C2 ;File already open +RDERRI * MODRND+9 ;Object not file +RDERRJ * &DF ;END OF FILE +RDERRK * DRERRE ;Insufficient access +RDERRL * EXTER0-&9 ;Attempt to point outside file +RDERRM * MODRND+&0D ;Invalid arg to RDSTAR +RDERRN * &C1 ;File not open for update +RDERRO * &D4 ;File not open for input ** 15/11/84 ** + + + +;MAPMAN RETURN CODES + +MPERRA * &C8 ;DISC NUMBER NOT FOUND +MPERRB * &C6 ;DISC SPACE EXHAUSTED +MPERRC * MODMAP+3 ;SIN NOT FOR START OF CHAIN +MPERRD * MODMAP+4 ;DISC NOT A FILE SERVER DISC +MPERRF * MODMAP+6 ;ILLEGAL DRIVE NUMBER +MPERRI * MODMAP+9 ;NEW MAP DOESN'T FIT IN OLD SPACE +MPERRJ * MODMAP+&0A ;DISC OF SAME NAME ALREADY IN USE ! +MPERRK * &D6 ;DISC NAME NOT FOUND +MPERRL * EXTER0-&A ;DISC ERROR ON MAP READ/WRITE +MPERRM * MODMAP+11 ;NO MORE SPACE IN MAP DESCRIPTORS +MPERRN * MODMAP+12 ;Insufficient user free space (yay!) + + +;DSCMAN RETURN CODES + +DCERRA * MODDSC+1 ;INVALID NUMBER OF SECTORS +DCERRB * MODDSC+2 ;STORE ADDRESS OVERFLOW +DCERRC * MODDSC+3 ;ACCESSING BEYOND END OF FILE +DCERRE * &C9 ;DISC PROTECTED +DCERRF * &C7 ;UNRECOVERABLE DISC ERROR + + +;COMMAND PROC Errors + +RNAMQQ * EXTER0-&10 ;Renaming across two discs +LODERA * EXTER0-&B ;Trying to load a directory +LODERB * DRERRE ;Insufficient access +SAVERA * MODCOM+3 ;Too much data sent from client +WAITER * MODCOM+4 ;Wait bombs out +COERRA * MODCOM+5 ;Invalid function code + +SAERRA * &CF ;Invalid setaccess string +SYNERR * &DC +NAMERR * &FD ;Bad file name etc. +NUMERR * &F0 ;Bad number +SAERRC * MODCOM+&0A ;File too big +WOTERR * &FE +SPERRA * MODCOM+&0C ;Bad privilege letter +PBERRA * MODCOM+&0D ;Excess data in PUTBYTES +INFERA * MODCOM+&0E ;Bad INFO argument. +ARGERR * MODCOM+&0F ;Bad arg to RDAR +DTERR * MODCOM+&10 ;Bad date and time + [ $CMOS +PRerrl * &CC ;Printer name too long ** 25/09/86 ** +Doorer * &CD ;Door open on FSMODE U ** 31/08/86 ** + ] + +;INTERNAL ERRORS + +IERRAA * 1 ;(SETFS) FRAME SIZE TOO BIG +IERRAB * 2 ;(ENTRY) FUNCT CODE = 0 +IERRAC * 3 ;(ENTRY) UNKNOWN ENTRY REASON +IERRAD * 4 ;(GETVEC) SIZE TOO BIG +IERRAE * 5 ;(GETVEC) INSUFFICIENT SPACE +IERRAF * 6 ;(GETVEC) SIZE OF STORE REQUESTED = 0 +IERRAH * 8 ;(GETINT) NOT A DIGIT +IERRAI * 9 ; UNABLE TO OPEN RXCB +IERRAJ * 10 ;(RDBTMP) BIT MAP DISC ERROR +IERRAK * 11 ;writing to sector zero + + + ;NEW ERRORS FOR LEVEL3 + + ;F4 ;Memory map error + ;F5 ;Internal bit map cache error + ;F6 ;cached bit map holds no free sectors + ;F8 ;write error (data read <> data written) + ;F9 ;attempting to zero an illegal amount of disc + ;FA ;multiple block allocate fails + ;FB ;memory error during initial MEMTST + ;FC ;single block allocate fails + +;COMMAND CODES SENT TO CLIENT + +CCSAVE * 1 +CCLOAD * 2 +CCCAT * 3 +CCINF * 4 +CCLGON * 5 +CCSDIS * 6 +CCSDIR * 7 +CCCMND * 8 +CCSLIB * 9 +CCDSCS * &A +CCUSRS * &B + +;M A N I F E S T S +;ODDS AND ENDS +Oswrch * &FFEE ;BBC addresses here +Osrdch * &FFE0 +Oscrlf * &FFE7 +Oscli * &FFF7 +Osasci * &FFE3 +Osword * &FFF1 +Osbyte * &FFF4 + +Stksze * &FF ;Size of argument stack +FDcyls * 80 ;No of cylinders per floppy +FDside * 2 ;No of sides per disc +FDsecs * 16 ;No of sectors per track (side) +Maxuse * 80 ;Maximum number of users +Baseyr * 81 ;Base year for date = 1981 +Thisyr * 88 ;Earliest year acceptable + [ $CMOS +Prport * &D1 ;Print server port +Prlong * 256 ;Print server max buffer length +Prpolp * &9F ;POLLPS reception port +Prpolr * &9E ;POLLPS reply port +Prtimo * 30 ;Printer timeout in seconds (3-650) + + +; Define non-volatile workspace in CMOS - 146818 clock chip +; Bytes 0-13 are date/time function, must not go beyond 63. + + ^ 14 ;Start after date/time space +CMinst # 0 ;**5/3/88** start of area to init +Stnids # 2 ;ECOnet station id + # 4 ;spares for MOS use +IEaddr # 8 ;INTERR Log out area +MUaddr # 1 ;MAXUSR storage area +MDaddr # 1 ;MAXDRV storage area +Praddr # 6 ;POLLPS name address +FSusid # 12 ;Stored command mode system id +FSusie # 0 ;End of system id space +PRnoFF # 1 ;**8/2/88** Non-zero to suppress FF +CAcopy # 1 ;**23/3/88** Non-zero if no ACORN copyright check +CMinen # 0 ;**5/3/88** End of area to init + ] + +ESC * &1B +ABTCH * "Q" +ACK * 6 +NACK * &15 + +;DIRTY MARKER (CLEAN=0) + +DIRTY * &FF +UNLKIT * &FF + +;INTER MODULE ARGUMENT STACK CONSTANTS + +FRAMSZ * 0 ;POSN OF FRAME SIZE ON ARGUMENT STACK +MODNME * 1 ;POSN OF MODULE NAME ON ARGUMENT STACK +ENTRES * 2 ;POSN OF MODULE ENTRY REASON ON ARGUMENT STACK +FINFO * ENTRES+1 ;SIZE OF INFO STORED ON ARGUMENT STACK + +ARGA * FINFO ;FOR FUNCTION CODE AND RETURN CODE +ARGB * ARGA+1 +ARGC * ARGB+1 +ARGD * ARGC+1 +ARGE * ARGD+1 +ARGF * ARGE+1 +ARGG * ARGF+1 +ARGH * ARGG+1 +ARGI * ARGH+1 +ARGJ * ARGI+1 +ARGK * ARGJ+1 +ARGL * ARGK+1 +ARGM * ARGL+1 +ARGN * ARGM+1 +ARGO * ARGN+1 +ARGP * ARGO+1 +ARGQ * ARGP+1 +ARGR * ARGQ+1 +ARGS * ARGR+1 +ARGT * ARGS+1 + +;DISC BLOCK SIZE +BLKSZE * &100 ;= 256 BYTES + + +;FLAGS AND MASKS (ACCESS BITS ETC.) +READAC * 1 ;BIT0 -> READ ACCESS +WRITAC * 2 ;BIT1 -> WRITE ACCESS +LOCKED * &10 ;BIT4 -> LOCK BIT +TYPE * &20 ;BIT5 -> TYPE BIT (DIR/FILE) +LOPRIV * &20 ;BIT5 -> Low privilege bit +OWNER * &40 ;BIT6 -> OWNER ACCESS BIT +SYSTPV * &40 ;BIT6 -> SYSTEM PRIVILEGE +NTSYST * &BF ;Complement of SYSTPV +INUSE * &80 ;BIT7 -> IN USE BIT +FILEJC * &80 ;BIT7 -> FILE JUST CREATED +TYPFIL * 0 ;OBJECT TYPE = FILE +TYPDIR * &20 ;OBJECT TYPE = DIRECTORY +ANYBDY * 0 ;ANYBODY ACCESS +RDWRAC * 3 ;READ WRITE ACCESS +RWLACC * &13 ;Read/write/locked access +ACCDEF * &C ;Owner RW, public no access +TXFLAG * &80 +RXFLAG * &7F +MONON * &FF +MONOFF * 0 ;Monitor switch + + +;D O S ROUTINES AND ADDRESSES + +TRADD * 1 +CMD * 5 +LENGTH * &B + +;PAGE ZERO + + ^ &B0 +ARGPTR # 2 ;PTR TO CUR STK ARGS +NEWARG # 2 ;PTR TO NEW ARGS + [ $CMOS +MAPTMP # 3 ;Temp (MAPMAN) ** +MPTMPA # 3 ;Temp (MAPMAN) ** +MPTMPB # 3 ;Temp (MAPMAN) ** +MPTMPC # 3 ;Temp (MAPMAN) ** + ] + + ^ &20 +CLRPTR # 2 ;PTR USED BY CLRSTR RTN +MOVFRM # 2 ;PTR USED BY MOVE & COMPAR RTNS +MOVTO # 2 ;PTR USED BY MOVE & COMPAR RTNS + [ $Level3 +COMPTR # 2 ;PTR TO COMND LINE (RDLINE) + ] +GENPTR # 2 ;PTR AVAILABLE TO ALL MODULES +USTPTR # 2 ;PTR TO USERTB (USRMAN/FINDMC) +URMPPT # 2 ;PTR TO USERINFO(USRMAN) +PREV # 2 ;PTR TO PREVIOUS CACHE ENTRY(STRMAN) +CRNT # 2 ;PTR TO CURRENT CACHE ENTRY(STRMAN) +CMPPTR # 2 ;PTR TO ARGUMENTS (STRMAN) +NAMPTR # 2 ;PTR TO FILE TITLE (DIRMAN) +PREVEN # 2 ;PTR TO PREVIOUS DIR ENTRY (DIRMAN) +CRNTEN # 2 ;CURRENT DIR ENTRY (DIRMAN) +TXTPTR # 2 ;USED TO PT TO CHARS IN TXTNAM(DIRMAN) +DIRFRE # 2 ;PTR TO FREE CHAIN PTR (DIRMAN) + [ $CMOS +OBJSIN # 3 ;Sin of current obj (DIRMAN) ** + ] +INFPTR # 2 ;PTR TO STORE AREA FOR RETRIEVE INFO +DPTRLD # 2 ;PTR TO FIRST BYTE OF A DIR +DPTRTR # 2 ;PTR TO LAST BYTE OF DIR +DRUSIN # 2 ;PTR TO USERINFO +HNDPTR # 2 ;PTR TO HANDLE INFO (SET BY FNDHND) +RNDPTR # 2 ;PTR TO OBJECT DETAILS (RNDMAN) +RNDTMP # 3 ;Temp (RNDMAN) ** +AUTPTR # 2 ;POINTER TO USERID (AUTMAN) +PWFPTR # 2 ;PASSWORD FILE POINTER(AUTMAN) +ATUSPT # 2 ;PTR TO AUTMAN'S USERINFO AREA + [ $Level3 +JWORK # 2 ;Used in UADE14 + ] +MAPPTR # 2 ;PTR TO BASE OF DISC MAP +MPSCPT # 2 ;POINTER INTO MAP +MPMBPT # 2 ;MAP BLOCK PTR +MAPENT # 2 ;PTR. TO MAP TABLE ENTRY +MPCYPT # 2 ;PTR TO CYLINDER MAP +MAPGEN # 2 ;GENERAL MAP MANAGER PTR +GNCBPT # 2 ;GENERAL CONTROL BLOCK POINTER + [ $CMOS +CBSIN # 3 ;Current CB Sin ** + ] +DNMPTR # 2 ;PTR TO DISC NAME (MAPMAN) + [ $Level3 +DNMBUF # &12 ;DISC NAME BUFFER +DSCTMP # 2 ;PTR TO A MAP'S DIRTY FLAG (DSCMAN) +CVTUPT # 2 ;USER INF. PTR. CVT. PROG. +SCTPTR # 2 ;PTR TO SECTOR ZERO (SEE STRTFS) + | +DIVPAR # 3 ;Temp (MAPMAN) ** +DIVTMP # 3 ;Temp (MAPMAN) ** +MPTMPD # 3 ;Temp (MAPMAN) ** +MPTMPE # 3 ;Temp (MAPMAN) ** + ] +NETCB # 2 ;POINTER TO NET CONTROL BLOCK (C.PROC.) +RTEPTR # 2 ;Ptr. to RNDTAB entry +RDUPTR # 2 ;Ptr. to user id. in RNDPTR +COZERO # 12 ;12 byte area used by C.proc. + ;zero page used in RENAME 24/9/84 +LAST * COZERO +NAME * LAST+1 +ONAME * NAME+1 +RTYPE * ONAME+1 +PTR * RTYPE+1 +PTR1 * PTR+2 +REXIST * PTR1+2 + ;*** + [ $Level3 +VSTPTR # 2 ;are used by VSTRNG only +OLDEV # 2 +GP1 # 2 ;ANOTHER GENERAL POINTER +BRKPTR * &FD ;2 byte pointer used in MOS BRK handling + | +GP1 # 2 ;ANOTHER GENERAL POINTER +BREGA # 3 ;3 byte work variable (MULTBS) ** +OFF1 # 1 ;Arg to MOVBLK ** +OFF2 # 1 ;Arg to MOVBLK ** +TEMPA # 2 ;Temp ** +TEMPB # 2 ;Temp ** + +; ** note that items marked ** are in zero page only to save space +; due to number of references. Move back to work pages if necessary. + + ^ &10 +Prxcb # 13 ;Print server receive CB +Prjump # 2 ;Print server next entry address +Pstate # 1 ;Print server status +Prbusy * &80 ;Print server busy + ] + + LNK UADE02 diff --git a/FileServer/SRC/FileServer/Uade02 b/FileServer/SRC/FileServer/Uade02 new file mode 100644 index 0000000..f077818 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade02 @@ -0,0 +1,675 @@ + OPT UADE02 ; > .Uade02 + TTL File server file UADE02 + +;********************************** +;* H E A D E R F I L E 2 * +;********************************** + +BRKVEC * &202 +BPUTV * &218 +TSTART * &F800 + +;*** STRMAN MANIFESTS *** +;CACHE ENTRY DESCRIPTOR OFFSETS + ^ 0 +CEDISC # 2 ;DISC NO +CESIN # 3 ;SIN OF OBJECT +CEBKNO # 2 ;START BLOCK NUMBER IN OBJECT +CEBLKS # 2 ;NUMBER OF BLOCKS OCCUPIED BY WINDOW +CESTA # 2 ;STORE ADDRESS OF OBJECT +CERCNT # 1 ;REFERENCE COUNT +CEAGE # 1 ;AGE FOR LRU REPLACEMENT ALGORITHM +CENEXT # 2 ;PTR TO NEXT DESCRIPTOR +CESIZE * @ ;SIZE OF A DESCRIPTOR +;THE ADDRESS OF DIRTY FLAG IS = STORE ADDRESS OF WINDOW - 1 + +;STRMAN BUFFER SIZE +LGBFSZ * 6 * BLKSZE ;SIZE OF A LARGE BUFFER(MUST BE MULTIPLE OF BLKSZE) +;** 6/12/84 ** + +;BUFFER AGES +LRU * 1 ;=> LEAST RECENTLY USED +MRU * &FF ;=> MOST RECENTLY USED + +;*** DIRMAN MANIFESTS *** +;DIRECTORY OFFSETS +;(HEADER INFORMATION) +;NOTE THAT A ONE BYTE SEQUENCE NUMBER (INCREMENTED WHEN +;WRITING A DIR TO DISC) BRACKETS A DIRECTORY. +;THE LEADING SEQUENCE NUMBER GOES AT BYTE OFFSET 2 +;AND THE TRAILING SQ NO IS THE LAST BYTE OF A DIR. +;THESE SQ NOS ARE USED TO DETECT DIRS WHICH HAVE NOT +;BEEN WRITTEN TO DISC COMPLETELY - +;NOTE DIRS CAN BE MULTI-SECTOR OBJECTS. +;SQ NOS ARE CHECKED WHENEVER A DIR IS LOADED. + ^ 0 +DRFRST # 2 ;PTR TO 1ST ENTRY (N.B. DON'T CHANGE THIS) +DRSQNO # 1 ;LEADING SEQUENCE NUMBER (1 BYTE) +DRNAME # &A ;(NAMLNT BYTES) DIRECTORY NAME +DRFREE # 2 ;PTR TO 1ST FREE ENTRY +DRENTS # 2 ;NUMBER OF DIRECTORY ENTRIES +DRSTAR # 0 ;FIRST ENTRY IN DIR +;(OFFSETS IN ENTRY) + ^ 0 +DRLINK # 2 ;PTR TO NEXT ENTRY (DON'T ALTER THIS) +DRTITL # &A ;TEXT NAME (PADDED WITH ZEROES) +DRLOAD # 4 ;LOAD ADDRESS +DREXEC # 4 ;EXECUTE ADDRESS +DRACCS # 1 ;ACCESS INFO +DRDATE # 2 ;DATE OF CREATION +DRSIN # 3 ;SIN OF OBJECT +DRENSZ * @ ;SIZE OF DIRECTORY ENTRY + +;OFFSETS FOR DETAILS RETRIEVED FROM A DIRECTORY +;NOTE THAT IF THE SIZE OF THE INFORMATION (INFNXT) IS +;EVER CHANGED YOU MUST CHANGE THE SIZE OF THE +;BUFFERS:- USWORK,ATUSRI + ^ 0 +INFNAM # &A ;FILE TITLE +INFLOA # 4 ;LOAD ADDRESS +INFEXE # 4 ;EXECUTE ADDRESS +INFACC # 1 ;ACCESS INFO (TYPE & ACCESS VECTOR) +INFDTE # 2 ;DATE OF CREATION +INFSIN # 3 ;SIN OF OBJECT +INFDIS # 2 ;DISC NUMBER +INFSZE # 3 ;SIZE OF OBJECT +INFNXT * @ ;NUMBER OF BYTES IN DETAILS + +;DIRMAN CONSTANTS +ACCMSK * &1F ;BITS 0 -> 4 (LWR/WR) +TLAMSK * &3F ;=> type/LWRWR mask +RWMSK * &F ;BITS 0 -> 3 (WR/WR) +DISCIN * ":" ;INDICATES DISC NAME IN FILE TITLE +TERMIN * &D ;STRING TERMINATOR +SEPART * "." ;FILE NAME SEPARATOR +NAMLNT * &A ;MAX LENGTH OF TEXT NAME (10 CHARS) +SPACE * " " ;SPACE CHARACTER +ROOT * "$" ;NAME OF ROOT DIRECTORY +MAXDIR * ((:MSB:(DRSTAR+255*DRENSZ))+1)*&100 + ;MAX SIZE A DIR IS ALLOWED TO BE +ENTTRM * 0 ;ENTRY TERMINATOR +EXTERM * &80 ;BLOCK TERMINATOR +JMPINS * &4C ;JMP INSTRUCTION +MAXENA * LGBFSZ / 27 ;NO. OF ENTRIES TYPE A +MAXENB * LGBFSZ / 68 ;"" "" " B +MAXENC * LGBFSZ / 11 ;"" "" " C +MAXEND * LGBFSZ / 18 ;"" "" " D + + +;*** AUTMAN & USRMAN MANIFESTS *** + +MAXPW * 6 ;MAX SIZE OF PASSWORD +MAXID * 10 ;MAXIMUM SIZE OF SINGLE USER ID +MAXUNM * 2 * MAXID+1 ;MAX USER IDS PLUS DOT +UTFRLN * 4 ;length of free space counter + +;PASSWORD FILE OFFSETS + ^ 0 +PWUSID # MAXUNM-1 ;USERID +PWPASS # MAXPW ;PASSWORD +PWFREE # UTFRLN ;free space for this user +PWFLAG # 1 ;FLAG (INUSE & SYSTEM PRIV) +PWENSZ * @ ;SIZE OF PASSWORD FILE ENTRY + +;*** USRMAN MANIFESTS *** +;USERTB OFFSETS + ^ 0 +UTMCNO # 3 ;START OF MACHINE NO **25/12/86* +UTUSID # MAXUNM+1 ;START OF USERID +UTDISC # 2 ;CURRENTLY SELECTED DISC NUMBER +UTPRIV # 1 ;SYSTEM PRIVILEGE & INUSE FLAG +UTHSLD # 1 ;HANDLE FOR SELECTED DIR + [ Pseudods = Yes +UTHUFD # 1 ;**26/6/87** handle for logon directory + ] +UTHNDB # 1 ;BYTE INDICATING HANDLES IN USE PER MC +UTFREE # UTFRLN ;User disc space allocation ** 2/10/84 ** +UTENSZ * @ ;SIZE OF A USERTB ENTRY +OPTMSK * &F ;Mask for user option bits +NTOPT * &F0 ;Complement of OPTMSK + + +;*** RNDMAN MANIFESTS *** +;HANDLE TABLE OFFSETS (HANDTB) + ^ 0 +HTHAND # 1 ;HANDLE NUMBER +HTMCNO # 3 ;MACHINE NUMBER OF OWNING M/C *25/12/86** +HTACC # 1 ;ACCESS TO & TYPE OF OBJECT +HTDISC # 2 ;DISC NUMBER OF OBJECT +HTSIN # 3 ;SIN OF OBJECT +HTMODE # 1 ;MODE OF USE FOR WHICH OPENED +HTRPTR # 2 ;Ptr. to RANDTB entry (2 bytes) +HTENSZ * @ ;SIZE OF A HANDTB ENTRY + +;RANDTB OFFSETS + ^ 0 +RTCSFP # 3 ;Current sequential file pointer +;Note RDSTAR in randman assumes that the +;two pointers are consecutive in this table +RTOSFP # 3 ;Old sequential file pointer +RTHWM # 3 ;HIGH WATER MARK +RTFSZE # 3 ;FILE SIZE +RTDESC # 2 ;ADDRESS OF CACHE DESCRIPTOR(HINT) +RTINUS # 1 ;INUSE+SEQ. NUMBER +RTENSZ * @ ;SIZE OF EACH RANDTB ENTRY + +;*** MAPMAN MANIFESTS *** +;MAPTB OFFSETS + ^ 0 +MPDCNO # 2 ;DISC NUMBER +MPNOCY # 2 ;NUMBER OF CYLINDERS +MPSECS # 3 ;NO. OF SECTORS PER DISC +MPDSCS # 1 ;NUMBER OF DISCS +MPSPCY # 2 ;SECTORS PER CYLINDER +MPBMSZ # 1 ;SIZE OF BIT MAP IN BLOCKS +MPADFT # 1 ;ADDED TO GET NEXT PHYSICAL DISC +MPDRNC # 1 ;INCREMENT TO NEXT LOGICAL DRIVE +MPRTSN # 3 ;SIN OF ROOT DIRECTORY +MPRTDT # 2 ;ROOT DATE +MPSCYL # 2 ;START CYLINDER +MP1BIT # 1 ;Non-zero if packed map, gives bytes/cyl +MPSZLN * @ ;End of part copied from sector zero +MPSCTT # 3 ;TOTAL NUMBER OF SECTORS +MPCYMP # 2 ;STORE ADDRESS OF CYLINDER MAP +MPTBSZ * @ ;SIZE OF MAPTB ENTRY + +;** SECTOR ZERO INFO ** + ^ 0 +MPDRNM # 4 ;POSN OF 'AFS0' IN SECTOR 0 +MPSZNM # &10 ;POSITION OF NAME IN SEC. ZERO +MPSZNC # 2 ;NUMBER OF CYLINDERS PER DISC +MPSZNS # 3 ;NUMBER OF SECTORS PER DISC + +; *** MPSZDN & MPSZSC. These are redundant and no longer required. +; they had been removed in the initial source combine. MPSZSC is +; referenced in FORM00 with a LDYIM, but it is never initialised. +; They are retained to keep the memory map consistent with the original +; binary + [ $CMOS +MPSZDN # 1 ;NUMBER OF DISCS +MPSZSC # 2 ;SECTORS PER CYLINDER + ] + +MPSZSB # 1 ;SIZE OF BIT MAP +MPSZAF # 1 ;ADDITION FOR NEXT PHYSICAL DISC +MPSZDI # 1 ;INCREMENT FOR NEXT LOGICAL DRIVE +MPSZSI # 3 ;SIN OF ROOT +MPSZDT # 2 ;DATE OF ROOT +MPSZSS # 2 ;START SECTOR +MPSZ1B # 1 ;Non-zero if packed map, gives bytes/cyl +SZOFF * &F6 ;OFFSET TO DRIVE DATA SECTOR + +; MAP BLOCK POINTERS + ^ 0 +BLKSN # 3 +BLKNO # 3 +MBSQNO # 1 +MGFLG # 1 +BILB # 2 +MBENTS * @ ;START OF MAP BLOCK ENTRIES +ENSZ * 5 ;BYTES IN MAP BLOCK ENTRY +MXENTS * 49 +LSTENT * MBENTS+(MXENTS-1)*ENSZ ;a better definition +LSTSQ * 255 +BTINBK * 256 ;BYTES IN A NORMAL DISC BLOCK +; +;BIT MAP FLAGS + +MPVAL * &FF ;offset of 'next bitmaps valid' flag + +; +; OFFSETS IN CACHE CONTROL BLOCK +; + ^ 0 +CAFLG # 1 +CBDA # 3 +CBSA # 2 +CBDR # 1 +CBAGE # 1 +CBSZ * @ +; +; INFORMATION ABOUT BIT MAP AND MAP BLOCK CACHES +; +NOBTMP * 5 ;NUMBER OF BIT MAP CACHE BLOCKS +NOMPBK * 15 ;NUMBER OF MAP BLOCK CACHE ENTRIES +SZBMAR * NOBTMP*BTINBK ; NUMBER OF BYTES IN BIT MAP CACHE +SZMBAR * NOMPBK*BTINBK ; NUMBER OF BYTES IN MAP BLOCK CACHE +SZBMCB * NOBTMP*CBSZ ; SIZE OF CACHE CONTROL BLOCK ENTRIES +SZMBCB * NOMPBK*CBSZ ; DITTO FOR MAP BLOCKS + +;NAME TABLE OFFSETS ETC. +DNAMLN * &10 ;SIZE OF DISC NAME +NTSIZE * 7 ;NO. OF ENTRIES +USED * 0 ;IN USE VALUE +UNUSED * &FE ;MOST RECENTLY USED VALUE + ^ 0 +NTNAME # DNAMLN ;DISC NAME +NTDNO # 2 ;DISC NO. +NTUSED # 1 ;IN USE PTR. +NTENSZ * @ ;SIZE OF ENTRY + +; These were removed in the orginal combined source +; but are still necessary + + [ $Level3 +;PAGE ZERO ADDRESSES +;NOTE THAT DOS USES (AD,C9,CB,DA->FF) FOR DISC I/O + [ SYS=0 +SAVCOM * &AD ;DISC TRANSFER COMMAND(READ/WRITE) +TRACK * &DA +SECTOR * &DB +WORK * &DF ;(DISC DRIVER DESCRIPTOR BLOCK) +DDRSTA * WORK ;STORE ADDRESS FOR BLKRD & BLKWR +DDRSPA * DDRSTA + 2 ;SPARE (I.E. NOT USED BY DISC DRIVER) +DDRSZE * DDRSPA + 2 ;NUMBER OF BYTES (LS FIRST) TO BE TRANSFERED +DDRSCT * DDRSZE + 2 ;LOGICAL START SECTOR NUMBER (MS FIRST) +CNTA * &F1 ;NUMBER OF RETRIES STILL TO GO +SECTNO * &F2 ;NUMBER OF SECTORS TO TRANSFER +RAMADR * &F7 ;2 BYTE STORE ADDRESS + ] + ] + + +;*** COMMAND PROC. MANIFESTS *** +;CONSTANTS +RXBUFL * 127 ;**8/2/88** Receive buffer length (<=127) +COPORT * &99 +FIFLSZ * &400 ;Initial size of file created by FIND +BUFSZ * &500 ;TX BUFFER SIZE +;Function numbers +DRPRS * 1 ;Preserve in dir. man. +DRRTR * 2 ;Retrieve in dir. man +MAPCS * 1 ;Create map space +MAPFS * 2 ;Free map space +MAPENS * 6 +;Bits and pieces +WAITCL * &50 ;No. of msecs wait for client +ONEMS * 5 ;No. of loops to give 1 msec (see WAIT) + +PSAVD * COPORT+1 ;Data port in save +TXRPT * &FF ;Do 255 times +TXDLY * &14 ;Delay 20 msec +LF * 10 +CR * &D +DOT * "." +FCCMND * 5 ;To recognise a command +FCCRET * 29 ; The create command 11/6/84 BC +HDRLEN * 5 ;Header of INCOMING message +MCTASK * &78 ;Mask for task number in control byte **1/5/86** +TXHDR * 2 ;Header length of OUTGOING message +CLIDLM * CR ;Delimiter in CLI table +CLIDL1 * CLIDLM-1 +SAVFTO * HDRLEN+&B +LODFTO * HDRLEN +EXAFTO * HDRLEN+3 +INFFTO * HDRLEN+1 +FNDFTO * HDRLEN+2 ;File find, not dir. find ?? + +;LOW LEVEL ADDRESSES + +;CLOCK CHIP ADDRESSES + +;STORE POINTERS + [ $Level3 + [ SYS=0 +FRESTR * &7A00 + | + [ WINCH=0 + [ DONGLE = 0 +FRESTR * &8A00 + | +FRESTR * &8B00 + ] ; DONGLE END + | +FRESTR * &7A00 ;FIRST FREE STORE LOCATION + ] ; WINCH END + ] ; SYS END + | ; ELSE CMOS / FILESTORE + [ Pseudods = No +FRESTR * &8000 + | +FRESTR * &8100 + ] + ] ; LEVEL3 END + + ^ FRESTR + + [ $Level3 +STKPTR # 2 ;VAL OF HARDWARE STACK PTR (STOP) + ] +FREPTR # 2 ;PTR TO FREE STORE (GETVEC) +ENDPTR # 2 ;PTR TO END OF FREE STORE (GETVEC) +BIGBUF # 2 ;PTR TO BIG BUFFER (STRMAN) +NUMBCE # 1 ;NO. OF CACHE DECRIPTORS +CACHSZ # 2 ;CACHE SIZE + +USERTB # 2 ;PTR TO START OF USERTB (USRMAN) +TITPTR # 2 ;PTR TO DIR NAME +USDISC # 2 ;HOLDS DISC NUMBER FOR USRMAN +USRACC # 1 ;ACCESS TO DIRECTORY +USRROT # 1 ;ROOT CHARACTER +USRSEP # 1 ;SEPARATOR CHARACTER +USRUFD # MAXUNM ;USERID +USRTER # 1 ;DIR NAME TERMINATOR +USRINF # INFNXT ;OBJECT DETAILS AREA(SEE DIRMAN.RETRV) +USWORK # 2 ;USRMAN WORK VARIABLE +USTEMP # 1 ;Temp general USRMAN store +UMHUFD # 1 ;Temp UFD store. +UMHCSD # 1 +UMHLIB # 1 +MCTEMP # 3 ;M/C NUMBER **25/12/86** +USERS # 1 ;NO. OF USERS +USSYS # 1 ;flag to indicate priv'd user logged on +CACHTB # 2 ;PTR TO FIRST CACHE ENTRY DESCRIPTOR +FRECHN # 2 ;PTR TO CHAIN OF FREE CACHE DESCRIPTORS +AMTNED # 2 ;AMOUNT OF STORE NEEDED FOR OBJECT +STRTMP # 2 ;STRMAN TEMP VARIABLE +BSTSTA # 2 ;BEST START POSITION +BSTEND # 2 ;BEST END POSITION +MINCST # 2 ;MINIMUM COST +COST # 2 +HANDTB # 2 ;PTR TO START OF HANDLE TABLE (RNDMAN) +RANDTB # 2 ;PTR TO START OF RANDOM ACCESS TABLE +RDBFAD # 2 ;Current buffer position (RNDMAN) +BTSXFD # 2 ;Bytes xferred in PB/GB (2 bytes) (RNDMAN) +BTSLFT # 2 ;Bytes left to transfer (2 bytes) +NEWFSZ # 3 ;New file size (arg to RDCHSZ routine) - 3 bytes +EOFFLG # 1 ;End-of-file flag (RNDMAN) +HTENTS # 1 ;NO. OF HAND. TBL. ENTRIES +RTNENT # 1 ;No. of RANDTB entries + [ $Level3 +INTEGR # 1 ;To hold an integer (RDINT) + ] +GVWRKA # 2 ;GETVEC WORK VARIABLE + [ $Level3 +ENWRKA # 2 ;ENTRY WORK VAR +TEMPA # 2 +TEMPB # 2 + ] +MCNUMB # 3 ;MC/NO LOOKED UP IN USERTB(USRMAN-FINDMC) **25/12/86** + [ $Level3 +DATE # 3 ;3 BYTE DATE VALUE Last byte = day + [ Dongle=0 +ORB # 1 +IRB # 1 +DDRB # 1 + ] +TIME # 5 ;TIME OF DAY +OTIME # 5 ;COMPARISON +NTIME # 5 ;WORK VARIABLE FOR TIME +SECS # 1 ;SECONDS +MINS # 1 ;MINUTES +HRS # 1 ;HOURS +DAYS # 1 +MUNTHS # 1 +REM # 1 ;DIVISION REMAINDER +DVSOR # 1 ;DIVISOR +DATBUF # &C ;Buffer for time chip data + | +DATE # 5 ;Date and time values +HRS * DATE+2 +MINS * DATE+3 +SECS * DATE+4 + ] +LASTNM # 2 ;PTR TO 1ST CHAR OF LAST TEXT NAME(DIRMAN) +DRDSNM # &11 ;BUFFER TO HOLD DISC NAME(17BYTES) +DIRACC # 1 ;) TYPE & ACCESS TO DIR (OWNER/ANYBODY) +DRDISC # 2 ;) DISC NO OF CURRENT DIR +DIRSIN # 3 ;) SIN OF CURRENT DIR +DIRSTT # 2 ;) START BLK NO OF DIRECTORY (=0) +DIRBKS # 2 ;) NO OF BLKS IN DIR +DIRSTA # 2 ;STORE ADDRESS OF DIR +DIRSZE # 3 ;3 BYTE VARIABLE HOLDING SIZE OF DIR +TXTNAM # NAMLNT+1 ;TEXT NAME (PADDED WITH SPACES) +DIRTMP # 3 ;3 BYTE TEMPORARY VARIABLE +DMTEMP # 3 + [ $Level3 +OBJSIN # 3 ;TEMP VAR HOLDING SIN OF OBJECT + ] +OBJACC # 1 ;TEMP VAR HOLDING ACC INFO FOR OBJECT +EXARG # 1 +EXENTR # 1 +EXENTS # 1 + [ $Level3 +DMSTX # 1 ;1 BYTE +DRCNT # 1 ;1 BYTE LOCN. + ] +EXRTN # 3 ;3 BYTES +TDATE # 2 +DIRWC # 1 ;FLAG FOR WILD CARDS +WILD1 # 1 ;USED IN FNDTEX +WILD2 # 1 +DIRFLG # 1 +ATDRIV # 1 ;DRIVE NUMBER(AUTMAN) +ATSTRA # 2 ;STORE ADDRESS OF PW FILE +ATINF # INFNXT ;INFORMATION FROM DIRMAN +ATUSRI # UTENSZ ;USERINFO VECTOR FOR AUTMAN +ATWORK # 1 ;AUTMAN WORK VARIABLE +DOTFLG # 1 ;FLAG DOT HAS OCCURED +DRIVES # 1 ;NUMBER OF DRIVES ATTACHED TO FS +MAPTB # 2 ;HOLDS ADDRESS OF MAP TABLE(MAPMAN) + [ $Level3 +DIVPAR # 3 +DIVTMP # 3 ;HOLDS BLOCKS TO ALLOCATE + ] +NAMETB # 2 ;NAME TABLE + [ $Level3 +; *** These were moved into Zero page in Filestore +MAPTMP # 3 ;TEMP VARIABLE +MPTMPA # 3 +MPTMPB # 3 +MPTMPC # 3 + ] +TMPSPC # 3 ;TEMPORARY SECTORS PER CYLINDER + [ $Level3 +MPSZEQ # 1 ;Indicates if zero length chain +MPCHFL # 1 ;HOLDS END OF CHAIN FLAGS + ] +MPDRVE # 1 ;HOLDS CURRENT DRIVE NUMBER + [ $Level3 +MPDSNO # 2 ;CURRENT DISC NO +MPSCST # 2 ;POINTER TO START OF DISC???? +MPTMPD # 3 ;GENERAL PURPOSE VARIABLE +MPTMPE # 3 ;GENERAL PURPOSE VARIABLE + ] +MKENVA # 3 +SAVSC # 3 +SAVPTB # 3 ;SAVE POINTER POSITION +SAVPTA # 3 ;SAVE POINTER +MBCBPT # 2 ;POINTER TO MAP BLOCK CONTROL BLOCKS +BMCBPT # 2 ;PONTER TO BIT MAP CONTROL BLOCK +NCBDB # 2 ;NUMBER OF CURRENT CONTROL BLOCK ENTRIES + [ $Level3 +CBSIN # 3 ;CURRENT CB SIN + ] +CBSTA # 2 ;CURRENT CB STORE ADDRESS +CBTPPT # 2 ;CB TEMPORARY POINTER +RBDA # 3 ;TRANSFER BLOCK DISC ADDRESS +ERRTYP # 1 ;READ OR WRITE DISC ERROR +DNDLTE # 1 ;DELETE CURRENT MAP BLOCK? +RSTFLG # 1 ;CYLINDER MAP STARTUP FLAG +CURDSC # 2 ;CURRENT DISC NO. +NXTDNO # 2 ;NEXT DISC NO. ALLOCATION +CURDRV # 1 ;CURRENT DRIVE +LDRNB # 1 ;LOGICAL DRIVE NUMBER (DSCMAN) +DCSECT # 3 ;SECTOR NUMBER +DRIVNO # 1 ;ACTUAL DRIVE NUMBER TO BE SELECTED +DCSTAD # 2 ;STORE ADDRESS +NBLKS # 2 ;NUMBER OF DISC BLOCKS TO BE TRANSFERED +DATARA # 16 ;AREA FOR TEST OF DISC BLOCK VALIDITY + [ $Level3 +OLDFDR # 1 ;LAST FDRIVE USED + ] +OLDSZE # 4 + [ $Level3 +CTRACK # 1 ;COPY OF TRACK NUMBER +CSECTR # 1 ;COPY OF 1 BYTE SECTOR NUMBER +CADDR # 2 ;COPY OF STORE ADDRESS +SECTSD # 2 ;NUMB OF SECTORS ON A SIDE OF DISC +SECTS # 2 ;NO. OF SECTS TO XFER + ] +DCRASH # 1 ;DISC CRASH INDICATION + [ $Level3 + [ BBC=0 +DSCCB # Length+4 +SAVCOM # 1 +TRACK # 1 +SECTOR # 1 +DDRSTA # 2 +DDRSPA # 2 +DDRSZE # 2 +DDRSCT # 2 +CNTA # 1 +SECTNO # 1 +DFNAME # 10 +DFLOAD # 2 +DFEXEC # 2 +DFSIZE # 3 +DFQUAL # 10 +DFSECT # 10 +RAMADR # 2 + ] +INTROT # 2 ;USED FOR A FILE TITLE (INIT) +USERNM # MAXUNM+1 ;HOLDS A USERID +BREGA # 3 + [ BBC=0 +RXTAB # 1 +RXCBN # 1 + ] + | +DNMBUF # &12 ;Disc name buffer +DSCCB # Length+4 +SAVCOM # 1 +DDRSTA # 2 +DDRSZE # 2 +RXTAB # 1 +RXCBN # 1 + ] +RXCBV # 0 ;RECEIVE CONTROL BLOCK VECTOR +CBFLG # 1 ;RECEIVE C.B. FIELDS +CBPORT # 1 +CBSTID # 2 + [ SYS=0 +CBBUF # 2 +CBBUFE # 2 + | +CBBUF # 4 +CBBUFE # 4 + ] +RXBUF # 1 ;Receive buffer +FCODE # 1 ;FN. code +CPUFD # 1 +CPCSD # 1 +CPLIB # 1 +MIDRX # RXBUFL+RXBUFL+1-(MIDRX-RXBUF) ;**8/2/88** +RXBUFT # 1 +TXBUF # 0 +CCODE # 1 ;Command code +RTCODE # 1 +MIDTX # &2E + + +;OTHER VARIABLES +COTEMP # 2 +COWORK # 0 +DETRAM # 0 +DETNAM # INFNXT ;DETAILS FROM RETRIEVE +DETACC * DETNAM+INFACC +DETSIN * DETNAM+INFSIN +DETDIS * DETNAM+INFDIS +DETSZ * DETNAM+INFSZE +TOSEND # 3 + [ $Level3 +OFFSET # 3 + ] +GBBXFD # 3 ;Bytes xfd in CP GETBYTES (3 bytes) +GBEFLG # 1 ;End of file flag (CP GETBYTES) +TXTBUF # RXBUFL ;**8/2/88** file title buffer +MAPTBF * TXTBUF ;Buffer MAPTB information in MAPMAN.MPREDR +QPTR # 1 +BPTR # 1 +CURBLK # 2 +OUTBSZ # 2 +BBUF # 2 +BBSIZE # 2 +BBEND # 2 +DANDS # 5 +DSCERR # 1 +RPLYPT # 1 +DATAIN # 3 +FINFLG # 1 +FILLFL # 1 +TIMER # 1 +TIMER1 # 1 +TIMER2 # 1 +QUOTED # 1 +TXJ # 1 +TXD # 1 +TXF # 1 + [ $Level3 +MONFLG # 1 + ] +OLDRXB # 2 + [ $Level3 +CDIRTB # 2 +CVTDRV # 1 +FSDNO # 2 +HNDROT # 1 +QUALIF # 1 +TXBYTS # 2 +TXBLKS # 2 + ] +MEMEND # 2 + [ 1=0 +TSTACK # 1 ;Store stack pointer in MAPMAN & CONVERT + ] + [ $Level3 +OLDBRK # 2 ;Store BRK vector in MAPMAN & CONVERT +OFF1 # 1 ;ARG TO MOVBLK +OFF2 # 1 ;ARG TO MOVBLK + ] +STRPTR # 2 ;Ptr. used in AUTMAN +PTREND # 2 ;Ptr. used in AUTMAN +RIPPLE # 1 + [ $Level3 +EVCHAR # 1 +IOBUF # 2 ;new big buffer +IOBSIZ # 2 +IOEND # 2 +ODSCMN # 11 + | +CMNDSW # 1 ;Zero=user mode, &40 door open, &80=cmnd0, &C0=cmnd1 + ] +MPNWFR # UTFRLN ;user free space calculation + [ $CMOS +Oswork # 5 ;OS control block + ] +MPscor # 2 ;Bitmap sector origin (MAPMAN) +MCopat # 3 ;"Already open at station m.n" + [ WINCH=0 + | +PARAMS # 4 +NOPRMS * 0 + ] + [ $CMOS +IEsin # 3 ;SIN of last disc error + [ Cachesw=Yes +ODSCMN # 11 + ] + +; Printer server variables + +Lastch # 1 ;Last char sent to printer +Lastct # 1 ;Last control byte for sequence check +Lastin # 3 ;Last busy station (zero if closed) +Printn # 6 ;Copy of alternate printserver name +Prpoll # 1 ;Receive CB number, or zero if none +Prwork # 8 ;Workspace for reading POLLPS packets +Pretry # 1 ;Retry counter for POLLPS replies +Prdata # Prlong+1 ;Printer data buffer +PRnotb # 1 ;**8/2/88** Non-zero if no trailer FF + ] + +DYNSTA * @ ;START OF DYNAMICALLY ALLOCATED STORE + + LNK Uade03 diff --git a/FileServer/SRC/FileServer/Uade03 b/FileServer/SRC/FileServer/Uade03 new file mode 100644 index 0000000..8efabe4 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade03 @@ -0,0 +1,1525 @@ + OPT UADE03 ; > .Uade03 + TTL File server file UADE03 + +;********************************** +;* U T I L I T I E S * +;********************************** + [ $Level3 + +ENPT ROUT + CMPIM 1 + BEQ START + RTS + NOP + = &60 + = COPYRIGHT + = 0 ;SOFTWARE VERSION NUMBER + = "Winchester File Server" +COPYRIGHT + = 0,"(C) 1988 Acorn",CR,0 + +; & ENPT +; & 0 + +START ROUT + + JSR VSTRIN + = 22, 7 ;select mode 7 + = CR,"Acorn File Server Level " +VERSN = "3 Version 1.",VERLA,VERLB,CR + = 21,"Version string",6 ;software protection + = " File server station " + NOP + + LDXIM 11 ;**9/7/87** set up to get net number +00 LDAAX CTABA + STAAX Rxcbv + DEX + BPL #00 + LDAIM &9C ;correct port + STA CBport + LDAIM 0 + STA Rxcbn + STA Rxbuf ;zero net in case no reply + STA Qptr + LDXIM :LSB:Rxcbn + LDYIM :MSB:Rxcbn + LDAIM &11 + JSR OSword ;set up receive + LDXIM 12-1 ;now set up broadcast +10 LDAAX #90 + STAAX CBflg + DEX + BPL #10 + LDAIM :LSB:Rxcbv + STA Netcb + LDAIM :MSB:Rxcbv + STA Netcb+1 + JSR SendX ;send off broadcast + LDXIM 2 ;short wait + JSR WaitX ;wait for response + LDA Rxbuf ;first reply byte is net id + STA CBstid+1 + + LDAIM &08 ;Print station number LH 21/10/85 + STA &0100 + LDAIM &13 + LDXIM &00 + LDYIM &01 + JSR OSWORD + LDA &0101 + STA CBstid +; LDA &0102 +; STA CBstid+1 + LDAIM 0 ;**12/6/87** zero task number for now + STA CBFLG + JSR PRTMC + + JSR VSTRIN + = 28, 0, 21, 39, 4 ;define a window + NOP + LDXIM WCMD + LDYIM /WCMD + JSR OSCLI + LDXIM WDCMD + LDYIM /WDCMD + JSR OSCLI + + + JMP STRTFS ; .. here we go .. + +90 = &82, &9C, &FF, &FF + = "BRIDGE" + = &9C, 0 + +DOBRK ROUT + JSR CURSON + JSR VSTRIN + = 28,0,23,39,0 + NOP + +;ammended BRK handling ** 30/9/84 ** + PLA ;get P + PLA + STA BRKPTR + PLA ;get address from stack + STA BRKPTR+1 ;standard places to put them + + LDYIM 0 +10 LDAIY BRKPTR + BEQ #20 + JSR OSASCI ;print the error message + INY + BNE #10 + +20 JMP TSTART + +;Store old value of BRKVEC +;and set new value to X/Y +; +;Called from MAPMAN and CONVERT block read routine + +SETBRK ROUT + LDA BRKVEC + STA OLDBRK + LDA BRKVEC + 1 + STA OLDBRK + 1 +SETBK1 SEI + STX BRKVEC + STY BRKVEC + 1 + CLI + RTS + +WCMD = "ADFS",CR ;SET WINCHESTER FILING SYSTEM +WDCMD = "DIR :0",CR ;SELECT DRIVE ZERO +PROT = 5,MASK ;SET PROTECTION except USER procedure + +TRACE ROUT + [ DEBUG > 0 + PHA + LDAIM DEBUG + BEQ #10 + PLA + JMP OSWRCH + +10 PLA + ] + RTS + | +START JMP STRTFS ; .. here we go .. + +CACORN = "(C)Acorn 1988" + ] + +;I N P U T - O U T P U T R O U T I N E S + +;Returns CC if digit or char. + +ISDCHA ROUT + PHA + CMPIM "0" + BCC #10 ;Fail + CMPIM "9"+1 + BCC #20 ;Succeed + PLA ;Now check if is char + +;Returns CC if is alpha (upper or lower) + +ISCHAR PHA + ANDIM &DF + CMPIM "A" + BCC #10 ;=> char < A + CMPIM "Z"+1 + BCC #20 ;=> char <= Z +10 SEC +20 PLA + RTS + + [ $Level3 +OSECHO ROUT + JSR OSRDCH + BCC #10 + LDAIM &7E ;escape found so ack and return bad char + JMP OSBYTE +10 JMP OSASCI ;read & echo a char + +VSTRIN ROUT + PLA + STA VSTPTR + PLA + STA VSTPTR + 1 + LDYIM 0 +10 INC VSTPTR + BNE #20 + INC VSTPTR + 1 +20 LDAIY VSTPTR + BMI #30 + JSR OSASCI + JMP #10 +30 JMI VSTPTR ;continue execution + + +WHEX ROUT + PHP ;WRITE A AS TWO HEX DIGITS + PHA + LSRA + LSRA + LSRA + LSRA + JSR #10 + PLA + PHA + ANDIM &F + JSR #10 + PLA + PLP + RTS + +WHEXD +10 CMPIM 10 + BMI #20 + CLC + ADCIM 7 +20 ADCIM "0" + JMP OSWRCH + + +;THE FOLLOWING ROUTINES READ A LINE OF TEXT +;TYPED AT A KEYBOARD INTO THE COMMAND LINE BUFFER (DOS=256) +;THE PAGE ZERO REGISTER COMPTR IS USED TO POINT +;INTO THE INPUT BUFFER. +;THE INDEX REGISTER Y IS USED TO REFER TO +;CHARACTERS IN THE INPUT BUFFER. +;THE ROUTINE GETINT READS CHARS FROM INPUT BUFFER +;AND CONVERTS THEM INTO INTEGERS (PLACED IN INTEGR). + + +SETCOM LDAIM 0 ;COMPTR := ADDR OF INPUT BUFFER + STA COMPTR + LDAIM 1 + STA COMPTR+1 + RTS + + +INCCOM ROUT + INC COMPTR ;COMPTR +:= 1 + BNE #10 + INC COMPTR+1 +10 RTS + + +RDLINE ROUT + JSR SETCOM + LDAIM &86 + JSR OSBYTE + STX OFF1 + JSR CURSON + LDXIM RDLNBK + LDYIM /RDLNBK + LDAIM 0 + JSR OSWORD + BCC #20 + LDAIM &7C + JSR OSBYTE + LDAIM &86 + JSR OSBYTE + SEC + TXA + SBC OFF1 + TAY +10 CPYIM 0 + BEQ RDLINE + STY OFF1 + JSR VSTRIN + = 8,32,8 + NOP + LDY OFF1 + DEY + JMP #10 + +20 JMP CURSOF +; +RDLNBK = 0,1,40,32,&80 +; + +;Turn Cursor On +; +CURSON JSR VSTRIN + = 23,1,1,0,0,0,0,0,0,0 + NOP + RTS + +;Turn Cursor off +; +CURSOF JSR VSTRIN + = 23,1,0,0,0,0,0,0,0,0 + NOP + RTS + + +;GETINT: READ A DECIMAL INTEGER INTO INTEGR. +;NOTE COMPTR IS LEFT POINTING TO THE CHARACTER +;FOLLOWING THE INTEGER. +;EXIT: A = RC (<>0 => NOT A DECIMAL INTEGER) + +GETINT ROUT + LDYIM 0 + TYA + STA TEMPB ;TEMPB := CHAR COUNT + STA INTEGR + STA INTEGR + 1 ;INTEGR := 0 + +10 LDAIY COMPTR + CMPIM "0" + BCC #20 + CMPIM ":" ;(':='9+1) + BCC #30 +20 LDA TEMPB ;FIRST CHAR ? + BNE #80 + LDAIM IERRAH + BNE #90 +30 SEC + SBCIM "0" + PHA ;PUSH DIGIT + INC TEMPB ;TEMPB +:= 1 + LDA INTEGR + ASLA + STA TEMPA + LDA INTEGR + 1 + ROLA + STA TEMPA + 1 ;TEMPA := INTEGR * 2 + LDXIM 3 +40 LDA INTEGR + ASLA + STA INTEGR + LDA INTEGR + 1 + ROLA + STA INTEGR + 1 + DEX + BNE #40 ;INTEGR * 8 + CLC + LDA INTEGR + ADC TEMPA + STA INTEGR + LDA INTEGR + 1 + ADC TEMPA + 1 + STA INTEGR + 1 + CLC + PLA ;PULL DIGIT + ADC INTEGR + STA INTEGR + LDA INTEGR + 1 + ADCIM 0 + STA INTEGR + 1 + JSR INCCOM ;COMPTR +:= 1 + JMP #10 + +80 LDAIM 0 ;RC:= 0 +90 RTS + + +;E R R O R H A N D L I N G + +USRERR ROUT ;USRERR + PHA + JSR OSCRLF + PLA + JSR LOOKER ;Get error msg. in MIDTX + LDXIM 0 +10 LDAAX MIDTX + JSR OSASCI + INX + CMPIM CR + BNE #10 + RTS + + + +;STOP: THIS ROUTINE BRINGS THE FILE +;SERVER TO A GRACEFULL HALT. +;IT PUSHES, ONTO THE HARDWARE +;STACK, P,A,X,Y AND REMEMBERS +;THE VALUE OF THE STACK PTR IN +;STKPTR (SEE HEADER FILE). + + +STOP PHP ;PUSH P,A,X,Y REMEMBER STK PTR + PHA + [ $CMOS + PHX + PHY + | + TXA + PHA + TYA + PHA + ] + TSX + STX STKPTR + [ 1=0 + BRK +STOPER = &00,CR,"STOP",CR + = 0 + | + JSR OSCRLF + JMP TSTART ;cant use BRK cos it's intercepted ** 28/9/84 ** + ] + +INTERR PHP + PHA + [ $CMOS + PHX + PHY + | + TXA + PHA + TYA + PHA + ] +; STA STOPER + JSR VSTRIN + = CR,"FS internal error #" + NOP + [ $CMOS + PLY + PLX + | + PLA + TAY + PLA + TAX + ] + PLA + PLP + JSR WHEX + JSR VSTRIN + = CR,"AT ADDRESS " + NOP + [ $CMOS + PLX + | + PLA + TAX + ] + PLA + JSR WHEX + TXA + JSR WHEX + JMP STOP + + | + +;E R R O R H A N D L I N G + +INTERR ROUT + PHY + PHX + PHA + LDXIM IEaddr ;Log out into RTC chip for persistence +10 PLA + STAAX Cozero-IEaddr ;for PEEK debugging + JSR OSwrad ;Write next byte off stack + INX + CPXIM IEaddr+5 + BCC #10 ;Copy A, X, Y, JSR address + +15 LDAAX IEsin-IEaddr-5 ;write last SIN + JSR OSwrad + INX + CPXIM IEaddr+8 + BCC #15 + + LDAIM 0 ;**29/4/88** temporary? deprotect store + JSR Doprot ;**29/4/88** to allow for taking dumps + + LDXIM 0 ;start flashing led + PHX ;save marker to check door opened +20 LDAIM 137 + PHX + JSR OSbyte ;invert led + LDAIM 128 ;read door switch + LDXIM 0 + JSR OSbyte + PLX + PLY + ANDIM 2 + BNE #40 ;br if door open now + TYA ;door ever opened? + BNE #50 +25 PHY ;save door opened latch + TXA + EORIM 1 ;invert led + TAX + TAY ;spin loop, A=Y=0 or 1 +30 PHA ;1.5us + PLA ;2us + INCA ;1us + BNE #30 ;1us = 5.5us inner loop + INY ;1us + BPL #30 ;1us = 700us outer loop + BRA #20 ;180ms half flash cycle + +40 TAY ;set Y non-zero to say door was open + BRA #25 + +50 LDXIM &FF ;Reset stack ptr - delayed for debugging + TXS + LDX RXTAB ;**29/4/88** cancel any pending RX CBs + BEQ #60 + LDAIM &34 + JSR OSBYTE +60 LDAIM 0 ;Indicate start in user mode required + JMP Strtf1 ;then start all over again + + + +USRERR * INTERR ;For now - what better? + +;OSrdad, OSwrad read and write a byte in the alternate non-volatile memory +;Entry: X=address to read/write; A=data if write +;Exit: A=read data if read. written data if write. X preserved, Y not. + +OSrdad ROUT + LDAIM 5 ;code for read + BRA #10 + +OSwrad STA OSwork+4 ;save data + LDAIM 6 +10 STX OSwork + STZ OSwork+1 + STZ OSwork+2 + STZ OSwork+3 + PHX + LDXIM :LSB:OSwork + LDYIM :MSB:OSwork + JSR OSword + PLX + LDA OSwork+4 + RTS + ] + + +;COMPAR: COMPARE TWO AREAS OF STORE, +;BYTE-BY-BYTE. + +;ENTRY: MOVFRM = PTR TO 1ST AREA +;MOVTO = PTR TO 2ND AREA +;X = NO. OF BYTES TO BE COMPARED + +;EXIT: A = 0 IF IDENTICAL +;<>0 IF NOT IDENTICAL +;N.B. STATE BITS (Z ETC) ARE ALSO SET. +;NOTE X,Y,A ARE DESTROYED. + + +COMPAR ROUT + TXA + TAY +10 DEY + LDAIY MOVFRM + CMPIY MOVTO + BNE #20 + DEX + BNE #10 +20 TXA + RTS + + +;F R E E S P A C E M A N A G E M E N T + + +;SPACE IS ALLOCATED FROM A +;CONTIGUOUS AREA OF MEMORY. N.B. +;THAT SPACE CANNOT BE RETURNED TO +;THE FREE POOL. + + +;GETVEC: RETURNS A POINTER TO A FREE +;AREA OF MEMORY. +;THE PAGE ZERO POINTER, +;FREPTR POINTS TO THE BEGINNING +;OF FREE SPACE. + + +;ENTRY: Y,X = SIZE (Y=LS) +;EXIT: Y,X = PTR TO VECTOR + +;FUNCTION:- + +;IF FREPTR+SIZE > ENDPTR +;THEN ERROR(INSUFFICENT SPACE) +;ELSE FREPTR +:=:= SIZE +;FI + +GETVEC ROUT + TXA ;FIRST CHECK THAT SIZE REQUESTED <> 0 + BNE #10 + TYA + BNE #10 + LDAIM IERRAF ;SIZE = 0 +00 JSR INTERR +10 CLC + TYA + ADC FREPTR + STA GVWRKA ;GETVEC WORK VARIABLE A + TXA + ADC FREPTR+1 + STA GVWRKA+1 + BCC #20 + LDAIM IERRAD ;X,Y TOO BIG! + [ $CMOS + BRA #00 + | + BNE #00 + ] +20 LDA ENDPTR ;IS GVWRKA > ENDPTR + CMP GVWRKA + LDA ENDPTR+1 + SBC GVWRKA+1 + BCS #30 + LDAIM IERRAE ;INSUFFICIENT SPACE + [ $CMOS + BRA #00 + | + BNE #00 + ] +30 LDY FREPTR + LDX FREPTR+1 + LDA GVWRKA + STA FREPTR + LDA GVWRKA+1 + STA FREPTR+1 + RTS + + +;CLRSTR: CLEARS A SPECIFIED STORE AREA TO ZERO. + +;ENTRY:- CLRPTR (PAGE ZERO) = START ADDRESS +;X,Y = NUMBER OF BYTES (Y=LS) +;NOTE A & TEMPA ARE DESTROYED BY THIS RTN + +CLRSTR ROUT + [ $CMOS + STZ TEMPA+1 + | + LDAIM 0 + STA TEMPA+1 + ] + STY TEMPA + TYA + BEQ #20 + LDAIM 0 +10 DEY + STAIY CLRPTR + BNE #10 +20 TXA + BEQ #30 + CLC + LDA CLRPTR + ADC TEMPA + STA CLRPTR + LDA CLRPTR+1 + ADC TEMPA+1 + STA CLRPTR+1 + LDYIM 1 + STY TEMPA+1 + DEY ;zero + TYA + STY TEMPA + DEX + [ $CMOS + BRA #10 + | + JMP #10 + ] + +30 RTS + + +;MOVBLK: MOVE DATA FROM PTR AT X OFFSET BY OFF1, TO +; PTR AT Y OFFSET BY OFF2. A CONTAINS THE AMOUNT +; TO MOVE. USEFUL FOR MOVING TO AND FROM THE STACK +; TO TABLES IN DYNAMIC AREA. +; + +MOVBLK ROUT + + PHA ;Push amount to move + CLC + LDAAX 0 + ADC OFF1 + STA MOVFRM ;Set "from" pointer + LDAAX 0001 + ADCIM 0 + STA MOVFRM+1 + + CLC + LDAAY 0 + ADC OFF2 ;Set "to" pointer + STA MOVTO + LDAAY 0001 + ADCIM 0 + STA MOVTO+1 + + [ $CMOS + PLX ;Set length for MOVE + | + PLA + TAX + ] + +;And drop into MOVE + +;MOVE: MOVE DATA FROM ONE AREA OF MEMORY TO A NEW AREA +;N.B. DATA AREAS SHOULD NOT OVERLAPP!!!!! + +;ENTRY: MOVFRM - PAGE ZERO FROM ADDRESS +;MOVTO - PAGE ZERO TO ADDRESS +;X - AMOUNT TO BE MOVED + +;NOTE THAT A,X,Y ARE DESTROYED BY THIS ROUTINE + +MOVE LDYIM 0 + TXA + BEQ #20 ;If zero to move, exit + +10 LDAIY MOVFRM + STAIY MOVTO + INY + DEX + BNE #10 +20 RTS + + +;MRKDRT: MARK A STORE BUFFER DIRTY + +;ENTRY: GENPTR => STORE ADDRESS OF BUFFER + +;SAVED: A,X,Y +;DESTROYED: GENPTR + + +MRKDRT ROUT + PHA ;PUSH A + [ $CMOS + PHY ;PUSH Y + | + TYA + PHA + ] + JSR DCGEN ;INITITIALISE GENPTR & Y + LDAIM DIRTY + STAIY GENPTR + [ $CMOS + PLY ;PULL Y + | + PLA + TAY + ] + PLA ;PULL A + RTS + + +;MRKCLE: MARK A STORE BUFFER CLEAN + +;ENTRY: GENPTR => STORE ADDR OF BUFFER +;SAVED: A,X,Y +;DESTROYED: GENPTR + +;MRKCLE PHA ;PUSH A +;PHY ;PUSH Y +;JSR DCGEN ;INITIALISE GENPTR & Y:=0 +;TYA +;STAIY GENPTR +;PLY ;PULL Y +;PLA ;PULL A +;RTS + + +DCGEN ROUT + LDA GENPTR + BNE #10 + DEC GENPTR+1 +10 DEC GENPTR + LDYIM 0 + RTS + + + +;I N T E R M O D U L E C O M M U N I C A T I O N + + +;ARGUMENTS ARE PASSED AROUND ON +;A SOFTWARE STACK. WHEN IN A +;MODULE ARGUMENTS SETUP BY THE +;CALLER (AND THOSE TO BE PASSED +;BACK) ARE POINTED TO BY THE +;PAGE ZERO REGISTER, ARGPTR. +;PARAMETERS FOR THE NEXT MODULE +;TO BE CALLED ARE POINTED TO BY +;THE PAGE ZERO REGISTER, NEWARG. +;THE POSN OF NEWARG RELATIVE TO +;ARGPTR IS SET BY THE SETFS ROUTINE. +;SETFS MUST BE CALLED +;BEFORE A MODULE IS CALLED. + + +;SETFS: SET FRAME SIZE. THIS RTN +;SETS UP THE CORRECT VALUE +;OF THE PAGE ZERO POINTER, +;NEWARG. +;ON ENTRY A = NUMBER OF ARGUMENT +;STACK POSNS TO BE SET ASIDE. +;IT ALSO PLACES ZERO IN THE REMEMBER ENTRY REASON SLOT. + + +;FUNCTION:- + +;NEWARG := ARGPTR+A+FINFO +;[NEWARG] := A+FINFO +;[NEWARG+ENTRES] := 0 + + +SETFS ROUT + CLC + ADCIM FINFO ;A:=FINFO+A + BCC #10 + LDAIM IERRAA ;FRAME SIZE TOO BIG + JSR INTERR ;INTERNAL ERROR +10 PHA ;PUSH A + ADC ARGPTR ;A:=A+LS(ARGPTR) + STA NEWARG ;LS(NEWARG) := A + LDA ARGPTR+1 ;A:=MS(ARGPTR) + ADCIM 0 + STA NEWARG+1 ;MS(NEWARG):=A + PLA ;PULL ACCUMULATOR + LDYIM FRAMSZ ;Y:=POSN OF FRAME SIZE INFO + STAIY NEWARG ;[NEWARG] :=A + LDYIM ENTRES ;Y:= POSN OF ENTRY REASON TO BE REMEMBERED + LDAIM 0 + STAIY NEWARG ;ENTRY REASON := 0 AT THE MOMENT + RTS + + + +;ENTRY: THIS RTN MUST BE CALLED ON +;EVERY ENTRY TO A MODULE. IT +;CHECKS THAT THE ENTRY CODE +;0 < (ARG0) >= A. IT ALSO PLACES +;THE NAME OF THE CALLED MODULE +;AND THE VALUE OF ARGA (THE ENTRY REASON) +;ON THE ARGUMENT STACK (THIS IS USEFUL WHEN DEBUGGING). + +;ON ENTRY:- + +;X = NUMB OF MODULE ENTRY POINTS +;A= NUMBER OF MODULE + +;FUNCTION:- + +;ARGPTR := NEWARG +;X := JUMP TABLE OFFSET +;NEWARG := $FFFF (SHOULD BE SET BY SETFS RTN) + + +ENTRY ROUT + LDYIM MODNME + STAIY NEWARG ;PUSH NAME OF CALLED MODULE ON ARG STACK + TXA ;A:= NUMBER OF EXPECTED ENTRY POINTS + LDYIM ARGA ;Y:=ARGA + CMPIY NEWARG + BPL #10 + LDAIM IERRAC ;UNKNOWN ENTRY REASON +00 JSR INTERR +10 LDAIY NEWARG ;A:=[NEWARG+ARGA] + BNE #20 + LDAIM IERRAB ;FUNCTION CODE = 0 + [ $CMOS + BRA #00 + | + BNE #00 + ] + +;NOW MAKE ARGPTR := NEWARG + +20 LDA NEWARG ;A:= LS(NEWARG) + STA ARGPTR ;LS(ARGPTR):=A + LDA NEWARG+1 ;A:=MS(NEWARG) + STA ARGPTR+1 ;MS(ARGPTR):=A +;NOW WORKOUT JUMP TABLE OFFSET + LDAIY ARGPTR + LDYIM ENTRES + STAIY ARGPTR ;COPY OF ARGA (THE ENTRY REASON) + [ $Level3 ; ********************** + STA ENWRKA ;ENWRKA:=[ARGPTR+ARGA] + DEC ENWRKA ;ENWRKA -:= 1 + ASL ENWRKA ;ENWRKA *:= 2 + LDX ENWRKA ;X := JUMP TABLE OFFSET + | + DECA ;CODE -:= 1 + ASLA ;CODE *:= 2 + TAX ;X := JUMP TABLE OFFSET + ] + LDAIM &FF + STA NEWARG + STA NEWARG+1 ;NEWARG := $FFFF + RTS + + + +;EXIT: THIS RTN SHOULD BE +;CALLED BY EVERY MODULE, JUST +;BEFORE IT RETURNS TO ITS CALLER. + +;FUNCTION:- + +;NEWARG := ARGPTR +;ARGPTR := ARGPTR-[ARGPTR] +;A := [NEWARG+ARGA] +;Y := ARGA + +PREXIT LDYIM ARGA ; Common return sequence + STAIY ARGPTR ; Falls into EXIT + +EXIT ROUT + LDYIM FRAMSZ ;Y:=POSN OF FRAME SIZE INFO + LDA ARGPTR ;A:=LS(ARGPTR) + STA NEWARG ;LS(NEWARG):=A + LDA ARGPTR+1 + STA NEWARG+1 ;NOW NEWARG=ARGPTR + SEC + LDA ARGPTR ;A:=LS(ARGPTR) + SBCIY ARGPTR ;A:=A-SIZE OF PREVIOUS STACK FRAME + STA ARGPTR ;LS(ARGPTR):=A + BCS #10 + DEC ARGPTR+1 ;MS(ARGPTR)-:=1 +10 LDYIM ARGA ;Y:=ARGA + LDAIY NEWARG ;A:=[NEWARG+ARGA] I.E. RETURN CODE + RTS + + + +;A R I T H M E T I C R O U T I N E S + + +MULTBS ROUT + LDXIM 8 ;BREGA *:= BLKSZE +10 ASL BREGA + ROL BREGA+1 + ROL BREGA+2 + DEX + BNE #10 + RTS + + +;SETTAB + +;ENTRY: X - NO. OF ENTRIES IN TABLE +;Y - SIZE OF EACH ENTRY + +;EXIT: Y -> TABLE (LO) +;X -> TABLE (HI) + +;TABLE IS CLEARED TO ZERO AFTER +;GETTING SPACE FROM GETVEC. + +SETTAB ROUT + [ $CMOS + STZ TEMPA + STZ TEMPA+1 + | + LDAIM 0 + STA TEMPA + STA TEMPA + 1 + ] +10 CLC + TYA + ADC TEMPA + STA TEMPA + BCC #20 + INC TEMPA+1 +20 DEX + BNE #10 + + LDY TEMPA + LDX TEMPA+1 + JSR GETVEC ;*** GET SPACE ** + [ $CMOS + PHY ;DONT' TRUST CLRSTR WITH X/Y + PHX + | + TYA + PHA ;DONT' TRUST CLRSTR WITH X/Y + TXA + PHA + ] + STY CLRPTR + STX CLRPTR+1 + LDY TEMPA + LDX TEMPA+1 + JSR CLRSTR + [ $CMOS + PLX + PLY + | + PLA + TAX + PLA + TAY + ] + RTS + + +GETBB ROUT + LDAIM 7 + LDYIM ARGA + STAIY NEWARG + JSR STRMAN ;Do get big buffer + BNE #20 + + LDXIM 3 + LDYIM ARGE +10 LDAIY NEWARG + STAAX BBUF ;Set address and size + DEY + DEX + BPL #10 + CLC + LDA BBUF + ADC BBSIZE + STA BBEND ;Set end address + LDA BBUF+1 + ADC BBSIZE+1 + STA BBEND+1 + + [ $Level3 + +;declare a new I/O side buffer for file transfers +;Nb 2nd processor FS only + [ $CMOS + STZ IOBUF ;even page boundary + | + LDXIM 0 + STX IOBUF ;even page boundary + ] + LDYIM &FF + LDAIM 180 + JSR OSBYTE ;read I/O OSHWM + + STX RXBUF+1 ;ready for i/o routine + [ 1=0 + STX CODTB1 ;modify table a bit + STX CODTB4 + ] + [ ZTIME=0 + STX CODTX4 + STX CODTX7 + STX CODTX8 + ] + + INX ;result returned in X + STX IOBUF+1 ;base of buffer + + LDAIM 135 + JSR OSBYTE ;read a char, get screen mode in Y + TYA + TAX ;read the bottom of display + LDAIM 133 + JSR OSBYTE ;result in X,Y + + STX IOEND + STY IOEND+1 + + SEC + TXA + SBC IOBUF + STA IOBSIZ ;get buffer size + TYA + SBC IOBUF+1 + STA IOBSIZ+1 ;two bytes + +;when reading unwritten sectors of disc, the store must be +;set to zero. This is to be done in the I/o side by a +;dubious bit of code, called by intercepting the OSBPUT vector +;The code itself is poked over in the following section + + LDXIM &FF + STX ODSCMN ;illegal value for big buffer cache + STX ODSCMN+1 + + STX RXBUF+2 + STX RXBUF+3 ;high order address + INX + STX RXBUF ;lo byte of address, hi byte already set up + + LDAIM 0 +20 RTS + + [ 1=1 + +GETBLA LDX RXBUF + LDAAX CODTAB + CMPIM &EA + BEQ GETBLB ;end marker + STA RXBUF + 4 ;byte to put in + + JSR GETBW ;do call + INC RXBUF + BNE GETBLA + +GETBLB LDAIM BPUTV + STA RXBUF + LDAIM /(BPUTV ) + STA RXBUF + 1 + LDAIM 0 + STA RXBUF + 4 ;data lo + JSR GETBW + INC RXBUF + LDA CODTB1 + STA RXBUF + 4 ;data hi + JSR GETBW + + [ ZTIME=0 + LDAIM &0216 + STA RXBUF + LDAIM /(&0216 ) + STA RXBUF + 1 + LDAIM CODTX1-CODTAB + STA RXBUF + 4 ;data lo + JSR GETBW + INC RXBUF + LDA CODTB1 + STA RXBUF + 4 ;data hi + JSR GETBW + ] + + RTS + +GETBW LDXIM RXBUF + LDYIM /(RXBUF ) + LDAIM 6 + JMP OSWORD ;call to ammend store + +CODTAB = &8D,&0B +CODTB1 = &00 ;ammended to buffer start + = &8C,&0A +CODTB4 = &00 +; STA CODTB2 +%2 ;ammend hi byte of address +; STY CODTB2 +%1 ;ammend hi byte of address + LDAIM 0 + TAY +CODTB2 STAAY &7C00 ;hi byte ammended + INY + BNE CODTB2 + RTS +;CODTB3 * CODTB2 +%2 + + [ ZTIME=0 +CODTX6 EORIM &FF ;invert input + PHA + LSRA + LSRA + LSRA + LSRA + = &20 ;JSR + = . - CODTAB + 3 +CODTX4 = &00 + PLA +CODTX2 ANDIM &0F + ORAIM &30 + CMPIM &3A + BCC CODTX3 + ADCIM &06 +CODTX3 JMP &E0A4 ;call wrch direct + +CODTX1 TAX + BEQ CODTX5 + LDA &FE64 + PHA + LDA &FE65 + = &20 + = CODTX6-CODTAB +CODTX7 = &00 + PLA + = &20 + = CODTX6-CODTAB +CODTX8 = &00 + LDAIM &20 + JSR &E0A4 +CODTX5 LDAIM 0 + STA &FE6B + LDAIM &FF + STA &FE64 + STA &FE65 + RTS + ] + NOP ;end marker + [ ZTIME=0 +RDTIME LDAIM &FF + JMP &FFD7 + +WRTIME LDAIM 0 + JMP &FFD7 + ] + ] ;*** 17/9/84 + | + [ Cachesw=Yes + LDXIM &FF + STX ODSCMN ;illegal value for big buffer cache + STX ODSCMN+1 + ] + LDAIM 0 +20 RTS + ] + +INCGPT INC GENPTR + BNE #30 + INC GENPTR+1 +30 RTS + + +MEMTST ROUT ;MEMTST + +;First find end of memory. Then test memory +;several times with random numbers and once each +;with %0 and $FF. + + [ $Level3 + + JSR VSTRIN + = CR,"Testing Memory",CR + NOP + + LDAIM :LSB:FRESTR + STA GENPTR ;NOTE ASSUMES FRESTR ON PAGE BOUNDARY + LDAIM :MSB:FRESTR + STA GENPTR+1 + LDYIM 0 +10 LDAIM &55 + STAIY GENPTR + LDAIM &FF + INY + STAIY GENPTR ;Clear address lines + INY + STAIY GENPTR + DEY + DEY + LDAIY GENPTR + CMPIM &55 + BNE #20 ;NE if found + LDX GENPTR+1 + INX + STX GENPTR+1 ;use page sized jumps + CPXIM &F8 ;look for start of NET code + BNE #10 + +20 DEY + CLC + TYA + STA NEWARG + LDA GENPTR+1 + SEC + SBCIM 1 + STA NEWARG+1 + JSR VSTRIN + = CR,"Last free location = " + NOP + LDA NEWARG+1 + JSR WHEX + LDA NEWARG + JSR WHEX + JSR OSCRLF + | + LDAIM 132 ;Top of RAM address + JSR OSbyte + DEY ;Leave a page for printer server + DEY ;And mark last address + STY Newarg+1 + LDYIM &FF + STY Newarg + ] + +;NOW TEST MEMORY + + LDAIM &44 ;Set "random number" + STA COZERO + LDAIM &55 + STA COZERO+1 + STA COZERO+2 + [ $CMOS + STZ ARGPTR ;Use ARGPTR as an error flag + | + LDAIM 0 + STA ARGPTR ;Use ARGPTR as an error flag + ] + LDXIM 3 +30 JSR RMTSTA ;Random number test + DEX + BNE #30 + LDAIM 0 + JSR RMTSTB + LDAIM &FF + JSR RMTSTB + + LDA NEWARG + STA MEMEND + LDA NEWARG+1 + STA MEMEND+1 + LDA ARGPTR ;Error flag + RTS + + +RMTSTA ROUT ;RMTSTA + +;Test from FREPTR to NEWARG using pseudo rand. nos. +;in COZERO +00/01/02 + + LDAIM :LSB:FRESTR + STA GENPTR + LDAIM :MSB:FRESTR + STA GENPTR+1 + +10 LDA COZERO + STA COZERO+3 ;Store for checking pass + LDA COZERO+1 + STA COZERO+4 + LDA COZERO+2 + STA COZERO+5 + LDYIM 0 +20 LDA COZERO + STAIY GENPTR + JSR RANDUM + INY + BNE #20 + +;Reset rand. no. and check page. + + LDA COZERO+3 + STA COZERO + LDA COZERO+4 + STA COZERO+1 + LDA COZERO+5 + STA COZERO+2 +30 LDA COZERO + CMPIY GENPTR + BEQ #40 ;OK, continue + JSR MEMERR +40 JSR RANDUM + INY + BNE #30 + +;Finished testing one page, do next one. + + INC GENPTR+1 + LDA NEWARG+1 + CMP GENPTR+1 + BCS #10 ;G/ptr >= NEWARG, continue. + RTS + + +RMTSTB ROUT ;RMTSTB + +;Test memory using value in A. + + STA COZERO + LDAIM :LSB:FRESTR + STA GENPTR + LDAIM :MSB:FRESTR + STA GENPTR+1 +10 LDYIM 0 + LDA COZERO +20 STAIY GENPTR + INY + BNE #20 ;Fill a page +30 LDAIY GENPTR + CMP COZERO + BEQ #40 ;OK, continue + JSR MEMERR +40 INY + BNE #30 + + INC GENPTR+1 + LDA NEWARG+1 + CMP GENPTR+1 + BCS #10 + RTS + + +RANDUM ROUT ;RANDUM + +;Generate next random number + + LDA COZERO + EORIM 2 + LSRA + LSRA + ROR COZERO + ROR COZERO+1 + ROR COZERO+2 + RTS + + + +MEMERR ROUT ;MEMERR + + [ $Level3 + +;Print error location and set flag + + + PHA + LDAIM &FF + STA ARGPTR ;Set error flag + TYA + PHA + JSR VSTRIN + = "Fails at: " + NOP + + LDA GENPTR+1 + JSR WHEX + CLC + PLA + TAY + ADC GENPTR + JSR WHEX + JSR OSCRLF + + PLA + RTS + + [ DONGLE=1 ; Keep track of days without dongle +INCDAY LDA DATE + CMPIM 28 + BCS #20 +10 INC DATE + JMP PRDTE + +20 LDA DATE+1 + ANDIM &F + CMPIM 2 + BEQ #60 + LDA DATE + CMPIM 30 + BCC #10 + LDXIM 4 + LDA DATE+1 + ANDIM &F +30 CMPAX MW30D-1 + BEQ #40 + DEX + BNE #30 + LDA DATE + CMPIM 31 + BNE #10 +40 LDA DATE+1 + ANDIM &F + CMPIM 12 + BEQ #50 + CLC + ADCIM 1 + TAX + LDA DATE+1 + ANDIM &F0 + STA DATE+1 + TXA + ORA DATE+1 + STA DATE+1 + LDAIM 1 + STA DATE + JMP PRDTE + +50 LDA DATE+1 + LSRA + LSRA + LSRA + LSRA + CLC + ADCIM 1 + ASLA + ASLA + ASLA + ASLA + ORAIM 1 + STA DATE+1 + LDAIM 1 + STA DATE +55 JMP PRDTE +60 LDA DATE + CMPIM 29 + BEQ #40 + LDA DATE+1 + LSRA + LSRA + LSRA + LSRA + CLC + ADCIM BASEYR + ANDIM &3 + BNE #40 + JMP #10 + ] + +MW30D = 4,6,9,11 + | + LDAIM &FB ; indicate memory error + JMP INTERR ; have to stop system + ] + +;pass userinfo pointer to CHANGESIZE + +JUSINF ROUT + LDYIM ARGB + LDAIY ARGPTR + TAX + INY + LDAIY ARGPTR + + LDYIM ARGK + STAIY NEWARG + DEY + TXA + STAIY NEWARG + RTS ;** 3/10/84 ** + + LNK Uade04 diff --git a/FileServer/SRC/FileServer/Uade04 b/FileServer/SRC/FileServer/Uade04 new file mode 100644 index 0000000..0e4fd36 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade04 @@ -0,0 +1,1411 @@ + OPT UADE04 ; > .Uade04 + TTL File server file UADE04 + + +;********************************* +;* FILE SERVER INITIALISATION * +;********************************* + + +INIT ROUT + LDAIM 7 + JSR SETRTN + JSR MAPMAN ;MAPMAN.RESTART + BNE #10 + + LDAIM 4 + JSR SETRTN + JSR USRMAN ;USRMAN.RESTART + BNE #10 + + LDAIM 4 + JSR SETRTN + JSR RNDMAN ;RNDMAN.RESTART + BNE #10 + + [ $Level3 + LDXIM &1F + LDYIM 2 + JSR SETTAB ;Table of qualifiers/directory handles + STY CDIRTB ;for DOS conversion. + STX CDIRTB+1 + ] + + LDAIM 6 + JSR SETRTN + JSR STRMAN ;STRMAN.RESTART + + [ $Level3 +00 BEQ #20 +10 PHA + JSR USRERR + PLA +20 RTS + +RSTAUT LDAIM 6 + JSR SETRTN ;AUTMAN.RESTART + JSR AUTMAN + JMP #00 + +STRTFS ROUT + + CLD + + JSR MEMTST ;Test memory. + BEQ ASKDAT ;OK + + JSR VSTRIN + = "Memory fault found",CR + = "File Server unable to start",CR + = "Ended",CR + NOP + RTS ;STOP !! + +ASKDAT ROUT + [ DONGLE=0 + JSR RTC + BEQ #10 + JSR VSTRIN + = CR,"Clock Failure",CR + NOP + JMP TSTART ; .. that's all folks .. + + | + + JSR STDATE ;FIND OUT THE DATE if no RTC + + ] +10 JSR RDTIME + JSR RDDRVS ;HOW MANY DRIVES? + + + +INITCO ROUT ;INITCO + +;Main start point of any FS command. +;Resets ENDPTR, FREPTR and re-allocates all tables. +;NOTE !! It is therefore assumed that maps etc. +;have been ensured to disc !! + + LDAIM :LSB:DYNSTA + STA FREPTR + LDAIM :MSB:DYNSTA + STA FREPTR+1 ;FREPTR := DYNSTA + | + BNE #10 + + LDAIM 6 ;Restart AUTMAN + JSR SETRTN + JSR AUTMAN ;AUTMAN.RESTART + BEQ #20 +10 PHA + JSR USRERR + PLA +20 RTS + +;Main start point +;Resets ENDPTR, FREPTR and re-allocates all tables. +;STRTF1 Entry with door state in A + +CMintb ;**5/3/88** table for initialising CMOS RAM + = &FE,&01 ;Set station id + complement + = 0,0,0,0 ;Reserved + = 0,0,0,0,0 ;Error logout + = 0,0,0 ;SIN of last disc access on error + = 80 ;Max users + = 6 ;Max drives + = "PRINT " ;printer name + = "SYST",CR ;maintenance userid + = 0,0,0,0,0,0 ;...continued + = :LSB:("S"+"Y"+"S"+"T"+&0D)+:MSB:("S"+"Y"+"S"+"T"+&0D) + = 0 ;printer page flag + = 0 ;ACORN copyright check flag + +Strtfs ROUT + LDXIM 1 ;Turn on LED during tests + LDAIM 137 + JSR OSbyte + JSR MEMTST ;Test memory - comes back only if OK + + LDXIM Stnids ;**5/3/88** find if CMOS initialised + JSR OSrdad + STA Cozero + LDXIM Stnids+1 + JSR OSrdad + SEC + ADC Cozero ;if station ids checksum + BEQ #20 ;then assume initialised + LDXIM CMinst +10 LDAAX CMintb-Stnids + PHX + JSR OSwrad + PLX + INX + CPXIM CMinen + BCC #10 + +20 JSR Pstart ;Now start the printserver + + LDAIM 128 ;read user switches + LDXIM 0 + JSR OSbyte +Strtf1 ROUT + STA Cozero+11 ;save door state in zero page + LDAIM MASK ;Protect against ECOnet interference + JSR Doprot + + LDXIM MUaddr ;Read number of users + JSR OSrdad ;From non-volatile memory + BEQ #00 ;Use max if unset + CMPIM Maxuse ;or if too big + BCC #01 +00 LDAIM Maxuse ;Set number of users to max +01 STA Users + + LDXIM MDaddr ;Read number of drives + JSR OSrdad ;From non-volatile memory + BEQ #02 ;Use default if unset + CMPIM 7 ;or if too big + BCC #03 +02 LDAIM 6 ;Set drives to Winnie + 2 floppies +03 STA Drives + + STZ Cmndsw ;Default to user mode + LDXIM 0 ;determine mode & led setting + LDA COZERO+11 ;reload entry door state + ANDIM 2 ;isolate door switch + BEQ #05 ;br if in user state (door closed) + LDAIM &80 ;else set command mode 0 + STA Cmndsw ;set in command mode + INX +05 LDAIM 137 + JSR OSbyte ;set led to command/user state + + JSR Getdte ;Get date & time from RTC chip + +Strtf2 ;Enter here after FSMODE M +10 + LDAIM :LSB:DYNSTA + STA FREPTR + STA Bigbuf ;Used in command mode only + LDAIM :MSB:DYNSTA + STA FREPTR+1 ;FREPTR := DYNSTA + STA Bigbuf+1 + ] + + LDA MEMEND + STA ENDPTR + LDA MEMEND+1 + STA ENDPTR+1 + +;GET SOME SPACE FOR THE ARGUMENT STACK AND SETUP ARGPTR + + LDYIM :LSB:STKSZE + LDXIM :MSB:STKSZE + JSR GETVEC + STY ARGPTR + STX ARGPTR+1 + +;NOW CLEAR THE ARGUMENT STACK TO ZERO + + STY CLRPTR + STX CLRPTR+1 ;CLRPTR:=ADDR OF ARGUMENT STACK + LDYIM :LSB:STKSZE + LDXIM :MSB:STKSZE + JSR CLRSTR + + [ $Level3 + + JSR VSTRIN + = CR,"Command :" + NOP + JSR CURSON + JSR OSECHO + PHA + JSR CURSOF + PLA + LDXIM 4 +10 CMPAX FSCTBA + BEQ #20 + DEX + BPL #10 + + JSR VSTRIN + = CR,"S, A, * ONLY" + NOP + JMP INITCO + +20 TXA + ASLA + TAX + LDAAX FSCTBB + STA TEMPA + LDAAX FSCTBB+1 + STA TEMPA+1 + JMI TEMPA + +FSCTBA = "SA*sa" + +FSCTBB & STRTUP + & ASKDAT + & OSCMD + & STRTUP + & ASKDAT + +OSCMD JSR RDLINE + LDXIM 0 + LDYIM 1 + JSR OSCLI + JMP INITCO + +;NORMAL FILE SERVER STARTUP +STRTUP ROUT + JSR RDUSRS + LDAIM 1 + JSR SETFS + JSR INIT + BEQ #10 + JMP INITCO ;Error => do again + +10 LDXIM :LSB:DOBRK + LDYIM :MSB:DOBRK + JSR SETBRK + JSR RSTAUT ;RESTART AUTMAN + JMP CMND ;JUMP TO FILE SERVER COMMAND PROCESSOR + + + +RDDRVS ROUT + JSR VSTRIN ;FINDOUT HOW MANY DRIVES THERE ARE + = CR,"Number of drives:" + NOP + JSR RDLINE + JSR GETINT ;INTEGR:=NUMBER OF DISCS + BNE RDDRVS + LDA INTEGR + 1 + BNE RDDRVS + LDA INTEGR + BEQ RDDRVS + STA DRIVES ;DRIVES:=NUMBER OF DRIVES ATTACHED TO FS + RTS + + + +STDATE ROUT + + [ DONGLE=1 ;ie dongle absent + +;If here, no time chip, so prompt for date + +10 JSR VSTRIN ;SETUP THE DATE + = CR,"Date (DD/MM/YY) = " + NOP + + JSR RDLINE ;READ A COMPLETE LINE + JSR GETINT ;GET DAY +20 BNE #10 + LDA INTEGR+1 + BNE #10 + LDA INTEGR + STA DATE ;LS(DATE) := DAY + LDAIY COMPTR + CMPIM "/" +30 BNE #20 + JSR INCCOM ;COMPTR +:=1 + JSR GETINT ;GET MONTH + BNE #30 + LDA INTEGR+1 + BNE #30 + LDA INTEGR + ANDIM &F0 + BNE #10 + LDA INTEGR + ANDIM &F + STA DATE+1 ;LS(DATE+01) := MONTH + LDAIY COMPTR + CMPIM "/" + BNE #30 + JSR INCCOM ;COMPTR +:=1 + JSR GETINT ;GET YEAR + BNE #30 + LDA INTEGR+1 +40 BNE #30 + LDA INTEGR + SEC + SBCIM BASEYR ;SUBTRACT 81 + BCS #50 ;**24/2/88** br if 19xx + ADCIM 100 ;**24/2/88** correct if 20xx +50 JSR SETYR ;Set year nybble + LDAIM 0 + STA DATE+2 ;With no time chip, day = 0 + JSR CHKDTE + BNE #40 + JSR PRDTE + ] + RTS + | + +;Perform remaining initialisation + + LDAIM 1 + JSR SETFS + BIT Cmndsw ;only call INIT in User mode + BMI #20 + JSR INIT + BNE #10 + +20 JSR Getbb ;get big buffer + JMP CMND ;JUMP TO FILE SERVER COMMAND PROCESSOR + +; DOPROT: +; set ECOnet protection state from mask in A. +; All regs destroyed. + +Doprot ROUT + STA OSwork+1 ;Save required mask + LDAIM 5 + STA OSwork ;Set protection call + LDXIM :LSB:OSwork + LDYIM :MSB:OSwork + LDAIM &13 + JMP OSword ;Set mask and return + +; GETDTE/SETDTE: +; Get or set the date vector from the MOS - slightly fudged interface +; includes the date and time. Must let the MOS manipulate the date chip +; due to interrupt constraints etc. + +; OSword entry: X/Y = address of 5 byte date/time vector. Order is: +; Day of month +; Year offset/month +; Hours +; Minutes +; Seconds + +Getdte ROUT + LDAIM 1 + BRA #10 + +Setdte LDAIM 2 +10 LDXIM :LSB:Date + LDYIM :MSB:Date + JMP OSword ; OSword 1 or 2 as appropriate + + +; Check the date for sensible values and report if silly + +MW30D = 4,6,9,11 + ] + +CHKDTE ROUT + LDA DATE + [ $Level3 + STA DAYS + ] + ANDIM 31 ;**24/2/88** isolate day of month + TAX + BEQ #40 + CMPIM 32 + BCS #40 + LDA DATE+1 + [ $Level3 + STA MUNTHS + ] + ANDIM &F + BEQ #40 + CMPIM 13 + BCS #40 + CMPIM 2 + BEQ #20 ; br to check leap year + TXA + CMPIM 31 + BCC #30 + LDXIM 4 + LDA DATE+1 + ANDIM &F +10 CMPAX MW30D-1 + BEQ #40 + DEX + BNE #10 + [ $Level3 + BEQ #30 + | + BRA #30 + ] + +20 TXA + CMPIM 29 + BCC #30 + CMPIM 30 + BCS #40 + LDA DATE+1 + ADCIM :LSB:(BASEYR*16) + ANDIM 3*16 + BNE #40 +30 LDAIM 0 + RTS + +40 LDAIM 1 + RTS + + [ $Level3 +;PRNTDG: PRINT A DECIMAL NUMBER < 100 +;ENTRY A:= NUMBER. C clear if to print leading zeroes + +PRNTDG ROUT + PHP ;**24/2/88** Save C + LDXIM &FF + SEC +10 INX + SBCIM &0A + BCS #10 + ADCIM &0A + PLP ;**24/2/88** Reset C + PHA + TXA ;OUTPUT TOP DIGIT + BCC #15 ;**24/2/88** br to ignore zero check + BEQ #20 +15 JSR #40 + JMP #30 +20 LDAIM " " + JSR OSWRCH +30 PLA +40 ORAIM "0" ;CONVERT TO CHAR + JMP OSWRCH + + +RDUSRS ROUT + JSR VSTRIN + = CR,"Stations:" + NOP + + JSR RDLINE + JSR GETINT + BNE RDUSRS + LDA INTEGR+1 + BNE RDUSRS + LDA INTEGR + BEQ RDUSRS + STA USERS + + CMPIM MAXUSE+1 ; USRLIM + BCS RDUSRS + RTS + + [ DONGLE=1 + +RDTIME ROUT + JSR VSTRIN + = CR,"Time (HH:MM:SS) = " + NOP + + JSR RDLINE ;INPUT TIME + JSR GETINT ;GET HOURS + BNE RDTIME + LDA INTEGR+1 + BNE RDTIME + LDA INTEGR + CMPIM 24 ;CHECK LESS THAN 24 HOURS + BCS RDTIME + STA HRS + LDAIY COMPTR + CMPIM ":" ;CHECK CORRECT SEPARATOR + BNE RDTIME + JSR INCCOM ;NEXT INTEGER + JSR GETINT + BNE RDTIME + LDA INTEGR+1 +10 BNE RDTIME + LDA INTEGR + CMPIM 60 +20 BCS RDTIME + STA MINS + LDAIY COMPTR + CMPIM ":" ;CHECK FOR SEPARATOR + BNE #10 + JSR INCCOM + JSR GETINT ;GET SECONDS + BNE #10 + LDA INTEGR+1 + BNE #10 + LDA INTEGR + CMPIM 60 ;CHECK LESS THAN 60 + BCS #20 + STA SECS + +SETTME ROUT + LDAIM 0 + LDXIM 4 +10 STAAX TIME + DEX + BPL #10 + JSR ZEROTM + LDA HRS + STA OTIME ;PREPARE TO CALCULATE CENTISECONDS + JSR M60 ;MULTIPLY BY 60 + JSR M60 ;DITTO + JSR M100 ;TO GET CENTISECONDS + JSR TIMADD ;KEEP TRACK OF TIME + JSR ZEROTM + LDA MINS + STA OTIME + JSR M60 + JSR M100 ;TO GET CENTISECONDS + JSR TIMADD ;KEEP TOTAL + JSR ZEROTM + + LDA SECS + STA OTIME + JSR M100 ;FOR CENTISECONDS + JSR TIMADD ;KEEP TOTAL + JSR TMTOT + LDXIM TIME + LDYIM /(TIME) + LDAIM 2 + JMP OSWORD + +TMTOT ROUT + LDXIM 4 +10 LDAAX TIME + STAAX OTIME + DEX + BPL #10 + RTS + +ZEROTM ROUT + LDAIM 0 + LDXIM 4 +10 STAAX OTIME + DEX + BPL #10 + RTS + +TIMADD ROUT + CLC + LDYIM 4 + LDXIM 0 +10 LDAAX TIME + ADCAX OTIME + STAAX TIME + INX + DEY + BPL #10 + RTS + +M60 ROUT + JSR TXOTN + LDXIM 6 + JSR SHNTBX + LDXIM 2 + JSR SHOTBX + SEC + LDXIM 0 + LDYIM 4 +10 LDAAX NTIME + SBCAX OTIME + STAAX OTIME + INX + DEY + BPL #10 + RTS + +M100 ROUT + JSR TXOTN + LDXIM 6 + JSR SHNTBX + LDXIM 2 + JSR SHOTBX + CLC + LDXIM 0 + LDYIM 4 +10 LDAAX NTIME + ADCAX OTIME + STAAX NTIME + INX + DEY + BPL #10 + LDXIM 3 + JSR SHOTBX + CLC + LDYIM 4 + LDXIM 0 +10 LDAAX NTIME + ADCAX OTIME + STAAX OTIME + INX + DEY + BPL #10 + RTS + + +TXOTN ROUT + LDXIM 4 +10 LDAAX OTIME + STAAX NTIME + DEX + BPL #10 + RTS + +SHNTBX ROUT + ASL NTIME + ROL NTIME+1 + ROL NTIME+2 + ROL NTIME+3 + ROL NTIME+4 + DEX + BNE SHNTBX + RTS + +SHOTBX ROUT + ASL OTIME + ROL OTIME+1 + ROL OTIME+2 + ROL OTIME+3 + ROL OTIME+4 + DEX + BNE SHOTBX + RTS + +PRTIM ROUT +PRTIME LDXIM :LSB:TIME + LDYIM :MSB:TIME + LDAIM 1 + JSR OSWORD + JSR DIV100 + JSR DIV60 + LDA REM + STA SECS + JSR DIV60 + LDA REM + STA MINS + JSR DIV24 + LDA REM + STA HRS + LDAIM &86 + JSR OSBYTE + STX POS + STY VPOS + JSR DWIND ;*** setup the window + JSR VSTRIN + = 31,30,1 + NOP + LDA HRS + CLC + JSR PRNTDG + LDAIM ":" + JSR OSWRCH + LDA MINS + CLC + JSR PRNTDG + LDAIM ":" + JSR OSWRCH + LDA SECS + CLC + JSR PRNTDG + JSR MWIND ;*** reset the window + LDXIM 4 + LDAIM 0 +10 ORAAX TIME + DEX + BPL #10 + TAX + BEQ #20 + LDXIM :LSB:TIME + LDYIM :MSB:TIME + LDAIM 1 + JSR OSWORD + SEC + LDA TIME+1 ;GONE PAST MIDNIGHT SO SET BACK TO APROX. ZERO + SBCIM &D6 + STA TIME+1 + LDA TIME+2 + SBCIM &83 + STA TIME+2 + LDA TIME+3 + SBCIM 0 + STA TIME+3 + LDA TIME+4 + SBCIM 0 + STA TIME+4 + LDXIM :LSB:TIME + LDYIM :MSB:TIME + LDAIM 2 + JSR OSWORD + JSR INCDAY +20 RTS + +TDVD ROUT + STA DVSOR + LDAIM 0 + LDXIM 4 +10 STAAX OTIME + DEX + BPL #10 + LDYIM &28 +20 DEY + BEQ #80 + ASL TIME + ROL TIME+1 + ROL TIME+2 + ROL TIME+3 + ROL TIME+4 + BPL #20 +30 + LDXIM :LSB:-5 +40 ROLAX TIME-:LSB:-5 + INX + BNE #40 + LDXIM :LSB:-5 +50 ROLAX OTIME-:LSB:-5 + INX + BNE #50 + SEC + LDA OTIME + SBC DVSOR + PHA + LDA OTIME+1 + SBCIM 0 + PHA + LDA OTIME+2 + SBCIM 0 + PHA + LDA OTIME+3 + SBCIM 0 + TAX + LDA OTIME+4 + SBCIM 0 + BCC #60 + STA OTIME+4 + STX OTIME+3 + PLA + STA OTIME+2 + PLA + STA OTIME+1 + PLA + STA OTIME + BCS #70 +60 PLA + PLA + PLA +70 DEY + BNE #30 +80 LDA OTIME + STA REM + RTS + +DIV100 ROUT + LDAIM 100 +DODVD JSR TDVD + LDXIM 0 + LDYIM 4 +10 ROLAX TIME + INX + DEY + BPL #10 + RTS + +DIV60 LDAIM 60 + BNE DODVD + +DIV24 LDAIM 24 + BNE DODVD + ] + + [ DONGLE=0 +RDTIME + ] +PRDTE + [ DONGLE=0 + JSR RDDONG + ] + +SCDATE + JSR DWIND ;set window + + JSR VSTRIN + = 12,31,0,1 + NOP + JSR DATE1 + JSR MONTH + JSR YR + + ;reset the window + +MWIND ;set window for monitor + JSR VSTRIN + = 28,0,21,39,4,31 +POS = 0 +VPOS = 0 + NOP + RTS + +DWIND ;set window for printing the date in + + LDAIM &86 + JSR OSBYTE ;read cursor position + STX POS + STY VPOS + JSR VSTRIN + = 28, 0, 24, 39, 22 + NOP + RTS + +YR ROUT + LDA Date ;**24/3/88** isolate year high order + ANDIM &E0 + STA Rem + LDA DATE+1 + LSRA + LSRA + LSRA + ORA Rem ;**24/2/88** include high order + LSRA + CLC + ADCIM BASEYR + PHA + CMPIM 100 + BCC #10 + PLA + SBCIM 100 + PHA + LDAIM 20 + BNE #20 +10 LDAIM 19 +20 CLC + JSR PRNTDG + PLA + CLC + JMP PRNTDG + + +MONTH ROUT + LDA DATE+1 + ANDIM &F + TAX + LDYAX MTAB1-1 +10 LDAAY MONTHS + BEQ #20 + JSR OSWRCH + INY + BNE #10 +MONOUT +20 LDAIM &20 + JMP OSWRCH + + +MONTHS +JAN = "January", 0 +FEB = "February", 0 +MAR = "March", 0 +APR = "April", 0 +MAY = "May", 0 +JUN = "June", 0 +JUL = "July", 0 +AUG = "August", 0 +SEP = "September", 0 +OCT = "October", 0 +NOV = "November", 0 +DEC = "December", 0 + +MTAB1 = JAN-MONTHS + = FEB-MONTHS + = MAR-MONTHS + = APR-MONTHS + = MAY-MONTHS + = JUN-MONTHS + = JUL-MONTHS + = AUG-MONTHS + = SEP-MONTHS +MTAB2 + = OCT-MONTHS + = NOV-MONTHS + = DEC-MONTHS + + + +DATE1 ROUT + LDA DATE + ANDIM &1F ;**24/2/88** isolate day of month + PHA + SEC ;**24/2/88** strip leading zero + JSR PRNTDG + PLA + CMPIM 10 + BCC #20 + SBCIM 10 + CMPIM 10 + BCC #30 +10 SBCIM 10 + CMPIM 10 + BCS #10 +20 TAY + CPYIM 1 + BEQ #40 + CPYIM 2 + BEQ #40 + CPYIM 3 + BEQ #40 +30 LDYIM 4 +40 DEY + LDXAY #80 +50 LDAAX #70 + BEQ #60 + JSR OSWRCH + INX + BNE #50 +60 LDAIM &20 + JMP OSWRCH + +70 +71 = "st", 0 +72 = "nd", 0 +73 = "rd", 0 +74 = "th", 0 + + +80 = #71-#70 + = #72-#70 + = #73-#70 + = #74-#70 + + + +SETYR ASLA + STA Rem + ASLA + ASLA + ASLA + ORA DATE+1 + STA DATE+1 ;Year is top nibble of DATE +01 + LDA Rem + ANDIM &E0 ;**24/2/88** Plus 3 high order bits in DATE + ORA Date + STA Date + RTS + + [ DONGLE=0 + ; Dongle has 4 time set registers :- MINS,HOURS,DATE,MONTH + ; Also has 4 alarm registers which are treated as RAM + ; to store YEAR and OLDMONTH to try to deal with year changes + ; Because cursed chip can not handle years. + ; All number are BCD coded in the chip + + ; DESIGNATION AS FOLLOWS :- + + ; TIME SET REGISTERS, + ; 0=MONTH 2=DATE 4=HOURS 6=MINS + + ; RAM REGISTERS, + ; 1=YEAR in lower 7 bits + ; 3=OLDMONTH and bit &10 to indicate LEAP pending (Was date) + ; + ; 5=Not Used + ; 7=Used to determine presence of chip (Was Mins) + + +SETTME ROUT + LDA DAYS ;**24/2/88** get year high order + ANDIM &E0 + STA Rem + LDA MUNTHS + LSRA + LSRA + LSRA + ORA Rem + LSRA + LDXIM 1 + JSR #95 ;set Year + +SETTM1 LDA MUNTHS + ANDIM &F + LDXIM 0 + JSR #95 ;set month + + LDA MUNTHS ; *** LH 15/1/86 *** + JSR SETMFX ; Fix year and month to form for register + LDXIM 3 + JSR #95 ; Set oldmonth to month and flag + + LDA MINS + LDXIM 6 + JSR #95 + + LDA HRS + LDXIM 4 + JSR #95 + + LDA DAYS + ANDIM 31 ;**24/2/88** isolate day of month + LDXIM 2 + JSR #95 + + JMP SCDATE ; SHOW DATE ON SCREEN + +SETMFX ; FIX MONTH AND FLAG ON SET TIME + PHA ; stack month and year + ANDIM &0F ; Mask MONTH + CMPIM 2 + BCC SETJAN ; Branch if Jan + BNE LHNOF ; >JAN so no flag pending + LDA DAYS + ANDIM 31 ;**24/2/88** isolate day of month + CMPIM 29 + BCS LHNOF ; >= 29 so no flag pending + +SETJAN ; befor Feb 29 so check for leap + PLA ; Retreive year + PHA + CLC + ADCIM :LSB:(BASEYR*16) + ANDIM 3*16 ; Leap year check + BNE LHNOF ; Not leap so flag clear + PLA + ANDIM &0F ; Otherwise + ORAIM &10 ; set flag on month + RTS + +LHNOF PLA + ANDIM &0F + RTS + +PRTIM INC OTIME ;** avoid tube failure 25/1/85 ** + BNE RTCX ;exit + INC OTIME+1 + BMI RTCX + SEC + ROR OTIME+1 +PRTIME JSR RDDONG + LDA HRS + ORA MINS + BNE PRTIM1 ;midnight + ORA SECS ;check not already done + BNE PRTIM2 + + INC SECS + JSR PRDTE ;reprint the date + JMP PRTIM2 + +PRTIM1 LDAIM 0 + STA SECS +PRTIM2 JSR DWIND ;set up window + JSR VSTRIN + = 31,30,1 + NOP + LDA HRS + CLC + JSR PRNTDG + LDAIM ":" + JSR OSWRCH + LDA MINS + CLC + JSR PRNTDG + JMP MWIND ;reset window and return + +RTC ;check that the read time clock is present + + LDXIM 7 + LDAIM &71 + JSR #95 ;write the minutes alarm register + + LDXIM 7 ;read the same register + JSR #00 + JSR #70 + EORIM &0D ;devious eh + BNE RTCX ;fail + + LDXIM 7 + JSR #95 ;write zero as well + + LDXIM 7 + JSR #00 ;read result + CMPIM 0 +RTCX RTS ;returns EQ if dongle present + +RDDONG + + LDXIM 6 ;read minutes + JSR #00 + JSR #70 + STA MINS + + LDXIM 4 ;hours + JSR #00 + JSR #70 + STA HRS + + LDXIM 2 ;days + JSR #00 + JSR #70 + STA DATE + + LDXIM 0 ;months + JSR #00 + JSR #70 + STA DATE+1 + + LDXIM 3 ;oldmonth + JSR #00 + JSR #70 + STA OTIME+2 ; somewhere but where + + + LDXIM 1 ;year (in alarm register) + JSR #00 + JSR #70 + JSR SETYR + ; JSR REDFIX ; Fix year and month if neccessary *** LH *** + ; *** 15/1/86 *** + ; RTS + + +REDFIX ; FIX year changes + ; Fix date on reading dongle + ; ENTRY DATE+1 has perceived month and year + ; OTIME+2 has OLDMONTH and Flag + ; OTIME+3 used + + LDA OTIME+2 + ANDIM &0F + STA OTIME+3 + LDA DATE+1 + ANDIM &0F ; A has month + CMP OTIME+3 + BCS LHLYCK ; Months are ok so leap year checks + ; Here month has decreased so reset year + LDA DATE+1 + CLC + ADCIM &10 ; Increment year will loop sometime + ; but who cares as product should + ; be dead by then + STA DATE+1 + BCC RFIXX2 ; **24/2/88** No carry from low order + LDA Date + ADCIM &1F ; **24/2/88** continue carry into high order + STA Date + BNE RFIXX2 ; Branch always (year <>0) + ; REWRITE DONGLE +LHLYCK LDA OTIME+2 + ANDIM &10 + BEQ RTCX ; No flag so exit + +LHFXNX + LDA DATE+1 ; Load new Month + ANDIM &0F + CMPIM 3 + BCC RTCX ; Not MAR yet so exit + ; Here it is March (or Later) in a leap year + ; So fix dates + DEC DATE ; DEC DAYS + BNE RFIXX2 ; RE WRITE DONGLE + + ; DAYS Became ZERO ! + DEC DATE+1 ; Decrement month is ok + LDA DATE+1 + ANDIM &0F ; Get new month saves confusion + CMPIM 2 + BNE LHNFEB ; IS NOT FEB SO CHECK OTHERS + LDAIM 29 ; Must be 29th + BNE RFIXEX ; Re Write DONGLE (ALWAYS) + +LHNFEB + LDXIM 4 +LHCHKL CMPAX MW30D - 1 + BEQ LHCKLX ; FOUND SO EXIT + DEX + BNE LHCHKL + LDAIM 31 + BNE RFIXEX + +LHCKLX LDAIM 30 +RFIXEX + + STA DATE +RFIXX2 + JSR CHKDTE + JMP SETTME + + +00 PHP ;same as POKE + TXA + JSR #05 + LDAIM &06 ;bits 7,5 are POWERFAIL and ALARM + STA DDRB + JSR #55 ;write DDRB + JSR #10 + LDXIM 2 + CLC + JSR #20 + NOP + NOP + JSR #50 + LDA IRB ;read IRB + ANDIM 1 + CLC + RORA + RORA + LDYIM 6 +25 PHA + TXA + ORAIM 1 + TAX + CLC + JSR #40 + NOP + NOP + JSR #50 + LDA IRB + LSRA + PHP + TXA + ANDIM &FE + TAX + CLC + JSR #40 + PLP + PLA + RORA + DEY + BNE #25 + CLC + RORA + PHA + JSR #15 + JSR #50 + LDX IRB + PLA + PLP + RTS ;all done + +05 LDXIM &A7 + STX DDRB + JSR #55 ;write DDRB + LDYIM 4 + ASLA + LDXIM 2 ;fall thru' + +30 RORA + JSR #35 + DEY + BNE #30 + RTS ;write bits one at a time + +10 JSR #15 + NOP + NOP + CLC + JSR #35 + NOP + NOP + RTS + +35 PHA + PHP + TXA + ORAIM 1 + TAX + JSR #40 + TXA + ANDIM &FE + TAX + PLP + JSR #40 + PLA + RTS + +15 LDXIM 0 + STX ORB + BEQ #45 + +40 NOP + NOP + NOP + NOP +20 TXA + ROLA + STA ORB + +45 PHP + PHA + TXA + PHA + TYA + PHA + LDAIM 151 + LDXIM &60 + LDY ORB + JSR OSBYTE + JMP #60 + +50 PHP + PHA + TXA + PHA + TYA + PHA + LDAIM 150 + LDXIM &60 + JSR OSBYTE + STY IRB + JMP #60 + +55 PHP + PHA + TXA + PHA + TYA + PHA + LDAIM 151 + LDXIM &62 + LDY DDRB + JSR OSBYTE +60 PLA + TAY + PLA + TAX + PLA + PLP + RTS + +95 PHP ;Set routine + JSR #85 ;convert to BCD (without corrupting X) + CPXIM 0 ;detect writing munths + BNE #99 + ORAIM &40 +99 PHA + TXA + JSR #05 + PLA + LDYIM 7 + JSR #30 + JSR #10 + JSR #15 + PLP + RTS + +70 LDYIM 0 + TAX + BEQ #75 +80 CLD + INY + SED + SEC + SBCIM 1 + BNE #80 + CLD +75 TYA + RTS + +85 TAY ;make BIN to BCD + BEQ #94 + LDAIM 0 + SED +90 CLC + ADCIM 1 + DEY + BNE #90 +94 CLD + RTS + ] + ] + + LNK Uade05 diff --git a/FileServer/SRC/FileServer/Uade05 b/FileServer/SRC/FileServer/Uade05 new file mode 100644 index 0000000..c31c42f --- /dev/null +++ b/FileServer/SRC/FileServer/Uade05 @@ -0,0 +1,209 @@ + OPT UADE05 ; > .Uade05 + TTL File server file UADE05 + +;********************************* +;* G L O R T N * +;* AND DOS CONVERSION * +;********************************* + +;***** R N D M A N R O U T I N E S ***** + +;FNDHND: SEARCHES THE HANDLE TABLE (HANDTB) +;FOR A SPECIFIED HANDLE. + +;ENTRY: A = HANDLE +;MCNUMB = MACHINE NUMBER + +;EXIT : A = RC +;HNDPTR - LEFT POINTING TO PARTICULAR ENTRY +;CONTAINING SPECIFIED (HANDLE,MC/NO). +;NOTE A,X,Y,RNDTMP ARE DESTROYED. + +FNDHND ROUT + STA RNDTMP ;RNDTMP := HANDLE + TAY + BEQ #40 ;INVALID HANDLE + JSR INITHD ;HNDPTR:=HANDTB;X:=HTENTS + +;FIRST SEE IF MACHINE NUMBER MATCHES + +20 LDYIM HTMCNO ;LSIG BYTE FIRST + LDAIY HNDPTR + CMP MCNUMB + BNE #30 + INY + LDAIY HNDPTR + CMP MCNUMB+1 + BNE #30 + INY + LDAIY HNDPTR + CMP MCNUMB+2 + BNE #30 + +;NOW SEE IF HANDLE MATCHES + + LDYIM HTHAND + LDA RNDTMP + CMPIY HNDPTR + BNE #30 + +;FOUND + + LDAIM 0 ;RC := 0 + RTS + +30 JSR INCHND ;MOVE HNDPTR TO NEXT ENTRY,DEX + BNE #20 +40 LDAIM RDERRB + RTS + + +INITHD LDA HANDTB ;HNDPTR := HANDTB + STA HNDPTR + LDA HANDTB+1 + STA HNDPTR+1 + LDX HTENTS ;X := HTENTS + RTS + + +INCHND ROUT + CLC ;HNDPTR +:= HTENSZ + LDA HNDPTR + ADCIM HTENSZ + STA HNDPTR + BCC #10 + INC HNDPTR+1 +10 DEX ;X -:= 1 + RTS + + +;USRMAN ROUTINES + +;FINDMC: FIND A USERTB ENTRY - SEARCH +;USERTB FOR AN ENTRY CONTAINING A +;GIVEN MACHINE NUMBER. +;NOTE THAT FINDMC MAY BE CALLED +;BY ANY MODULE. +;(THIS FUNCTION WILL PROBABLY +;NEED SPEEDING UP - POSSIBLY USING +;A HASH TABLE FOR USERTB) + +;ENTRY: THE VARIABLE, MCNUMB, +;SHOULD CONTAIN THE +;NUMBER OF THE MACHINE +;TO BE LOOKED UP IN USERTB. + +;EXIT: A = RC +;IF A = 0 +;THEN USTPTR (PAGE ZERO) IS +;LEFT POINTING TO THE USERTB ENTRY +;FI + + +FINDMC ROUT + JSR INITUS ;USTPTR:=USERTB,X:=UTENTS +10 LDA MCNUMB ;LS(MC/NO) + LDYIM UTMCNO + CMPIY USTPTR + BNE #20 + INY + LDA MCNUMB+1 + CMPIY USTPTR + BNE #20 + INY + LDA MCNUMB+2 + CMPIY USTPTR + BNE #20 + LDYIM UTPRIV + LDAIY USTPTR + ANDIM INUSE + BEQ #20 + + LDAIM 0 ;RETURN CODE + RTS + +20 JSR INCUST ;USTPTR+:=UTENSZ,X-:=1 + BNE #10 + LDAIM URERRA ;RC:=MACHINE NOT LOGGED ON + RTS + + +INITUS LDA USERTB ;USTPTR:=USERTB,X:=USERS + STA USTPTR + LDA USERTB+1 + STA USTPTR+1 + LDX USERS + RTS + + +INCUST ROUT + CLC ;USTPTR+:=UTENSZ,X-:=1 + LDA USTPTR + ADCIM UTENSZ + STA USTPTR + BCC #10 + INC USTPTR+1 +10 DEX + RTS + + +DRVINF LDYIM ARGB ;A := DRIVE NUMBER + STAIY NEWARG + DEY ;Y := ARGA + LDAIM 8 ;MAPMAN.DRIVEINFO + STAIY NEWARG + JMP MAPMAN + + +;Flushes store and ensures map for drive +;passed in A. + +FLUDRV ROUT + JSR DRVINF ;GET DISC NO. + BNE #10 ;ABORT IF ERROR + + LDAIM 8 + JSR SETRTN + JSR STRMAN ;*** FLUSH STORE ** + BNE #10 + + LDAIM 6 + JSR SETRTN + JSR MAPMAN ;*** ENSURE DISC ** +10 RTS + + +;Flushes all drives in system, so it is +;safe to start from scratch !! + +FLUSYS ROUT + LDA DRIVES +10 + [ $Level3 + SEC + SBCIM 1 + | + DECA + ] + BMI #20 + PHA + JSR FLUDRV + BNE #30 +15 PLA + [ $Level3 + JMP #10 + | + BRA #10 + ] + +20 LDAIM 16 + JSR SETRTN + JMP MAPMAN ;MAPMAN.FLUSYS to empty map caches + +30 CMPIM MPERRF ;Bad drive no? + BEQ #15 ;yes, ignore (inter-disc gap) + JSR USRERR + PLA + RTS + + LNK Uade06 diff --git a/FileServer/SRC/FileServer/Uade06 b/FileServer/SRC/FileServer/Uade06 new file mode 100644 index 0000000..73a536d --- /dev/null +++ b/FileServer/SRC/FileServer/Uade06 @@ -0,0 +1,644 @@ + OPT UADE06 ; > .Uade06 + TTL File server file UADE06 + + +;********************************** +;* U S R M A N * +;********************************** + +;USRMAN: USRMAN (THE USER TABLE MANAGER) +;KEEPS INFORMATION ABOUT LOGGED ON USERS. +;USRMAN MAINTAINS A DATA STRUCTURE +;KNOWN AS THE USERTB. THIS TABLE +;CONTAINS INFORMATION ABOUT WHICH +;USERS ARE LOGGED ON, THE +;NUMBER OF THE MACHINE, HANDLES +;FOR UFD & CURRENTLY SELECTED DIRECTORY, +;AND OTHER USER STATE INFORMATION. + +;THE USERTB CONTAINS THE FOLLOWING INFO:- +;0) MACHINE NUMBER +;1) USERID +;2) CURRENT SELECTED DISC NUMBER +;3) SYSTEM PRIVILEGE FLAG +;4) HANDLE FOR UFD (USER FILE DIR) +;5) HANDLE FOR SELECTED DIR +;6) HANDLE BYTE (A RECORD OF WHICH HANDLES ARE INUSE) + + +;************ MAIN ROUTINE ************ + + +USRMAN ROUT + LDXIM 10 ;USRMAN HAS 10 ENTRY POINTS + LDAIM MODUSR ;A:=NAME OF THIS MODULE + JSR ENTRY + [ $Level3 + LDAAX USRTNS + STA USJUMP+1 + LDAAX USRTNS+1 + STA USJUMP+2 + ] + LDAIM 15 + JSR SETFS + [ $Level3 +USJUMP JMP USJUMP + | + JMIX USRTNS + ] +USEXIT JMP PREXIT +USRTNS + & USNWMC ;1 => REGISTER A MACHINE(LOGON) + & USDLMC ;2 => DELETE MACHINE FROM USERTB(LOGOFF) + & USSDSC ;3 => SELECT DISC + & USREST ;4 => RESTART + & USSDIR ;5 => SELECT DIRECTORY + & USUSER ;6 => USER INFO (PRIV & MC/NO OF GIVEN USERID) + & USUSRS ;7 => LOGGED ON USERS + & USQUIT ;8 => update all users free space ** 3/10/84 ** + & USFREE ;9 => update single user allocation + & USDALL ;10=> delete all machines in USERTB ** 11/1/85 ** + + +;************ USNWMC ************ + +;USNWMC: USRMAN.NEW MACHINE (LOGON) +;ENTRY: ARGB,C,D = (MC/NO) +;ARGE,F = (PTR TO USERID FOLLOWED BY PASSWORD) + +;EXIT : ARGA = RC +;ARGB,C = (PTR TO USERINFO) +;ARGD = UFD HANDLE +;ARGE = CSD HADLE +;ARGF = LIB HANDLE +;ARGG = Option bits (bottom two) +;ARGH = Privilege ** 27/9/84 ** + +;FUNCTION: - + +;IF machine already in USERTB (I.E. LOGGED ON) +;THEN close all open files, +;close all open dirs; +;remove USERTB entry +;FI; + +;check validity of password;read option bits + +;FOR each drive WHILE NOT found +;DO IF $.USERID exists +;THEN get handles for ufd, library and selected dir; +;found := TRUE +;FI +;OD; + +;IF NOT found +;THEN use root dir for ufd, library & selected dir +;FI + +USNWMC ROUT + JSR CHKMC ;Logged on? + BEQ #05 ;Br if it is + +;FIND A FREE USERTB ENTRY + + LDA MCTEMP ;MCTEMP SET BY CHKMC + ORA MCTEMP+1 + ORA MCTEMP+2 ;**25/12/86** + BNE #10 + LDAIM URERRF ;RC:=M/C NUMBER = ZERO + [ $Level3 + BNE #25 + | + BRA #25 + ] +;CHECK PASSWORD + +05 JSR LOGOFF ;log previous session off +10 LDAIM 2 ;AUTMAN.CHECKPW + JSR SETRTN + LDYIM ARGF ;**25/12/86** + LDAIY ARGPTR + DEY + STAIY NEWARG ;MS(PTR TO USERID FOLLOWED BY PW) + LDAIY ARGPTR + DEY + STAIY NEWARG ;LS(PTR TO USERID) + JSR AUTMAN + BNE #25 + + JSR INITUS ;USTPTR:=USERTB,X:=USERS + LDYIM UTPRIV +15 LDAIY USTPTR ;HOLDS THE INUSE FLAG + BEQ #30 + JSR INCUST + BNE #15 + LDAIM URERRB ;RC:=USERTB FULL +25 JMP #70 + +;SETUP USERTB ENTRY + +30 LDYIM ARGF + LDAIY NEWARG ;Read PW Flag byte + STA USTEMP ;Store so can return option bits + ORAIM INUSE ;and mark in use. + LDYIM UTPRIV + STAIY USTPTR ;:= INUSE + privileges flags *** 25/5/86 *** + LDA MCTEMP ;(MCTEMP SET BY CHKMC) + LDYIM UTMCNO + STAIY USTPTR + LDA MCTEMP+1 + INY + STAIY USTPTR + LDA MCTEMP+2 + INY + STAIY USTPTR ;MACHINE NUMBER + + LDAIM ARGB ;copy disc space into table + STA OFF1 + LDAIM UTFREE + STA OFF2 + LDXIM NEWARG + LDYIM USTPTR + LDAIM UTFRLN + JSR MOVBLK ;** 2/10/84 ** + + LDYIM ARGE ;**25/12/86** + LDAIY ARGPTR + STA MOVFRM + INY + LDAIY ARGPTR + STA MOVFRM+1 + CLC + LDA USTPTR + ADCIM UTUSID + STA MOVTO + LDA USTPTR+1 + ADCIM 0 + STA MOVTO+1 + LDXIM UTDISC-UTUSID + JSR MOVE ;COPY USERID INTO USERTB + + LDAIM 0 + LDYIM UTHNDB + STAIY USTPTR + +;NOW TRY TO FIND A UFD FOR THIS USER +;SO TRY TO RETRIEVE $.USERID BY SEARCHING ALL THE DRIVES + + LDAIM &FF ;**14/06/86** + STA USWORK+1 ;**14/06/86** USWORK+1 := -1 + STA USWORK ;USWORK := -1 := DEVICE NO **25/12/86** + LDYIM ARGG ;**25/12/86** + LDAIY NEWARG ;**25/12/86** disc containing user pw file +40 JSR DRVINF ;MAPMAN.DRIVEINFO + BNE #55 ;**14/06/86** + BIT USWORK+1 ;**14/06/86** + BPL #42 ;**14/06/86** skip if disc already found + LDA USWORK ;**14/06/86** else set lowest disc found + STA USWORK+1 ;**14/06/86** + +42 JSR SUSRDI ;Set users disc no. + JSR GETUFD ;GET HANDLES FOR UFD + BEQ #70 + +;haven't matched full name here, so see about partial match **18/9/84** + + LDYIM MAXID+UTUSID+1 ;look for a "." +45 LDAIY USTPTR + CMPIM SEPART + BEQ #50 + DEY + CPYIM UTUSID + BNE #45 ;look right through the string + [ $Level3 + BEQ #55 + | + BRA #55 + ] + +50 LDAIM TERMIN ;abbreviate the name string + STAIY USTPTR + [ $Level3 + TYA + PHA + | + PHY ;save pointer across call + ] + + LDA USWORK + JSR DRVINF ;get drive info + JSR SUSRDI ;set up the info + JSR GETUFD + TAX ;save RC + + [ $Level3 + PLA + TAY + | + PLY + ] + LDAIM SEPART + STAIY USTPTR ;restore the string to its former glory + + TXA ;restore RC + BEQ #70 ;all ok here + +55 INC USWORK ;USWORK +:=1 + LDA USWORK ;**14/06/86** + CMP DRIVES ;**14/06/86** check all drives + BCC #40 ;**14/06/86** try next logical drive + + +;If a UFD does not exist on any disc then +;make UFD := selected dir := root dir on the +;lowest logical drive + + LDA USWORK+1 ; ** 14/06/86 ** + JSR DRVINF + JSR SUSRDI ;Set user disc no. + JSR GTROOT + BEQ #70 + JSR LOGOFF ;CLEAN UP if no dirs available + +70 LDYIM ARGB + PHA ;Store return code + LDA USTPTR + STAIY ARGPTR + INY + LDA USTPTR+1 + STAIY ARGPTR + INY + JSR MOVHND + LDA USTEMP ;Read PW flag byte + PHA + ANDIM OPTMSK ;Mask off option bits + LDYIM ARGG + STAIY ARGPTR + PLA + INY + ANDIM SYSTPV ;** 27/9/84 ** + STAIY ARGPTR ;return user's privilege + PLA ;Restore return code + JMP USEXIT + + +SUSRDI LDYIM ARGB + LDAIY NEWARG + LDYIM UTDISC + STAIY USTPTR + LDYIM ARGC + LDAIY NEWARG + LDYIM UTDISC+1 + STAIY USTPTR ;DISC NUMBER + RTS + + +;************ USDLMC ************ + + +;USDLMC: DELETE USERTB ENTRY FOR GIVEN MACHINE NUMBER + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) + +;EXIT: ARGA = RC + +;FUNCTION: FIND USERTB ENTRY AND MARK IT NOT IN USE. + + +USDLMC ROUT + JSR SETUTP + JSR LOGOFF + LDAIM 0 + JMP USEXIT + + + +;************ USSDSC ************ + + +;USSDSC: USRMAN.SELECT DISC + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) +;ARGD = LS(DISC NO) +;ARGE = MS(DISC NO) +;ARGF = CURRENT UFD HANDLE +;ARGG = CURRENT CSD HANDLE +;ARGH = CURRENT LIB HANDLE + +;EXIT : ARGA = RC +;ARGB = NEW UFD +;ARGC = NEW CSD +;ARGD = NEW LIB + +;FUNCTION:- +;IF specified disc loaded +;THEN close ufd, library & selected dir; +;IF $.USERID exists on selected dir; +;THEN get handles for ufd, library & selected dir +;ELSE ufd:=selected dir:=library:=root dir +;FI + + +USSDSC ROUT + JSR SETUTP ;SETUP USTPTR TO POINT INTO USERTB + +;FIRST, SEE WHETHER SPECIFIED DISC IS LOADED + + LDYIM ARGD + LDAIY ARGPTR + STA USDISC + INY + LDAIY ARGPTR + STA USDISC+1 ;USDISC:=SELECTED DISC NUMBER + + LDYIM ARGC + STAIY NEWARG + DEY ;Y:=ARGB + LDA USDISC + STAIY NEWARG + DEY ;Y:= ARGA + LDAIM 4 ;MAPMAN.SINOFROOT + STAIY NEWARG + JSR MAPMAN + BNE #10 + +;NOW CLOSE THREE HANDLES FOR +;OLD DISC + + LDYIM ARGF + LDAIY ARGPTR + JSR CLOSE + BNE #10 + LDYIM ARGG + LDAIY ARGPTR + JSR CLOSE + BNE #10 + LDYIM ARGH + LDAIY ARGPTR + JSR CLOSE + BNE #10 +;PUT SELECTED DISC NUMBER INTO THE USERTB + + LDYIM UTDISC + LDA USDISC + STAIY USTPTR + INY + LDA USDISC+1 + STAIY USTPTR + +;SEE IF A UFD EXISTS IN THE ROOT DIR FOR THIS USER + + JSR GETUFD + BEQ #10 + +;OTHERWISE MAKE THE ROOT DIR THE UFD, LIB & SELECTED DIR + + JSR GTROOT + +10 LDYIM ARGB + JSR MOVHND ;PUT HANDLES ON STACK + JMP USEXIT + + + +;************ USREST ************ + + +;USREST: RESTART +;1) CALL GETVEC TO GRAB AN AREA +;OF STORE FOR THE USERTB. +;2) SETUP THE VARAIBLE (USERTB) +;TO POINT TO THIS AREA. +;3) CALL CLRSTR TO INITIALISE THE +;WHOLE TABLE TO ZERO. + + +USREST ROUT + LDX USERS + LDYIM UTENSZ + JSR SETTAB + STY USERTB + STX USERTB+1 + LDAIM 0 + STA USSYS ;priv'd user logged-on flag + JMP USEXIT + + + +;************ USSDIR ************ + + +;USSDIR: USRMAN.SELECT DIRECTORY + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) +;ARGD = LS(PTR TO DIR TITLE) +;ARGE = MS(PTR TO DIR TITLE) +;ARGF = UFD HANDLE +;ARGG = CURRENT SEL. DIR. HND + +;EXIT : ARGA = RC +;ARGB = HANDLE FOR NEW CSD + +;FUNCTION:- + +;IF dir title = null string +;THEN make the current selected dir=ufd +;ELIF directory exists +;THEN open selected dir; +;close old selected dir +;ELSE return error +;FI + + +USSDIR ROUT + JSR SETUTP ;SETUP USTPTR + + LDYIM ARGF + LDAIY ARGPTR + STA UMHUFD + INY + LDAIY ARGPTR + STA UMHCSD +;FIRST, RETRIEVE THE DIRECTORY + + LDYIM ARGD + LDAIY ARGPTR + STA TITPTR + STA GENPTR + INY + LDAIY ARGPTR + STA TITPTR+1 ;TITPTR := ADDR OF DIR NAME + STA GENPTR+1 ;GENPTR := PTR TO DIR TITLE + + [ $Level3 + LDYIM 0 + LDAIY GENPTR + | + LDAI GENPTR + ] + CMPIM TERMIN + BNE #10 + +;NOW CALL RNDMAN TO CREATE A COPY OF THE HANDLE +;FOR THE UFD. + + LDA UMHCSD + JSR CLOSE ;CLOSE OLD SELECTED DIR. + BNE #30 + + LDAIM 5 ;RNDMAN.COPY + JSR SETUSA ;**25/12/86** + INY + LDA UMHUFD ;SET USER ROOT TO COPY + STAIY NEWARG ;ARGD = HANDLE OF UFD + JSR RNDMAN ;RNDMAN.COPY + BNE #30 + + LDYIM ARGE + LDAIY NEWARG ;HANDLE FROM RNDMAN + [ $Level3 + JMP #20 + | + BRA #20 + ] + +10 LDAIM &C1 ;accept all wild cards + JSR RETRV ;CALL DIRMAN.RETRV & CHECK THAT ITS A DIR + BNE #30 + +;NOW GET A HANDLE FOR IT + + JSR OPEN ;USRHND:=HANDLE FOR NEW SELECTED DIR + BNE #30 + PHA + +;NOW CLOSE THE OLD SELECTED DIR + + LDA UMHCSD + JSR CLOSE + BNE #40 ;If this close fails, close new one too + PLA + +20 LDYIM ARGB + STAIY ARGPTR ;Set new handle + LDAIM 0 + +30 JMP USEXIT + +40 STA TEMPA ;Store rcode + PLA ;Pull new csd + JSR CLOSE ;Close it + LDA TEMPA ;Restore rcode + [ $Level3 + BNE #30 + | + BRA #30 ;End + ] + + + +;************ USUSER ************ + + +;USUSER: USER INFO + +;ENTRY: ARGB=LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) +;ARGD = LS(PTR TO USERID) +;ARGE = MS(PTR TO USERID) + +;EXIT : ARGA = RC +; ARGB = USER PRIVILEDGE +; ARGC-E machine number **25/12/86** +; ARGF,G pointer to userid information ** 5/10/84 ** + + +USUSER ROUT + JSR INITUS + LDYIM ARGD + LDAIY ARGPTR + STA URMPPT ;Pointer to User Id to check + INY + LDAIY ARGPTR + STA URMPPT+1 + +10 LDYIM UTPRIV ;Check if entry in use + LDAIY USTPTR + BPL #50 ;Nope -> continue + +;NOW SEE IF USERIDS MATCH + + LDAIM UTUSID + STA OFF2 ;Offset in user-table + LDYIM 0 ;Offset of argument name + +20 LDAIY URMPPT + STY OFF1 + CPYIM 21 ;Max user length + BNE #30 ;Not at end yet -> go on + + CMPIM TERMIN ;At end, check user name given is terminated + BEQ #40 ;Yes -> found + [ $Level3 + BNE #50 + | + BRA #50 ;No -> continue search + ] + +30 LDY OFF2 + EORIY USTPTR + INC OFF2 ;Increment USTPTR offset for next time + ANDIM &DF ;Complete comparison + BNE #50 ;Not the same -> go on to next one + + LDY OFF1 ;Point to char. offset from USTPTR + LDAIY URMPPT ;The same => check if end of string + INY ;Increment for next time + + CMPIM TERMIN + BNE #20 ;Not terminators => continue search + +;FOUND IT - SO COPY PRIV & MC/NO INTO STACK + +40 LDYIM UTPRIV + LDAIY USTPTR + ANDIM SYSTPV+LOPRIV ;**25/5/86** + LDYIM ARGB + STAIY ARGPTR ;Privileges flags + + LDYIM UTMCNO + LDAIY USTPTR + LDYIM ARGC + STAIY ARGPTR + LDYIM UTMCNO+1 + LDAIY USTPTR + LDYIM ARGD + STAIY ARGPTR + LDYIM UTMCNO+2 + LDAIY USTPTR + LDYIM ARGE + STAIY ARGPTR ;MC/NO + INY + LDA USTPTR + STAIY ARGPTR + INY + LDA USTPTR+1 + STAIY ARGPTR ;**5/10/84** + + LDAIM 0 + [ $Level3 + BEQ #60 + | + BRA #60 + ] + +50 JSR INCUST + BNE #10 + LDAIM URERRE +60 JMP USEXIT + + + LNK Uade06A diff --git a/FileServer/SRC/FileServer/Uade06A b/FileServer/SRC/FileServer/Uade06A new file mode 100644 index 0000000..cd677f1 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade06A @@ -0,0 +1,654 @@ + OPT UADE06 ; > .Uade06A + TTL File server file UADE06A + + +;**************** USUSRS ************ + +;ENTRY: ARGB = Start entry +;ARGC = No. of entries +;ARGD-E Result buffer +;ARGF = Caller privilege flag +;ARGG = M/C mode flag. Zero for job/task nos, +- if not + +;EXIT : +;ARGB = No. of entries found +;ARGC-D Result end ptr. + +;V. similar to examine and discs. Given entry point +;to list of users and number of entries required, +;supplies info. on as many as possible, returning +;the number found and a pointer to the byte after +;the info. for use in transmitting the data +;out to client. + + +USUSRS ROUT + JSR INITUS ;Set USTPTR and X + LDYIM ARGB + LDAIY ARGPTR + STA TEMPA ;Start entry + INY + LDAIY ARGPTR + STA TEMPA+1 ;No. of entries wanted + INY + LDAIY ARGPTR + STA GENPTR ;Result ptr. + INY + LDAIY ARGPTR + STA GENPTR+1 + + LDAIM &FF + STA TEMPB ;Entry pt. counter + [ $Level3 + LDAIM 0 + STA TEMPB+1 ;No. of entries found + | + STZ TEMPB+1 ;No. of entries found + ] + +10 LDYIM UTPRIV + +;First loop round finding entries in use until +;ENTRY = TEMPA = START ENTRY + + LDAIY USTPTR + BPL #30 ;Not in use, don't count + +;** skip privileged users (27/9/84) +;** unless caller is privileged (16/1/85) + + ANDIM SYSTPV ;privileged, + BEQ #20 + LDYIM ARGF ;unless caller privileged then + LDAIY ARGPTR ;these "dont exist" + BEQ #30 + +20 INC TEMPB ;Inc. current entry + LDA TEMPB + CMP TEMPA ;Current >= start entry ? + BCS #40 ;Yes => start copying to result + +30 JSR INCUST ;Jump to next entry + BNE #10 ;If not off end of table, do again + [ $Level3 + BEQ #70 + +40 TXA + PHA + | + BRA #70 ;Otherwise, finish + +40 + PHX + ] + LDXIM 0 + LDYIM UTMCNO + LDAIY USTPTR + STAIX GENPTR + INY + JSR INCGPT + LDAIY USTPTR + STAIX GENPTR ;Set m/c number + INY ;**20/5/87** + JSR INCGPT + LDAIY USTPTR + LSRA ;**20/5/87** position job/task number + LSRA + LSRA + STAIX GENPTR ;**20/5/87** Set job/task number + LDYIM ARGG + LDAIY ARGPTR + BNE #45 ;**20/5/87** Skip increment if not wanted + JSR INCGPT +45 LDYIM UTUSID ;User id. offset +50 LDAIY USTPTR + STAIX GENPTR + JSR INCGPT + CMPIM CR ;Is terminated ?? + BEQ #60 + + INY + CPYIM UTUSID+MAXUNM ;Finished ? + BNE #50 ;**23/4/85** + LDAIM CR ;**16/1/85** + STAIX GENPTR + JSR INCGPT + +60 LDYIM UTPRIV ;Get privilege byte + LDAIY USTPTR + ANDIM SYSTPV ; +LOPRIV ;**25/5/86 + 31/10/86** + STAIX GENPTR + JSR INCGPT ;Point to next entry + [ $Level3 + PLA + TAX + | + PLX ;Restore table entry count + ] + + INC TEMPB+1 ;Inc. no. found + LDA TEMPA+1 + CMP TEMPB+1 ;No. found = no. requested ? + BEQ #70 ;Yes => stop + + JSR INCUST ;Step through table + BNE #10 ;Do again + +70 LDYIM ARGB + LDA TEMPB+1 + STAIY ARGPTR + INY + LDA GENPTR + STAIY ARGPTR + INY + LDA GENPTR+1 + STAIY ARGPTR + LDAIM 0 + JMP USEXIT + + +;******************* + +USQUIT ROUT + JSR INITUS ;setup USTPTR +10 LDYIM UTPRIV ;scan for inuse entries + LDAIY USTPTR + BEQ #20 + [ $Level3 + TXA + PHA + | + PHX ;preserve X over LOGOFF call + ] + JSR USENS ;ensure all free space entries up to date + [ $Level3 + PLA + TAX + | + PLX + ] +20 JSR INCUST + BNE #10 + JMP USEXIT ;end of routine + + +USFREE ROUT ;** 6/2/85 ** + + LDA USTPTR + PHA + LDA USTPTR+1 + PHA ;save this value over call + + JSR INITUS ;update all incarnations of a user free space + STX USTEMP ;save counter + +10 LDYIM ARGB + LDAIY ARGPTR + STA GENPTR + INY + LDAIY ARGPTR + STA GENPTR+1 ;pointer to supplied name + + LDYIM UTPRIV + LDAIY USTPTR + BPL #50 ;not in use so skip + + LDXIM 0 + LDYIM UTUSID +20 LDAIY USTPTR + EORIX GENPTR + ANDIM &DF + BNE #50 + LDAIY USTPTR + CMPIM TERMIN + BEQ #40 ;end of name + + INC GENPTR + BNE #30 + INC GENPTR+1 + +30 INY + CPYIM MAXID+UTUSID+1 + BNE #20 ;continue + +40 LDAIM ARGD ;update the free space + STA OFF1 + LDXIM ARGPTR + LDAIM UTFREE + STA OFF2 + LDYIM USTPTR + LDAIM 4 ;arguments supplied on stack + JSR MOVBLK + +50 JSR INCUST + DEC USTEMP + BNE #10 ;not end of table + + PLA + STA USTPTR+1 + PLA + STA USTPTR + + LDAIM 0 + JMP USEXIT + +;**************** USDALL **************** + +;ENTRY: none + +;EXIT: none + +;USES: USTPTR + +;All logged on users are logged off. + +USDALL ROUT + JSR INITUS ;Set up to scan all users + LDAIM 0 ;Assume return code + PHA +10 LDYIM UTPRIV + LDAIY USTPTR ;See if slot in use + BPL #20 + PLA ;Current worst return code + [ $Level3 + TAY + TXA + PHA ;Save index + TYA + JSR LOGOFF ;Logoff this machine + TAY + PLA + TAX ;Reload index + TYA + | + PHX ;Save index + JSR LOGOFF ;Logoff this machine + PLX ;Reload index + ] + PHA ;Save new worst return code +20 JSR INCUST ;Attempt to logoff all users + BNE #10 + PLA ;Return code + JMP USEXIT + + + +SETUTP LDYIM ARGB ;SETUP USTPTR + LDAIY ARGPTR + STA USTPTR + INY + LDAIY ARGPTR + STA USTPTR+1 + RTS + + +CHKMC LDYIM ARGB ;SEE IF MACHINE LOGGED ON + LDAIY ARGPTR + STA MCNUMB ;N.B. USE MCTEMP BECAUSE MCNUMB IS USED GLOBALLY + STA MCTEMP ;=LS(MC/NO) + INY + LDAIY ARGPTR + STA MCNUMB+1 + STA MCTEMP+1 ;=CS(MC/NO) + INY + LDAIY ARGPTR ;**25/2/86** + STA MCNUMB+2 + STA MCTEMP+2 ;=MS(MC/NO) + JMP FINDMC + + +RETRV ROUT + LDYIM ARGH ;A passed in call + STAIY NEWARG ;wild card flag + + LDAIM 2 ;DIRMAN.RETRIEVE + JSR SETUSA ;MOVE USTPTR ONTO NEWARG STACK + INY + LDA TITPTR + STAIY NEWARG ;ARGD + INY + LDA TITPTR+1 + STAIY NEWARG ;PTR TO DIR NAME + INY + LDAIM :LSB:USRINF + STAIY NEWARG + INY + LDAIM :MSB:USRINF ;ADDRESS OF DETAILS AREA + STAIY NEWARG + JSR DIRMAN + BNE #20 + LDYIM ARGB + LDAIY NEWARG + STA USRACC ;USRACC:=ACCESS TO OBJECT + ANDIM TYPDIR + BNE #10 + LDAIM URERRD ;RC:=OBJECT NOT A DIR + RTS + +10 LDAIM 0 ;RC := 0 +20 RTS + + +SETUID ROUT + LDYIM UTUSID ;Copy userid from USERTB to USRUFD +10 LDAIY USTPTR ;Copies all chars regardless of termination + STAAY USRUFD-UTUSID + INY + CPYIM UTUSID+MAXUNM + BNE #10 + RTS + + +MAKHDS ROUT + JSR OPEN ;MAKE HANDLES FOR UFD & SELECTED DIR + BNE #20 + + STA UMHUFD ;make this the handle for the UFD + [ Pseudods = Yes + LDYIM UTHUFD ;**26/6/87** and store in user table + STAIY USTPTR + ] + + JSR OPEN ;now get a handle for selected dir + BEQ #10 + PHA + JSR CLUFDR ;CLOSE UFD + PLA + RTS + +10 STA UMHCSD + LDAIM 0 +20 RTS + + + +OPEN ROUT + LDAIM 1 ;CALL RNDMAN.OPEN FOR DIR IN USRINF + JSR SETUSA ;COPY USTPTR ONTO NEWARG STACK + INY + LDAIM 0 ;MODE := 0 + STAIY NEWARG + INY ;Y:=E + LDA USRACC + STAIY NEWARG + INY ;Y:=ARGF + LDAIM :LSB:USRINF + STAIY NEWARG + INY + LDAIM :MSB:USRINF + STAIY NEWARG ;PTR TO OBJECT DETAILS + JSR RNDMAN + BNE #10 + LDYIM ARGB + LDAIY NEWARG + LDYIM 0 +10 RTS + +; SETUSA: Move Arg, USTPTR onto NEWARG stack +; SETUSR: Move just USTPTR onto NEWARG stack +; Exit: Y=ARGC + +SETUSA ROUT ;Move Arg in A onto NEWARG stack **25/12/86** + JSR SETRTN +SETUSR LDYIM ARGB ;MOVE USTPTR ONTO NEWARG STACK + LDA USTPTR + STAIY NEWARG + INY + LDA USTPTR+1 + STAIY NEWARG + RTS + + +;LOGOFF: CLOSE ALL HANDLES OPENED BY M/C & FREE USERTB ENTRY +;Return code as entered, or replaced by any LOGOFF error code + +LOGOFF ROUT + PHA + LDAIM 6 + JSR SETUSA + JSR RNDMAN ;*** CLOSE ALL ENTRIES ** + BEQ #10 + [ $Level3 + TAY + PLA ;**1/6/88** stack bad return code + TYA + | + PLY ;**1/6/88** stack bad return code + ] + PHA + +;NOW CLEAR USERTB ENTRY TO ZERO + +10 JSR USENS ;update all free space entries + BEQ #20 + [ $Level3 + TAY + PLA ;**1/6/88** stack bad return code + TYA + | + PLY ;**1/6/88** stack bad return code + ] + PHA +20 LDYIM UTPRIV ;check for priv'd user + LDAIY USTPTR ;** 27/9/84 ** + ANDIM SYSTPV + BEQ #30 ;not priv'd + DEC USSYS ;decrement counter +30 LDAIM 0 + LDYIM UTENSZ-1 ;**1/6/88** +40 STAIY USTPTR + DEY + BPL #40 + PLA + RTS + + +USENS CLC ;** 2/10/84 ** + LDYIM ARGD + LDA USTPTR + ADCIM :LSB:UTUSID + STAIY NEWARG ;nb ARGB,C unused here + + INY + LDA USTPTR+1 + ADCIM :MSB:UTUSID + STAIY NEWARG + + LDAIM UTFREE + STA OFF1 + LDAIM ARGF + STA OFF2 + LDXIM USTPTR + LDYIM NEWARG + LDAIM UTFRLN + JSR MOVBLK + + LDAIM 8 ;ensure free store in PW file + JSR SETRTN + JMP AUTMAN + + +CLOSE PHA + LDAIM 3 ;RNDMAN.CLOSE + JSR SETUSA ;PLACE PTR TO USERINFO ON NEWARG STACK + INY + PLA + STAIY NEWARG ;**25/12/86** + JMP RNDMAN + + +CLUFDR ROUT + LDA UMHUFD ;CLOSE UFD + BEQ #10 + JSR CLOSE + [ $Level3 + PHA + LDAIM 0 + STA UMHUFD + PLA + | + STZ UMHUFD + ] +10 RTS + + +CLSLDR LDA UMHCSD + BEQ #10 + JSR CLOSE + [ $Level3 + PHA + LDAIM 0 + STA UMHCSD + PLA + | + STZ UMHCSD + ] +10 RTS + + +;GETUFD: SEE IF THERE IS A UFD IN THE ROOT DIR ON +;CURRENTLY SELECTED DISC. +;IF THERE IS A UFD THEN MAKE HANDLES FOR +;THE UFD & THE CURRENTLY SELCECTED DIRECTORY. +;ALSO SEARCH FOR LIB. IF FOUND, GET HANDLE +;FOR IT, IF NOT LIB:=CSD/UFD + +;EXIT: A := RC + + +GETUFD ROUT + JSR SETUID ;COPY USERID INTO USRUFD + LDAIM TERMIN + STA USRTER + LDAIM SEPART + JSR #20 ;**7/7/88** complete name & retrieve + BNE #10 + LDAIM OWNER + [ $Level3 + ORA USRACC + STA USRACC ;OWNER ACCESS TO UFD + BNE #00 ;Common code + | + TSB USRACC ;OWNER ACCESS TO UFD + BRA #00 ;Common code + ] + +GTROOT JSR RTROOT + BNE #10 +00 JSR MAKHDS ;MAKE HANDLES + BNE #10 + JSR GETLBH ;LOOK FOR LIB FILE +10 RTS + +RTROOT LDAIM TERMIN +20 STA USRSEP + LDAIM ROOT + STA USRROT + LDAIM :LSB:USRROT + STA TITPTR + LDAIM :MSB:USRROT + STA TITPTR+1 + LDAIM 0 ;no wild cards here + JMP RETRV ;RETRIEVE ROOT DIR + + + +;TRY TO RETRIEVE FILE "LIBRARY". +;IF FOUND, OPEN AND PUT HANDLE +;IN LIB. LOCATION. IF NOT, OPEN +;ROOT, WHICH WILL BE LIBRARY + +;** 15/9/83 ** + +GETLBH ROUT + LDYIM UTDISC + LDAIY USTPTR + STA USDISC ;**7/7/88** + INY + LDAIY USTPTR + STA USDISC+1 ;save users disc number + + [ $Level3 + LDAIM 0 + STA UMHLIB ;spare counter + | + STZ UMHLIB ;spare counter + ] +10 LDA UMHLIB + JSR DRVINF ;drive exists ? + BNE #20 ;no + JSR SUSRDI + + LDAIM :LSB:DEFLIB ;PTR. TO LIB. TITLE + STA TITPTR + LDAIM :MSB:DEFLIB + STA TITPTR+1 + + LDAIM 0 ;no wild cards here + JSR RETRV + + BEQ #30 ;OK, FOUND SO OPEN + CMPIM DRERRC + BNE #50 ;IF ERROR NOT "NOT FOUND", ABORT + +20 INC UMHLIB + LDA UMHLIB ;**14/06/86** + CMP DRIVES ;**14/06/86** + BCC #10 ;loop until all drives tried + +;Now retrieve root. Then open and return +;handle for lib. + + JSR #40 ;**7/7/88** must reset drive first + JSR RTROOT ; retrieve + BNE #50 + +30 JSR OPEN + BNE #50 ;ABORT IF ERROR + STA UMHLIB ;STORE HANDLE + LDAIM 0 ;GIVE Z SET + +40 TAX + LDYIM UTDISC+1 ;restore the old values + [ $Level3 ; *********** B U G ****************** + STA USDISC+1 + | + LDA USDISC+1 + ] + STAIY USTPTR + DEY + [ $Level3 ; *********** B U G ****************** + STA USDISC + | + LDA USDISC + ] + STAIY USTPTR + TXA ;restore return code + RTS + +50 PHA + JSR CLUFDR + JSR CLSLDR + PLA + [ $Level3 + BNE #40 + | + BRA #40 + ] + +DEFLIB = "$.library",CR + +MOVHND ROUT + PHA + INY + INY + LDXIM 2 +10 LDAAX UMHUFD + STAIY ARGPTR + DEY + DEX + BPL #10 + PLA + RTS + + LNK Rman01 diff --git a/FileServer/SRC/FileServer/Uade0A b/FileServer/SRC/FileServer/Uade0A new file mode 100644 index 0000000..916f2e4 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade0A @@ -0,0 +1,596 @@ + OPT UADE0A ; > .Uade0A + TTL File server file UADE0A + +;********************************** +;* S T R M A N * +;********************************** + + +;STRMAN: THE STORE MANAGER IS RESPONSIBLE +;FOR MAINTAINING A CACHE OF +;VARIABLE LENGTH (BUT AN INTEGRAL NUMBER +;OF DISC BLOCKS) OBJECT WINDOWS. + +;THE CONTENTS OF THE CACHE IS DESCRIBED BY +;A ONE WAY CHAIN OF DESCRIPTORS. +;THESE DESCRIPTORS ARE KEPT IN AN ORDER WHICH +;DESCRIBES THE POSITION OF THE WINDOWS IN MEMORY. +;NOTE THAT EACH OBJECT IN THE CACHE +;IS PRECEEDED BY A ONE BYTE DIRTY MARKER. + + +;********* MAIN ROUTINE ********* + +STRMAN ROUT + LDXIM 9 ;STRMAN HAS 9 ENTRY POINTS + LDAIM MODSTR ;A:=NAME OF THIS MODULE + JSR ENTRY + [ $Level3 + LDAAX STRTNS + STA STJUMP+1 + LDAAX STRTNS+1 + STA STJUMP+2 + LDAIM &F + JSR SETFS ;SET FRAME SIZE +STJUMP JMP STJUMP + | + LDAIM &F + JSR SETFS ;SET FRAME SIZE + JMIX STRTNS + ] +STRTNS + & STDTSA ;1 => DISC ADDRESS TO STORE ADDRESS + & STENWD ;2 => ENSURE WINDOW + & STULWD ;3 => UNLOCK CACHED WINDOW + & STFLWD ;4 => FLUSH WINDOW + & STRALL ;5 => REMOVE ALL BLOCKS OF AN OBJECT FROM CACHE + & STREST ;6 => RESTART + & STGBB ;7 => GET BIG BUFFER + & STEMPT ;8 => EMPTY THE CACHE OF ALL OBJECTS FROM A DISC + & STRDRT ;9 => REMOVE ALL DIRTY BLOCKS OF AN OBJECT +STEXIT JMP PREXIT + + +;************ STDTSA ************ + + +;STDTSA: DISC ADDRESS TO STORE ADDRESS + +;ENTRY: ARGB = LS(DISC NUMBER) +;ARGC = MS(DISC NUMBER) +;ARGD = LS(SIN) +;ARGE = CS(SIN) +;ARGF = MS(SIN) +;ARGG = LS(LOGICAL BLOCK NUMBER) +;ARGH = MS(LOGICAL BLOCK NUMBER) +;ARGI = LS(NO OF BLOCKS) +;ARGJ = MS(NO OF BLOCKS) + +;EXIT: ARGA = RC +;ARGB = LS(STORE ADDRESS) +;ARGC = MS(STORE ADDRESS) +;ARGD = LS(STORE ADDR OF CACHE DESCR) +;ARGE = MS(STORE ADDR OF CACHE DESCR) + + +;FUNCTION: THE CACHE IS SEARCHED TO SEE IF +;THE SPECIFIED WINDOW IS IN MEMORY. +;IF IT IS NOT IN THE CACHE THEN IT +;HAS TO BE READ FROM DISC. +;WHEN THE WINDOW IS IN THE CACHE +;THE ENTRY'S REFERNCE COUNT IS INCREMENTED +;AND ITS AGE SET TO MRU. +;NOTE IF THE WINDOW IS NOT FOUND +;IN THE CACHE IT IS NECESSARY TO +;FIND A STORE BUFFER INTO WHICH +;IT MAY BE READ FROM DISC-THIS CAN +;INVOLVE ONE, OR MORE, OLD WINDOWS +;BEING WRITTEN OUT TO CREATE SPACE. + +;IF WINDOW IN CACHE +;THEN AGE OF BLOCK := MRU; +;REFERENCE COUNT OF WINDOW +:= 1 +;ELSE GET A FREE STORE BUFFER; #THIS IS A LITTLE INVOLVED# +;READ OBJECT FROM DISC; +;AGE OF OBJECT := MRU; +;REFERENCE COUNT OF WINDOW := 1 +;FI + + + +STDTSA ROUT + JSR TSTSIN + BNE #20 + JSR INSRCH ;INIT PREV,CRNT,CMPPTR +10 LDXIM 9 + JSR COMP ;COMPARE DISC NO,SIN,BLK NO,NO OF BLOCKS + BNE #30 + +;ITS IN THE CACHE + + JSR INCCNT ;REF COUNT +:= 1 + LDYIM CEAGE + LDAIM MRU ;MARK IT MRU + STAIY CRNT + JSR RETSTA ;RETURN STORE ADDR & ADDR OF CRNT DESCR + LDAIM 0 +20 + [ $CMOS + BRA #60 + | + JMP #60 + ] + +30 JSR NXTCRN ;CRNT:=NEXT OF CRNT + BNE #10 + +;ITS NOT IN THE CACHE SO GET SOME FREE SPACE +;AND HAVE THE OBJECT READIN. + + LDYIM ARGI + LDAIY ARGPTR + STA BREGA + INY + LDAIY ARGPTR + STA BREGA+1 + [ $CMOS + STZ BREGA+2 + | + LDAIM 0 + STA BREGA + 2 + ] + JSR MULTBS ;BREGA *:=BLKSZE + LDA BREGA+2 + BEQ #40 + LDAIM STERRE ;SIZE TO BIG + [ $CMOS + BRA #60 + | + BNE #60 + ] + +40 LDA BREGA + STA AMTNED + LDA BREGA+1 + STA AMTNED+1 ;AMTNED := BREGA + JSR FREEST ;GET AMTNED WORTH OF FREE STORE + BNE #60 + +;AT THIS POINT CRNT PTS TO A CACHE ENTRY +;DESCRIPTOR. NOW COPY DISC NO, SIN, +;BLKNO, NO OF BLOCKS INTO CRNT. + + CLC + LDA ARGPTR + ADCIM ARGB + STA MOVFRM + LDA ARGPTR+1 + ADCIM 0 + STA MOVFRM+1 ;MOVFRM := ARGPTR + ARGB + LDA CRNT + STA MOVTO + LDA CRNT+1 + STA MOVTO+1 + LDXIM 9 + JSR MOVE + +;READ OBJECT FROM DISC & INITIALISE REF COUNT & AGE + + JSR RETSTA ;PUT STORE ADDR ON ARGPTR STACK + JSR READ ;READ OBJECT FROM DISC + BEQ #50 + PHA ;Store return code + LDYIM CERCNT + LDAIM 0 + STAIY CRNT ;Make sure ref. count = 0 + PLA ;return code stored over REMVIT + JSR REMVIT + [ $CMOS + BRA #60 + | + BNE #60 + ] + +50 LDYIM CERCNT + LDAIM 1 + STAIY CRNT ;REF COUNT := 1 + LDYIM CEAGE + LDAIM MRU + STAIY CRNT ;AGE := MRU + LDAIM 0 ;RC := 0 +60 JMP STEXIT + + + +;************ STENWD ************ + + +;STENWD: ENSURE WINDOW. THIS ENSURES THAT A GIVEN +;WINDOW IS UPTO DATE ON DISC. + +;ENTRY: ARGB = LS(WINDOW STORE ADDRESS) +;ARGC = MS(WINDOW STORE ADDRESS) +;ARGD = 0 => DON'T DECREMENT REF COUNT +;<> 0 => DECREMENT REF COUNT + +;EXIT : ARGA = RC + +;FUNCTION: 1) SEARCH CACHTB FOR ENTRY +;2) IF DIRTY WRITE TO DISC & MARK IT CLEAN +;3) DECREMENT ITS REFERENCE COUNT IF NEED BE + + + +STENWD ROUT + JSR FNDSTA + BEQ #10 + JSR INTERR +10 JSR ENSURE ;ENSURE WINDOW UPTO DATE ON DISC + PHA + LDYIM ARGD + LDAIY ARGPTR ;IS USE COUNT TO BE DECREMENTED + BEQ #20 + JSR DECCNT +20 PLA + BEQ #30 ;skip if all ok + JSR REMVIT ;else remove the object from the cache +30 JMP STEXIT ;RC preserved + + + + +;************ STULWD ************ + + +;STULWD: UNLOCK BUFFER. THIS FUNCTION DECREMENTS +;A STORE BUFFER'S REFERENCE COUNT. + +;ENTRY: ARGB = LS(BUFFER STORE ADDRESS) +;ARGC = MS(BUFFER STORE ADDRESS) + +;EXIT : ARGA = RC + +;FUNCTION: 1) SEARCH THE CACHE FOR SPECIFIED BUFFER. +;2) DECREMENT THE BUFFER'S REFERENCE COUNT. + +;NOTE THIS OPERATION WILL NOT WRITE THE BLOCK +;TO DISC EVEN IF IT IS MARKED DIRTY. + + +STULWD ROUT + JSR FNDSTA + BEQ #10 + JSR INTERR +10 JSR DECCNT + LDAIM 0 + JMP STEXIT + + + +;************ STFLWD ************ + + +;STFLWD:FLUSH WINDOW. THIS FUNCTION INFORMS +;STRMAN THAT A STORE BUFFER WILL PROBABLY NOT +;BE NEEDED IN THE NEAR FUTURE. + +;ENTRY: ARGB = LS(BUFFER STORE ADDRESS) +;ARGC = MS(BUFFER STORE ADDRESS) + +;EXIT : ARGA = RC + +;FUNCTION: 1) SEARCH CACHTB FOR THE BUFFER +;AND THEN DECREMENT ITS REFERENCE COUNT +;2) IF BUFFER MARKED 'DIRTY' +;THEN WRITE IT TO DISC +;3) AGE OF BUFFER := LRU (I.E. VERY OLD) +;4) IF REFCOUNT=0 THEN REMOVE OBJ FROM CACHE + + +STFLWD ROUT + JSR FNDSTA + BEQ #10 + JSR INTERR +10 JSR ENSURE + PHA + JSR DECCNT + LDYIM CEAGE + LDAIM LRU + STAIY CRNT + JSR TSTCNT + BNE #20 + JSR REMVIT +20 PLA ;RC from ENSURE + JMP STEXIT + + + +;************ STRALL ************ + + +;STRALL: REMOVES ALL THE BLOCKS, BELONGING TO +;A SPECIFIED FILE, FROM THE CACHE. +;NOTE IT IS ASSUMED THAT STEPS ARE TAKEN, +;BEFORE STRALL IS CALLED, TO +;AVOID BLOCKS OF THE FILE BEING LOADED. + + +;ENTRY: ARGB = LS(DISC NUMBER) +;ARGC = MS(DISC NUMBER) +;ARGD = LS(SIN) +;ARGE = CS(SIN) +;ARGF = MS(SIN) + +;EXIT : ARGA = RC + +;FUNCTION: 1) SCAN THE CACHTB REMOVING ALL THE +;WINDOWS BELONGING TO THIS FILE. +;2) THE WINDOWS MARKED DIRTY ARE WRITTEN TO DISC. +;3) THE WINDOWS ARE THEN REMOVED FROM +;THE CACHE. + + +STRALL ROUT + JSR TSTSIN + BNE #10 + + LDXIM 5 ;COMPARE DISC NUMBER & SIN + JSR EXPELL ;REMOVE ALL OBJECTS WITH GIVEN DISC NO & SIN + +10 JMP STEXIT + + +;************ STREST ************ + + +;STREST: RESTART +;1)GETVEC SPACE FOR +;a)THE BIG BUFFER +;b)FIRST CACHE ENTRY DESCRIPTOR & MAKE +;CACHTB PT TO IT. +;c)NUMBCE+1 CACHE ENTRY DESCRIPTORS & PUT +;THEM ON THE FREE CHAIN (FRECHN). +;d)THE CACHE ITSELF (CACHSZ BYTES) + + + + +STREST ROUT + LDYIM :LSB:LGBFSZ ;Y:=LS(SIZE OF BIG BUFFER) + LDXIM :MSB:LGBFSZ ;X:=MS(SIZE OF BIG BUFFER) + JSR GETVEC ;Get big buffer + STY BIGBUF + STX BIGBUF+1 ;BIGBUF:=ADDR OF BIG BUFFER + +;CREATE THE FIRST CACHE DESCRIPTOR (CACHTB) + + JSR CRDESC + LDA CRNT + STA CACHTB + LDA CRNT+1 + STA CACHTB+1 ;CACHTB := ADDR OF DESC. FOR 1ST ENTRY + +;NOW CALCULATE NO. OF CACHE DESCRIPTORS +;AND CACHE SIZE. + +;CACHSZ := ENDPTR-FREPTR +;CACHSZ -:= (DESC. SIZE) * 2 +;NO. OF OBJECTS := CACHSZ / (OBJECT SIZE+DESC. SIZE) +;CACHSZ -:= DESC.SIZE*NO. OF OBJECTS + + + LDAIM CESIZE + ROLA + STA TEMPA ;TEMPA := DESC. SIZE * 2 + SEC + LDA ENDPTR + SBC FREPTR + SBC TEMPA + STA DIVPAR + STA CACHSZ + LDA ENDPTR+1 + SBC FREPTR+1 + STA DIVPAR+1 + STA CACHSZ+1 + + LDXIM 0 +10 SEC + LDA DIVPAR + SBCIM CESIZE ;(Object size + desc. size) lo + STA DIVPAR + LDA DIVPAR+1 + SBCIM 1 ;(Object size + desc. size) hi + STA DIVPAR+1 + BCC #20 + INX + ORA DIVPAR + BEQ #20 + BCS #10 +20 STX NUMBCE ;No. of cache objects : +30 SEC ;NOW SUBTRACT C.D. SIZE, NUMBCE TIMES + LDA CACHSZ + SBCIM CESIZE + STA CACHSZ + BCS #35 + DEC CACHSZ+1 +35 DEX + BNE #30 + + [ $Level3 + JSR VSTRIN + = CR,"Cache size - " + NOP + + LDA CACHSZ+1 + JSR WHEX + LDA CACHSZ + JSR WHEX + + JSR VSTRIN + = " objects - " + NOP + + LDA NUMBCE + JSR WHEX + JSR OSCRLF + ] + +;NOW CREATE (NUMBCE+1) DESCRIPTORS & PLACE THEM ON +;THE FREE CHAIN. + + [ $CMOS + STZ FRECHN + STZ FRECHN+1 ;FRECHN := 0 + | + LDAIM 0 + STA FRECHN + STA FRECHN+1 ;FRECHN := 0 + ] + LDX NUMBCE + INX ;X:=NUMBCE+1 +40 JSR CRDESC ;CREATE A DESCRIPTOR + JSR MKFREE ;PLACE IT ON THE FREE CHAIN + DEX + BNE #40 + +;NOTE THAT THE FOLLOWING CODE IS ONLY TEMPORARY +;EVENTUALLY WE WANT TO USE THE REMAINDER OF FREE STORE +;FOR THE CACHE (N.B. CREATEING SUFFICIENT DESCRIPTORS). + +;NOW CREATE THE CACHE AREA ITSELF + + LDY CACHSZ ;Y:=LS(SIZE OF CACHE AREA) + LDX CACHSZ+1 ;X:=MS(SIZE OF CACHE AREA) + JSR GETVEC + STY CLRPTR + STX CLRPTR+1 + +;MAKE FIRST DESCRIPTOR PT TO FIRST FREE CACHE BYTE + + JSR STCRNT ;PREV:=CACHTB + LDYIM CESTA + LDA CLRPTR + STAIY PREV + LDA CLRPTR+1 + INY + STAIY PREV ;STORE OF PREV := PTR TO FIRST FREE BYTE + + JSR FRDESC ;GET A FREE DESCRIPTOR + LDYIM CENEXT + LDA CRNT + STAIY PREV + LDAIM 0 + STAIY CRNT + INY + LDA CRNT+1 + STAIY PREV ;NEXT OF PREV := CRNT + LDAIM 0 + STAIY CRNT ;NEXT OF CRNT := 0 + +;MAKE LAST DESCRIPTOR POINT TO LAST+1 FREE BYTE + + LDYIM CESTA + SEC ;BECAUSE WE WANT TO ADD 1 + LDA CLRPTR + ADC CACHSZ + STAIY CRNT + LDA CLRPTR+1 + ADC CACHSZ+1 + INY ;Y := CESTA + 01 + STAIY CRNT + +;NOW CLEAR WHOLE OF THE CACHE TO ZERO + + LDY CACHSZ + LDX CACHSZ+1 + JSR CLRSTR + + LDAIM 0 ;RC := 0 + JMP STEXIT + + + +;************ STGBB ************* + + +;STGBB: GET BIG BUFFER +;THIS FUNCTION SUPPLIES THE STORE ADDRES +;AND SIZE OF A LARGE BUFFER. +;THIS BUFFER SHOULD BE USED FOR LARGE +;TRANSFERS TO AND FROM THE DISC. +;ENTRY: +;EXIT : ARGB = LS(BUFFER STORE ADDRESS) +;ARGC = MS(BUFFER STORE ADDRESS) +;ARGD = LS(SIZE OF BUFFER) +;ARGE = MS(SIZE OF BUFFER) + + + +STGBB ROUT + LDYIM ARGB + LDA BIGBUF + STAIY ARGPTR ;LS(BUFFER ADDRESS) + INY ;Y:=ARGC + LDA BIGBUF+1 + STAIY ARGPTR ;MS(BUFFER ADDRESS) + INY ;Y:=ARGD + LDAIM :LSB:LGBFSZ + STAIY ARGPTR ;LS(BUFFER SIZE) + INY ;Y:= ARGE + LDAIM :MSB:LGBFSZ + STAIY ARGPTR ;MS(BUFFER SIZE) + LDAIM 0 + JMP STEXIT + + + +;************ STEMPT ************ + + +;STEMPT: EMPTY THE CACHE OF ALL THE OBJECTS WHICH +;CAME FROM A SPECIFIED DISC. + +;ENTRY: ARGB = LS(DISC NUMBER) +;ARGC = MS(DISC NUMBER) + +;EXIT : ARGA = RC + + +STEMPT ROUT + LDXIM 2 ;COMPARE DISC NUMBER + JSR EXPELL ;REMOVE ALL OBJECTS ON SPECIFIED DISC FROM CACHE + JMP STEXIT + +;STRDRT: REMOVES ALL THE DIRTY BLOCKS, BELONGING TO +;A SPECIFIED FILE, FROM THE CACHE. +;NOTE IT IS ASSUMED THAT STEPS ARE TAKEN, +;BEFORE STRALL IS CALLED, TO +;AVOID BLOCKS OF THE FILE BEING LOADED. + + +;ENTRY: ARGB = LS(DISC NUMBER) +;ARGC = MS(DISC NUMBER) +;ARGD = LS(SIN) +;ARGE = CS(SIN) +;ARGF = MS(SIN) + +;EXIT : ARGA = RC + +;FUNCTION: 1) SCAN THE CACHTB REMOVING ALL THE DIRTY +;WINDOWS BELONGING TO THIS FILE. +;2) THE WINDOWS MARKED DIRTY ARE WRITTEN TO DISC. +;3) THE WINDOWS ARE THEN REMOVED FROM +;THE CACHE. + + +STRDRT ROUT + JSR TSTSIN + BNE #10 + + LDAIM &FF ;=> Only remove DIRTY windows + LDXIM 5 ;COMPARE DISC NUMBER & SIN + JSR EXPELA ;REMOVE ALL DIRTY OBJECTS +;WITH GIVEN DISC NO & SIN +10 JMP STEXIT + + LNK Uade0B diff --git a/FileServer/SRC/FileServer/Uade0B b/FileServer/SRC/FileServer/Uade0B new file mode 100644 index 0000000..a7514ae --- /dev/null +++ b/FileServer/SRC/FileServer/Uade0B @@ -0,0 +1,800 @@ + OPT UADE0B ; > .Uade0B + TTL File server file UADE0B + + +;********************************** +;* STRMAN UTILITIES * +;********************************** + + +CRDESC ROUT + [ $CMOS + PHY ;CREATE A NEW DESCRIPTOR + PHX + | + TYA ;CREATE A NEW DESCRIPTOR + PHA + TXA + PHA + ] + LDYIM CESIZE + LDXIM 0 + JSR GETVEC + STY CRNT + STY CLRPTR + STX CRNT+1 ;CRNT := ADDR OF NEW DESCRIPTOR + STX CLRPTR+1 + LDYIM CESIZE + LDXIM 0 + JSR CLRSTR ;CLEAR DESCRIPTOR TO ZERO + [ $CMOS + PLX + PLY + | + PLA + TAX + PLA + TAY + ] + RTS + +MKFREE ROUT + [ $CMOS + PHX ;PUSH X + | + TXA + PHA + ] + LDXIM CESIZE ;CLEAR CRNT DESCRIPTOR + LDAIM 0 + TAY +10 STAIY CRNT + INY + DEX + BNE #10 + LDA FRECHN ;PLACE CRNT DESCRIPTOR ON FREE CHAIN + LDYIM CENEXT + STAIY CRNT + LDA FRECHN+1 + INY + STAIY CRNT ;NEXT OF CRNT := (FRECHN) + LDA CRNT + STA FRECHN + LDA CRNT+1 + STA FRECHN+1 ;FRECHN := CRNT + [ $CMOS + PLX ;PULL X + | + PLA + TAX + ] + RTS + + +FRDESC ROUT + LDA FRECHN ;REMOVE A DESCRIPTOR FROM FREE CHAIN + STA CRNT + LDA FRECHN+1 + STA CRNT+1 ;CRNT := PTR TO A FREE ENTRY + ORA CRNT + BNE #10 + LDAIM STERRG ;NO FREE CACHE DESCRIPTORS + JSR INTERR +10 LDYIM CENEXT + LDAIY CRNT + STA FRECHN + INY + LDAIY CRNT + STA FRECHN+1 ;FRECHN:=NEXT OF CRNT + RTS + + +STCRNT LDA CACHTB ;PREV:=CACHTB;CRNT:=NEXT OF PREV + STA PREV + LDA CACHTB+1 + STA PREV+1 + LDYIM CENEXT + LDAIY PREV + STA CRNT + INY + LDAIY PREV + STA CRNT+1 + RTS + + +INSRCH JSR STCRNT ;INITIALISE CRNT,CMPPTR + CLC + LDA ARGPTR + ADCIM ARGB + STA CMPPTR + LDA ARGPTR+1 + ADCIM 0 + STA CMPPTR+1 + RTS + + +NEXTCE ROUT + LDYIM CENEXT ;PREV:=CRNT;CRNT:=NEXT OF CRNT + LDAIY CRNT + INY + ORAIY CRNT + BEQ #10 ;NO MORE ENTRIES (A=0) + LDA CRNT + STA PREV + LDA CRNT+1 + STA PREV+1 + DEY ;Y := CENEXT + LDAIY CRNT + TAX + INY + LDAIY CRNT + STA CRNT+1 + TXA + STA CRNT + LDAIM &FF ;A INDICATES THAT THERE ARE MORE ENTRIES +10 RTS + + +COMP ROUT + TXA ;COMPARE CRNT ENTRY WITH X ARGS + TAY +10 DEY + LDAIY CMPPTR + CMPIY CRNT + BNE #20 + DEX + BNE #10 +20 TXA + RTS + + +TSTSIN ROUT + LDYIM ARGD + LDAIY ARGPTR + INY + ORAIY ARGPTR + INY + ORAIY ARGPTR + BNE #10 + LDAIM STERRB ;SIN = 0 + RTS + +10 LDAIM 0 + RTS + + +RETSTA LDYIM CESTA + LDAIY CRNT + LDYIM ARGB + STAIY ARGPTR ;LS(STORE ADDRESS) + LDYIM CESTA+1 + LDAIY CRNT + LDYIM ARGC + STAIY ARGPTR ;MS(STORE ADDRESS) + INY ;Y := ARGD + LDA CRNT + STAIY ARGPTR + INY + LDA CRNT+1 + STAIY ARGPTR ;ADDRESS OF CRNT DESCRIPTOR + RTS + + +READ JSR MRKCLN ;MARK BUFFER CLEAN + LDAIM 1 ;READ OBJECT + JSR SETRTN ;DSCMAN.READ + [ $CMOS + BRA TRANSF + | + JMP TRANSF + ] + + +ENSURE ROUT + JSR TSTMRK ;IS IT DIRTY? + BEQ #10 + LDAIM 2 + JSR SETRTN + JSR TRANSF ;WRITE IT TO DISC + BNE #10 + JSR MRKCLN ;preserve return code from TRANSF +10 RTS + + +TRANSF LDA CRNT + STA MOVFRM + LDA CRNT+1 + STA MOVFRM+1 + CLC + LDA NEWARG + ADCIM ARGB + STA MOVTO + LDA NEWARG+1 + ADCIM 0 + STA MOVTO+1 + LDXIM &B ;DISC NO -> STORE ADDRESS + JSR MOVE + JMP DSCMAN + + +REMVIT ROUT + PHA ;PUSH A + JSR TSTCNT + BEQ #10 + LDAIM STERRH + JSR INTERR +10 LDYIM CENEXT ;REMOVE CRNT FROM IN USE CHAIN + LDAIY CRNT + STAIY PREV + PHA + INY + LDAIY CRNT + STAIY PREV ;NEXT OF PREV := NEXT OF CRNT + PHA + JSR MKFREE ;PLACE IT ON FREE CHAIN + PLA + STA CRNT+1 + PLA + STA CRNT ;CRNT := NEXT OF PREV + PLA ;PULL A + RTS + + +;EXPELL: ROUTINE TO REMOVE OBJECTS FROM THE CACHE. +;ENTRY: X := 2 => MATCH ON DISC NUMBER (I.E. ARGB&ARGC) +;X := 5 => MATCH ON DISC NUMBER + SIN + +;THE ENTRY EXPELA IS USED FROM STRDRT WITH +;A NON-ZERO TO INDICATE THAT ONLY DIRTY +;BLOCKS SHOULD BE REMOVED FROM THE CACHE. + +EXPELL ROUT + LDAIM 0 ;=> REMOVE ALL BLOCKS REGARDLESS +EXPELA PHA + STX STRTMP ;STRTMP := X + JSR INSRCH +20 LDX STRTMP + JSR COMP ;COMPARE DISC NUMBER & (POSSIBLY) SIN + BNE #60 + JSR TSTCNT + BEQ #30 + LDAIM STERRH ;REF COUNT > 0 + JSR INTERR + +;ENSURE THE OBJECT & THEN REMOVE IT FROM THE CACHE + +30 PLA + PHA + BEQ #50 ;EQ => REMOVE ALL BLOCKS + JSR TSTMRK ;NZ => REMOVE DIRTY BLOCKS ONLY + BEQ #60 ;NOT DIRTY, GO TO NEXT BLOCK + + JSR ENSURE ;ENSURE ITS UPTO DATE ON DISC + PHA ;save error code (4/4/86) + LDYIM CEAGE ;Age entry considerably (16/1/85) + LDAIM &80 + STAIY CRNT + PLA + BNE #70 ;br if error + [ $CMOS + BRA #60 + | + BEQ #60 + ] + +50 JSR ENSURE ;Ensure up to date on disc + JSR REMVIT ;Destroy file so remove all + BNE #70 ;Detect disc errors + LDYIM CENEXT ;REMVIT compacted everything + LDAIY CRNT + INY + ORAIY CRNT + BNE #20 +60 JSR NEXTCE ;PREV:=CRNT;CRNT:=NEXT OF CRNT + BNE #20 + PLA ;RESTORE STACK + LDAIM 0 ;RC:=0 + RTS + +70 + [ $CMOS + PLX ;save A, clean stack + TAX + | + TAX ;save A, clean stack + PLA + TXA + ] + RTS + + +FNDSTA ROUT + LDYIM ARGB ;FIND CACHE ENTRY WITH GIVEN STORE ADDRESS + LDAIY ARGPTR + STA STRTMP + INY + LDAIY ARGPTR + STA STRTMP+1 + JSR STCRNT +10 LDYIM CESTA + LDAIY CRNT + CMP STRTMP + BNE #20 + INY + LDAIY CRNT + CMP STRTMP+1 + BEQ #30 +20 JSR NEXTCE + BNE #10 + LDAIM STERRF ;INVALID WINDOW ADDRESS +30 RTS + + +DECGEN SEC + LDYIM CESTA + LDAIY CRNT + SBCIM 1 + STA GENPTR + INY + LDAIY CRNT + SBCIM 0 + STA GENPTR+1 + RTS + + +MRKCLN PHA ;MARK STORE BUFFER CLEAN + [ $CMOS + PHY ;SAVE Y + | + TYA + PHA + ] + JSR DECGEN ;GENPTR SHOULD CONTAIN ADDRESS OF BUFFER + LDAIM 0 ;A := 0 + [ $CMOS + STAI GENPTR ;[GENPTR] := 0 + PLY ;PULL Y + | + TAY + STAIY GENPTR ;[GENPTR] := 0 + PLA + TAY + ] + PLA ;PULL A + RTS + + +TSTMRK JSR DECGEN ;TEST DIRTY MARKER - NOTE THIS RTN DESTROYS A & Y + [ $CMOS + LDAI GENPTR ;A:=[GENPTR] + | + LDYIM 0 + LDAIY GENPTR ;A:=[GENPTR] + ] + RTS + + +INCCNT ROUT + LDYIM CERCNT ;INCREMENT REFERENCE COUNT + LDAIY CRNT + CMPIM &FF + BNE #10 + LDAIM STERRK ;REFERENCE COUNT = $FF + JSR INTERR +10 + [ $CMOS + INCA + | + CLC + ADCIM 1 + ] + STAIY CRNT + RTS + + +DECCNT ROUT + LDYIM CERCNT ;DECREMENT REFERENCE COUNT + LDAIY CRNT + BNE #10 + LDAIM STERRD ;REFERENCE COUNT = 0 + JSR INTERR +10 + [ $CMOS + DECA + | + SEC + SBCIM 1 + ] + STAIY CRNT + RTS + +TSTCNT LDYIM CERCNT ;TEST VALUE OF REFERNENCE COUNT + LDAIY CRNT + RTS + + +;FREEST: GET AMTNED WORTH OF FREE STORE. +;EXIT : A = RC +;CRNT POINTS TO DESCRIPTOR WITH STORE ADDRESS SET + +;FUNCTION:- +;1) AGE ALL THE ENTRIES IN THE CACHE +;2)FIND OUT THE MOST COST EFFECTIVE AREA +;OF MEMORY TO USE. + +;WHILE crnt <> 0 AND min cost <> 0 +;DO IF amount needed<=(storeaddrOFcrnt-storeaddrOFprev +;- lengthOFprev-2) +;THEN IF cost 0 +;THEN prev := crnt; +;cost := 0 +;ELSE cost +:= cost OF crnt +;FI; +;crnt := next OF crnt +;FI +;OD; + +;WHILE crnt <> best end +;DO ensure(crnt); #ENSURE WINDOW UPTO DATE ON DISC# +;remove(crnt) #REMOVE CRNT FROM IN USE CHAIN# +;OD; + +;crnt := get free descriptor; +;straddrOFcrnt:=straddrOFprev+lengthOFprev+1 + +FREEST ROUT + LDA AMTNED + ORA AMTNED+1 + BNE #05 + LDAIM STERRE + RTS + +;FIRST,AGE EACH OBJECT IN THE CACHE + +05 JSR STCRNT ;PREV:=CACHTB;CRNT:=NEXT OF PREV + +10 LDYIM CEAGE + LDAIY CRNT + CMPIM LRU + BEQ #15 + [ $CMOS + DECA + | + SEC + SBCIM 1 + ] + STAIY CRNT ;AGE OF CRNT -:= 1 +15 JSR NXTCRN + BNE #10 + +;NOW SEE WHICH IS THE BEST AREA OF MEMORY TO USE + + JSR STCRNT + [ $CMOS + STZ BSTSTA + STZ BSTSTA+1 ;BSTSTA : = 0 + STZ BSTEND + STZ BSTEND+1 ;BSTEND := 0 + STZ COST + STZ COST+1 ;COST := 0 + | + LDAIM 0 + STA BSTSTA + STA BSTSTA+1 ;BSTSTA : = 0 + STA BSTEND + STA BSTEND+1 ;BSTEND := 0 + STA COST + STA COST+1 ;COST := 0 + ] + LDAIM &FF + STA MINCST + LDAIM &7F + STA MINCST+1 ;MINCST := $7FFF + +20 JSR TSTGAP + BEQ #22 + JMP #45 + +;SEE IF COST < MIN COST + +22 LDXIM &FF ;X<>0 here + LDA COST + PHA + LDA COST+1 + PHA ;save cost for new algorithm + + LDYIM CENEXT + LDAIY PREV + STA GP1 + INY + LDAIY PREV + STA GP1+1 ;intermediate pointer + + LDAIY GP1 + CMP CRNT+1 + BNE #30 + DEY + LDAIY GP1 + CMP CRNT + BNE #30 ;skip if not single slot + + LDYIM CEAGE + LDAIY GP1 ;get the age + TAX + STA COST ;make new account + [ $CMOS + STZ COST+1 + | + LDAIM 0 + STA COST+1 + ] + + LDY AMTNED+1 + LDA AMTNED + BEQ #25 + INY + +25 DEY + BEQ #30 + CLC + TXA + ADC COST + STA COST + BCC #25 + INC COST+1 + BNE #25 + +30 LDA COST + CMP MINCST + LDA COST+1 + SBC MINCST+1 + BCS #35 + + LDA PREV + STA BSTSTA + LDA PREV+1 + STA BSTSTA+1 ;BSTSTA := PREV + LDA CRNT + STA BSTEND + LDA CRNT+1 + STA BSTEND+1 ;BSTEND := CRNT + LDA COST + STA MINCST + LDA COST+1 + STA MINCST+1 ;MINCST := COST + ORA MINCST + TAX + +35 PLA + STA COST+1 + PLA + STA COST ;restore old value of COST + TXA + BEQ #65 ;I.E. FOUND A GAP + LDYIM CENEXT + LDAIY PREV + TAX + INY + LDAIY PREV + STA PREV+1 + TXA + STA PREV ;PREV := NEXT OF PREV + + LDYIM CEBLKS + LDAIY PREV ;get length + TAX ;count around the loop + +40 SEC + LDA COST + LDYIM CEAGE + SBCIY PREV + STA COST + BCS #43 + DEC COST+1 ;cost -:= cost OF prev*length OF prev +43 DEX + BNE #40 ;count for length of blocks + JMP #20 + +45 JSR TSTCNT + BEQ #50 + +;COST := 0; PREV := CRNT + + [ $CMOS + STZ COST + STZ COST+1 + | + LDAIM 0 + STA COST + STA COST+1 + ] + LDA CRNT + STA PREV + LDA CRNT+1 + STA PREV+1 + [ $CMOS + BRA #55 + | + JMP #55 + ] + +50 LDYIM CEBLKS + LDAIY CRNT ; grab length (one byte only) + TAX +52 CLC ;cost +:=(cost OF crnt)*(length OF crnt) + LDA COST + LDYIM CEAGE + ADCIY CRNT + STA COST + BCC #54 + INC COST+1 +54 DEX + BNE #52 + +55 JSR NXTCRN ;CRNT := NEXT OF CRNT + BEQ #60 + JMP #20 + +;FIRST SEE IF WE FOUND AN AREA OF MEMORY TO USE + +60 LDA BSTSTA + ORA BSTSTA+1 + BNE #65 + LDAIM STERRL ;STORE DEADLOCK !!!! + RTS ;**15/6/87** return to client (was JSR INTERR) + +;NOW REMOVE ALL THE OBJECTS IN THE GAP + +65 LDA BSTSTA + STA PREV + LDA BSTSTA+1 + STA PREV+1 ;PREV := BSTSTA + LDYIM CENEXT + LDAIY PREV + STA CRNT + INY + LDAIY PREV + STA CRNT+1 ;CRNT := NEXT OF PREV + +;NOW CREATE THE GAP (IF NECESSARY) + + LDAIM 0 + PHA ;save RC +70 LDA BSTEND ;WE MUST DO THIS TEST FIRST + CMP CRNT + BNE #80 + LDA BSTEND+1 + CMP CRNT+1 + BNE #80 + + JSR NEWDES ;GET FREE DESCR,CHAIN IT IN,CALC STORE ADDR + PLA ;RC here + RTS + +80 JSR ENSURE + BEQ #85 + + CMPIM &C9 ;look for protected disc + BEQ #90 ;skip as object is now removed anyway + + JSR INTERR +85 JSR REMVIT + [ $CMOS + BRA #70 + | + JMP #70 + ] + +90 TAX + PLA ; change old RC + BNE #95 + TXA +95 PHA ;change return code + [ $CMOS + BRA #85 + | + JMP #85 + ] + + +NEWDES ROUT + JSR FRDESC ;CRNT := NEW DESCRIPTOR + +;storeaddrOFcrnt:=storeaddrOFprev+lengthOFprev+1 + + JSR LNTPRE + SEC ;BECAUSE WE WANT TO ADD 1 + LDYIM CESTA + LDAIY PREV + ADC BREGA + STAIY CRNT + INY + LDAIY PREV + ADC BREGA+1 + STAIY CRNT + +;NOW CHAIN IT IN + + LDYIM CENEXT + LDAIY PREV + STAIY CRNT + INY + LDAIY PREV + STAIY CRNT ;NEXT OF CRNT := NEXT OF PREV + DEY ;Y:=CENEXT + LDA CRNT + STAIY PREV + INY + LDA CRNT+1 + STAIY PREV ;NEXT OF PREV := CRNT + RTS + + +LNTPRE LDYIM CEBLKS ;BREGA := LENGTH OF PREV (IN BYTES) + LDAIY PREV + STA BREGA + INY + LDAIY PREV + STA BREGA+1 + JMP MULTBS + + +;TSTGAP: A:= IF amount needed <= storeaddrOFcrnt- +;storeaddrOFprev-lengthOFprev-2 +;THEN 0 +;ELSE FF +;FI + +TSTGAP ROUT + JSR LNTPRE ;BREGA := LENGTH OF PREV(IN BYTES) + CLC + LDYIM CESTA + LDAIY CRNT + SBCIY PREV + STA STRTMP + INY + LDAIY CRNT + SBCIY PREV + STA STRTMP+1 ;STRTMP:=straddrOFcrnt-straddrOFprev-1 + SEC + LDA BREGA + ADC AMTNED + STA BREGA + LDA BREGA+1 + ADC AMTNED+1 + STA BREGA+1 ;BREGA:=amountneeded+lengthOFprev+1 + BVC #10 + LDAIM STERRM ;OVERFLOW!!! + JSR INTERR +10 SEC + LDA STRTMP + SBC BREGA + LDA STRTMP+1 + SBC BREGA+1 + BMI #20 + LDAIM 0 ;I.E. GAP BIG ENOUGH + RTS + +20 LDAIM &FF ;I.E GAP TOO SMALL + RTS + + +NXTCRN LDYIM CENEXT ;CRNT := NEXT OF CRNT + LDAIY CRNT + TAX + INY + LDAIY CRNT + STA CRNT+1 + TXA + STA CRNT + ORA CRNT+1 ;A:= CRNT ! CRNT +01 + RTS + + LNK Uade0C diff --git a/FileServer/SRC/FileServer/Uade0C b/FileServer/SRC/FileServer/Uade0C new file mode 100644 index 0000000..0c8ae8f --- /dev/null +++ b/FileServer/SRC/FileServer/Uade0C @@ -0,0 +1,653 @@ + OPT UADE0C ;FILE > Uade0C + TTL File server file UADE0C + +;********************************** +;* D I R M A N * +;********************************** + +;DIRMAN: THE DIRECTORY MANAGER. +;1) PRESERVE SIN OF AN OBJECT IN A DIR +;2) RETRVE SIN OF AN OBJ WITH GIVEN FILE TITLE +;3) DELETE - REMOVE A DIR ENTRY +;4) SETATTRIBS +;5) CREATE DIR +;6) CHANGE OBJECT SIZE +;7) EXAMINE +;8) FORMATTED DETAILS OF DIR ENTRY +;9) MAKE DIRECTORY removed ** 3/10/84 ** +;10) GIVE DISC NAME FROM FILE TITLE +;11) Remove a directory ** 24/9/84 ** +;12) Preserve object (without DELCHK) ** 25/9/84 ** +;13) Check if object will preserve **23/3/88** + +DIRMAN LDXIM 13 + LDAIM MODDIR + JSR ENTRY + [ $Level3 + LDAAX DRRTNS + STA DRJUMP+1 + LDAAX DRRTNS+1 + STA DRJUMP+2 + ] + + LDAIM &19 + JSR SETFS + [ $Level3 +DRJUMP JMP DRJUMP + | + JMIX DRRTNS + ] +DRRTNS + & DRPRES ;1 => PRESERVE OBJECT + & DRRETR ;2 => RETRIEVE OBJECT + & DRDELT ;3 => DELETE OBJECT + & DRSACC ;4 => SET ATTRIBUTES + & DRCRDR ;5 => CREATE DIRECTORY + & DRCHSZ ;6 => CHANGE SIZE OF OBJECT + & DREXAM ;7 => GIVE DETAILS FOR EXAMINE + & DRINFO ;8 => DETAILS OF OBJECT(CHAR STRING FORMAT) + & DRMAKE ;9 => MAKE A DIR (DON'T PRESERVE) + & DRFTDN ;10 => FILE TITLE -> DISC NO. + & DRDELT ;11 => Remove a directory + & DRPRES ;12 => Preserve object without delchk + & DRPRES ;13 => Check if object will preserve +DREXIT JMP PREXIT ;**25/12/86** + +;*********** DRPRES *********** + +;DRPRES: PRESERVE THE SIN OF AN OBJECT WITH A GIVEN TITLE + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE +;ARGF-I LOAD ADDR +;ARGJ-M EXEC ADDR +;ARGN = TYPE AND ACCESS (TLWR/WR) +;ARGO-P DATE CREATED +;ARGQ-S SIN +;ARGT = WILD CARD FLAG + +;EXIT : +;ARGA = RC +;ARGB-C DISC NO +;ARGD-E SIN OF OBJECT TO BE DELETED +;ARGG = Access byte + +;N.B. IF ARGD!ARGE!ARGF = 0 THEN NO DELETE NEEDED + + +DRPRES ROUT + LDYIM ARGT ;get wild card flag + LDAIY ARGPTR + STA DIRWC ;save flag for decoding routines + JSR INITDV ;INIT VARIABLES + BNE #10 + +;CHECK FOR OWNER ACCESS + + JSR TSTOWN + BNE #10 + +;RETRIEVE APPROPRIATE DIR + + JSR RETDIR + BNE #10 + + LDYIM ARGA + LDAIY ARGPTR ;check entry code + EORIM 12 ;dont do DELCHK in retain + JSR RETA12 ;special case +10 PHA ;**25/12/86** + LDA OBJACC + LDYIM ARGG + STAIY ARGPTR + PLA + [ $CMOS + BRA DREXIT ;**25/12/86** + | + JMP DREXIT ;**25/12/86** + ] + + +;************ DRRETR ************ + +;DRRETR: RETRIEVE DETAILS OF A SPECIFIED OBJECT + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE +;ARGF-G ADDRESS OF STORE AREA TO CONTAIN DETAILS +;ARGH = Wild card flag + +;EXIT: ARGA = RC +;ARGB = TYPE OF OBJECT & MAX ACCESS ALLOWED TO IT +; Also contains "lock" bit and OWNER/PUBLIC bit + +;DETAILS INCLUDE:- +;FILE TITLE (10 BYTES) +;LOAD ADDR (4BYTES), +;EXEC ADDR (4BYTES), +;ACC INFO (1 BYTE), +;CREATION DATE (2 BYTE), +;SIN (3BYTES), +;DISC NO (2BYTES), Set after any non-syntax error ** 14/10/86 ** +;SIZE (3BYTES). + + +DRRETR ROUT + JSR DRRET2 ;**4/4/88** call as subroutine + [ $CMOS + BRA DREXIT + | + JMP DREXIT + ] + +DRRET2 LDYIM ARGH + LDAIY ARGPTR + ORAIM &02 ;**2/6/87** "^" allowed at end + STA DIRWC ;get wild card flag + JSR INITDV + BEQ #00 + JMP #60 +00 JSR SETINF ;**08/02/87** + + LDYIM INFDIS ;in case fail later still make some details + LDA DRDISC ;point to disc number (if any) as this is + STAIY INFPTR ;needed by RENAME + INY + LDA DRDISC+1 + STAIY INFPTR ;end ** 14/10/86 ** + +;RETRIEVE RELEVENT DIR + + JSR TSTROT ;TEST FOR + BNE #20 + +;SUPPLY DETAILS OF ROOT DIR + + LDAIM ROOT ;**4/4/88** Set up name + JSR OUTCH + LDXIM 9 + JSR OUTSPS + JSR SETINF ;Reset INFPTR + +05 LDYIM INFLOA + LDXIM 8 + LDAIM 0 +10 STAIY INFPTR ;LOAD ADDRESS:=EXEC ADDR:=0 + INY + DEX + BNE #10 + + LDA DIRACC + LDYIM ARGB + STAIY ARGPTR ;ACCESS TO ROOT DIR + LDYIM INFACC + LDAIM TYPDIR+LOCKED + STAIY INFPTR + INY + LDA TDATE ;(DATE OF CREATION ROOT) + STAIY INFPTR + INY + LDA TDATE+1 + STAIY INFPTR + LDA DIRSIN + INY + STAIY INFPTR + LDA DIRSIN+1 + INY + STAIY INFPTR + LDA DIRSIN+2 + INY + STAIY INFPTR + JSR DIROBJ ;**08/02/87** Copy DIRSIN to OBJSIN + JSR RETDSZ ;PLACE DISC NO & SIZE IN INFPTR + [ $CMOS + BRA #50 + | + JMP #50 + ] + +20 JSR TSTPAR ;**23/1/87** check if ^ for parent + BNE #25 +; JSR RETPAR ;**23/1/87** retrieve parent directory +; BNE #40 +; JSR UNLOCK +21 CLC ;**20/5/87** copy name of parent directory + LDA DIRSTA + ADCIM DRNAME + STA MOVFRM + LDA DIRSTA+1 + ADCIM 0 + STA MOVFRM+1 + LDYIM NAMLNT-1 +22 LDAIY MOVFRM + STAIY INFPTR + DEY + BPL #22 + [ $CMOS ; This looks like a bugfix in Filestore 1.31 but not included in the L3 code + LDA DATE ;set date to today (????????) + STA TDATE + LDA DATE+1 + STA TDATE+1 + BRA #05 ;**23/1/87** complete info entry a la root + | + BMI #05 ;**23/1/87** complete info entry a la root + ] + + [ Pseudods = Yes +25 LDYIM 1 ;**20/5/87** check lone pseudo-directory + LDAIY NAMPTR + CMPIM TERMIN + BNE #27 + DEY + LDAIY NAMPTR + JSR Testpd + BNE #27 + JSR LOADDR ;**20/5/87** load directory + BNE #60 + [ $CMOS ; This looks like a bugfix in Filestore 1.31 but not included in the L3 code + LDA DATE ;set date to today (????????) + STA TDATE + LDA DATE+1 + STA TDATE+1 + ] + + | + [ $CMOS +25 BRA #27 + | +25 BNE #27 + ] + ] +26 JSR UNLOCK + [ $CMOS + BRA #21 ;**20/5/87** go update details + | + JMP #21 ;**20/5/87** go update details + ] +27 LDYIM ARGH ;get flag + LDAIY ARGPTR + RORA + BCC #30 + JSR RETEND ;get directory + [ $CMOS + BRA #40 + | + JMP #40 + ] +30 JSR RETENT +40 BNE #60 + JSR Tsparn ;**2/6/87** parent at end? + BEQ #26 ;**2/6/87** yes, extract details now + +;COPY DETAILS INTO STORE AREA POINTED TO BY INFPTR + + JSR DETALS + PHA ;Push return code + +;NOW CALCULATE CALLER'S ACCESS TO THE OBJECT + + JSR MAXACC + + LDYIM ARGB + STAIY ARGPTR ;TYPE & MAX ACCESS ALLOWED TO OBJECT + JSR UNLOCK ;STRMAN.UNLOCK (DIR) + PLA ;Pull DETALS return code + BNE #60 ;Error + +50 LDAIM 0 ;RC:=0 +60 RTS ;**4/4/88** + +;MAKE INFPTR POINT TO DETAILS AREA + +SETINF ROUT + LDYIM ARGF + LDAIY ARGPTR + STA INFPTR + INY + LDAIY ARGPTR + STA INFPTR+1 + INY + RTS + + + +;************ DRDELT ************ + + +;DRDELT: DELETE + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE + +;EXIT : +;ARGA = RC +;ARGB-C DISC NO +;ARGD-F SIN OF OBJECT TO BE DELETED + + +DRDELT ROUT + LDYIM ARGG + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV ;INIT VARIABLES + BNE #20 + +;CHECK FOR OWNER ACCESS + + JSR TSTOWN + BNE #20 + +;RETRIEVE APPROPRIATE DIR ENTRY + + JSR RETENT ;RETRIEVE REQ'D ENTRY + BNE #20 + +;FIRST CHECK THAT ENTRY MAY BE DELETED + + LDYIM ARGA ;check entry code + LDAIY ARGPTR ;** 24/9/84 ** + CMPIM 11 + BEQ #10 ;skip delete check if 'remove' called + + JSR DELCHK + BEQ #10 + JSR UNLOCK + BNE #20 + +;NOW REMEMBER DISC NO & SIN OF OBJECT TO BE DELETED + +10 JSR CRNSIN ;OBJSIN := SIN OF CRNTEN + JSR ARGDSN ;PLACE DISC NO & SIN ON ARGPTR STACK + +;NOW UNCHAIN CURRENT DIR ENTRY & PLACE +;IT ON THE FREE CHAIN + + LDYIM DRLINK + LDAIY CRNTEN + STAIY PREVEN + INY + LDAIY CRNTEN + STAIY PREVEN ;[PREVEN] := [CRNTEN] + + JSR FREECH ;PLACE CRNTEN ENTRY ON FREE CHAIN + +;NOW DECREMENT COUNT OF NUMBER OF DIR ENTRIES + + JSR SETGEN ;GENPTR := [DIRSTA] + SEC + LDYIM DRENTS + LDAIY GENPTR + SBCIM 1 + STAIY GENPTR + INY + LDAIY GENPTR + SBCIM 0 + STAIY GENPTR ;[DIRSTA + DRENTS] -:= 1 + +;ENSURE UPTO DATE ON DISC + + JSR ENSRIT + +20 JMP DREXIT ;**25/12/86** + + +;************ DRSACC ************ + + +;DRSACC: SET ATTRIBUTES + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE +;ARGG = FN +; FN = 1 => SET LOAD/EXEC & ACCESS +; FN = 2 => SET LOAD ADDR +; FN = 3 => SET EXEC ADDR +; FN = 4 => SET ACCESS BYTE +; FN = 5 => SET DATE +;ARGH +n (depending on ARGF) = ATTRIBUTES TO SET + +;EXIT : ARGA = RC + + +;FORMAT OF ACCESS BYTE:- + +;BIT0->PUBLIC HAS READ ACCESS +;BIT1->PUBLIC HAS WRITE ACCESS +;BIT2->OWNER HAS READ ACCESS +;BIT3->OWNER HAS WRITE ACCESS +;BIT4->ENTRY IS LOCKED + +DRSAT1 = DRLOAD ;Offsets in directory entry + = DRLOAD + = DREXEC + = DRACCS + = DRDATE + +DRSAT2 = 9 ;Length of data + = 4 + = 4 + = 1 + = 2 + +DRSACC ROUT + [ $CMOS + STZ DMTEMP+2 ;save space for Access arg + | + LDAIM 0 + STA DMTEMP+2 ;save space for Access arg + ] + LDYIM ARGF + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV ;INITIALISE VARIABLES + BNE #50 + + LDYIM ARGG ;CHECK IF JUST DATE UPDATE + LDAIY ARGPTR + CMPIM 5 + BEQ #10 ;NO NEED FOR OWNER ACCESS + +;CHECK FOR OWNER ACCESS + + JSR TSTOWN + BNE #50 + +;RETRIEVE APPROPRIATE DIR ENTRY + +10 JSR RETENT + BNE #50 + +20 LDYIM ARGG + LDAIY ARGPTR + STA DMTEMP+1 ;Store for later + LDYIM ARGH ;Position of access if A=4 + CMPIM 4 ;If SETACCESS, must mask off access bits + BEQ #25 ;Is SETACCESS -> check access byte + CMPIM 5 ;** 31/1/85 ** + BEQ #55 + CMPIM 1 + BNE #40 ;Is "all attribs" so check access + LDYIM ARGP ;Position of access if A = 1 + +25 STY DMTEMP ;Store offset of access + LDAIY ARGPTR ;Read access byte + ANDIM ACCMSK ;Mask off access bits + ORA DMTEMP+2 + STA DMTEMP+2 + STAIY ARGPTR + TAX ;Store for later + +;** 15/11/84 ** w/ access illegal + ANDIM &0C ;owner bits set + BEQ #35 + ANDIM &04 ;at least r bit set + BNE #35 + LDAIM SAERRA ;'bad attribute' error + [ $Level3 + BNE #45 + | + BRA #45 + ] + +35 JSR ISDIR + BNE #55 ;Is not a directory, so continue + TXA + ANDIM ACCMSK-RWMSK ;just the lock bit + ORAIM TYPDIR ;Or in directory info. if a dir. + LDY DMTEMP + STAIY ARGPTR ;Stuff access argument + LDA DMTEMP+1 ;Load function no. + CMPIM 1 + BNE #55 ;Check not setting load/exec. of a dir. + +40 JSR ISDIR ;Check if is directory + BNE #55 ;Cannot set load/exec address of dir., so error + LDAIM DRERRF ;Bad arg. + +45 JSR UNLOCK ;Otherwise, error + [ $CMOS +50 BRA #65 ;Error exit + | +50 JMP #65 ;Error exit + ] + +55 LDYIM ARGG ;Here, all checks made, so set attribs + LDAIY ARGPTR + TAY + LDAIM ARGH ;Set args for block move from stack + STA OFF1 ;to some offset in CRNTEN + LDAAY DRSAT1-1 ;Get offset in dir. entry + STA OFF2 ;"Move to" offset + LDAAY DRSAT2-1 ;Length to move + LDXIM ARGPTR ;"Move from" ptr. + LDYIM CRNTEN ;"Move to" ptr. + JSR MOVBLK ;Move args to stack + + LDYIM ARGG + LDAIY ARGPTR + CMPIM 5 ;DON'T SET ALL DATES + BEQ #60 + + JSR FNDTEZ ;try for any more entries + BNE #60 + JMP #20 + +60 JSR ENSRIT ;Ensure directory and exit + +65 JMP DREXIT ;**25/12/86** + + + +;************ DRCRDR ************ + + +;DRCRDR: CREATE & PRESERVE A NEW DIRECTORY + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE +;ARGF = Size of directory ** 15/9/83 ** +;ARGG = Wild card flag + +;EXIT : +;ARGA = RC +;ARGB-C DISC NO +;ARGD-F SIN OF OBJECT TO BE DELETED + +DRCRDR ROUT + LDYIM ARGG + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV + BNE #40 + +;CHECK FOR OWNER ACCESS + + JSR TSTOWN + BNE #40 + +;Load parent directory and save SIN **23/1/87** + + JSR RETDIR + BNE #40 + LDA DIRSIN + STA EXRTN + LDA DIRSIN+1 + STA EXRTN+1 + LDA DIRSIN+2 + STA EXRTN+2 + JSR UNLOCK ;release parent pro tem + JSR TSTPAR ;prohibit new name of "^" + BEQ #50 + [ Pseudods = Yes + LDYIM 0 ;**20/5/87** prohibit new names of "&", "%", "@" + LDAIY NAMPTR + JSR Testpd + BNE #15 + JSR TSTTER + BEQ #50 + ] +15 LDYIM ARGG + LDAIY ARGPTR + STA DIRWC ;**24/7/87** get wild card flag again + JSR INITDV ;reinitialise variables + BNE #40 + +;CREATE A VIRGIN DIRECTORY + + LDYIM ARGF + LDAIY ARGPTR + STA DIRTMP+1 ;DIRTMP := SIZE OF DIRECTORY REQD. + [ $CMOS + STZ DIRTMP + STZ DIRTMP+2 + | + LDAIM 0 + STA DIRTMP + STA DIRTMP+2 + ] + JSR MAKDIR ;SETUP ARGPTR ARGUMENTS FOR DIRMAN.PRESERVE + BNE #40 + +;NOW UNLOCK THE CREATED DIR - THE RETAIN RTN +;ENSURES THAT ITS UPTO DATE ON DISC + + JSR UNLOCK + +;NOW HAVE IT RETAINED + + JSR INITDV ;REINITIALISE VARIABLES + BEQ #30 + +20 ;OBJSIN:=SIN OF NEW DIR(RETAIN DESTROYS OBJSIN) + JSR DELOBJ ;**** 17/3/83 **** + [ $CMOS + BRA #40 + | + JMP #40 + ] + +;LOAD APPROPRATE DIR + +30 JSR RETDIR + BNE #20 + +;NOW HAVE IT RETAINED IN THIS DIR + + JSR RETAIN + BNE #20 +40 JMP DREXIT + +50 LDAIM DRERRA ;Can't use name "^" + [ $CMOS + BRA #40 + | + BNE #40 + ] + + + LNK UADE0CA diff --git a/FileStore/SRC/FileStore/Uade0CA.6502 b/FileServer/SRC/FileServer/Uade0CA similarity index 82% rename from FileStore/SRC/FileStore/Uade0CA.6502 rename to FileServer/SRC/FileServer/Uade0CA index 10febab..c96e59d 100644 --- a/FileStore/SRC/FileStore/Uade0CA.6502 +++ b/FileServer/SRC/FileServer/Uade0CA @@ -29,11 +29,7 @@ DRCHSZ ROUT [ 1=1 LDAIM IERRAC ;Not used in FileStore ** 29/09/86 ** -;v1.23 - JMP USRERR -;v1.31 -; JMP INTERR - + JMP INTERR | LDYIM ARGI LDAIY ARGPTR @@ -56,7 +52,11 @@ DRCHSZ ROUT CMPIM TYPDIR BNE #10 LDAIM DRERRF ;WRONG TYPE + [ $CMOS BRA #40 + | + BNE #40 + ] ;DEAL WITH A FILE @@ -64,7 +64,11 @@ DRCHSZ ROUT ANDIM WRITAC BNE #20 LDAIM DRERRL ;NO WRITE ACCESS ! + [ $CMOS BRA #40 + | + BNE #40 + ] ;CHECK THAT THE FILE IS NOT OPEN @@ -73,7 +77,11 @@ DRCHSZ ROUT JSR RNDMAN BNE #30 LDAIM DRERRI + [ $CMOS BRA #40 + | + BNE #40 + ] ;NOW CALL MAPMAN TO HAVE THE SIZE CHANGED @@ -135,7 +143,12 @@ DEXTAB & EXRTNA & EXRTND DREXAM ROUT + [ $CMOS STZ DIRFLG + | + LDAIM 0 + STA DIRFLG + ] LDYIM ARGK LDAIY ARGPTR ORAIM &02 ;**2/6/87** "^" allowed at end of name @@ -153,8 +166,12 @@ DREXAM ROUT CMPIM 5 BCC #15 ;IF <5, OK LDAIM DRERRO ;BAD ARG. TO EXAMINE + [ $CMOS BRA #20 - + | + BNE #20 + ] + 15 STA EXARG ;TYPE OF RESULT INY LDAIY ARGPTR @@ -177,8 +194,15 @@ DREXAM ROUT ;INTO RESULT AREA. LDYIM DRNAME ;OFFSET IN DIR. + [ $Level3 + LDXIM 0 + ] 30 LDAIY DPTRLD + [ $Level3 + STAIX INFPTR + | STAI INFPTR + ] INY JSR INCIPT CPYIM DRFREE @@ -200,8 +224,12 @@ DREXAM ROUT INY LDA DRDISC+1 STAIY ARGPTR + [ $CMOS BRA #70 - + | + JMP #70 + ] + 35 JSR INTPRE ;PREVEN := DIRSTA ;FOR I=0 TO EXENTR DO @@ -217,8 +245,12 @@ DREXAM ROUT TAX BEQ #45 ;LOOP FINISHED JSR MOVCRN ;PREVEN := CRNTEN + [ $CMOS BRA #40 - + | + JMP #40 + ] + ;SET ROUTINE TO BE USED, DEPENDING ;ON EXARG. ;EXRTN := JMP @@ -240,12 +272,27 @@ DREXAM ROUT 50 PHA ;STORE NO. OF ENTRIES JSR EXRTN ; call routine BEQ #55 + [ $CMOS PLX ;Restore stack + | + TAX + PLA ;Restore stack + TXA + ] JSR UNLOCK + [ $CMOS BRA #75 ;Error -> exit [always jump] - + | + BNE #75 ;Error -> exit [always jump] + ] + 55 PLA + [ $CMOS INCA ;ADD NO. OF ENTS. + | + CLC + ADCIM 1 ;ADD NO. OF ENTS. + ] PHA LDA CRNTEN STA PREVEN @@ -260,7 +307,12 @@ DREXAM ROUT ;FINALLY, SET END OF BLOCK INDICATOR. 60 PHA 65 LDAIM EXTERM + [ $CMOS STAI INFPTR + | + LDYIM 0 + STAIY INFPTR + ] JSR INCIPT ;INCREMENT POINTER TO END OF BLOCK (USED IN TXCB). LDYIM ARGB LDA INFPTR @@ -304,105 +356,50 @@ DREXAM ROUT DRINFO ROUT -;v1.23 - LDYIM ARGH - LDAIY ARGPTR - STA DIRWC ;get wild card flag - JSR INITDV - BNE #20 - - JSR SETINF - JSR TSTROT - BNE #10 - JSR DIROBJ - - LDAIM ROOT - JSR OUTCH ;Ouput dir. name - LDXIM &0A - JSR OUTSPS ;Pad dir. name - - JSR OUTZRO ;Output 8 zeros - JSR OUTSP - JSR OUTZRO ;8 more zeros (exec address) - - LDXIM 3 - JSR OUTSPS - JSR OUTSZA + JSR DRRET2 ;**4/4/88** Retrieve info to output area BNE #40 - LDAIM TYPDIR :OR: LOCKED ;TYPE = DIRECTORY - ASLA - JSR OUTACA ;Output access - - LDXIM 4 - JSR OUTSPS - - LDXIM 2 - JSR OUTRTD - LDA OBJSIN + 2 + JSR SETINF ;Set pointer to result area + LDA INFPTR ;Set up to copy details + STA MOVFRM ;(as we will overwrite output area) + LDA INFPTR+1 + STA MOVFRM+1 + SEC + LDAIM :LSB:DETNAM + STA MOVTO + SBCIM :LSB:DRTITL + STA CRNTEN ;Save for use in EXAM routines + LDAIM :MSB:DETNAM + STA MOVTO+1 + SBCIM :MSB:DRTITL + STA CRNTEN+1 + LDXIM INFNXT ;Move all details + JSR MOVE + + JSR MOVEFT ;Copy info as text, name first + JSR OUTSP + JSR OUTLEX + [ $CMOS + STZ FILLFL + | + LDAIM 0 + STA FILLFL + ] + LDA DETSZ+2 JSR OUTBYT - LDA OBJSIN + 1 + LDA DETSZ+1 JSR OUTBYT - LDA OBJSIN + LDA DETSZ JSR OUTBYT -;v1.23 - BRA #30 -;v1.31 -; JMP #30 ;FINISHED ..... - -;HERE DOING NON-ROOT OBJECT - -10 JSR RETENT ;RETRIEVE BOTTOM ENTRY - BNE #40 - - JSR OUTENT ;Put out entry details - JSR UNLOCK ;UNLOCK CURRENT DIR. (note does PHA/PLA) -20 BNE #40 ;Unsuccessful MAPMAN call - - -;v1.31 -; JSR DRRET2 ;**4/4/88** Retrieve info to output area -; BNE #40 -; -; JSR SETINF ;Set pointer to result area -; LDA INFPTR ;Set up to copy details -; STA MOVFRM ;(as we will overwrite output area) -; LDA INFPTR+1 -; STA MOVFRM+1 -; SEC -; LDAIM :LSB:DETNAM -; STA MOVTO -; SBCIM :LSB:DRTITL -; STA CRNTEN ;Save for use in EXAM routines -; LDAIM :MSB:DETNAM -; STA MOVTO+1 -; SBCIM :MSB:DRTITL -; STA CRNTEN+1 -; LDXIM INFNXT ;Move all details -; JSR MOVE -; -; JSR MOVEFT ;Copy info as text, name first -; JSR OUTSP -; JSR OUTLEX -; STZ FILLFL -; LDA DETSZ+2 -; JSR OUTBYT -; LDA DETSZ+1 -; JSR OUTBYT -; LDA DETSZ -; JSR OUTBYT -; LDXIM 3 -; JSR OUTSPS -; JSR OUTEN2 ;Rest of entry common with EXAM + LDXIM 3 + JSR OUTSPS + JSR OUTEN2 ;Rest of entry common with EXAM ;END OF ENTRY. PUT CR AT END TO FORCE ;A NEW LINE IF OSASCII'ING AT THE ;CLIENT END, AND EXTERM CHAR. TO ;INDICATE END OF DATA. -;v1.23 -30 - LDAIM CR JSR OUTCH LDAIM EXTERM diff --git a/FileServer/SRC/FileServer/Uade0D b/FileServer/SRC/FileServer/Uade0D new file mode 100644 index 0000000..e6c0f08 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade0D @@ -0,0 +1,793 @@ + OPT UADE0D ;FILE > Uade0D + TTL File server file UADE0D + +;******************************** +;* DIRMAN UTILITIES * +;******************************** + +;******** GETDIR ROUTINE ********* + +;GETDIR: LOADS THE DIRECTORY SPECIFIED BY A FILE TITLE. + +;EXIT: A = RC +;DIRSTA = ADDR OF DIR IN MEMORY + +;IF TITLE = OR +;TITLE = +;THEN load 'current dir' #set by INITDV# +;ELSE call RETENT #retrieve entry# +;check that entry is for a directory +;DIRSIN := SIN of current entry +;load new current directory +;FI + +;NOTE that GETDIR in cases where an error occurs +;will UNLOCK anything that it loaded. + + [ 1=0 +GETDIR + STZ DIRFLG + ] +GETDRD ROUT + JSR TSTROT ;$? + BEQ #50 + JSR TSTERM ;$? + BEQ #50 + + INY ;**20/5/87** test pseudo-directory + LDAIY NAMPTR + DEY + CMPIM TERMIN ;**20/5/87** single char only + BNE #20 + LDAIY NAMPTR + JSR Testpd + BEQ #50 + +20 BIT DIRFLG + BMI #30 + JSR RETENT + [ $CMOS + BRA #40 + | + JMP #40 + ] + +30 JSR RETEND +40 BNE #60 + JSR Tsparn ;See if it is parent + BEQ #45 + JSR TSTDIR ;SEE IF ITS A DIR-TSTDIR WILL UNLOCK IF REQD. + BNE #60 + JSR SETSIN +45 JSR UNLOCK +50 JSR LOADDR ;Unlocked if any error +60 RTS + +;CHKTIT: CHECKS THE SYNTAX OF A FILE TITLE. +;ENTRY: NAMPTR => PTR TO FILE TITLE, +;TO BE RECOGNISED. + +;EXIT : A = RC (0=>SUCCESS) +;LASTNM => ADDRESS OF THE LAST +;TEXT NAME IN THE FILE TITLE. + +;::=$|<file name> +;<file name)::= <text name><title component> +;<title component>::=<terminator>|<separator><file name> + +CHKTIT ROUT + [ $CMOS + LDAIM &3C + TRB DIRWC ;top bits only + | + LDA DIRWC + ANDIM &C3 + STA DIRWC ;top bits only + ] + LDYIM 0 ;Y:=PTR TO CHAR + STY DIRTMP ;counter for loop here + JSR SETLST ;SETUP LASTNM + LDAIY NAMPTR + CMPIM ROOT + BEQ #00 ;**20/5/87** check pseudo-directories also + JSR Testpd + BNE #20 ;SEE IF ITS A <file name> +00 INY + LDAIY NAMPTR + CMPIM SEPART ;IS IT A <separator> + BEQ #10 + CMPIM TERMIN ;IS IT A <terminator> + BEQ #40 + [ $CMOS + BRA #55 ;RC:=INVALID SEPARATOR + | + BNE #55 ;RC:=INVALID SEPARATOR + ] +;TRY TO RECOGNISE <file name> + +10 INY +20 STY DIRTMP+1 ;save offset + JSR SETLST ;SETUP LASTNM +30 JSR CHKTEX ;RECOGNISE <text name> + BNE #60 + LDAIY NAMPTR + CMPIM TERMIN + BNE #50 + + INC DIRTMP + LDX DIRTMP + CPXIM 2 + BEQ #40 ;match here + + LDA DIRWC ;last level here + ANDIM &3F + BIT DIRWC + BVC #35 + ORAIM &80 +35 STA DIRWC + LDY DIRTMP+1 ;restore Y + [ $CMOS + BRA #30 ;do loop again + | + JMP #30 ;do loop again + ] + +40 LDAIM 0 ;RC := 0 + RTS + +50 CMPIM SEPART + BEQ #10 +55 LDAIM DRERRA +60 RTS + +;CHKTEX: RTN TO RECOGNISE <text name> + +CHKTEX ROUT + LDXIM NAMLNT ;X:=MAX NO. OF CHARS IN <text name> +10 LDAIY NAMPTR + CMPIM &21 + BCC #40 + CMPIM &7F + BCS #40 ;Nope => error + + BIT DIRWC + BPL #20 + CMPIM "*" + BEQ #30 + CMPIM "#" + BEQ #30 + +20 CMPIM """" ;** 21/9/83 ** + BEQ #40 + CMPIM ":" + BEQ #40 + CMPIM "*" + BEQ #40 + CMPIM "." + BEQ #40 + CMPIM "#" + BEQ #40 ;Nope => error + CMPIM "$" + BEQ #40 ;** 18/9/84 ** +30 INY + DEX + BNE #10 +40 LDAIM 0 + CPXIM NAMLNT ;TEST LENGTH OF <text name> + BNE #50 + LDAIM DRERRA ;INVALID TEXT NAME +50 TAX ;SET FLAGS + RTS + +SETLST ROUT + TYA ;RTN TO SETUP LASTNM + CLC + ADC NAMPTR + STA LASTNM + LDA NAMPTR+1 + ADCIM 0 + STA LASTNM+1 + RTS + +;FNDTEX: SEARCH CUR DIR FOR NAME IN TXTNAM. +;N.B. DIR ENTRIES ARE SORTED, +;KEY=<file title>. + +;ENTRY: DIRSTA=STORE ADDR OF DIR TO BE SEARCHED. + +;EXIT : A=0 => NAME FOUND +;PREVEN => PTR TO PREVIOUS ENTRY +;CRNTEN => PTR TO CURRENT ENTRY + +FNDTEX ROUT + JSR INTPRE ;PREVEN := addr of 1st entry + [ $CMOS + STZ WILD1 ;flag for wild cards + | + LDAIM 0 + STA WILD1 ;flag for wild cards + ] +10 JSR SETCRN + BEQ #30 ;end of dir ? + LDYIM DRTITL + LDXIM 0 + + JSR #50 ;look up name with wild cards + BCS #40 + PHP + LDA WILD1 + BNE #15 + PLP + BMI #30 + PHP +15 PLP +FNDTEZ JSR MOVCRN + [ $CMOS + BRA #10 ;repeat until end + | + JMP #10 ;repeat until end + ] + +30 LDAIM DRERRC + RTS + +40 LDAIM 0 + RTS ;exit ok + +50 LDAAX TXTNAM + CMPIM "*" + BNE #80 + INC WILD1 + INX + [ $CMOS +60 PHX + PHY + JSR #50 + PLY + PLX + | +60 TXA + PHA + TYA + PHA + JSR #50 + PLA + TAY + PLA + TAX + ] + BCS #95 + INY + CPYIM 12 + BCC #60 + +70 LDAAX TXTNAM + CMPIM &20 + BEQ #95 + CMPIM &0D + BEQ #95 + CPXIM 10 ;returns C=1 at end-of-name + RTS + +80 CPYIM 12 + BCS #70 + JSR CPCHAR + BNE #90 + INX + INY + BNE #50 + +90 CLC +95 RTS + +CPCHAR ROUT + CMPIM "#" + BEQ #10 + JSR CAPS + PHA + LDAIY CRNTEN + JSR CAPS + STA WILD2 + PLA + CMP WILD2 + RTS + +10 INC WILD1 ;set flag + LDAIY CRNTEN ;must NOT match a space + CMPIM SPACE + PHP + PLA + EORIM 2 ;flip Z flag + PHA + PLP ;return Z=1 if not a space + RTS + +CAPS ROUT + STA WILD2 + CMPIM "A" + BCC #10 + CMPIM "z"+1 + BCS #10 + CMPIM "Z"+1 + BCC #30 + CMPIM "a" + BCS #20 +10 SEC + [ $CMOS + BRA #30 + | + BCS #30 + ] + +20 CLC +30 LDAIM &F9 + RORA + RORA + RORA + AND WILD2 + RTS + +INTPRE LDA DIRSTA ;PREVEN := DIRSTA + STA PREVEN + LDA DIRSTA+1 + STA PREVEN+1 + RTS + +MOVCRN LDA CRNTEN ;PREVEN := CRNTEN + STA PREVEN + LDA CRNTEN+1 + STA PREVEN+1 + RTS + +SETCRN CLC ;RTN TO SETUP CRNTEN (CURRENT ENTRY) PTR + LDYIM DRLINK + LDAIY PREVEN + ADC DIRSTA + STA CRNTEN + INY + LDAIY PREVEN + ADC DIRSTA+1 + STA CRNTEN+1 + LDYIM 0 + LDAIY PREVEN + INY + ORAIY PREVEN ;IF [PREVEN] = 0 THEN A:=0 + RTS + +;INITDV: INITIALISES SEVERAL DIRMAN VARIABLES. + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE + +;FUNCTION:- + +;DRUSIN => PTR TO USERINFO +;MCNUMB => MACHINE NO OF CALLER +;NAMPTR => PTR TO FILE TITLE +;DRDISC => SELECTED DISC NUMBER +;DIRACC => IF CHAR[0] OF FILE TITLE = ROOT +; THEN IF SYST PRIVILEGED +; THEN OWNER ACCESS +; ELSE ANYBODY ACCESS +; FI +; ELIF CHAR[0] OF FILE TITLE = "^" +; THEN ACCESS OF PARENT DIRECTORY +; ELIF CHAR[0] OF FILE TITLE = "&" +; THEN OWNDER ACCESS +; ELIF CHAR[0] OF FILE TITLE = "%" +; THEN CURRENT ACCESS TO LIBRARY DIRECTORY +; ELSE ACCESS TO CURRENTLY SELECTED DIR +; FI ! TYPDIR + +;DIRSIN => IF DISC NAME PRESENT +; THEN SIN OF ROOT DIRECTORY ON NAMED DISC +; ELIF CHAR[0] OF FILE TITLE = ROOT +; THEN SIN OF ROOT DIRECTORY +; ELIF CHAR[0] OF FILE TITLE = "^" +; THEN SIN OF PARENT DIRECTORY +; ELIF CHAR[0] OF FILE TITLE = "&" +; THEN SIN OF UFD +; ELIF CHAR[0] OF FILE TITLE = "%" +; THEN SIN OF LIBRARY +; ELSE SIN OF CURRENTLY SELECTED DIR +; FI +;TDATE => IF ROOT DIR IMPLIED +; THEN DATE ROOT DIR CREATED (SEE MAPTB) +; FI +;DIRSTT := 0 START BLK NO + +;EXIT: A = RC + +INITDV ROUT + LDYIM ARGB + LDAIY ARGPTR + STA DRUSIN + INY + LDAIY ARGPTR + STA DRUSIN+1 ;DRUSIN:=PTR TO USER INFO + + INY + LDAIY ARGPTR + STA NAMPTR + INY + LDAIY ARGPTR + STA NAMPTR+1 ;NAMPTR := PTR TO FILE TITLE + + LDYIM UTMCNO + LDAIY DRUSIN + STA MCNUMB + INY + LDAIY DRUSIN + STA MCNUMB+1 + INY + LDAIY DRUSIN ;**25/12/86** + STA MCNUMB+2 ;MCNUMB := MACHINE NO OF CALLER + +;PRECEEDED BY A DISC NAME? + + LDYIM 0 + LDAIY NAMPTR + CMPIM DISCIN ;DISC NAME PRESENT?? + BEQ #00 + JMP #60 + +00 LDXIM DNAMLN ;X:=MAX LENGTH OF DISC NAME + LDAIM :LSB:DRDSNM + STA MOVTO + LDAIM :MSB:DRDSNM + STA MOVTO+1 ;MOVTO:=PTR TO DRDSNM BUFFER + + INC NAMPTR + BNE #05 + INC NAMPTR+1 ;NAMPTR+:=1 + +05 LDAIY NAMPTR +10 STAIY MOVTO ;COPY DISC NAME INTO DRDSNM + CMPIM TERMIN ;TERMINATOR? + BEQ #40 + CMPIM SEPART ;SEPARATOR? + BNE #20 + LDAIM TERMIN + STAIY MOVTO ;TERMINATE DISC NAME + INY + LDAIY NAMPTR ;**20/5/87** disc name, must prohibit "^","&", "%" + CMPIM "^" ;**20/5/87** as these have a disc name implied + [ Pseudods = Yes + BEQ #15 + CMPIM "&" + BEQ #15 + CMPIM "%" + ] + BNE #40 +15 INY + LDAIY NAMPTR ;**20/5/87** check single char names only + DEY + CMPIM TERMIN + BEQ #22 + CMPIM SEPART + BEQ #22 + [ $CMOS + BRA #40 + | + BNE #40 + ] + +20 INY + LDAIY NAMPTR + DEX + BNE #10 + LDAIM TERMIN + STAIY MOVTO ;TERMINATE DISC NAME + LDAIY NAMPTR + CMPIM TERMIN + BEQ #40 + CMPIM SEPART + BEQ #30 +22 LDAIM DRERRA ;BAD FILE TITLE +25 RTS + +30 INY +40 CLC + TYA + ADC NAMPTR + STA NAMPTR + BCC #50 + INC NAMPTR+1 ;NAMPTR:=PTR TO FILE TITLE + +;GET DISC NUMBER OF NAMED DISC + +50 LDAIM &A + JSR SETRTN + INY + LDAIM :LSB:DRDSNM + STAIY NEWARG + INY + LDAIM :MSB:DRDSNM + STAIY NEWARG ;PTR TO DISC NAME + JSR MAPMAN ;MAPMAN.DISCNAME->DISCNUMB + BNE #25 + LDYIM ARGB + LDAIY NEWARG + STA DRDISC + INY + LDAIY NEWARG + STA DRDISC+1 + [ $CMOS + BRA #65 + | + JMP #65 + ] + +;WAS ROOT DIR SPECIFIED + +60 JSR TSROOT ;IS ROOT DIR SPECIFIED? + BNE #75 + LDYIM UTDISC + LDAIY DRUSIN + STA DRDISC + INY + LDAIY DRUSIN + STA DRDISC+1 ;DRDISC:=SELECTED DISC NUMBER +65 LDAIM ANYBDY+TYPDIR + STA DIRACC ;DIRACC:=ANYBDY!TYPDIR + LDYIM UTPRIV + LDAIY DRUSIN + ANDIM SYSTPV + BEQ #70 + LDAIM OWNER+TYPDIR + STA DIRACC ;DIRACC:=OWNER!TYPDIR + +;GET SIN OF ROOT ON SELECTED DISC + +70 LDAIM 4 ;(SIN OF ROOT) + JSR SETDSA ;PLACE DISC NO ON NEWARG STACK + JSR MAPMAN ;CALL MAPMAN.SINOFROOT + BNE #84 + LDYIM ARGB + LDAIY NEWARG + STA DIRSIN + INY + LDAIY NEWARG + STA DIRSIN+1 + INY + LDAIY NEWARG + STA DIRSIN+2 ;DIRSIN:=SIN OF ROOT + INY + LDAIY NEWARG + STA TDATE ;TDATE:=DATE OF ROOT + INY + LDAIY NEWARG + STA TDATE+1 + [ $CMOS + BRA #82 + | + JMP #82 + ] + +;LOOK UP ACCESS, DISC NUMBER, & SIN OF SELECTED DIR + + [ Pseudods = Yes +72 LDA UMHUFD ;**20/5/87** "&", get ufd + [ $CMOS + BRA #78 + | + JMP #78 + ] + +74 LDA UMHLIB ;**20/5/87** "%", get lib + [ $CMOS + BRA #78 + | + JMP #78 + ] + ] + +75 INY ;**20/5/87** check pseudo-directory names + LDAIY NAMPTR ;**20/5/87** single char only + CMPIM SEPART + BEQ #76 + CMPIM TERMIN + BNE #77 +76 DEY + LDAIY NAMPTR + CMPIM "^" ;**20/5/87** parent directory + BEQ #85 + [ Pseudods = Yes + CMPIM "&" ;**20/5/87** ufd + BEQ #72 + CMPIM "%" ;**20/5/87** lib + BEQ #74 + ] +77 LDYIM UTHSLD ;OFFSET OF HANDLE FOR SELECTED DIR + LDAIY DRUSIN ;A:=HANDLE FOR SELECTED DIR +78 JSR FNDHND ;FIND HANDLE IN HANDTB + BNE #84 + + LDYIM HTACC ;check that its a dir + LDAIY HNDPTR + ANDIM TYPDIR + BNE #80 + LDAIM DRERRD ;OBJECT NOT A DIR + RTS + +80 CLC + LDA HNDPTR ;HNDPTR SETUP BY FNDHND + ADCIM HTACC + STA MOVFRM + LDA HNDPTR+1 + ADCIM 0 + STA MOVFRM+1 + LDAIM :LSB:DIRACC + STA MOVTO + LDAIM :MSB:DIRACC + STA MOVTO+1 + LDXIM 6 ;DIRACC,DRDISC,DIRSIN + JSR MOVE ;COPY INFO FROM HANDTB INTO DIRMAN VARIABLES + +82 LDAIM 0 + STA DIRSTT + STA DIRSTT+1 ;DIRSTT:=0 +84 RTS + +85 JSR #77 ;**20/5/87** initialise to current directory + LDYIM HTDISC ;**1/6/88** "^" for parent directory + LDAIY HNDPTR ;**1/6/88** get current disc + STA DRDISC + INY + LDAIY HNDPTR + STA DRDISC+1 + JSR RETPAR ;**20/5/87** retrieve parent + BNE #84 + JSR UNLOCK + [ $CMOS + BRA #82 + | + BEQ #82 + ] + +LDDR ROUT + LDAIM 5 + JSR SETRTN + JSR SETDIR + JSR MAPMAN ;MAPMAN.SIZEINFO + BNE #10 + LDYIM ARGB + LDAIY NEWARG + STA DIRSZE + INY + LDAIY NEWARG + STA DIRSZE+1 ;DIRSZE:=SIZE OF DIR IN BYTE + INY + LDAIY NEWARG + STA DIRSZE+2 + INY + LDAIY NEWARG + STA DIRBKS + INY + LDAIY NEWARG + STA DIRBKS+1 ;DIRBKS:=NO OF BLOCKS USED BY DIR + [ $CMOS + STZ DIRSTT + STZ DIRSTT+1 ;DIRSTT:=0(START ADDR IN DIR) + | + LDAIM 0 + STA DIRSTT + STA DIRSTT+1 ;DIRSTT:=0(START ADDR IN DIR) + ] + JSR SETDIR + LDAIM 1 + JSR SETRTN ;STRMAN.DISC ADDR TO STORE ADDR + JSR STRMAN + BNE #10 + LDYIM ARGB + LDAIY NEWARG + STA DIRSTA + STA DPTRLD + INY + LDAIY NEWARG + STA DIRSTA+1 + STA DPTRLD+1 ;DPTRLD:=PTR TO 1ST BYTE OF DIR + LDAIM 0 ;RC:=0 +10 RTS + +; Load directory. It will be locked if return code is zero, unlocked if not. + +LOADDR ROUT + JSR LDDR ;TRY AND LOAD THE DIR + BNE #20 + +;SEE IF LEADING AND TRAILING SEQUENCE NUMBERS MATCH +;IN THE PROCESS SETUP DPTRTR (PTR TO LAST BYTE OF DIR) + + LDYIM DRSQNO + LDAIY DPTRLD + TAX ;X:=LEADING SQ. NO. + SEC + LDA DPTRLD + SBCIM 1 + STA DPTRTR + LDA DPTRLD+1 + SBCIM 0 + STA DPTRTR+1 ;DPTRTR:=DPTRLD-1 + CLC + LDA DPTRTR + ADC DIRSZE + STA DPTRTR + LDA DPTRTR+1 + ADC DIRSZE+1 + STA DPTRTR+1 ;DPTRTR:=PTR TO LAST BYTE OF DIR + TXA + LDYIM 0 + CMPIY DPTRTR ;A:=TRAILING SQ. NO. + BEQ #10 + LDAIM DRERRB ;BROKEN DIR + JMP UNLOCK ;Unlock and return **25/12/86** + +10 LDYIM ARGA + LDAIY NEWARG ;RC +20 RTS + +SETDIR LDAIM :LSB:DRDISC ;MOVE DISC NO->DIRBKS ONTO NEWARG STACK + STA MOVFRM + LDAIM :MSB:DRDISC + STA MOVFRM+1 + CLC + LDA NEWARG + ADCIM ARGB + STA MOVTO + LDA NEWARG+1 + ADCIM 0 + STA MOVTO+1 + LDXIM 9 + JMP MOVE + +STAARG LDA DIRSTA ;MOVE DIRSTA ONTO ARG STACK FOR STRMAN + LDYIM ARGB + STAIY NEWARG + STA GENPTR ;SETUP GENPTR FOR MRKDRT RTN + LDA DIRSTA+1 + INY + STAIY NEWARG + STA GENPTR+1 + RTS + +UNLOCK ROUT + PHA + LDAIM 3 ;CALL STRMAN.UNLOCK + JSR SETRTN + JSR STAARG + JSR STRMAN + BEQ #10 + JSR INTERR +10 PLA + RTS + +ENSRIT LDAIM 2 ;CALL STRMAN.ENSURE FOR DIR + JSR SETRTN + JSR STAARG + JSR MRKDRT + LDYIM ARGD + LDAIM UNLKIT + STAIY NEWARG ;ENSURE AND UNLOCK THE OBJECT + +;NOW INC SEQ. NOS. + + LDYIM DRSQNO + LDAIY DPTRLD + [ $CMOS + INCA ;A:=NEW SQ NO + STAIY DPTRLD ;1ST SQ NO + STAI DPTRTR ;LST SQ NO + | + TAX + INX + TXA ;A:=NEW SQ NO + STAIY DPTRLD ;1ST SQ NO + LDYIM 0 + STAIY DPTRTR ;LST SQ NO + ] + + JMP STRMAN + + LNK UADE0DA diff --git a/FileServer/SRC/FileServer/Uade0DA b/FileServer/SRC/FileServer/Uade0DA new file mode 100644 index 0000000..3de589b --- /dev/null +++ b/FileServer/SRC/FileServer/Uade0DA @@ -0,0 +1,601 @@ + OPT UADE0D ;FILE > Uade0DA + TTL File server file UADE0DA + +;RETDIR: RETRIEVE DIR BEFORE LAST COMPONENT OF FILE TITLE. + +;EXIT: A = RC +;NAMPTR = PTR TO LAST TEXT NAME. +;DIRSTA = ADDR OF DIR IN MEMORY + +;FUNCTION: IF SYNTAX OF FILE TITLE OK +;THEN RETRIEVE PENULTIMATE DIR +;FI + +RETDIR ROUT + JSR CHKTIT ;CHECK SYNTAX OF FILE TITLE + BNE #70 + +;attempts to delete "$" fail in eyecatching manner +;**20/5/87** and "^", "&", "%" and "@" too! + + JSR ISLAST ;**23/1/87** check if name is last + BNE #10 + JSR TSTROT ;look for ROOT here + BEQ #02 + JSR TESTPD ;**20/5/87** check pseudo-directories also + BNE #10 + JSR TSTTER + BNE #10 +02 LDAIM DRERRC ;'not found', well it cant be can it ! +05 RTS ;exit with error + +10 JSR LOADDR ;LOAD CURRENT DIR + BNE #05 ;Fail, return (dir not locked **25/12/86**) + +;IF THE FIRST NAME=ROOT or "^" or "$" or "%" or "@" +;THEN WE HAVE TO ADJUST NAMPTR + + JSR TSROOT ;SEE IF FIRST NAME COMPONENT=ROOT + BEQ #15 + JSR Testpd ;**20/5/87** or pseudo-directory + BNE #20 + INY + LDAIY NAMPTR + CMPIM SEPART ;**20/5/87** must be single char + BNE #20 +15 CLC + LDA NAMPTR + ADCIM 2 + STA NAMPTR + BCC #20 + INC NAMPTR+1 ;NAMPTR+:=2 + +20 JSR ISLAST ;Check if last text name + BEQ #60 + +;COPY NEXT TEXT NAME COMPONENT INTO TXTNAM +;& MOVE NAMPTR TO NEXT COMPONENT + + JSR LOADTX + + JSR Tsparn ;**2/6/87** test for parent "^" + BNE #30 + JSR Unlock + JSR Retpar ;**2/6/87** retrieve parent + BEQ #20 + RTS + +;CHECK DIR EXISTS + +30 JSR FNDTEX ;SEARCH DIR FOR TEXT NAME + BNE #45 + +;FIRST CHECK THAT ITS A DIR + +40 JSR ISDIR + BEQ #50 + JSR FNDTEZ ;try on next match + BEQ #40 +45 JMP UNLOCK ;unlock the entry + +;NOW PREPARE FOR NEXT DIR TO BE LOADED, AND +;UNLOCK THE CURRENT ONE + +50 JSR SETSIN ;DIRSIN := SIN OF NEXT DIR TO BE LOADED +55 JSR UNLOCK ;UNLOCK CURRENT DIR + JSR LOADDR ;**2/6/87** load next directory + BNE #70 + [ $CMOS + BRA #20 + | + BEQ #20 + ] + +60 LDAIM 0 +70 RTS + +ISDIR LDYIM DRACCS + LDAIY CRNTEN ;check type found + ANDIM TYPDIR + CMPIM TYPDIR + RTS + +ISLAST ROUT ;Test if name is last + LDA NAMPTR + CMP LASTNM + BNE #10 + LDA NAMPTR+1 + CMP LASTNM+1 +10 RTS ;Exit with Z set correctly + +RETENT ROUT + JSR RETDIR ;FIND APPROPRIATE DIR + BNE #10 + JSR LOADTX ;COPY LAST TEXTNAME INTO TXTNAM + LDAIM &02 ;**2/6/87** is "^" allowed? + BIT Dirwc + BEQ #00 + JSR Tsparn ;**2/6/87** test for parent "^" + BNE #00 + JSR Unlock + [ $CMOS + BRA Retpar + | + JMP Retpar + ] + +00 JSR FNDTEX ;SEARCH FOR LAST TEXT NAME + BEQ #10 +05 JSR UNLOCK +10 RTS + +RETEND JSR RETENT ;**20/5/87** + BNE #10 + JSR Tsparn ;**8/8/87** test for parent "^" + BEQ #10 +20 JSR ISDIR + BEQ #10 + JSR FNDTEZ + BEQ #20 + [ $CMOS + BRA #05 + | + BNE #05 + ] + +Tsparn ROUT ;**1/6/87** + LDA TXTNAM ;**1/6/87** test for parent "^" + CMPIM "^" + BNE #10 + LDA TXTNAM+1 + CMPIM &20 +10 RTS + +; Retrieve parent directory **23/1/87** + +RETPAR ROUT + JSR LOADDR ;**23/1/87** load current directory + BNE #50 + LDYIM DRSTAR+DRLINK ;**23/1/87** special unchained entry? + LDAIM &FF + CMPIY DPTRLD + BNE #60 + INY + CMPIY DPTRLD + BNE #60 + LDYIM DRSTAR+DRSIN ;**23/1/87** extract parent SIN only + LDAIY DPTRLD + STA DIRSIN + INY + LDAIY DPTRLD + STA DIRSIN+1 + INY + LDAIY DPTRLD + STA DIRSIN+2 + JSR UNLOCK ;release current directory + + LDYIM UTPRIV ;now select access + LDAIY DRUSIN + ANDIM SYSTPV ;same as now if system user + BNE #30 + LDAIM 4 ;MAPMAN.SINOFROOT + JSR SETDSA + JSR MAPMAN ;**1/6/88** revised tests + BNE #70 ;fail if can't locate root + LDYIM ARGB ;check if parent is root directory + LDAIY NEWARG + CMP DIRSIN + BNE #30 ; no, will use same access as child + INY + LDAIY NEWARG + CMP DIRSIN+1 + BNE #30 + INY + LDAIY NEWARG + CMP DIRSIN+2 + BNE #30 +20 LDAIM TYPDIR+ANYBDY ;root, access reverts now to public + STA DIRACC + +30 JSR LOADDR ;load parent directory + BNE #50 + LDAIM 0 +50 RTS + +60 LDAIM DRERRC ;parent not found +70 JMP UNLOCK ;unlock and exit + +TSTDIR ROUT + JSR ISDIR ;Test CRNTEN for directory + BEQ #10 + JSR UNLOCK ;UNLOCK CURRENT DIR IF ENTRY NOT FOR A DIR + LDAIM DRERRD ;RC := OBJECT NOT A DIR +10 RTS + +SETSIN LDYIM DRSIN ;DIRSIN := SIN OF CRNTEN + LDAIY CRNTEN + STA DIRSIN + INY + LDAIY CRNTEN + STA DIRSIN+1 + INY + LDAIY CRNTEN + STA DIRSIN+2 + RTS + +;MAXACC: CALC ACCESS TO A PARTICULAR DIR ENTRY +;EXIT: A:=OBJACC:= TYPE & MAX ACCESS TO OBJECT + +MAXACC ROUT + LDYIM DRACCS + LDAIY CRNTEN + ANDIM TLAMSK + STA OBJACC ;OBJACC:=TYPE & ACCESS SPECIFIED IN DIR ENTRY + ANDIM TYPDIR + BEQ #10 + +;ITS A DIR SO OBJACC := TYPDIR!DIRACC + + LDA DIRACC + ANDIM OWNER ;** 30/9/84 ** + ORA OBJACC + [ $CMOS + BRA #30 + | + JMP #30 + ] + +;ITS A FILE SO +;IF (DIRACC & OWNER) = OWNER +;THEN TYPFIL!((OBJACC SHR 2)&RDWRACC)!(OBJACC&RDWRAC) +;ELSE TYPFIL ! (OBJACC & RDWRAC) +;FI + +10 LDA DIRACC + ANDIM OWNER + BEQ #20 ;BRANCH IF ANYBODY + +;OWNER ACCESS + + LDA OBJACC + LSRA + LSRA + ANDIM RDWRAC + TAX ;X:= A & RDWRAC + LDA OBJACC + ANDIM LOCKED ;** 28/3/85 ** + STA OBJACC + TXA + ORA OBJACC + [ $CMOS + BRA #30 + | + JMP #30 + ] + +;ANYBODY ACCESS + +20 LDA OBJACC + ANDIM RWLACC ;ANYBODY ACCESS +30 STA OBJACC + LDA DIRACC + ANDIM OWNER + ORA OBJACC ;Include owner bit in result + STA OBJACC + RTS + +LOADTX ROUT + LDAIM :LSB:TXTNAM ;MOVE TEXT NAME INTO TXTNAM + STA TXTPTR + LDAIM :MSB:TXTNAM + STA TXTPTR+1 + LDYIM 0 +10 LDAIY NAMPTR + CMPIM TERMIN + BEQ #20 + CMPIM SEPART + BEQ #20 + STAIY TXTPTR ;MOVE CHAR INTO TXTNAM + INY + [ $CMOS + BRA #10 + | + JMP #10 + ] + +;MAKE NAMPTR PT TO 1ST CHAR AFTER <terminator>|<separator> + +20 TYA + SEC ;ADD 1 + ADC NAMPTR + STA NAMPTR + BCC #30 + INC NAMPTR+1 + +;FILL REMAINDER OF TXTNAM WITH SPACES + +30 CPYIM NAMLNT+1 ;** 5/9/84 ** + BEQ #40 + LDAIM SPACE + STAIY TXTPTR + INY + BNE #30 +40 RTS + +SETFRE ROUT + CLC ;SETUP DIRFRE (ADDR OF FREE CHAINPTR IN DIR) + LDA DIRSTA + ADCIM DRFREE + STA DIRFRE + LDA DIRSTA+1 + ADCIM 0 + STA DIRFRE+1 + LDYIM 0 ;TEST FOR [DIRFRE]=0 + LDAIY DIRFRE + INY + ORAIY DIRFRE ;A=0 IF NO FREE ENTRIES + RTS + +;DELCHK: RTN TO CHECK WHETHER A DIR ENTRY MAY BE DELETED + +;EXIT: A = RC + +;FUNCTION: IF ENTRY 'LOCKED' +;THEN ERROR (I.E. A>0) +;ELIF OBJECT OPEN +;THEN ERROR +;ELIF TYPE = TYPDIR ANDF NOT EMPTY +;THEN ERROR +;ELSE OBJECT MAY BE DELETED (I.E. A = 0) +;FI + +DELCHK ROUT + LDYIM DRACCS + LDAIY CRNTEN + ANDIM LOCKED + BEQ #10 + LDAIM DRERRG + RTS + +;SAVE SIN OF OBJECT TO BE DELETED + +10 JSR CRNSIN ;OBJSIN := SIN OF OBJECT + +;SEE IF THE OBJECT TO BE DELETED IS OPEN + + LDAIM 2 + JSR SETDSA ;SETUP DISC NO AND SIN ON NEWARG STACK + JSR RNDMAN ;RNDMAN.INFO + BNE #20 + LDAIM DRERRI ;CANNOT DELETE OPENED OBJECT + RTS + +;IF IT IS DIR MAKE SURE THAT IT IS EMPTY + +20 LDYIM DRACCS + LDAIY CRNTEN + ANDIM TYPDIR + BEQ #50 ;Exit; A=0 and Z set + +;LOAD FIRST BLOCK OF THE DIR +;TO SEE IF IT IS EMPTY + + LDAIM 1 + JSR SETDSA ;PLACE DISC NO AND SIN ON NEWARG STACK + LDYIM ARGG + LDAIM 0 + STAIY NEWARG ;LS + INY + STAIY NEWARG ;MS(BLK NO) START BLOCK NO := 0 + INY ;Y:=ARGI + [ $CMOS + INCA ;one + STAIY NEWARG + INY + DECA ;zero + | + LDAIM 1 + STAIY NEWARG + INY + LDAIM 0 + ] + STAIY NEWARG ;NO OF BLOCKS TO BE LOADED := 1 + JSR STRMAN + BNE #50 + LDYIM ARGB + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 ;GENPTR:=STORE ADDRESS OF LOADED DIR + LDYIM DRFRST ;PTR TO FIRST DIR ENTRY IN USE + LDAIY GENPTR + INY + ORAIY GENPTR + PHA ;PUSH A + LDAIM 4 + JSR SETRTN + JSR STRMAN ;STRMAN.FLUSH WINDOW + BEQ #40 + [ $CMOS + PLX + TAX + | + TAX + PLA + TXA + ] + RTS + +40 PLA + BEQ #50 + LDAIM DRERRJ +50 RTS + +FREECH ROUT + JSR SETFRE + LDYIM 0 ;RTN TO PLACE ENTRY ON FREE CHAIN + LDAIY DIRFRE + STAIY CRNTEN + INY + LDAIY DIRFRE + STAIY CRNTEN ;[CRNTEN] := [FREE ENTRY PTR] + + SEC ;CALC RELATIVE ADDRESS OF CRNTEN + LDA CRNTEN + SBC DIRSTA + LDYIM 0 + STAIY DIRFRE + LDA CRNTEN+1 + SBC DIRSTA+1 + INY + STAIY DIRFRE ;[DIRFRE] := DIR ENTRY + RTS + +; SETDSA: Put arg, DRDISC & OBJSIN on NEWARG stack +; SETDSN: Put just DRDISC & OBJSIN on NEWARG stack +; Exits: Y=ARGF + +SETDSA ROUT + JSR SETRTN ;Put arg on NEWARG stack **25/12/86** +SETDSN LDYIM ARGB ;PUT DISC NO & OBJSIN ON NEWARG STACK + LDA DRDISC + STAIY NEWARG + INY + LDA DRDISC+1 + STAIY NEWARG + INY + LDA OBJSIN + STAIY NEWARG + INY + LDA OBJSIN+1 + STAIY NEWARG + INY + LDA OBJSIN+2 + STAIY NEWARG + RTS + +ARGDSN LDYIM ARGB ;PLACE DISC NO & OBJSIN ON ARGPTR STACK + LDA DRDISC + STAIY ARGPTR + INY + LDA DRDISC+1 + STAIY ARGPTR + INY + LDA OBJSIN + STAIY ARGPTR + INY + LDA OBJSIN+1 + STAIY ARGPTR + INY + LDA OBJSIN+2 + STAIY ARGPTR + RTS + +CRNSIN LDYIM DRSIN ;OBJSIN := SIN OF CRNTEN + LDAIY CRNTEN + STA OBJSIN + INY + LDAIY CRNTEN + STA OBJSIN+1 + INY + LDAIY CRNTEN + STA OBJSIN+2 + RTS + +SINSZE LDAIM 5 ;CALL MAPMAN.SIZE FOR OBJSIN + JSR SETDSA + JMP MAPMAN + +RETDSZ LDYIM INFDIS ;MOVE DISC NO & SIZE INTO INFPTR + LDA DRDISC + STAIY INFPTR + INY + LDA DRDISC+1 + STAIY INFPTR + JSR SINSZE + PHA ;Record MAPMAN return code + LDYIM ARGB ;MOVE SIZE ON NEWARG STACK TO INFPTR + LDAIY NEWARG + LDYIM INFSZE + STAIY INFPTR + LDYIM ARGC + LDAIY NEWARG + LDYIM INFSZE+1 + STAIY INFPTR + LDYIM ARGD + LDAIY NEWARG + LDYIM INFSZE+2 + STAIY INFPTR ;MS(SIZE) + PLA ;Restore MAPMAN return code + RTS + +TSROOT ROUT + LDYIM 0 ;TEST FOR <root> + LDAIY NAMPTR + CMPIM ROOT + RTS + +TSTROT ROUT + JSR TSROOT ;TEST FOR <root><terminator> +00 BNE #10 +TSTTER INY +05 LDAIY NAMPTR + CMPIM TERMIN +10 RTS + +TSTERM LDYIM 0 ;is file title <term> omly? + [ $CMOS + BRA #05 + | + BEQ #05 + ] + +TSTPAR ;**23/1/87** + LDYIM 0 + LDAIY NAMPTR + CMPIM "^" ;check parent directory name + [ $CMOS + BRA #00 + | + JMP #00 + ] + +TESTPD ROUT ;**2/6/87** test pseudo-directory name + CMPIM "^" + [ Pseudods = Yes + BEQ #10 + CMPIM "&" + BEQ #10 + CMPIM "%" + BEQ #10 + CMPIM "@" + ] +10 RTS + +TSTOWN ROUT + LDA DIRACC ;TEST FOR OWNER ACCESS + ANDIM OWNER + CMPIM OWNER + BEQ #10 + LDAIM DRERRE ;INSUFFICIENT ACCESS +10 RTS + +SETGEN LDA DIRSTA ;GENPTR := [DIRSTA] + STA GENPTR + LDA DIRSTA+1 + STA GENPTR+1 + RTS + +;OUTPUT LOAD AND EXECUTE ADDRESSES +;FOR THE CURRENT ENTRY. + +OUTLEX LDYIM DRLOAD + JSR OUTHEX + JSR OUTSP + LDYIM DREXEC + JSR OUTHEX + LDXIM 3 + JMP OUTSPS ;SPACE AND EXIT + + LNK UADE0E diff --git a/FileServer/SRC/FileServer/Uade0E b/FileServer/SRC/FileServer/Uade0E new file mode 100644 index 0000000..e2836d2 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade0E @@ -0,0 +1,715 @@ + OPT UADE0E ;FILE > Uade0E + TTL File server file UADE0E +;******************************** +;* DIRMAN U T I L I T I E S 2 * +;******************************** + +DETALS ROUT + CLC ;COPY CRNTEN DETAILS INTO INFPTR + LDA CRNTEN + ADCIM DRTITL + STA MOVFRM + LDA CRNTEN+1 + ADCIM 0 + STA MOVFRM+1 + LDYIM INFDIS-1 ;COPY LOAD ADDR -> SIN +10 LDAIY MOVFRM + STAIY INFPTR + DEY + BPL #10 + +;COPY DISC NO & SIZE OF OBJECT INTO DETAILS AREA + + JSR CRNSIN ;OBJSIN := SIN OF CRNTEN + JMP RETDSZ + +;********** MAKDIR RTN ********** + +;MAKDIR : CREATE A VIRGIN DIR + +;ENTRY: DRDISC = DISC NUMBER +;DIRTMP := SIZE OF DIR REQUIRED(APPROX) +;EXRTN := SIN of parent, or zero if none (not coded) + +;EXIT: A := RC +;ARGPTR STACK INITIALISED FOR PRESERVE + + +MAKDIR ROUT + LDAIM 1 ;MapMan.CreateSpace + JSR SETDSA ;PUT DISC NO ON NEWARG STACK + LDYIM ARGD + LDA DIRTMP + STAIY NEWARG ;LS(SIZE) + INY + LDA DIRTMP+1 ;DIRTMP := SIZE OF NEW DIR + STAIY NEWARG ;CS(SIZE) + INY + LDA DIRTMP+2 + STAIY NEWARG ;MS(SIZE) + + JSR JUSING ;pass pointer to user info **3/10/84** + + JSR MAPMAN ;MAPMAN.CREATE SPACE + BNE #20 + + [ $CMOS + JSR GETDTE ;Read date & time + ] + +;SETUP DETAILS ON ARGPTR STACK FOR RETAIN RTN + + LDYIM ARGD + LDAIY NEWARG + STA DIRSIN + LDYIM ARGQ + STAIY ARGPTR + LDYIM ARGE + LDAIY NEWARG + STA DIRSIN+1 + LDYIM ARGR + STAIY ARGPTR + LDYIM ARGF + LDAIY NEWARG + STA DIRSIN+2 ;DIRSIN := SIN OF NEW DIR + LDYIM ARGS + STAIY ARGPTR + JSR DIROBJ ;OBJSIN := SIN OF NEW DIR + + LDYIM ARGF + LDAIM 0 +10 STAIY ARGPTR ;LOAD ADDR:=EXEC ADDR:=0 + INY + CPYIM ARGN + BCC #10 + + LDAIM TYPDIR+LOCKED + STAIY ARGPTR ;TYPE & ACCESS INFO + + INY + LDA DATE + STAIY ARGPTR + INY + LDA DATE+1 + STAIY ARGPTR ;DATE CREATED + + JSR LOADDR ;LOAD DIR INTO STORE + BEQ #30 + + CMPIM DRERRB + BEQ #25 ;Press on here, but relock directory + +;IF WE CANNOT LOAD IT THEN CLEAN UP + + PHA ;REMEMBER RC + JSR ARGOBJ ;OBJSIN:=SIN OF NEWDIR + JSR DELB ;FREE SPACE ALLOCATED IN DISC MAP + PLA +20 RTS + +;CLEAR DRFRST -> DRENTS + +25 JSR INCCNT ;Relock broken directory **25/12/86** + +30 LDA DIRSTA + STA CLRPTR + STA GENPTR + LDA DIRSTA+1 + STA CLRPTR+1 + STA GENPTR+1 + LDYIM DRSTAR+DRENSZ ;**23/1/87** zero first entry also + LDXIM 0 + JSR CLRSTR + +;Make dummy unchained first entry for parent ptr **23/1/87** + + LDYIM DRSTAR + LDAIM &FF + STAIY GENPTR ;mark entry not chained + INY + STAIY GENPTR + LDYIM DRSTAR+DRSIN + LDA EXRTN ;copy SIN of parent + STAIY GENPTR + INY + LDA EXRTN+1 + STAIY GENPTR + INY + LDA EXRTN+2 + STAIY GENPTR + +;NOW FORMAT IT + + CLC + LDA DIRSTA + ADCIM DRSTAR+DRENSZ ;**23/1/87** + STA CRNTEN + LDA DIRSTA+1 + ADCIM 0 + STA CRNTEN+1 ;CRNTEN PTS TO FIRST ENTRY TO BE MARKED FREE + JSR FORMAT + BEQ #40 + + JSR DELOBJ ;DELETE THE OBJECT + +40 RTS + +;FORMAT: RTN TO INCREASE THE NO OF FREE ENTRIES IN A DIR + +;ENTRY:OBJSIN = SIN OF DIR +;CRNTEN = PTR TO NEXT POSN TO BE PLACED ON FREE CHAIN +;DIRTMP = SIZE OF DIR (IN BYTES) +;DPTRLD = PTR TO FIRST BYTE OF DIR + +;EXIT : A = RC +;N.B. CRNTEN & DIRTMP ARE DESTROYED +;DPTRTR IS UPDATED + + +FORMAT ROUT + JSR DECCRN ;CRNTEN -:=DRENSZ + + CLC ;WE WANT TO SUBTRACT ONE AS WELL + LDA DIRTMP + SBCIM DRENSZ + STA DIRTMP + BCS #05 + DEC DIRTMP+1 ;N.B. WE SUBTRACT ONE FOR THE TRAILING SQ NO + +05 CLC + LDA DIRTMP + ADC DIRSTA + STA DIRTMP + LDA DIRTMP+1 + ADC DIRSTA+1 + STA DIRTMP+1 ;DIRTMP:=DIRSTA+DIRSIZE-DRENSZ-1 + +10 JSR INCCRN ;CRNTEN +:= DRENSZ + + LDA DIRTMP + CMP CRNTEN + LDA DIRTMP+1 + SBC CRNTEN+1 + BCC #20 ;BRANCH IF CRNTEN > DIRTMP + + JSR FREECH ;PLACE CRNTEN ON THE FREE CHAIN + [ $CMOS + BRA #10 + | + JMP #10 + ] + +;NOW SHRINK THE DIR TO AN 'EXACT' SIZE + +20 LDAIM 3 + JSR SETDSA ;PLACE DISCNO & OBJSIN ON NEWARG STACK + + LDA CRNTEN + STA DIRSZE + STA DPTRTR + LDA CRNTEN+1 + STA DIRSZE+1 ;DIRSZE := CRNTEN + STA DPTRTR+1 ;DPTRTR := PTR TO LAST BYTE OF DIR (SQ.NO.) + INC DIRSZE ;ADD ON 1 FOR TRAILING SQ. NO. + BNE #30 + INC DIRSZE+1 ;DIRSZE := CRNTEN + 1 +30 SEC + LDA DIRSZE + SBC DIRSTA + STA DIRSZE + LDYIM ARGG + STAIY NEWARG ;LS(SIZE) + LDA DIRSZE+1 + SBC DIRSTA+1 + STA DIRSZE+1 ;DIRSZE := CRNTEN + 1 - DIRSTA + INY + STAIY NEWARG ;CS(SIZE) + INY + LDAIM 0 + STAIY NEWARG + + JSR JUSINF ;** 3/10/84 ** + + JSR MAPMAN ;MAPMAN.CHANGESIZE + BNE #40 + +;NOW INSERT TRAILING SQ. NO. AND THEN + + LDYIM DRSQNO + LDAIY DPTRLD + [ $CMOS + STAI DPTRTR ;SET TRAILING SQ. NO. = LEADING SQ. NO. + | + LDYIM 0 + STAIY DPTRTR ;SET TRAILING SQ. NO. = LEADING SQ. NO. + ] + +;NOTE FORMAT DOES NOT ENSURE THE DIR OR THE MAP. +;SO WE MARK THE DIR DIRTY IN CASE IT GETS REMOVED FROM THE CACHE. + + LDA DPTRLD + STA GENPTR + LDA DPTRLD+1 + STA GENPTR+1 + JSR MRKDRT ;MARK IT DIRTY + + LDAIM 0 ;RC := 0 + +40 RTS + +JUSING LDYIM ARGB ;21/12/84 + LDAIY ARGPTR ;passed in original call + TAX + INY + LDAIY ARGPTR + + LDYIM ARGH + STAIY NEWARG + DEY + TXA + STAIY NEWARG + RTS + +DECCRN ROUT + SEC ;CRNTEN -:= DRENSZ + LDA CRNTEN + SBCIM DRENSZ + STA CRNTEN + BCS #10 + DEC CRNTEN+1 +10 RTS + + + +;********* EXAMINE UTILS ******** + + +;ALL INFO IN MACHINE READABLE FORM +;AND FILE TITLE. + +;ON ENTRY, INFPTR POINTS TO RESULT +;AREA. ON EXIT, INFPTR POINTS TO +;BYTE AFTER RESULT. + +EXRTNA ROUT + JSR MOVEFT ;10 BYTE FILE TITLE + + LDYIM DRLOAD + [ $Level3 + LDXIM 0 + ] + +;MOVE ALL OTHER INFO FROM DIR. TO +;RESULT AREA. + +05 LDAIY CRNTEN + [ $Level3 + STAIX INFPTR + | + STAI INFPTR + ] + JSR INCIPT + INY + CPYIM DRENSZ + BNE #05 + JSR CRNSIN ;GET SIN OF CURRENT ENTRY + JSR SINSZE ;GET SIZE ON STACK + BNE #20 + LDYIM ARGB ;COPY SIZE -> INFO AREA + [ $Level3 + LDXIM 0 + ] +10 LDAIY NEWARG + [ $Level3 + STAIX INFPTR + | + STAI INFPTR + ] + JSR INCIPT + INY + CPYIM ARGE + BNE #10 + [ $Level3 + TXA ;Successful exit + | + LDAIM 0 ;Successful exit + ] +20 RTS + + +;ALL INFORMATION, FORMATTED IN CHAR. STRING + +EXRTNB ROUT + JSR OUTENT ;Output entry details + BNE #10 + +ERTNBZ LDAIM ENTTRM ;Terminate string + JSR OUTCH + LDAIM 0 +10 RTS + + +OUTENT ROUT + JSR MOVEFT ;Print file title + JSR OUTSP + JSR OUTLEX + JSR OUTSZE + BNE #10 ;Map error +OUTEN2 JSR OUTACC + LDXIM 4 + JSR OUTSPS + JSR OUTDAT + JSR OUTSIN + LDAIM 0 ;Successful exit +10 RTS + + +;FILE TITLE + TITLE LENGTH, M/C READABLE + +EXRTNC ROUT + [ $CMOS + LDAIM NAMLNT + STAI INFPTR ;File title length + | + LDXIM 0 + LDAIM NAMLNT + STAIX INFPTR ;File title length + ] + JSR INCIPT + JSR MOVEFT ;Note pointer to locn. after f.t. + LDAIM 0 + RTS ;Successful exit + + + +;FILE TITLE + ACCESS IN CHAR FORM + +EXRTND ROUT + JSR MOVEFT + JSR OUTSP + JSR OUTACC + [ $CMOS + BRA ERTNBZ + | + JMP ERTNBZ + ] + +;*** MINOR UTILITIES *** + + +;MOVE FILE TITLE FROM DIRECTORY TO +;!INFPTR. ON EXIT, INFPTR POINTS TO +;BYTE AFTER FILE TITLE. + +MOVEFT ROUT + LDYIM DRTITL + [ $CMOS +10 LDAIY CRNTEN + STAI INFPTR + | + LDXIM 0 +10 LDAIY CRNTEN + STAIX INFPTR + ] + INY + JSR INCIPT + CPYIM DRTITL+NAMLNT + BCC #10 + RTS + + +OUTSPS JSR OUTSP + DEX + BNE OUTSPS + RTS + + + +;OUTPUT A SPACE AND INCREMENT INFPTR. + +OUTSP LDAIM SPACE + [ $CMOS +OUTCH STAI INFPTR + JMP INCIPT ;INCREMENT POINTER + | +OUTCH STX DMSTX + LDXIM 0 + STAIX INFPTR + LDX DMSTX + JMP INCIPT ;INCREMENT POINTER + ] + +;FOUR BYTES IN REVERSE ORDER IN HEX +;FROM CURRENT DIR. ENTRY + +;Y POINTS TO CURRENT ENTRY DATA. + +OUTHEX INY + INY + INY + [ $CMOS + STZ FILLFL ;Set space fill ON + | + LDAIM 0 + STA FILLFL ;Set space fill ON + ] + LDAIY CRNTEN + JSR OUTBYT ;TOP DIGIT + DEY + LDAIY CRNTEN + JSR OUTBYT + DEY + LDAIY CRNTEN + JSR OUTBYT ;TWO DIGITS + DEY + LDAIY CRNTEN ;Fall into OUTBYT + + +;OUTPUT TOP OF A IN HEX + +OUTBYT ROUT + PHA + LSRA + LSRA + LSRA + LSRA + JSR OUTDIG + + PLA +OUTDIG ANDIM &F + BNE #10 ;Non-zero, don't worry about fill + BIT FILLFL + BPL #10 ;Switch -ev => fill space + LDAIM SPACE + [ $CMOS + BRA OUTCH ;Space and exit + +10 STZ FILLFL ;Printing a digit, so switch leading 0's off + | + BNE OUTCH ;Space and exit + +10 PHA + LDAIM 0 + STA FILLFL ;Printing a digit, so switch leading 0's off + PLA + ] + CMPIM &A + BCC #20 + ADCIM 6 +20 ADCIM &30 + [ $CMOS + BRA OUTCH + | + BNE OUTCH + ] + +;THREE BYTE SIN IN HEX + +OUTSIN LDYIM DRSIN+2 + [ $CMOS + STZ FILLFL + | + LDAIM 0 + STA FILLFL + ] + + LDAIY CRNTEN + JSR OUTBYT + DEY + LDAIY CRNTEN + JSR OUTBYT + DEY + [ $CMOS + STZ FILLFL ;Switch leading spaces off + LDAIY CRNTEN + BRA OUTBYT + | + LDAIM 0 + STA FILLFL ;Switch leading spaces off + LDAIY CRNTEN + JMP OUTBYT + ] + +;OUTPUT DATE TO INFPTR IN DD/MM/YY FORMAT + +OUTDAT ROUT + LDYIM DRDATE + LDAIY CRNTEN + + PHA ;**24/2/88** + ANDIM &1F ;**24/2/88** Isolate day of month + JSR OUTDEC + + LDAIM ":" + JSR OUTCH + + PLA ;**24/2/88** + ANDIM &E0 ;**24/2/88** Year high order + STA Fillfl ;**24/2/88** + LDYIM DRDATE+1 + LDAIY CRNTEN + PHA + ANDIM &F + JSR OUTDEC ;MONTH + LDAIM ":" + JSR OUTCH + + PLA + LSRA + LSRA + LSRA + ORA Fillfl ;**24/2/88** + LSRA + CLC + +;ADD TO GET BASEYR + + ADCIM BASEYR + CMPIM 100 ;**24/2/88** Year 20xx? + BCC #10 + SBCIM 100 +10 JSR OUTDEC + JMP OUTSP + + + +;OUTPUT A IN DECIMAL. NOTE A IS +;ASSUMED <100 COZ ROUTINE ONLY +;USED IN WRITING DATE. + +OUTDEC ROUT + LDXIM &FF ;TOP DIGIT IS IN X + SEC +10 INX + SBCIM &A + BCS #10 ;IF >=10, CARRY ON + ADCIM &A + PHA + TXA ;OUTPUT TOP DIGIT + JSR #20 + PLA +20 ORAIM "0" ;CONVERT TO CHAR. + JMP OUTCH + + + +;OUTPUT ACCESS BYTE AS A PADDED +;CHAR STRING, 7 BYTE LONG. ON +;EXIT, INFPTR POINTS TO BYTE AFTER +;ACCESS STRING. + +OUTACC ROUT + LDYIM DRACCS ;OFFSET IN DIR. ENTRY + LDAIY CRNTEN + ASLA ;ONE LEFT SO ACCESS BITS ROTATED INTO B.7 + LDXIM 0 + LDYIM 0 + +;LOOP ROUND FIRST FOUR ACCESS FIELDS + +10 JSR OACCCH + INX + CPXIM 4 + BNE #10 + + PHA + LDAIM "/" + JSR OUTCH + PLA + + JSR OACCCH ;OWNER ACCESS WRITE + INX + +;FINALLY OWNER ACCESS READ + JSR OACCCH + +;NOW PAD TO THE RIGHT, Y BEING +;NO OF SPACES NEEDED. + +20 JSR OUTSP + DEY + BNE #20 + RTS + +ACCTAB = "DLWRWR" + +OACCCH ASLA + PHA + BMI #40 + INY ;ACCESS NOT SET, INC SPACE COUNT + PLA + RTS + +40 LDAAX ACCTAB + JSR OUTCH + PLA + RTS + + + +;GET SIZE FROM MAP AND OUTPUT IN +;HEX (3 BYTES, 5 DIGITS). + +OUTSZE ROUT + JSR CRNSIN ;SET CURRENT SIN TO A VARIABLE + JSR SETDSN ;SET DISC NO. + SIN ON STACK + JSR SINSZE ;GET SIZE FROM MAP + BNE #20 ;ERROR ... EXIT + + LDYIM ARGD ;TOP BYTE OF SIZE + [ $CMOS + STZ FILLFL ;NO leading spaces + | + LDAIM 0 ;NO leading spaces + STA FILLFL + ] + LDAIY NEWARG + JSR OUTBYT ;TOP DIGIT + + DEY + LDAIY NEWARG + JSR OUTBYT + + DEY + LDAIY NEWARG + JSR OUTBYT + LDXIM 3 + JSR OUTSPS + LDAIM 0 ;SUCCESSFUL EXIT + +20 RTS + + + +INCIPT ROUT + INC INFPTR + BNE #10 + INC INFPTR+1 +10 RTS + + + + +;CHECK THAT THE NUMBER OF ENTRIES +;ASKED FOR OF A CERTAIN TYPE OF +;EXAMINE IS LESS THAN MAX. NO. + +ENTTAB = MAXENA + = MAXENB + = MAXENC + = MAXEND + +CHKENS ROUT ;CHKENS + LDX EXARG + CPXIM 4 + BEQ #10 ;Asking for dir.name only, exit, C clear + CMPIM 0 ;**1/5/87** If zero, set to max + BEQ #05 + CMPAX ENTTAB + RTS + +05 LDAAX Enttab ;**1/5/87** load max for exam type +10 CLC + RTS + + LNK UADE0EA diff --git a/FileServer/SRC/FileServer/Uade0EA b/FileServer/SRC/FileServer/Uade0EA new file mode 100644 index 0000000..36aee97 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade0EA @@ -0,0 +1,487 @@ + OPT UADE0E ;FILE > Uade0EA + TTL File server file UADE0EA + +;************ RETAIN ************* + +;RETAIN: RTN TO RETAIN A SIN IN A +;SPECIFIED DIRECTORY, WITH +;GIVEN FILE NAME. + +;ENTRY: ARGUMENTS ON ARGPTR STACK, AS SPECIFIED +;FOR DIRMAN.DRPRES. + +;EXIT : +;A = RC +;ARGB-C DISC NO +;ARGD-F SIN OF OBJECT TO BE DELETED + +;NOTE OBJSIN CAN BE DESTROYED BY RETAIN + +;FUNCTION: + +;IF TYPE = TYPDIR +;THEN PUT LAST COMPONENT OF FILE TITLE IN DIR HEADER +;FI; +;IF ENTRY ALREADY EXISTS +;THEN CHECK THAT IT MAY BE DELETED; +;CHECK THAT TYPES AGREE; +;CALL MAPMAN.ENSURE(MAP) +;NOTE SIN OF OBJECT TO BE DELETED; +;UPDATE DIR ENTRY (all except access - including name); +;ENSURE DIRECTORY UPTO DATE ON DISC; +;RETURN(success,disc no,sin) +;ELIF ROOM FOR A NEW ENTRY +;THEN CALL MAPMAN.ENSURE(MAP); +;UPDATE DIRECTORY; +;ENSURE DIR UPTO DATE ON DISC; +;RETURN(success,0,0) +;ELSE RETURN(directory full) +;FI + +RETAIN ROUT + LDAIM &FF +RETA12 STA TEMPA ;skip DELCHK entry point + JSR LOADTX + LDA TXTNAM ;**1/6/87** prohibit pseudo-directory names + JSR Testpd + BNE #10 + LDA TXTNAM+1 + CMPIM &20 + BNE #10 + LDAIM DRERRA + [ $CMOS + BRA #15 + | + BNE #15 + ] + +10 JSR FNDTEX ;DOES TEXT NAME ALREADY EXIST ? + BNE #40 + +;ENTRY ALREADY EXISTS + + LDA TEMPA ;check entry point + BEQ #25 ;skip if RENAME involved ** 25/9/84 ** + + JSR DELCHK ;CAN IT BE DELETED ? + BEQ #25 +15 JSR UNLOCK ;UNLOCK THE LOADED DIR +20 RTS + +;SEE IF TYPES MATCH + +25 LDYIM ARGN + LDAIY ARGPTR ;TYPE & ACCESS OF OBJECT TO BE PRESERVED + ANDIM TYPE + STA TEMPA + LDYIM DRACCS + LDAIY CRNTEN + STA OBJACC ;OBJACC:=OLD ACCESS FIELD IN DIR + ANDIM TYPE + CMP TEMPA + BEQ #30 + LDAIM DRERRK ;TYPES DON'T MATCH + [ $CMOS + BRA #15 + | + BNE #15 + ] + +30 JSR #45 ;**1/6/88** check entry code and update header + JSR CRNSIN ;OBJSIN:=SIN OF OBJECT TO BE DELETED + JSR COPYDT ;COPY OBJECT DETAILS INTO DIR + JSR COPYNM ;Copy name TXTNAM -> dir. entry + LDYIM DRACCS ;BUT KEEP OLD ACCESS FIELD + LDA OBJACC + STAIY CRNTEN + JSR ARGDSN ;MOVE DISC NO & OBJSIN ONTO ARGPTR STACK + JMP ENSRIT ;STRMAN.ENSURE(DIR) + +;MAKE A NEW DIR ENTRY + +40 JSR SETFRE ;DIRFRE := ADDR OF FREE ENTRY PTR + BNE #50 + JSR UNLOCK + +;THE DIR IS FULL SO TRY AND INCREASE ITS SIZE + + JSR CHZSZE ;INCREASE DIR SIZE + BNE #20 + JSR LOADDR ;RELOAD THE DIR + BEQ #10 ;TRY AGAIN + RTS ;Failed, exit (directory unlocked) **25/12/86** + +45 LDYIM ARGA ;**1/6/88** check if preserve-check only + LDAIY ARGPTR + EORIM 13 ;set zero if so + BEQ #47 ;and go unlock and return + JSR RATDIR ;IF DIR THEN UPDATE NAME IN HEADER + BNE #47 + JSR ENSMAP ;ENSURE MAP OF OBJECT TO BE RETAINED + BNE #47 + RTS + +47 TAY + PLA + PLA + TYA + [ $CMOS + BRA #15 + | + JMP #15 + ] + +50 JSR #45 ;**1/6/88** check entry code and update header + +;REMOVE ENTRY FROM FREE CHAIN AND INSERT +;IT IN APPROPRIATE POSITION, ON THE IN USE CHAIN. + + LDYIM DRLINK + LDAIY PREVEN + STA TEMPA + INY + LDAIY PREVEN + STA TEMPA+1 ;TEMPA := [PREVEN] + + DEY ;Y:= DRLINK + LDAIY DIRFRE + STAIY PREVEN + INY + LDAIY DIRFRE + STAIY PREVEN ;[PREVEN] := [DIRFRE] + + JSR SETCRN ;CRNTEN := STORE ADDRESS OF [DIRFRE] + + LDYIM DRLINK + LDAIY CRNTEN + STAIY DIRFRE + INY + LDAIY CRNTEN + STAIY DIRFRE ;[DIRFRE] := [CRNTEN] + DEY ;Y:=DRLINK + LDA TEMPA + STAIY CRNTEN + INY + LDA TEMPA+1 + STAIY CRNTEN ;[CRNTEN] := TEMPA + +;INCREMENT DIR ENTRY COUNT + + JSR SETGEN ;GENPTR := [DIRSTA] + [ $Level3 + CLC + ] + + LDYIM DRENTS + LDAIY GENPTR + [ $CMOS + INCA + | + ADCIM 1 + ] + STAIY GENPTR + [ $CMOS + BNE #60 + ] + INY + LDAIY GENPTR + [ $CMOS + INCA + | + ADCIM 0 + ] + STAIY GENPTR ;[DIRSTA + DRENTS] +:= 1 + +;COPY TEXT NAME INTO DIR ENTRY + +60 JSR COPYNM + +;COPY DETAILS ON ARGPTR STACK INTO DIR ENTRY + + JSR COPYDT + JSR ENSRIT ;STRMAN.ENSURE(directory) + JSR ARGDSN ;Copy Disc & SIN to stack, then zero SIN + +;CLEAR SIN TO ZERO + + LDAIM 0 + LDYIM ARGD + LDXIM 3 +70 STAIY ARGPTR ;:=0 + INY + DEX + BNE #70 +80 RTS + + +;RATDIR: IF RETAINING A DIR - WE COPY INTO ITS HEADER +;THE LAST COMPONENT OF A FILE TITLE. +;THIS IS THE DIR'S NAME & PROVIDED FOR THOSE +;CLIENTS WANTING TO DISPLAY A DIR'S NAME +;DURING EXAMINE. + +RATDIR LDYIM ARGN + LDAIY ARGPTR + ANDIM TYPDIR + BEQ #80 + +;AS WE ARE RETAINING A DIR WE MUST COPY THE CONTENTS +;OF TXTNAM INTO THE HEADER OF THIS DIR. + + JSR ARGOBJ ;OBJSIN:=SIN OF OBJECT TO BE PRESERVED + JSR SINSZE ;FIND OUT THE DIR'S SIZE + BNE #80 + LDYIM ARGE + LDAIY NEWARG ;LS(NO OF BLOCKS) + PHA + INY + LDAIY NEWARG ;MS(NO OF BLOCKS) + PHA + LDAIM 1 + JSR SETDSA ;PUT DISCNO & OBJSIN ON NEWARG STACK + INY + LDAIM 0 + STAIY NEWARG + INY + STAIY NEWARG ;BLOCK NO. = 0 + PLA + LDYIM ARGJ + STAIY NEWARG ;MS(NO OF BLOCKS) + PLA + DEY ;Y:= ARGI + STAIY NEWARG ;LS(NO OF BLOCKS) + JSR STRMAN ;STRMAN.DISC ADDR->STORE ADDR + BNE #80 + +;NOW THE DIR IS LOADED - SO COPY THE CONTENTS OF +;TXTNAM INTO THE HEADER OF THE DIR + + LDYIM ARGB + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 + CLC + LDA GENPTR + ADCIM DRNAME + STA MOVTO + LDA GENPTR+1 + ADCIM 0 + STA MOVTO+1 + LDAIM :LSB:TXTNAM + STA MOVFRM + LDAIM :MSB:TXTNAM + STA MOVFRM+1 + LDXIM NAMLNT + JSR MOVE + + LDYIM DRSTAR ;**08/02/87** + LDAIM &FF + CMPIY GENPTR ;parent pointer in first entry? + BNE #90 + INY + CMPIY GENPTR + BNE #90 + LDYIM DRSTAR+DRSIN ;yes, update to current parent + LDA DIRSIN + STAIY GENPTR + INY + LDA DIRSIN+1 + STAIY GENPTR + INY + LDA DIRSIN+2 + STAIY GENPTR + +90 JSR MRKDRT ;MARK IT DIRTY + LDAIM 2 + JSR SETRTN ;N.B. STR ADDR ALREADY ON NEWARG STACK + LDYIM ARGD + LDAIM UNLKIT + STAIY NEWARG ;ENSURE & UNLOCK THE DIR + JMP STRMAN + + +;COPY LOAD ADDR -> SIN, WHICH ARE ON ARGPTR STACK, +;INTO THE DIR ENTRY POINTED TO BY CRNTEN. + +COPYDT LDAIM ARGF + STA OFF1 ;Move from offset + LDAIM DRLOAD + STA OFF2 ;Move to offset + LDXIM ARGPTR ;Move from ptr. + LDYIM CRNTEN ;Move to ptr. + LDAIM &E ;Move 14 bytes + JMP MOVBLK + + +;Copy object name from TXTNAM to dir. entry + +COPYNM LDAIM :LSB:TXTNAM + STA MOVFRM + LDAIM :MSB:TXTNAM + STA MOVFRM+1 + CLC + LDA CRNTEN + ADCIM DRTITL + STA MOVTO + LDA CRNTEN+1 + ADCIM 0 + STA MOVTO+1 + LDXIM NAMLNT + JMP MOVE + + +INCCRN ROUT + CLC ;CRNTEN +:= DRENSZ + LDA CRNTEN + ADCIM DRENSZ + STA CRNTEN + BCC #10 + INC CRNTEN + 1 +10 RTS + + +ARGOBJ LDYIM ARGQ ;OBJSIN:=SIN OF OBJECT TO BE PRESERVED + LDAIY ARGPTR + STA OBJSIN + INY + LDAIY ARGPTR + STA OBJSIN+1 + INY + LDAIY ARGPTR + STA OBJSIN+2 + RTS + + +ENSMAP JSR ARGOBJ ;ENSURE OBJECT'S MAP IS UPTO DATE ON DISC +ENSOMP LDAIM 6 + JSR SETDSA ;PUT DISC NO & OBJSIN ON NEWARG STACK + JMP MAPMAN ;MAPMAN.ENSUREMAP + + +DELOBJ ROUT + PHA ;REMOVE NEWDIR FROM CACHTB + JSR ARGOBJ ;OBJSIN:=SIN OF OBJECT WHICH WAS TO BE PRESERVED + + JSR REMOVE ;remove the cache entry + TAX ;save RC + PLA + BNE #10 + TXA ;substitute RC here +10 CMPIM &C9 ;look for 'write protect' + BEQ #30 + PHA + JSR DELB ;rest of DLETIT + TAX ;save RC + PLA ;get old RC + BNE #30 ;skip if there is previous error + TXA ;else return new error +30 RTS + +DELB ROUT + LDAIM 2 + JSR SETDSA + JSR JUSING ;** 21/12/84 ** + JSR MAPMAN ;MAPMAN.FREESPACE + BNE #10 + + LDAIM 6 + JSR SETDSA + JSR MAPMAN ;MAPMAN.ENSURE MAP + BEQ #20 +10 JSR INTERR +20 RTS + +REMOVE LDAIM 5 + JSR SETDSA ;REMOVE OBJSIN FROM CACHE + JMP STRMAN ;STRMAN.REMOVE + + +;INCREASE THE SIZE OF A DIR + +;ENTRY: DIRSIN = SIN OF DIR TO HAVE ITS SIZE CHANGED +;EXIT: A = RC + +CHZSZE ROUT + JSR DIROBJ ;OBJSIN := DIRSIN + JSR REMOVE ;REMOVE OBJSIN FROM THE CACHE + JSR SINSZE + BNE #10 + LDYIM ARGB + LDAIY NEWARG + STA CRNTEN + INY + LDAIY NEWARG + STA CRNTEN+1 ;CRNTEN:=EXACT CURRENT SIZE OF DIR + LDYIM ARGE + LDAIY NEWARG + STA BREGA + INY + LDAIY NEWARG + STA BREGA+1 ;BREGA := NUMBER OF BLOCKS + [ $CMOS + STZ BREGA+2 + | + LDAIM 0 + STA BREGA+2 + ] + JSR MULTBS ;BREGA *:= BLKSZE + CLC + LDA BREGA + ADCIM :LSB:BLKSZE + STA DIRTMP + LDA BREGA+1 + ADCIM :MSB:BLKSZE + STA DIRTMP+1 ;DIRTMP:=SIZEOFDIR+BLKSZE(INTEGRAL NB OF BLKS) + +;TEST FOR MAX SIZE OF DIR ALLOWED + + LDAIM :LSB:MAXDIR + CMP DIRTMP + LDAIM :MSB:MAXDIR + SBC DIRTMP+1 + BCS #20 + LDAIM DRERRM +10 RTS + + +20 LDAIM 3 + JSR SETDSA + INY + LDA DIRTMP + STAIY NEWARG ;LS(NEW SIZE) + INY + LDA DIRTMP+1 + STAIY NEWARG ;CS(NEW SIZE) + INY + LDAIM 0 + STAIY NEWARG ;MS(NEW SIZE) + JSR JUSINF ;** 3/10/84 ** + JSR MAPMAN ;MAPMAN.CHANGESIZE + BNE #30 + JSR LDDR ;LOAD CURRENT DIR + BNE #30 + LDA CRNTEN + BNE #25 + DEC CRNTEN+1 +25 DEC CRNTEN ;CRNTEN-:=1(TO OVERWRITE OLD TRALNG SQ NO) + CLC + LDA DIRSTA + ADC CRNTEN + STA CRNTEN + LDA DIRSTA+1 + ADC CRNTEN+1 + STA CRNTEN+1 ;CRNTEN PTS TO NEXT ENTRY TO BE MADE FREE + JSR FORMAT ;FORMAT DIR + JSR ENSRIT ;ENSURE ITS UPTO DATE ON DISC & UNLOCKIT + BNE #30 + +;ENSURE THE OBJECT MAP + + JSR ENSOMP ;N.B. OBJSIN MUST = SIN OF DIR + BEQ #30 + JSR INTERR +30 RTS + + LNK UADE0F diff --git a/FileServer/SRC/FileServer/Uade0F b/FileServer/SRC/FileServer/Uade0F new file mode 100644 index 0000000..88f6a5a --- /dev/null +++ b/FileServer/SRC/FileServer/Uade0F @@ -0,0 +1,599 @@ + + OPT UADE0F ;> Uade0F + TTL File server file UADE0F + +;********************** +;* A U T M A N * +;********************** + +;AUTMAN: THE AUTHENTICATION MANAGER +;THE PASSWORD FILE CONTAINS A NUMBER +;OF ENTRIES, EACH OF WHICH HAS THE FOLLOWING FORM:- +;0) USERID (10 BYTES) +;1) PASSWORD (6 BYTES) +;4) Free space (4 bytes) +;3) FLAG (1 BYTE) - INUSE & privileges FLAG + +APWIND * 4 ;window size in blocks + +;***** MAIN ROUTINE ***** + +AUTMAN ROUT + LDXIM 10 ;AUTMAN HAS 10 ENTRY POINTS + LDAIM MODAUT ;A:=NAME OF THIS MODULE + JSR ENTRY + [ $Level3 + LDAAX ATRTNS + STA ATJUMP+1 + LDAAX ATRTNS+1 + STA ATJUMP+2 + LDAIM 0 + STA ATDRIV ;**23/1/87** altered in ATNWUS + ] + + LDAIM 9 + STA ATWORK ;**31/10/83** >0 -> dont keep window with empty slot + [ $CMOS + STZ ATDRIV ;**23/1/87** both altered in ATNWUS + ] + JSR SETFS + [ $Level3 +ATJUMP JMP ATJUMP + | + JMIX ATRTNS + ] +ATRTNS + & ATNWUS ;1 => NEW USER + & ATCKPW ;2 => CHECK PASSWORD + & ATSTPW ;3 => SET PASSWORD + & ATDLUS ;4 => DELETE USER + & ATSPRV ;5 => SET PRIVILEGE + & ATREST ;6 => RESTART + & ATSOPT ;7 => SET "USER OPTION" + & ATENS ;8 => Update user disc space in PW file ** 2/10/84 ** + & ATFREE ;9 => Return user disc space + & ATWRIT ;10=> Write user disc space +ATEXIT JMP PREXIT + +PWTITL = "$.PASSWORDS",CR + +;***** ATNWUS ***** + +;ATNWUS: NEW USER - MAKE AN ENTRY IN THE PASSWORD FILE + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO USERID + +;EXIT: ARGA = RC + +;FUNCTION:- +;0) CHECK THAT CALLER HAS SYSTEM PRIV +;1) CHECK THAT USERID DOES NOT EXIST ALREADY +;2) CHECK SYNTAX OF USERID +;3) MAKE AN ENTRY IN PW FILE + +ATNWUE ROUT ;Here to enlarge the file on retry + STA ATWORK ;Nonzero flag + JSR APENRG ;Enlarge the file + BNE ATEXIT + +ATNWUS ROUT + [ $CMOS + STZ DOTFLG + | + LDAIM 0 + STA DOTFLG + ] + JSR CHKPRV ;CHECK THAT CALLER HAS SYSTEM PRIV + BNE ATEXIT + JSR SETAUT ;AUTPTR:=PTR TO USERID + +;SEE IF USERID EXISTS ALREADY + + [ $CMOS + STZ ATDRIV + | + LDAIM 0 + STA ATDRIV + ] + JSR FDUSID + BNE #05 + LDAIM ATERRF ;USERID ALREADY IN USE + [ $CMOS + BRA #27 + | + BNE #27 + ] + +;Find free slot in p/w file + + [ $CMOS +05 STZ ATWORK ;Find free slot + STZ ATDRIV ;**23/1/87** First drive to scan in default + | +05 LDAIM 0 + STA ATWORK ;Find free slot + STA ATDRIV ;**23/1/87** First drive to scan in default + ] + JSR ATOPWF ;**22/5/88** Scan drives to open pw file + BEQ #10 + CMPIM ATERRB ;Not found? + BEQ ATNWUE ;Go enlarge file + [ $CMOS + BRA ATEXIT ;Exit on other error + | + BNE ATEXIT ;Exit on other error + ] + +;Check syntax of userid + +10 LDYIM 0 + STY DOTFLG +20 LDXIM MAXID + LDAIY AUTPTR ;Check first char is alpha only + JSR ISCHAR + BCS #25 ;Nope -> error + +22 LDAIY AUTPTR + JSR ISDCHA ;Is digit or char + BCS #24 ;Nope + INY + DEX + BNE #22 + + LDAIY AUTPTR ;Check char after user id. is terminator +24 CMPIM CR + BEQ #30 ; => continue + + CMPIM DOT + BNE #25 + + LDA DOTFLG + BNE #25 + INC DOTFLG + + CPYIM MAXID+1 ;should have had a "." before this + BCS #25 + INY + BCC #20 + +25 LDAIM ATERRG ;SYNTAX ERROR IN USERID +27 JMP #65 + +;SEE IF THERE IS ANY ROOM IN PW FILE + +30 TYA ;Check if ptr. zero + BEQ #25 ; => bad user id. + EORIM MAXUNM + STA DOTFLG ;0=> maximum length + + LDYIM PWUSID +35 LDAIY AUTPTR ;Set userid (terminated CR) + CMPIM DOT + BNE #40 + + LDX DOTFLG + BNE #40 + + LDA PWFPTR + BNE #37 + DEC PWFPTR+1 +37 DEC PWFPTR + [ $CMOS + BRA #45 + | + JMP #45 + ] + +40 STAIY PWFPTR + CMPIM CR + BEQ #50 ;Check for end of userid +45 INY + BNE #35 + +50 LDA DOTFLG + BNE #55 + + INC PWFPTR + BNE #55 + INC PWFPTR+1 + +55 LDYIM PWPASS + LDAIM TERMIN + STAIY PWFPTR ;PASSWORD = "" + + LDYIM PWFREE ;space allocation always maximum + LDAIM 4 + LDXIM UTFRLN-1 +60 STAIY PWFPTR ;** 2/10/84 ** + INY + DEX + BNE #60 + TXA + STAIY PWFPTR + + LDYIM PWFLAG + LDAIM INUSE + STAIY PWFPTR + JSR MARKDT ;MARK PW FILE DIRTY + LDAIM 0 ; success return code +65 JSR APENFL ;**25/12/86** flush from cache + JMP ATEXIT + +; ATOPWF finds a suitable password file, on disc with +; user's CSD if available, else on lowest numbered drive +; Exit A=0 if OK else error code + +ATOPWF ROUT ;**22/5/88** + JSR CHKPRV ;**23/1/87** To get GENPTR:=Userinfo + BNE #10 + LDYIM UTDISC + LDAIY GENPTR + TAX + INY + LDAIY GENPTR + LDYIM ARGC + STAIY NEWARG ;Selected disc number to stack + TXA + DEY + STAIY NEWARG + LDAIM 15 + JSR SETRTN + JSR MAPMAN ;MAPMAN.MPDRNB + BNE #07 ;use default if error + LDYIM ARGB + LDAIY NEWARG ;Else get selected drive number + STA ATDRIV +07 JSR FDUSID +10 RTS + +;***** ATCKPW ***** + +;ATCKPW: CHECK PASSWORD + +;ENTRY: +;ARGB-C SPARE +;ARGD-E PTR TO USERID FOLLOWED BY PW + +;EXIT: ARGA = RC +;ARGB-E LS User disc space **2/10/84** +;ARGF = FLAG BYTE FROM PW FILE +;ARGG = Drive number of PW file **25/12/86** + +ATCKPW ROUT + JSR SETAUT ;AUTPTR:=PTR TO USERID + JSR FDUSID ;SEARCH PW FILE FOR USERID + BNE #30 + + JSR ATFIND ;is user already logged on + BCC #10 ;yes + + LDAIM PWFREE + LDXIM PWFPTR + [ $CMOS + BRA #20 + | + BNE #20 + ] + +10 JSR ATFPTR ;make pointer + LDAIM UTFREE + LDXIM GENPTR + +20 STA OFF1 + LDYIM ARGPTR + LDAIM ARGB + STA OFF2 + LDAIM 4 + JSR MOVBLK ;general move routine + + LDYIM PWFLAG + LDAIY PWFPTR + LDYIM ARGF + STAIY ARGPTR + INY + LDA ATDRIV + STAIY ARGPTR ;**25/12/86** Set PW file drive + +;NOW SEE IF PASSWORDS MATCH + + JSR CHEKPW + JSR APENFL ;remove the referenced block +30 JMP ATEXIT + +;***** ATSTWP ***** + +;ATSTPW: SET PASSWORD + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO OLD PW FOLLOWED BY NEW PW + +;EXIT: ARGA = RC + +;FUNCTION:- IF OLD PW MATCHES +;EXISTING PW IN PW FILE THEN CHANGE PW. + +ATSTPW ROUT + JSR SETAP1 ;Set AUTPTR to point to user id. + JSR FDUSID ;SEARCH PW FILE FOR USERID + BNE #50 + +;NOW SEE IF OLD PW MATCHES THAT IN PW FILE + + LDYIM ARGD + LDAIY ARGPTR + STA AUTPTR + INY + LDAIY ARGPTR + STA AUTPTR+1 ;AUTPTR USED BY CHEKPW + LDYIM 0 ;Offset for first pw + JSR CHEKP1 + BNE #40 + +;CHECK SYNTAX OF NEW PW + + JSR STEPUR ;Step Y past first PW + STY OFF1 ;OFFSET FOR START OF NEW PW + LDXIM MAXPW +10 LDAIY AUTPTR + CMPIM TERMIN + BEQ #30 + JSR ISDCHA ;Is digit or character ? + BCS #20 ;Nope => error + + INY + DEX + BNE #10 + LDAIY AUTPTR + CMPIM TERMIN + BEQ #30 ;SYNTAX OF PW OK +20 LDAIM ATERRE + [ $CMOS + BRA #40 + | + BNE #40 + ] + +;NOW COPY NEW PW INTO PW FILE + +30 LDAIM PWPASS ;Copy new PW into PW file + STA OFF2 ;Note OFF1 already set + LDXIM AUTPTR ;"From" ptr. + LDYIM PWFPTR ;"To" ptr. + LDAIM MAXPW + JSR MOVBLK + + JSR MARKDT ;MARK PW FILE STORE BUFFER DIRTY + LDAIM 0 +40 JSR APENFL ;clear out the referenced block +50 JMP ATEXIT + +;***** ATDLUS ***** + +;ATDLUS: DELETE USER FROM PASSWORD FILE + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO USERID + +;EXIT: ARGA = RC + +ATDLUS ROUT + JSR ATOPWF ;**22/3/88** open suitable password file + BNE #30 ;**22/3/88** br if error (including unprivileged) + +;NOW CLEAR PASSWORD FILE ENTRY + + LDXIM PWENSZ + LDYIM 0 + TYA +10 STAIY PWFPTR + INY + DEX + BNE #10 + JSR MARKDT ;MARK PW FILE BUFFER DIRTY + LDAIM 0 + JSR APENFL ;Flush PW FILE + +30 JMP ATEXIT + +;***** ATSPRV ***** + +;ATSPRV: SET PRIVILEGE OF A SPECIFIED USER + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO USERID +;ARGF = PRIV. FLAG (0 => user, 1 => syst priv, 2 => low priv) + +;EXIT: ARGA = RC + +ATSPRT = 0, SYSTPV, LOPRIV, 0 ; table for priv bits *** 25/5/86 *** + +ATSPRV + JSR ATOPWF ;**22/3/88** open suitable password file + BNE #30 ;**22/3/88** br if error (including unprivileged) + + LDYIM ARGF + LDAIY ARGPTR ;Load priv. flag + ANDIM 3 ;**25/5/86** mask low value bits + TAY ;**25/5/86** for indexing + LDAAY ATSPRT ;**25/5/86** get priv bit setting + STA ATWORK ;Mask to be OR'd in to PW file + LDYIM PWFLAG + LDAIY PWFPTR + ANDIM NTSYST-LOPRIV ;**25/5/86** Mask off priv bits + [ $CMOS + BRA ATENPW ;OR in ATWORK, ensure PW file + | + JMP ATENPW ;OR in ATWORK, ensure PW file + ] + +;***** ATREST ***** + +;ATREST: AUTMAN.RESTART +;FINDOUT THE DISC NUMBER OF THE DISC +;WHICH CONTAINS THE PASSWORD FILE. +;NOTE IF PW FILE NOT FOUND A <>0 RC IS RETURNED + +;EXIT: ARGA = RC + +ATREST ROUT + LDAIM :LSB:ATUSRI + STA ATUSPT + LDAIM :MSB:ATUSRI + STA ATUSPT+1 ;ATUSPT := PTR TO AUTMAN'S USERINFO AREA + + LDAIM ATERRA ;**25/12/86** Assume the worst + STA ATWORK + + LDYIM UTPRIV + LDAIM SYSTPV+INUSE + STAIY ATUSPT ;AUTMAN HAS SYSTEM PRIV + [ $CMOS + STZ ATDRIV ;DRIVE NUMBER + | + LDAIM 0 + STA ATDRIV ;DRIVE NUMBER + ] +10 LDA ATDRIV ;A:=DRIVE NUMBER + JSR DRVINF ;MAPMAN.DRIVEINFO + BNE #30 ;**14/06/86** + + JSR RETPWF ;RETRIEVE PW FILE + BEQ #20 + CMPIM DRERRC ;IF RC=CANNOT FIND OBJECT THEN TRY NEXT DRIVE + BEQ #30 + JSR INTERR + [ $CMOS +20 STZ ATWORK ;**25/12/86** PW file found + | +20 LDAIM 0 + STA ATWORK ;**25/12/86** PW file found + ] +30 INC ATDRIV ;ATDRIV+:= 1 + LDA ATDRIV ;**14/06/86** + CMP DRIVES ;**14/06/86** + BCC #10 ;**14/06/86** Continue until all checked + LDA ATWORK ;**25/12/86** RC reflects presence of password file + JMP ATEXIT + + +;***** ATSOPT ***** + +;Set user option bits in PW flag (bottom two bits) + +;ENTRY: ARGB/C = ptr. to user info (lo/hi) +; ARGD = new option bits (bottom two bits) + +;EXIT : ARGA = RC + +ATSOPT ROUT + JSR SETAP1 ;Set AUTPTR -> user id. + JSR FDUSID ;Find user id. in pw file + BNE #20 + LDYIM ARGD + LDAIY ARGPTR + ANDIM OPTMSK ;Mask off option bits + STA ATWORK + LDYIM PWFLAG + LDAIY PWFPTR ;Read PW flag byte + ANDIM NTOPT ;Mask off all but option bits + +ATENPW + +;Exit code shared by ATSPRV + + ORA ATWORK ;OR in option bits + CMPIY PWFPTR ;**25/12/86** Has option changed? + BEQ #10 ;**25/12/86** skip marking dirty if not + STAIY PWFPTR + JSR MARKDT ;Mark PW file dirty +10 LDAIM 0 ;Return code (restored over ENSPWF) + JSR APENFL ;Ensure PW file +20 JMP ATEXIT + +;***** ATENS ***** + +;ensure that user disc allocation is up to date +;on disc. + +;ENTRY ARGB,C unset +; ARGD,E pointer to user id +; ARGF,G,H,I value to write + +ATENS ROUT + JSR SETAUT ;point to userid + JSR FDUSID ;lookup the name + BNE #60 + +10 LDAIM ARGF + STA OFF1 + LDAIM PWFREE + STA OFF2 + LDXIM ARGPTR + LDYIM PWFPTR + LDAIM 0 ;**25/12/86** prepare move routine + JSR MOVBLK + LDXIM UTFRLN + JSR COMPAR ;**25/12/86** has field changed? + BEQ #20 ;**25/12/86** no, do not mark dirty + LDXIM UTFRLN ;**25/12/86** yes, copy field + JSR MOVE ;**25/12/86** pointers are preset + JSR MARKDT +20 JSR APENLV ;unlock PW file + LDAIM 0 + [ $CMOS + BRA #60 + | + BEQ #60 + ] + +;***** ATFREE ***** + +;ENTRY ARGB,C ptr to callers info +; ARGD,E ptr to user name + +;EXIT ARGB,C,D,E user free space + +ATFREE JSR ATFIND ;is user logged on + BNE #60 ;some error here + BCC #30 ;user logged on + + JSR SETAUT + JSR FDUSID + BNE #60 ;not found + + LDAIM PWFREE + STA OFF1 + LDXIM PWFPTR + SEC + [ $CMOS + BRA #40 + | + BCS #40 + ] + +30 JSR ATFPTR ;grasp pointer from stack + LDAIM UTFREE + STA OFF1 + LDXIM GENPTR + CLC + +40 LDAIM ARGB + STA OFF2 + LDYIM ARGPTR + + PHP + LDAIM 4 + JSR MOVBLK ;copy the info to the appropriate place + PLP + LDAIM 0 + BCC #60 +50 JSR APENFL + +60 JMP ATEXIT ;and return to caller + + LNK UADE0FA diff --git a/FileStore/SRC/FileStore/Uade0FA.6502 b/FileServer/SRC/FileServer/Uade0FA similarity index 86% rename from FileStore/SRC/FileStore/Uade0FA.6502 rename to FileServer/SRC/FileServer/Uade0FA index 1b94f98..f2b7377 100644 --- a/FileStore/SRC/FileStore/Uade0FA.6502 +++ b/FileServer/SRC/FileServer/Uade0FA @@ -1,4 +1,3 @@ - OPT UADE0F ;> Uade0FA TTL File server file UADE0FA @@ -210,11 +209,16 @@ FDUSID ROUT BEQ #05 CMPIM DRERRC ;**25/12/86** onto next disc if no pw file BEQ #02 + [ $CMOS + RTS + ] -;v1.31 -; RTS - + [ $CMOS 05 STZ DOTFLG ;initialise the flag for every lookup + | +05 LDAIM 0 + STA DOTFLG ;initialise the flag for every lookup + ] LDYIM PWFLAG LDAIY PWFPTR @@ -246,7 +250,11 @@ FDUSID ROUT LDAIY AUTPTR CMPIM TERMIN BEQ #40 ;End and terminated + [ $CMOS BRA #60 ;Not terminated so step on + | + BNE #60 ;Not terminated so step on + ] 20 INC TEMPA INC TEMPB @@ -271,7 +279,11 @@ FDUSID ROUT LDA DOTFLG BEQ #60 ;should have found one by now + [ $CMOS BRA #10 ;Dot found so continue + | + BNE #10 ;Dot found so continue + ] 40 LDAIM 0 ;FOUND IT 42 RTS @@ -281,26 +293,24 @@ FDUSID ROUT ;NOW MAKE PWFPTR POINT TO THE NEXT ENTRY -;v1.23 + [ $Level3 60 JSR APTEST ;check for end-of-window BNE #65 JSR APEND ;check end-of-file BEQ #90 - CMPIM -1 ;check alternative RC - BNE #42 JSR APNEXT ;get next window BNE #42 65 JMP #05 - -;v1.31 -;60 JSR APTEST ;check for end-of-window -; BNE #05 -; JSR APEND ;check end-of-file -; BEQ #90 -; JSR APNEXT ;get next window -; BEQ #05 -; RTS - + | +60 JSR APTEST ;check for end-of-window + BNE #05 + JSR APEND ;check end-of-file + BEQ #90 + JSR APNEXT ;get next window + BEQ #05 + RTS + ] + 90 LDAIM 0 ;**25/12/86** flush final block JSR APENFL BNE #42 @@ -393,12 +403,22 @@ SETAP1 ;Set pointer to callers user id ;**** Initialisation of variables **** APINIT ROUT + [ $CMOS STZ STRPTR STZ STRPTR+1 ;start := 0 STZ PTREND STZ PTREND+1 ;end := 0 STZ PWFPTR STZ PWFPTR+1 ;current := 0 + | + LDAIM 0 + STA STRPTR + STA STRPTR+1 ;start := 0 + STA PTREND + STA PTREND+1 ;end := 0 + STA PWFPTR + STA PWFPTR+1 ;current := 0 + ] JSR RETPWF ;read the password file info BEQ #20 ;first call has no window to release CMPIM DRERRC ;**25/12/86** file not found? @@ -424,18 +444,15 @@ APNEXT LDAIM 0 ;flush previous block SEC LDA ATINF+INFSZE+1 SBC STRPTR+1 ;get number of blocks remaining - -;v1.24 - BNE #30 ;detect zero - LDAIM 1 - BRA #40 ;skip next bit - -;v1.31 - ;LDX ATINF+INFSZE ;**1/6/88** round up if part sector - ;BEQ #30 - ;INCA - ;BEQ #35 ;**1/6/88** in case now 256 - + LDX ATINF+INFSZE ;**1/6/88** round up if part sector + BEQ #30 + [ $Level3 + CLC + ADCIM 1 + | + INCA + ] + BEQ #35 ;**1/6/88** in case now 256 30 CMPIM APWIND BCC #40 ;<= window size left 35 LDAIM APWIND @@ -467,32 +484,16 @@ APNEXT LDAIM 0 ;flush previous block LDAIY NEWARG STA GENPTR+1 ;get number of blocks loaded -;v1.23 - LDA STRPTR ;look for runnimg over page boundary - CMPIM 1-PWENSZ - BCC #50 - DEC PTREND+1 - -50 LDYIM CEBLKS ;from cache descriptor + LDYIM CEBLKS ;from cache descriptor LDAIY GENPTR CLC - ADC PTREND+1 - -;v1.31 -; LDYIM CEBLKS ;from cache descriptor -; LDAIY GENPTR -; CLC -; ADC STRPTR+1 ;**1/6/88** - + ADC STRPTR+1 ;**1/6/88** STA PTREND+1 ;update PTREND by this value PLA - -;v1.31 -; BCC #60 ;**1/6/88** br if password file not too big -; JSR APENFL ;**1/6/88** flush unwanted segment -; LDAIM ATERRB ;**1/6/88** else say entry not found - + BCC #60 ;**1/6/88** br if password file not too big + JSR APENFL ;**1/6/88** flush unwanted segment + LDAIM ATERRB ;**1/6/88** else say entry not found 60 RTS ;return code from STRMAN ;**** Update counters, test end condition **** @@ -514,16 +515,15 @@ APTEST ROUT INC PWFPTR+1 20 - -;v1.31 -; LDA STRPTR+1 ;**1/6/88** test for endfile -; CMP ATINF+INFSZE+1 -; BCC #30 -; LDA STRPTR -; CMP ATINF+INFSZE -; BCS #40 - -;30 + [ $CMOS + LDA STRPTR+1 ;**1/6/88** test for endfile + CMP ATINF+INFSZE+1 + BCC #30 + LDA STRPTR + CMP ATINF+INFSZE + BCS #40 +30 + ] SEC LDA PTREND @@ -539,42 +539,35 @@ APTEST ROUT BCS #50 40 LDAIM 0 50 RTS + ;**** test for end of PW file **** APEND ROUT LDXIM &FF - LDA PTREND - CMP ATINF+INFSZE - BNE #10 LDA PTREND+1 CMP ATINF+INFSZE+1 BCC #10 - INX + BNE #00 + LDA PTREND + CMP ATINF+INFSZE + BCC #10 +00 INX 10 TXA ;set code RTS ;Z shows condition -;v1.31 -;APEND ROUT -; LDXIM &FF -; LDA PTREND+1 -; CMP ATINF+INFSZE+1 -; BCC #10 -; BNE #00 -; LDA PTREND -; CMP ATINF+INFSZE -; BCC #10 -;00 INX -;10 TXA ;set code -; RTS ;Z shows condition ;**** release old window **** APENLV ROUT PHA LDAIM 3 ;STRMAN.unlock window + [ $CMOS BRA #10 ;but leave it in cache - + | + BNE #10 ;but leave it in cache + ] + APENFL PHA LDAIM 4 ;STRMAN.flush old window 10 JSR SETRTN @@ -595,19 +588,15 @@ APENFL PHA 30 RTS ;return error APENRG ROUT ;enlarge the password file + LDA ATINF+INFSZE+2 + BNE #00 + LDA ATINF+INFSZE+1 ;**1/6/88** see if maximal size already + CMPIM &FE ;**1/6/88** won't work if bigger than this + BCC #05 ;**1/6/88** because two byte offsets only used +00 LDAIM ATERRH ;**1/6/88** password file too big + RTS -;v1.31 -; LDA ATINF+INFSZE+2 -; BNE #00 -; LDA ATINF+INFSZE+1 ;**1/6/88** see if maximal size already -; CMPIM &FE ;**1/6/88** won't work if bigger than this -; BCC #05 ;**1/6/88** because two byte offsets only used -;00 LDAIM ATERRH ;**1/6/88** password file too big -; RTS -; -;05 - - LDAIM 14 ;MAPMAN.changesize without space check +05 LDAIM 14 ;MAPMAN.changesize without space check JSR DSCSIA ;put disc number & SIN onto NEWARG stack INY LDAIM 0 @@ -628,13 +617,7 @@ APENRG ROUT ;enlarge the password file LDAIM 13 ;Zero area of disc JSR DSCSIA INY - -;v1.23 - LDAIM 0 ;ATINF+INFSZE - -;v1.31 -; LDA ATINF+INFSZE - + LDA ATINF+INFSZE STAIY NEWARG INY LDA ATINF+INFSZE+1 diff --git a/FileServer/SRC/FileServer/Uade10 b/FileServer/SRC/FileServer/Uade10 new file mode 100644 index 0000000..320e4fd --- /dev/null +++ b/FileServer/SRC/FileServer/Uade10 @@ -0,0 +1,315 @@ + OPT UADE10 ;> Uade10 + TTL File server file UADE10 + + +;********************************** +;* M A P M A N * +;********************************** + +;THE MAP TABLE (MAPTB) CONTAINS :- +;0) DISC NUMBER (2 BYTES) +;1) NO. OF SECTORS/TRACKS ON DISC (2 BYTES) +;2) SIN OF ROOT DIRECTORY (3 BYTES) +;3) DATE ROOT CREATED (2 BYTES) +;DRIVE NUMBER PROVIDES THE OFFSET IN MAPTB. +;POSSIBLE STATES ARE :- + +MAPMAN ROUT + + LDXIM 16 ;MAPMAN ENTRY POINTS + LDAIM MODMAP ;A := NAME OF THIS MODULE + JSR ENTRY + [ $Level3 + LDAAX MPRTNS + STA MPJUMP+1 + LDAAX MPRTNS+1 + STA MPJUMP+2 + LDAIM 20 + JSR SETFS +MPJUMP JMP MPJUMP ;JUMP TO CORRECT ROUTINE + | + LDAIM 20 + JSR SETFS + JMIX MPRTNS ;JUMP TO CORRECT ROUTINE + ] + +;ADDRESSES OF ENTRY POINTS FOR EACH ROUINE +MPRTNS + & MPCRSP ;1 => CREATE SPACE + & MPFRSP ;2 => FREE SPACE + & MPCHSZ ;3 => CHANGE SIZE + & MPSNRT ;4 => SIN OF ROOT + & MPSZIN ;5 => SIZE OF CHAIN + & MPENSR ;6 => WRITE MAP TO DISC + & MPREST ;7 => START + & MPDSNB ;8 => RETURN DISC NUMBER FOR A GIVEN DRIVE + & MPREDR ;9 => RESTART ONE DRIVE + & MPDNNA ;10 => RETURN NUMBER FOR GIVEN DISC NAME + & MPNADN ;11 => RETURN NAME FOR GIVEN DISC NO. + & MPFREE ;12 => FREE AREA ON DISC + & MPZDSK ;13 => ZERO AREA OF DISC + & MPCHSJ ;14 => changesize without space check + & MPDRNB ;15 => return drive number from disc number + & MPFLSH ;16 => flush bit map and map block caches + +MPENSR LDAIM 0 ;Null routine now +MPEXIT JMP PREXIT + +;MPCRSP: CREATE SPACE + +;ENTRY: +;ARGB-C DISC NUMBER +;ARGD-F NUMBER OF BYTES WANTED +;ARGG-H Ptr to user info + +;EXIT: +;ARGA = RC +;ARGB-C DISC NUMBER +;ARGD-F SIN +;ARGG-H Ptr to user info + +;FUNCTION: MAPTB IS SEARCHED TO FIND THE RELEVANT ENTRY. IF THE SECTOR MAP +;IS NOT IN STORE, IT IS READ IN. THE FREE SPACE COUNT IS CHECKED TO SEE IF +;THE SPACE IS AVAILABLE. A CHAIN IS CREATED, THE FREE COUNT IS DECREMENTED +;AND THE MAP IS MARKED DIRTY. THE SIN OF THE FIRST BLOCK OF THE CHAIN IS +;RETURNED. + +MPBLTX = "paMseJ" ;Mapblocktext + +MPCRSP LDYIM ARGG + JSR MPMKFR ;make pointer + LDAIM ARGD + STA MAPTMP + LDAIM UTFREE + STA MAPTMP+1 + LDXIM :LSB:(1-UTFRLN) + SEC + +10 LDY MAPTMP+1 + LDAIY GENPTR + LDY MAPTMP + SBCIY ARGPTR + STAAX MPNWFR-:LSB:(1-UTFRLN) ;save this result + INC MAPTMP + INC MAPTMP+1 + INX + BNE #10 + + LDY MAPTMP+1 + LDAIY GENPTR + SBCIM 0 ;extra length byte + STA MPNWFR+(UTFRLN-1) + + LDAIM MPERRN ;error code to return with insufficient free space + BCC #20 + + [ $CMOS + STZ ERRTYP ;NO ERRORS YET!!! + STZ DNDLTE + | + LDAIM 0 + STA ERRTYP ;NO ERRORS YET!!! + STA DNDLTE + ] + JSR FNDMAP ;GET POINTER TO MAPTB + BEQ #25 +20 JMP #90 +25 LDA Mpdrve ;**24/2/88** check drive for write protect + JSR Testdv + BNE #20 + LDYIM ARGD ;NUMBER OF BYTES REQUIRED + LDAIY ARGPTR + STA DIVPAR + INY + LDAIY ARGPTR + STA DIVPAR+1 + INY + LDAIY ARGPTR + STA DIVPAR+2 + JSR DVDE ;TO FIND MOST LIKELY NUMBER OF BLOCKS + BCC #30 + JMP #85 +30 LDYIM MPCYMP ;READY TO CHECK IF ENOUGH ROOM + LDAIY MAPPTR + STA MPCYPT + INY + LDAIY MAPPTR + STA MPCYPT+1 + SEC + LDYIM 0 + LDAIY MPCYPT + SBC DIVTMP ;FOR NUMBER OF BLOCKS + STAIY MPCYPT + INY + LDAIY MPCYPT + SBC DIVTMP+1 + STAIY MPCYPT + INY + LDAIY MPCYPT + SBC DIVTMP+2 + STAIY MPCYPT + [ $Level3 + BCS #40 ;BRANCH IF NO ROOM +35 JMP #80 +40 JSR FNDCY ;FIND LARGEST CYLINDER + JSR RDBTMP ;READ IN THE BIT MAP + BNE #35 ;**25/12/86** Disc fault - say no room + | + BCC #55 ;BRANCH IF NO ROOM + JSR FNDCY ;FIND LARGEST CYLINDER + JSR RDBTMP ;READ IN THE BIT MAP + BNE #55 ;**25/12/86** Disc fault - say no room + ] + JSR ALBLK ;ALLOCATE ONE BLOCK AS MAP BLOCK + LDA MPTMPA + LDYIM ARGD + STAIY ARGPTR ; SAVE SIN OF NEW FILE + INY + LDA MPTMPA+1 + STAIY ARGPTR + INY + LDA MPTMPA+2 + STAIY ARGPTR + LDA DIVTMP ;ONE LESS BLOCK REQUIRED + BNE #42 + LDA DIVTMP+1 + BNE #41 + DEC DIVTMP+2 +41 DEC DIVTMP+1 +42 DEC DIVTMP + + SEC + JSR RDMPBK ;ALLOCATE SPACE FOR MAP BLOCK + LDA DIVTMP+2 + ORA DIVTMP+1 + ORA DIVTMP ;CHECK IF ONLY ONE BLOCK REQUIRED + BEQ #60 ;BRANCH IF JUST ONE BLOCK + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + LDA MPTMPB ;POINTS TO CYCLINDER MAP + STA MPCYPT + LDA MPTMPB+1 + STA MPCYPT+1 + LDYIM 0 + LDAIY MPCYPT ;CHECK FOR NO FREE SPACR + INY + ORAIY MPCYPT + BEQ #45 ;BRANCH TO GET NEW CYLINDER + JSR ABLKS ; ALLOCATE THE REST OF THE BLOCKS +45 LDA DIVTMP + ORA DIVTMP+1 + ORA DIVTMP+2 ;CHECK IF ALL BLOCKS ALLOCATED + BEQ #60 ;OK IF THEY HAVE + JSR FLBLKS ;OTHERWISE CONTINUE ALLOCATING BLOCKS + BCC #60 ;CARRY CLEAR IF OK +50 LDA ERRTYP + STA DNDLTE + JSR MPDLTE ;CLEAR ALL BLOCKS + JSR ULMB + JSR ENSMB + JSR ENSBM + [ $CMOS +55 BRA #80 ;INDICATE NO ROOM + | +55 JMP #80 ;INDICATE NO ROOM + ] + +60 JSR RDmpbd ;**8/5/87** Read block at ARGD + LDA MAPTMP + STA MPSCPT + STA CBSTA + LDA MAPTMP+1 + STA MPSCPT+1 + STA CBSTA+1 + + LDYIM BLKSN + LDXIM 5 ;mapblock identifier text +70 LDAAX MPBLTX + STAIY MPSCPT + INY + DEX + BPL #70 + + LDYIM BILB + LDA DIVPAR ;FILL IN ODD BYTES + STAIY MPSCPT + INY + LDA DIVPAR+1 + STAIY MPSCPT + JSR MMBWT + JSR ENSBM ;ENSURE THE BIT MAPS + JSR ENSMB ;ENSURE THE MAP BLOCKS + LDA ERRTYP + BNE #50 + [ $CMOS + BRA #90 ;INDICATES ALL WAS WELL + | + BEQ #90 ;INDICATES ALL WAS WELL + ] + +80 CLC + LDYIM 0 + LDAIY MPCYPT + ADC DIVTMP + STAIY MPCYPT + INY + LDAIY MPCYPT + ADC DIVTMP+1 + STAIY MPCYPT + INY + LDAIY MPCYPT + ADC DIVTMP+2 + STAIY MPCYPT + LDA ERRTYP + BEQ #85 + SEC + LDYIM 0 + LDAIY MPCYPT + SBCIM 1 + STAIY MPCYPT ;MAP BLOCK LEFT! + INY + LDAIY MPCYPT + SBCIM 0 + STAIY MPCYPT + INY + LDAIY MPCYPT + SBCIM 0 + STAIY MPCYPT + LDAIM MPERRC + [ $CMOS + BRA #90 + | + BNE #90 + ] + +85 LDAIM MPERRB +90 LDYIM ARGG + JSR MPSETF ;update the user free store if operation ok + JMP MPEXIT + +;MPFLSH; Flush bit map and map block caches. This is done when a disc is to be +; Changed, otherwise we can get confused over who's blocks are cached. + +MPFLSH ROUT ;**26/2/87** + JSR ENSBM ;Ensure all bitmaps + JSR ENSMB ;Ensure all map blocks + JSR SETBM ;Scan all bit map CBs and mark idle + JSR #50 + JSR SETMB ;Scan all map block CBs and mark idle + JSR #50 + JMP MPEXIT + +50 LDX NCBDB +60 LDYIM CAFLG + LDAIM 0 + STAIY GNCBPT ;Zero all flags + JSR ADGNCB + DEX + BNE #60 + TXA + RTS + + + LNK UADE10A diff --git a/FileStore/SRC/FileStore/Uade10A.6502 b/FileServer/SRC/FileServer/Uade10A similarity index 85% rename from FileStore/SRC/FileStore/Uade10A.6502 rename to FileServer/SRC/FileServer/Uade10A index 8dbed15..b9e9a04 100644 --- a/FileStore/SRC/FileStore/Uade10A.6502 +++ b/FileServer/SRC/FileServer/Uade10A @@ -40,16 +40,30 @@ MPCHSZ ROUT LDAIM MPERRN BCC #10 ;exit 'cos there's no room + [ $CMOS BRA #08 + | + BCS #08 + ] MPCHSJ JSR FNDMAP BNE #10 + [ $CMOS 08 STZ ERRTYP ;NO ERRORS STZ DNDLTE STZ MPTMPB STZ MPTMPB+1 STZ MPTMPB+2 STZ SAVSC ;FIRST BLOCK FLAGGED + | +08 LDAIM 0 + STA ERRTYP ;NO ERRORS + STA DNDLTE + STA MPTMPB + STA MPTMPB+1 + STA MPTMPB+2 + STA SAVSC ;FIRST BLOCK FLAGGED + ] JSR MPsetd ;**8/5/87** MPTMPA->ARGD LDAIY ARGPTR ;GET LENGTH IN BYTES STA DIVPAR @@ -69,8 +83,12 @@ MPCHSJ JSR FNDMAP 13 JSR DVDE ;DIVIDE BYTES TO GET BLOCKS BCC #16 LDAIM MPERRB + [ $CMOS BRA #10 - + | + BNE #10 + ] + 16 LDA DIVTMP ;DECREMENT SINCE NO MAP BLOCK REQUIRED BNE #18 LDA DIVTMP+1 @@ -79,10 +97,17 @@ MPCHSJ JSR FNDMAP 17 DEC DIVTMP+1 18 DEC DIVTMP + [ $CMOS STZ MPTMPB STZ MPTMPB+1 STZ MPTMPB+2 - + | + LDAIM 0 + STA MPTMPB + STA MPTMPB+1 + STA MPTMPB+2 + ] + 19 LDA MAPTMP ;ADDRESS OF MAP BLOCK STA MPMBPT LDA MAPTMP+1 @@ -122,8 +147,12 @@ MPCHSJ JSR FNDMAP STA MPTMPA+2 CLC JSR RDMPBK ;READ IN NEW MAP BLOCK + [ $CMOS BRA #19 ;**8/5/87** - + | + JMP #19 ;**8/5/87** + ] + 26 CLC ; KEEP ADDING UP NUMBER OF BLOCKS LDYIM 3 LDAIY MPMBPT @@ -149,7 +178,11 @@ MPCHSJ JSR FNDMAP LDA MPMBPT+1 ADCIM :MSB:ENSZ STA MPMBPT+1 + [ $CMOS BRA #20 + | + JMP #20 + ] 30 LDA MPTMPB ;NOW SEE ABOUT THE SIZE CMP DIVTMP @@ -225,8 +258,14 @@ MPCHSJ JSR FNDMAP INY STAIY MPMBPT 40 ;FIND CYLINDER NUMBER + [ $CMOS STZ MPTMPC ;ZERO CYLINDER COUNT STZ MPTMPC+1 + | + LDAIM 0 + STA MPTMPC ;ZERO CYLINDER COUNT + STA MPTMPC+1 + ] 43 SEC LDYIM MPSPCY LDA MPTMPE @@ -243,7 +282,11 @@ MPCHSJ JSR FNDMAP INC MPTMPC BNE #43 INC MPTMPC+1 + [ $CMOS BRA #43 + | + JMP #43 + ] 46 JSR RDBTMP ;READ THE RELEVANT BIT MAP BEQ #47 @@ -272,7 +315,11 @@ MPCHSJ JSR FNDMAP STA MPTMPD BCS #50 DEC MPTMPD+1 + [ $CMOS BRA #50 + | + JMP #50 + ] 56 LDA MPTMPB PHA ; SAVE THIS COUNT @@ -293,13 +340,22 @@ MPCHSJ JSR FNDMAP 66 LDA MPTMPB ;CHECK IF ALL BLOCKS HAVE BEEN FREED BNE #67 DEC MPTMPB+1 + [ $CMOS 67 DECA - STA MPTMPB + | +67 SEC + SBCIM 1 + ] + STA MPTMPB ORA MPTMPB+1 BEQ #73 ; ZERO WHEN ALL DEALLOCATED PLA PLP ;GET VALUES BACK + [ $CMOS BRA #63 ;JUMP BACK TO FREE NEXT + | + JMP #63 ;JUMP BACK TO FREE NEXT + ] 70 STAIY MPSCPT ;SAVE THIS VALUE LDXIM 8 ;SET UP FOR WHOLE BYTE @@ -310,7 +366,11 @@ MPCHSJ JSR FNDMAP RORA ;SET UP FOR FREEING BLOCKS PHP PHA + [ $CMOS BRA #66 + | + JMP #66 + ] 73 PLA PLP ;CLEAR VALUES ON STACK @@ -349,7 +409,12 @@ MPCHSJ JSR FNDMAP LDA MPSCPT+1 ADCIM :MSB:ENSZ STA MPSCPT+1 + [ $CMOS STZ MPTMPE ;don't delete this map block + | + LDAIM 0 + STA MPTMPE ;don't delete this map block + ] JSR CLRBLK 90 JSR ULBM JSR ENSMB @@ -415,52 +480,26 @@ NEEDMR ROUT BEQ #30 ; EMPTY MAP BLOCK SO ALLOCATE FROM SIN 20 SEC LDA MPMBPT - -;v1.23 - SBCIM ENSZ + PHA + SBCIM :LSB:ENSZ STA MPMBPT - LDA MPMBPT + 1 - SBCIM /(ENSZ ) - STA MPMBPT + 1 - LDYIM 0 ; GET A CURRENT DISC ADDRESS + LDA MPMBPT+1 + PHA + SBCIM :MSB:ENSZ + STA MPMBPT+1 + LDYIM 0 ; GET A CURRENT DISC ADDRESS LDAIY MPMBPT STA MPTMPA INY LDAIY MPMBPT - STA MPTMPA + 1 + STA MPTMPA+1 INY LDAIY MPMBPT - STA MPTMPA + 2 - CLC - LDA MPMBPT - ADCIM ENSZ + STA MPTMPA+2 + PLA + STA MPMBPT+1 ;**1/7/88** restore pointer + PLA STA MPMBPT - LDA MPMBPT + 1 - ADCIM /(ENSZ ) - STA MPMBPT + 1 - -;v1.31 -; PHA -; SBCIM :LSB:ENSZ -; STA MPMBPT -; LDA MPMBPT+1 -; PHA -; SBCIM :MSB:ENSZ -; STA MPMBPT+1 -; LDYIM 0 ; GET A CURRENT DISC ADDRESS -; LDAIY MPMBPT -; STA MPTMPA -; INY -; LDAIY MPMBPT -; STA MPTMPA+1 -; INY -; LDAIY MPMBPT -; STA MPTMPA+2 -; PLA -; STA MPMBPT+1 ;**1/7/88** restore pointer -; PLA -; STA MPMBPT - 30 JSR DIVSEC ; FIND CYLINDER FROM SIN LDA MPTMPB ;GET CYLINDER TO SOMEWHERE USEFUL STA MPTMPC @@ -486,8 +525,12 @@ NEEDMR ROUT JSR FLBLKS ; FILL IN THE REST OF THE BLOCKS BCS #40 ; BRANCH IF ALL WENT WELL JSR ENSBM + [ $CMOS BRA CSEND - + | + JMP CSEND + ] + 40 LDA SAVPTB ; IT FAILED SO DEALLOCATE ANY BLOCKS STILL ALLOCATED STA MPTMPA ; GET SIN BACK LDA SAVPTB+1 @@ -498,7 +541,12 @@ NEEDMR ROUT STA MPSCPT LDA SAVPTA+1 STA MPSCPT+1 + [ $CMOS STZ MPTMPE ; LEAVE CURRENT MAP BLOCK ALONE + | + LDAIM 0 + STA MPTMPE ; LEAVE CURRENT MAP BLOCK ALONE + ] JSR CLRBLK ; TIDY UP 50 CLC LDYIM 0 @@ -516,11 +564,19 @@ NEEDMR ROUT LDA ERRTYP BEQ #60 LDAIM MPERRC + [ $CMOS 55 BRA MPCHEN + | +55 BNE MPCHEN + ] 60 LDAIM MPERRB ; FLAG NO ROOM + [ $CMOS BRA MPCHEN - + | + BNE MPCHEN + ] + CSEND JSR RDmpbd ;**8/5/87** Read block at ARGD LDA MAPTMP STA MPMBPT @@ -555,15 +611,19 @@ MPCHEN BNE #80 ;SETS UP TABLE FOR FREE STORE MANAGEMENT MPREST ROUT + [ $CMOS STZ ERRTYP - -;v1.23 - STZ MAPTMP - STZ MAPTMP+1 - STZ MPTMPA - STZ MPTMPA+1 - STZ MPTMPB - + | + LDAIM 0 + STA ERRTYP + ] + [ $Level3 + STA MAPTMP + STA MAPTMP+1 + STA MPTMPA + STA MPTMPA+1 + STA MPTMPB + ] LDX DRIVES ;FOR LOOP LDYIM MPTBSZ JSR SETTAB ;SET MAP TABLE AND CLEAR STORE @@ -595,29 +655,29 @@ MPREST ROUT LDXIM 1 STX NXTDNO + [ $CMOS STZ NXTDNO+1 ;SET DISC ALLOCATION NO. + | + DEX + STX NXTDNO+1 ;SET DISC ALLOCATION NO. + ] JSR INBKMN + [ $CMOS STZ MPDRVE -;v1.23 - STZ LDRNB -20 LDA MPDRVE - STA DRIVNO - LDA FREPTR - -;v1.31 -;20 LDA FREPTR - + | + LDAIM 0 + STA MPDRVE + ] + [ $Level3 + STA LDRNB + ] +20 LDA FREPTR STA MPSCPT ;GENERAL PTR. TO SEC. ZERO DATA LDA FREPTR+1 STA MPSCPT+1 - -;v1.23 - LDA DRIVNO ;CURRENT DRIV NUMBER - -;v1.31 -; LDA MPDRVE -; STA DRIVNO + LDA MPDRVE + STA DRIVNO JSR RDDATA ;GET INFO FROM DISC BNE #50 ;Ignore if disc error ** 14/06/86 ** @@ -635,28 +695,20 @@ MPREST ROUT STAIY Mapptr ;... so mark map entry unused INY STAIY Mapptr ;by saying it has no cylinders - - -;v1.23 + [ $CMOS BRA #50 ; ** 14/10/86 ** -;NOW CREATE CYCLINDER MAP FOR THIS DISC'S MAP + | + BNE #50 ; ** 14/10/86 ** + ] -30 JSR Defdsc ;Define disc parameters to MOS +30 + [ $CMOS + JSR Defdsc ;Define disc parameters to MOS BNE #25 ; back off map entry if failed - - JSR MPMPSZ ;GET SIZE OF MAP - JSR DIVSEC ; GET NO. OF TRACKS - LDYIM MPNOCY - CLC - LDA MPTMPB ;CALCULATE SIZE OF CY.MAP - STAIY MAPPTR ; SAVE NO. OF TRACKS - INY - ROL MPTMPB -; STA MPTMPB ; MULTIPLY TRACKS BY TWO - LDA MPTMPB+ 1 - STAIY MAPPTR - ROL MPTMPB+ 1 - + ] + +;NOW CREATE CYCLINDER MAP FOR THIS DISC'S MAP + JSR MPRESZ ;**5/3/88** get number of cylinders CLC ;NOW INCREASE SIZE TO HOLD FREE SPACE COUNT LDA MPTMPB ADCIM 3 @@ -672,69 +724,55 @@ MPREST ROUT TXA STAIY MAPPTR JSR MPSTCY + [ $Level3 LDYIM MPADFT CLC 50 INC MPDRVE ; ** 14/06/86 ** drives contiguously numbered JSR MPADMP INC LDRNB - LDA LDRNB - -;v1.31 -; BNE #50 ; ** 14/10/86 ** - -;NOW CREATE CYCLINDER MAP FOR THIS DISC'S MAP -;30 JSR MPRESZ ;**5/3/88** get number of cylinders -; CLC ;NOW INCREASE SIZE TO HOLD FREE SPACE COUNT -; LDA MPTMPB -; ADCIM 3 -; TAY -; LDA MPTMPB+1 -; ADCIM 0 -; TAX -; JSR GETVEC ;get space for cylinder map -; TYA ; SAVE ADDRESS OF CY.MAP -; LDYIM MPCYMP -; STAIY MAPPTR -; INY -; TXA -; STAIY MAPPTR -; JSR MPSTCY -;50 JSR MPADMP -; INC MPDRVE ; ** 14/06/86 ** drives contiguously numbered -; LDA MPDRVE - + LDA LDRNB + | +50 JSR MPADMP + INC MPDRVE ; ** 14/06/86 ** drives contiguously numbered + LDA MPDRVE + ] CMP DRIVES BNE #20 LDAIM 0 ;RC JMP MPEXIT -;v1.31 -;MPRESZ ROUT ;**5/3/88*** calculate number of cylinders -; JSR MPMPSZ ;total number of sectors -; STZ MPTMPB -; STZ MPTMPB+1 -; LDYIM MPDSCS -; LDAIY MAPPTR -; TAX -;10 LDYIM MPNOCY -; CLC -; LDAIY MAPPTR -; ADC MPTMPB -; STA MPTMPB -; INY -; LDAIY MAPPTR -; ADC MPTMPB+1 -; STA MPTMPB+1 -; DEX -; BNE #10 -; STAIY MAPPTR ;restore total count -; DEY -; LDA MPTMPB -; STAIY MAPPTR -; CLC -; ROL MPTMPB ;multiply cyls by two -; ROL MPTMPB+1 -; RTS +MPRESZ ROUT ;**5/3/88*** calculate number of cylinders + JSR MPMPSZ ;total number of sectors + [ $CMOS + STZ MPTMPB + STZ MPTMPB+1 + | + LDAIM 0 + STA MPTMPB + STA MPTMPB+1 + ] + LDYIM MPDSCS + LDAIY MAPPTR + TAX +10 LDYIM MPNOCY + CLC + LDAIY MAPPTR + ADC MPTMPB + STA MPTMPB + INY + LDAIY MAPPTR + ADC MPTMPB+1 + STA MPTMPB+1 + DEX + BNE #10 + STAIY MAPPTR ;restore total count + DEY + LDA MPTMPB + STAIY MAPPTR + CLC + ROL MPTMPB ;multiply cyls by two + ROL MPTMPB+1 + RTS ;MPSZIN: RETURNS THE LENGTH OF A CHAIN IN BYTES AND BLOCKS @@ -756,7 +794,11 @@ MPSZIN ROUT JSR RDmpbd ;**8/5/87** Read block at ARGD BEQ #10 LDAIM MPERRC ;ERROR RETURN OF NOT START + [ $CMOS BRA #20 ;AND RETURN + | + BNE #20 ;AND RETURN + ] 10 LDA MAPTMP STA MPMBPT diff --git a/FileStore/SRC/FileStore/Uade11.6502 b/FileServer/SRC/FileServer/Uade11 similarity index 89% rename from FileStore/SRC/FileStore/Uade11.6502 rename to FileServer/SRC/FileServer/Uade11 index 864790e..c742e24 100644 --- a/FileStore/SRC/FileStore/Uade11.6502 +++ b/FileServer/SRC/FileServer/Uade11 @@ -29,9 +29,15 @@ MPFRSP ROUT JSR FNDMAP ;GET CURRENT MAP TABLE POSITION BNE #10 + [ $CMOS STZ ERRTYP STZ DNDLTE - + | + LDAIM 0 + STA ERRTYP + STA DNDLTE + ] + LDYIM ARGG JSR MPFRAD BNE #10 @@ -53,7 +59,12 @@ MPFRSP ROUT ;EXIT: ARGA = RC MPREDR ROUT + [ $CMOS STZ ERRTYP + | + LDAIM 0 + STA ERRTYP + ] LDA BBUF STA DSCCB+TRADD ;SET UP AREA TO READ IN SECTOR TWO STA MPSCPT @@ -65,8 +76,10 @@ MPREDR ROUT LDAIY ARGPTR STA CURDRV ;SET CURRENT DRIVE STA MPDRVE - + + [ $Level3 JSR RDSTWO ;GET SECTOR ZERO TO BIG BUFFER + BNE #20 ;**6/7/88** JSR CHKDSC ;CHECK DISC IS FS DISC BNE #20 @@ -76,23 +89,24 @@ MPREDR ROUT ;occurs, MAPTB can be replaced. ; Having stored old MAPTB entry, replace with stuff ;from sector zero. + | + JSR SMPPTR ;**6/7/88** MAPPTR to map table + LDYIM MPNOCY ;**6/7/88** see if drive was used + LDAIY MAPPTR + INY + ORAIY MAPPTR + BEQ #20 ;**6/7/88** no, pretend mount ok now + + LDA MPDRVE + JSR RDSTWO ;GET SECTOR ZERO TO BIG BUFFER + BNE #30 ;**6/7/88** -;v1.31 -; JSR SMPPTR ;**6/7/88** MAPPTR to map table -; LDYIM MPNOCY ;**6/7/88** see if drive was used -; LDAIY MAPPTR -; INY -; ORAIY MAPPTR -; BEQ #20 ;**6/7/88** no, pretend mount ok now -; -; LDA MPDRVE -; JSR RDSTWO ;GET SECTOR ZERO TO BIG BUFFER -; BNE #30 ;**6/7/88** - -; JSR CHKDSC ;CHECK DISC IS FS DISC -; BNE #30 + JSR CHKDSC ;CHECK DISC IS FS DISC + BNE #30 ; Store old MAPTB entry for use after new entry has been copied. + ] + LDYIM MPDCNO 10 LDAIY MAPPTR @@ -101,27 +115,12 @@ MPREDR ROUT CPYIM MPTBSZ BNE #10 -;v1.23 JSR SMAPEN ;Move sector zero info. from BBUF - JSR MPMPSZ - JSR DIVSEC ; GET NO. OF TRACKS - LDYIM MPNOCY - CLC - LDA MPTMPB ;CALCULATE SIZE OF CY.MAP - STAIY MAPPTR ; SAVE NO. OF TRACKS - INY - ROL MPTMPB ; MULTIPLY TRACKS BY TWO - LDA MPTMPB+ 1 - STAIY MAPPTR - ROL MPTMPB+ 1 - -;v1.31 -; JSR MPRESZ ;**5/3/88** get size of disc - + JSR MPRESZ ;**5/3/88** get size of disc JSR CHMPSZ ;CHECK MAP WILL FIT IN AVAILABLE SPACE BNE #30 - + JSR MPSTCY ;SET CORRECT MAP (MOST RECENT) JSR AGENTB ;AGE NAME TABLE @@ -142,29 +141,35 @@ MPREDR ROUT JSR CHDNAM ;CHECK DISC NAME AND PUT IN NAME TABLE BNE #30 ;POSSIBLY NOT UNIQUE DISC + + [ $CMOS JSR Defdsc ;Define disc parameters to MOS BNE #30 - + ] + LDAIM 0 ;=> Success 20 JMP MPEXIT ;*** EXIT ** 30 PHA ;Error exit !! + [ $Level3 LDYIM MPTBSZ-1 40 LDAAY MAPTBF STAIY MAPPTR ;Restore MAPTB information, DEY ;so that state is as before BPL #40 - JSR Defdsc - -;v1.31 -; LDYIM MPNOCY ;**6/7/88** mark entry unavailable -; LDAIM 0 -; STAIY MAPPTR -; INY -; STAIY MAPPTR - + | + LDYIM MPNOCY ;**6/7/88** mark entry unavailable + LDAIM 0 + STAIY MAPPTR + INY + STAIY MAPPTR + ] PLA + [ $CMOS BRA #20 + | + JMP #20 + ] ;MPDRNB: @@ -220,8 +225,12 @@ MPDSNB ROUT LDYIM ARGC STAIY ARGPTR LDAIM 0 ;RC + [ $CMOS BRA #20 - + | + BEQ #20 + ] + 10 LDAIM MPERRF 20 JMP MPEXIT @@ -244,22 +253,34 @@ MPDNNA ROUT CMPIM CR BNE #10 LDAIM MPERRK + [ $CMOS BRA #50 ;null disc name - + | + BNE #50 ;null disc name + ] + 10 LDAIY GENPTR CMPIM CR BEQ #20 ;ARG. IS TERMINATED CR, SO NEEDS PADDING STAAY DNMBUF INY + [ $CMOS BRA #10 - + | + JMP #10 + ] + 20 LDAIM SPACE 30 CPYIM DNAMLN ;CONTINUE PADDING ? BCS #40 ;NOPE, Y>=DNAMLN STAAY DNMBUF ;YEP, CONTINUE INY + [ $CMOS BRA #30 - + | + BNE #30 + ] + 40 JSR FNDNAM ;LOOK UP NAME IN NAME TABLE BNE #50 ;NOT FOUND ... @@ -299,8 +320,12 @@ MPNADN ROUT BEQ #10 LDAIM MPERRA ;DISC NO. NOT FOUND + [ $CMOS BRA #20 - + | + BNE #20 + ] + 10 LDYIM ARGB CLC LDA DNMPTR @@ -389,7 +414,12 @@ MPZDSK ROUT INY LDAIY ARGPTR STA OLDSZE+2 + [ $CMOS STZ OLDSZE+3 + | + LDAIM 0 + STA OLDSZE+3 + ] JSR ZERDSK JMP MPEXIT @@ -411,11 +441,20 @@ MPZDSK ROUT ; MPSCOR points to first byte of bit map sector RDBTMP ROUT ;READ BIT MAP + [ $CMOS STZ CBSIN ;ZERO OUT SIN STZ CBSIN+1 STZ CBSIN+2 STZ MPSCPT STZ MPSCPT+1 + | + LDAIM 0 + STA CBSIN ;ZERO OUT SIN + STA CBSIN+1 + STA CBSIN+2 + STA MPSCPT + STA MPSCPT+1 + ] LDYIM MP1BIT LDAIY MAPPTR ;**23/1/87** See if packed bitmap BNE #60 @@ -441,13 +480,7 @@ RDBTMP ROUT ;READ BIT MAP LDA RSTFLG BNE #30 LDAIM IERRAJ - -;v1.23 - JSR USRERR - -;v1.31 -; JSR INTERR - + JSR INTERR 30 LDA CBSTA STA CLRPTR LDA CBSTA+1 @@ -485,14 +518,23 @@ RDBTMP ROUT ;READ BIT MAP ADCIY MAPPTR ;entry must not cross sector bdry BCC #70 BEQ #70 ;exact fit allowed ok + [ $CMOS 80 STZ MPSCPT ;flows or new sector + | +80 LDAIM 0 + STA MPSCPT ;flows or new sector + ] INC CBSIN BNE #70 INC CBSIN+1 BNE #70 INC CBSIN+2 + [ $CMOS BRA #70 - + | + JMP #70 + ] + 90 LDA CBTPPT ;CHECK IF CYLINDER FOUND ORA CBTPPT+1 BEQ #50 ; FOUND SO GO AND READ IN @@ -511,8 +553,12 @@ RDBTMP ROUT ;READ BIT MAP BNE #96 DEC CBTPPT+1 96 DEC CBTPPT + [ $CMOS BRA #90 - + | + JMP #90 + ] + ; ; READ THE BLOCK SPECIFIED AT ARGD INTO STORE ; @@ -538,17 +584,7 @@ RDMPBK ROUT ;READ IN MAP BLOCK STA CBSIN+1 LDA MPTMPA+2 STA CBSIN+2 -;v1.23 - LDA MBCBPT ; GET CORRECT POINTER - STA GNCBPT - LDA MBCBPT + 1 - STA GNCBPT + 1 - LDAIM NOMPBK ;NUMBER OF MAP BLOCK ENTRIES - STA NCBDB - - -;v1.31 -;JSR SETMB ;**1/7/88** + JSR SETMB ;**1/7/88** PLP ;GET CARRY FLAG BACK BCS #30 ;BRANCH IF NOT TO BE READ IN JSR GTBTS ; GET THE MAP BLOCK TO STORE @@ -582,8 +618,12 @@ RDMPBK ROUT ;READ IN MAP BLOCK 30 JSR FNDMB BCC #40 LDYIM CBSA + [ $CMOS BRA #50 - + | + JMP #50 + ] + 40 JSR GETFR ;JUST FIND A FREE SPACE BNE #20 LDYIM CBDR @@ -613,7 +653,11 @@ RDMPBK ROUT ;READ IN MAP BLOCK LDYIM :LSB:BTINBK LDXIM :MSB:BTINBK JSR CLRSTR ;CLEAR MAP BLOCK TO ZEROES SINCE NOT READ IN + [ $CMOS BRA #10 + | + JMP #10 + ] ; CALCULATE THE NUMBER OF SECTORS REQUIRED FROM ; THE NUMBER OF BYTES REQUIRED. @@ -627,9 +671,16 @@ RDMPBK ROUT ;READ IN MAP BLOCK ; Carry Set if Overflow ; DVDE ROUT + [ $CMOS STZ DIVTMP STZ DIVTMP+1 STZ DIVTMP+2 + | + LDAIM 0 + STA DIVTMP + STA DIVTMP+1 + STA DIVTMP+2 + ] LDA DIVPAR ORA DIVPAR+1 ORA DIVPAR+2 @@ -652,8 +703,12 @@ DVDE ROUT INC DIVTMP BNE #10 INC DIVTMP+1 + [ $CMOS BRA #10 - + | + JMP #10 + ] + 20 LDA DIVPAR ;REPLACE LOWER BYTE ADCIM :LSB:BTINBK STA DIVPAR diff --git a/FileStore/SRC/FileStore/Uade11A.6502 b/FileServer/SRC/FileServer/Uade11A similarity index 82% rename from FileStore/SRC/FileStore/Uade11A.6502 rename to FileServer/SRC/FileServer/Uade11A index 2aa342e..159c7a0 100644 --- a/FileStore/SRC/FileStore/Uade11A.6502 +++ b/FileServer/SRC/FileServer/Uade11A @@ -22,8 +22,14 @@ GETPOS ROUT LDA MAPGEN+1 ADCIM :MSB:MBENTS STA MAPGEN+1 + [ $CMOS STZ MPTMPE STZ MPTMPE+1 ;CLEAR VARIABLES + | + LDAIM 0 + STA MPTMPE + STA MPTMPE+1 ;CLEAR VARIABLES + ] 10 LDA MPTMPE CMPIM :LSB:(MXENTS-1) ;CHECK FOR END OF LIST LDA MPTMPE+1 @@ -47,8 +53,12 @@ GETPOS ROUT 35 INC MPTMPE ;MPTMPE HOLDS NUMBER OF ENTRIES WE'VE LOOKED AT BNE #10 INC MPTMPE+1 + [ $CMOS BRA #10 - + | + JMP #10 + ] + 40 CLC 50 RTS ;RETURNS HERE WITH CARRY CLEAR, ALL OK, SET IF NOT. @@ -68,126 +78,77 @@ GETPOS ROUT ; USES MPTMPE GTCYPS ROUT -;v1.23 LDA MPTMPC - STA MPTMPE ;SAVE CURRENT POSITION - LDA MPTMPC+ 1 - STA MPTMPE+ 1 + ASLA + STA MPTMPE ;**1/7/88** current position*2 + LDA MPTMPC+1 + ROLA + STA MPTMPE+1 CLC LDA MAPGEN ;POINT TO START OF MAP - ADCIM 3 + ADCIM 3 STA MAPGEN BCC #10 - INC MAPGEN+ 1 -10 LDA MPTMPE ;CHECK IF POSITION FOUND - ORA MPTMPE+ 1 - BEQ #40 - CLC - LDA MAPGEN - ADCIM 2 ;FOR NEXT ENTRY + INC MAPGEN+1 +10 CLC + LDA MAPGEN ;**1/7/88** add offset to cylinder + ADC MPTMPE STA MAPGEN - BCC #20 - INC MAPGEN+ 1 -20 LDA MPTMPE - BNE #30 - DEC MPTMPE+ 1 -30 DEC MPTMPE - BRA #10 -40 LDA MPTMPC - STA MPTMPE - LDA MPTMPC + 1 - STA MPTMPE + 1 -50 LDYIM 0 ;NOW LOOK FOR POSITION WITH FREE BLOCK + LDA MAPGEN+1 + ADC MPTMPE+1 + STA MAPGEN+1 + LSR MPTMPE+1 + ROR MPTMPE + +30 LDYIM 0 ;NOW LOOK FOR POSITION WITH FREE BLOCK LDAIY MAPGEN INY ORAIY MAPGEN - BNE #90 ;FOUND IF NON ZERO + BNE #50 ;FOUND IF NON ZERO INC MPTMPE - BNE #60 - INC MPTMPE+ 1 -60 LDA MPTMPE + BNE #32 + INC MPTMPE+1 +32 LDA MPTMPE LDYIM MPNOCY ;CHECK FOR END OF CYCLINDER MAP CMPIY MAPPTR INY - LDA MPTMPE+ 1 + LDA MPTMPE+1 SBCIY MAPPTR - BCS #80 - LDAIM 2 -70 CLC ;NOT END SO LOOK AT NEXT ENTRY + BCS #40 + LDAIM 2 ;NOT END SO LOOK AT NEXT ENTRY +35 CLC ADC MAPGEN STA MAPGEN - BCC #50 - INC MAPGEN + 1 - BRA #50 -80 STZ MPTMPE ;END SO BACK TO BEGINNING - STZ MPTMPE+ 1 + BCC #30 + INC MAPGEN+1 + [ $CMOS + BRA #30 + | + JMP #30 + ] + + [ $CMOS +40 STZ MPTMPE ;END SO BACK TO BEGINNING + STZ MPTMPE+1 + | +40 LDAIM 0 + STA MPTMPE ;END SO BACK TO BEGINNING + STA MPTMPE+1 + ] LDYIM MPCYMP LDAIY MAPPTR ;GET START OF CYLINDER MAP STA MAPGEN INY LDAIY MAPPTR - STA MAPGEN + 1 - LDAIM 3 - BRA #70 -90 RTS - -;1.31 -; LDA MPTMPC -; ASLA -; STA MPTMPE ;**1/7/88** current position*2 -; LDA MPTMPC+1 -; ROLA -; STA MPTMPE+1 -; CLC -; LDA MAPGEN ;POINT TO START OF MAP -; ADCIM 3 -; STA MAPGEN -; BCC #10 -; INC MAPGEN+1 -;10 CLC -; LDA MAPGEN ;**1/7/88** add offset to cylinder -; ADC MPTMPE -; STA MAPGEN -; LDA MAPGEN+1 -; ADC MPTMPE+1 -; STA MAPGEN+1 -; LSR MPTMPE+1 -; ROR MPTMPE -;30 LDYIM 0 ;NOW LOOK FOR POSITION WITH FREE BLOCK -; LDAIY MAPGEN -; INY -; ORAIY MAPGEN -; BNE #50 ;FOUND IF NON ZERO -; INC MPTMPE -; BNE #32 -; INC MPTMPE+1 -;32 LDA MPTMPE -; LDYIM MPNOCY ;CHECK FOR END OF CYCLINDER MAP -; CMPIY MAPPTR -; INY -; LDA MPTMPE+1 -; SBCIY MAPPTR -; BCS #40 -; LDAIM 2 ;NOT END SO LOOK AT NEXT ENTRY -;35 CLC -; ADC MAPGEN -; STA MAPGEN -; BCC #30 -; INC MAPGEN+1 -; BRA #30 -; -;40 STZ MPTMPE ;END SO BACK TO BEGINNING -; STZ MPTMPE+1 -; LDYIM MPCYMP -; LDAIY MAPPTR ;GET START OF CYLINDER MAP -; STA MAPGEN -; INY -; LDAIY MAPPTR -; STA MAPGEN+1 -; LDAIM 3 ;GET POINTER TO START OF ENTRIES -; BRA #35 -; -;50 RTS + STA MAPGEN+1 + LDAIM 3 ;GET POINTER TO START OF ENTRIES + [ $CMOS + BRA #35 + | + BNE #35 + ] + +50 RTS ; FIND CYLINDER ; @@ -203,12 +164,22 @@ GTCYPS ROUT ; USES MAPTMP MPTMPA MPTMPB FNDCY ROUT + [ $CMOS STZ MAPTMP ;ZERO VALUES STZ MAPTMP+1 STZ MPTMPA STZ MPTMPA+1 STZ MPTMPC STZ MPTMPC+1 + | + LDAIM 0 + STA MAPTMP ;ZERO VALUES + STA MAPTMP+1 + STA MPTMPA + STA MPTMPA+1 + STA MPTMPC + STA MPTMPC+1 + ] CLC LDA MPCYPT ;GET TO START OF ENTRIES ADCIM 3 @@ -278,10 +249,18 @@ SIZE ROUT INY LDAIY MAPPTR STA TMPSPC+1 + [ $CMOS STZ MPTMPD ;CLEAR VARIABLES STZ MPTMPD+1 STZ MPTMPE STZ MPTMPE+1 + | + LDAIM 0 + STA MPTMPD ;CLEAR VARIABLES + STA MPTMPD+1 + STA MPTMPE + STA MPTMPE+1 + ] LDYIM 0 10 LDAIY MPSCPT BEQ #80 ;NO FREE BITS IN THIS PART @@ -309,13 +288,21 @@ SIZE ROUT DEX BNE #20 65 INY + [ $CMOS BRA #10 - + | + JMP #10 + ] + 70 LDA MPTMPD ORA MPTMPD+1 BNE #50 ;END IF ALREADY SOME COUNT + [ $CMOS BRA #30 - + | + BEQ #30 + ] + 80 LDA MPTMPD ORA MPTMPD+1 BNE #55 @@ -327,8 +314,12 @@ SIZE ROUT INC MPTMPE+1 85 JSR TESTME ;**23/1/87** test for end of map BCC #65 + [ $CMOS BRA #48 - + | + BCS #48 + ] + ; FILL BLOCKS ; ALLOCATES REST OF BLOCKS THAT ARE REQUIRED ; @@ -381,10 +372,20 @@ FLBLKS ROUT BEQ #10 JSR RDBTMP ; GET THE BIT MAP BNE #00 ;**23/2/87** Failed + [ $CMOS BRA FLBLKS ; KEEP TRYING TO ALLOCATE - + | + BEQ FLBLKS ; KEEP TRYING TO ALLOCATE + ] + + [ $CMOS 30 STZ MPTMPC ;GO BACK TO THE BEGINNING STZ MPTMPC+1 + | +30 LDAIM 0 + STA MPTMPC ;GO BACK TO THE BEGINNING + STA MPTMPC+1 + ] LDYIM MPCYMP ;RETURN CYLINDER MAP TO BEGINNING CLC LDAIY MAPPTR @@ -394,8 +395,12 @@ FLBLKS ROUT LDAIY MAPPTR ADCIM 0 STA MPCYPT+1 + [ $CMOS BRA #20 - + | + JMP #20 + ] + 40 CLC ;INDICATE OK RTS @@ -495,8 +500,12 @@ ADDFR ROUT BEQ #40 LDX MPTMPC LDY MPTMPC+1 + [ $CMOS BRA #20 - + | + JMP #20 + ] + 10 CLC LDA MAPGEN ADCIM 2 @@ -506,14 +515,22 @@ ADDFR ROUT 20 CPXIM 0 BEQ #30 DEX + [ $CMOS BRA #10 - + | + JMP #10 + ] + 30 CPYIM 0 BEQ #40 DEX DEY + [ $CMOS BRA #10 - + | + JMP #10 + ] + 40 LDYIM 0 CLC ;NOW ADD THE NEW VALUES LDAIY MAPGEN diff --git a/FileServer/SRC/FileServer/Uade12 b/FileServer/SRC/FileServer/Uade12 new file mode 100644 index 0000000..5e47abc --- /dev/null +++ b/FileServer/SRC/FileServer/Uade12 @@ -0,0 +1,776 @@ + OPT UADE12 ;> Uade12 + TTL File server file UADE12 + +;** MAPMAP UTILS II(2) ** + +;SET POINTER TO ENTRY IN MAP TABLE +;CORRESPONDING TO DRIVE IN CURDRV. +;POINTER IN BOTH MAPPTR AND MAPENT. + +SMPPTR ROUT + LDX CURDRV + LDA MAPTB + STA MAPPTR + LDA MAPTB+1 + STA MAPPTR+1 +10 DEX + BMI #20 + JSR MPADMP + [ $CMOS + BRA #10 + | + JMP #10 + ] + +20 LDA MAPPTR + STA MAPENT + LDA MAPPTR+1 + STA MAPENT+1 + RTS + +;RDDATA: READ DISC INFO FROM SECTOR 0 INTO +;STORE STARTING AT ADDRESS IN FREPTR. + +;ENTRY: A = DRIVE NO. + +;EXIT: A = RC + +;FUNCTION: - +;0) SET FDRIVE, OLDFDR & SELECT & START DRIVE +;1) SEEK TRACK ZERO +;2) READ SECTOR 0 + +;RDSTWO ENTRY POINT FOR USE WHEN +;DDRSTA POINTER ALREADY SET UP. + +RDDATA ROUT + LDY FREPTR + STY DSCCB+TRADD + LDY FREPTR+1 + STY DSCCB+TRADD+1 ;DDRSTA:=STORE ADDR FOR SECTOR + [ $CMOS + STZ DSCCB + STZ DSCCB+TRADD+2 + STZ DSCCB+TRADD+3 + | + LDYIM 0 + STY DSCCB + STY DSCCB+TRADD+2 + STY DSCCB+TRADD+3 + ] + + [ $Level3 + [ WINCH=0 +RDSTWO STA Drivno + LDXIM Length+3-Cmd + LDAIM 0 +00 STAAX Dsccb+Cmd ;Zero part of disc CB ** 27/9/86 ** + DEX + BPL #00 + LDA Drivno + LSRA + RORA + RORA + RORA + STA DSCCB+CMD+1 + LDAIM &08 + STA DSCCB+CMD + LDA DSCCB+TRADD + STA MPCYPT + LDA DSCCB+TRADD+1 + STA MPCYPT+1 + LDAIM 0 + STA RBDA ;Sector zero + INC DSCCB+LENGTH+1 ;All was zero +10 JSR DSCCMD + BNE #20 + LDYIM SZOFF + LDAIY MPCYPT + STA DSCCB+CMD+3 + INY + LDAIY MPCYPT + STA DSCCB+CMD+2 + INY + LDA DRIVNO + LSRA + RORA + RORA + RORA + ORAIY MPCYPT + STA DSCCB+CMD+1 + JSR DSCCMD + BEQ #30 +20 LDY Dsccb ;Bad drive? **27/9/86 ** + CPYIM &65 + BEQ #30 ;Don't bother with alternate + LDY RBDA + BNE #30 + INC RBDA + INC DSCCB+CMD+3 + BNE #10 + +30 TAX ;Set CC + RTS + | ; not Winchester +RDSTWO STA DSCCB ;SET DRIVE NUMBER + + STA DSCCB+PARAMS ;TRACK ZERO + LDAIM 2 ;SECTOR TWO + STA DSCCB+PARAMS+ 1 ;SECTOR TWO + LDAIM 3 ;NUMBER OF PARAMETERS + STA DSCCB+NOPRMS + LDAIM &21 ; ONE SECTOR + STA DSCCB+PARAMS+ 2 + LDAIM &53 ;FOR READ + STA DSCCB+CMD + + JSR DSCCMD + + RTS + ] + + | ; not Level3 + +RDSTWO STZ RBDA ;Sector zero +RDSTWX STA Drivno ;Enter here with sector (<256) preset + JSR Defdef ;Define default drive parameters + LDXIM Length+3-Cmd +00 STZAX Dsccb+Cmd ;Zero part of disc CB ** 27/9/86 ** + DEX + BPL #00 + LDAIM &08 + STA DSCCB+CMD + LDA Drivno + LSRA + RORA + RORA + RORA + STA DSCCB+CMD+1 + LDA DSCCB+TRADD + STA MPCYPT + LDA DSCCB+TRADD+1 + STA MPCYPT+1 + INC DSCCB+LENGTH+1 ;All was zero +10 LDA RBDA ;**18/2/88** Set sector + STA DSCCB+CMD+3 + STZ DSCCB+CMD+2 + JSR DSCCMD + BNE #20 + LDYIM SZOFF + LDAIY MPCYPT + STA DSCCB+CMD+3 + INY + LDAIY MPCYPT + STA DSCCB+CMD+2 + INY + LDA DRIVNO + LSRA + RORA + RORA + RORA + ORAIY MPCYPT + STA DSCCB+CMD+1 + JSR DSCCMD + BEQ #30 +20 LDY Dsccb ;Bad drive? **27/9/86 ** + CPYIM &65 + BEQ #30 ;Don't bother with alternate + LDY RBDA + BNE #30 + INC RBDA + BRA #10 + +30 TAX ;Set CC + RTS + ] + +; +; MAKE AN ENTRY IN THE MAP BLOCK +; +; ON ENTRY +; MKENVA HOLD THE NUMBER OF BLOCKS TO ALLOCATE +; MAPTMP POINT TO THE MAP BLOCK +; MPTMPC points to allocation cylinder number +; +; ON EXIT +; C SET IF FAILED +; +; USES : MAPGEN, MPTMPA, MPTMPB, MPTMPC, MPTMPE +; +MKEN ROUT + LDYIM MPSPCY + LDAIY MAPPTR + STA TMPSPC + INY + LDAIY MAPPTR + STA TMPSPC+1 + LDA MAPGEN + PHA + LDA MAPGEN+1 + PHA + LDA MAPTMP ;GET POINTER TO MAP BLOCK + STA MAPGEN + LDA MAPTMP+1 + STA MAPGEN+1 + JSR GETPOS ;GET NEXT FREE POSITION IN MAP BLOCK + BCS #10 ;BRANCH IF ROOM + JMP #30 +10 LDYIM MPCYMP ;GET ADDRESS OF CYLINDER MAP + LDAIY MAPPTR + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 + SEC + LDYIM 0 ;CHECK IF ROOM FOR ANOTHER BLOCK + LDAIY MAPGEN + SBCIM 1 + STAIY MAPGEN + INY + LDAIY MAPGEN + SBCIM 0 + STAIY MAPGEN + INY + LDAIY MAPGEN + SBCIM 0 + STAIY MAPGEN + BCC #15 + LDA MAPTMP + STA MPMBPT + STA CBSTA + LDA MAPTMP+1 + STA MPMBPT+1 + STA CBSTA+1 + JSR MMBLKD + JSR GTCYPS ;get closest cylinder block + LDA MAPGEN + STA MPTMPB + LDA MAPGEN+1 + STA MPTMPB+1 + LDA MPTMPE + STA MPTMPC ;NEW CYLINDER COUNT + LDA MPTMPE+1 + STA MPTMPC+1 + JSR RDBTMP + BNE #12 ;**23/2/87** Failed + JSR ALBLK ;GET NEW MAP BLOCK + SEC + JSR RDMPBK ;GET AREA OF STORE FOR IT + LDA ERRTYP + BEQ #20 +12 JSR ULMB +15 JMP #90 + +20 CLC + LDA MPMBPT ;GET POINTER TO OLD MAP BLOCK + STA CBSTA + ADCIM :LSB:LSTENT ;POINT TO LAST ENTRY + STA MPMBPT + LDA MPMBPT+1 + STA CBSTA+1 + ADCIM :MSB:LSTENT + STA MPMBPT+1 + LDYIM 0 ;SAVE SIN OF NEW MAP BLOCK + LDA MPTMPA + STAIY MPMBPT + INY + LDA MPTMPA+1 + STAIY MPMBPT + INY + LDA MPTMPA+2 + STAIY MPMBPT + INY ;NOW SAVE LENGTH + LDAIM 1 + STAIY MPMBPT + INY + [ $CMOS + DECA ;ZERO + | + LDAIM 0 + ] + STAIY MPMBPT + JSR MMBWT + JSR ULMB + CLC + LDYIM MPCYMP ;GET ADDRESS OF CYLINDER MAP + LDAIY MAPPTR + STA MAPGEN + ADCIM 3 ;POINT TO START OF ENTRIES + STA MPTMPB + INY + LDAIY MAPPTR + STA MAPGEN+1 + ADCIM 0 + STA MPTMPB+1 + JSR GTCYPS + LDA MAPGEN + STA MPCYPT + LDA MAPGEN+1 + STA MPCYPT+1 + LDA MPTMPE + STA MPTMPC + LDA MPTMPE+1 + STA MPTMPC+1 + JSR RDBTMP + BNE #12 ;**23/12/87** Failed + LDA MAPTMP + STA MAPGEN ;SAVE ADDRESS OF NEW MAP BLOCK + LDA MAPTMP+1 + STA MAPGEN+1 + JSR SIZE + LDA MPTMPD ;number of contiguous blocks + CMP MKENVA + LDA MPTMPD+1 + SBC MKENVA+1 + BCS #25 + LDA MPTMPD + STA MKENVA + LDA MPTMPD+1 + STA MKENVA+1 +25 JSR GETPOS ;GET FREE POSITION IN MAP BLOCK + [ $CMOS +30 STZ MPTMPE + STZ MPTMPE+1 ;ZERO VARIABLES + STZ MPTMPE+2 + LDYIM 0 + | +30 LDAIM 0 + STA MPTMPE + STA MPTMPE+1 ;ZERO VARIABLES + STA MPTMPE+2 + TAY + ] +35 LDAIY MPSCPT ;LOOK FOR BLOCKS TO ALLOCATE + BEQ #45 ;NOT FOUND + LDXIM 8 +40 RORA + BCS #50 + DEX + INC MPTMPE ;STILL NOT FOUND + BNE #40 + INC MPTMPE+1 + [ $CMOS + BRA #40 ;CHECK NEXT ONE + | + JMP #40 ;CHECK NEXT ONE + ] + +45 CLC ;NEXT BYTE SO ADD 8 + LDA MPTMPE + ADCIM 8 + STA MPTMPE + INY + BCC #35 + INC MPTMPE+1 + CLC ;**1/7/88** + [ $CMOS + BRA #35 + | + BCC #35 + ] + +50 PHA + LDA MPTMPE + ORA MPTMPE+1 + STA MPTMPB+2 ;**23/1/87** Fla for start of cylinder + LDA MKENVA + STA MPTMPB + LDA MKENVA+1 + STA MPTMPB+1 + PLA +55 CLC + RORA + PHP + PHA + LDA MPTMPB + BNE #57 + DEC MPTMPB+1 +57 DEC MPTMPB + LDA MPTMPB+1 + ORA MPTMPB + BEQ #60 + PLA + PLP + DEX + BNE #55 + STAIY MPSCPT + INY + LDAIY MPSCPT + LDXIM 8 + RORA + [ $CMOS + BRA #55 + | + JMP #55 + ] + +60 PLA + PLP + DEX +65 RORA + DEX + BNE #65 + STAIY MPSCPT + LDA MPTMPC + PHA + LDA MPTMPC+1 + PHA ;SAVE POSITION +70 LDA MPTMPC ;NOW GET DISC ADDRESS + ORA MPTMPC+1 ;IF ZERO THS IS IT! + BEQ #80 + CLC + LDA MPTMPE + ADC TMPSPC + STA MPTMPE + LDA MPTMPE+1 + ADC TMPSPC+1 + STA MPTMPE+1 + BCC #75 + INC MPTMPE+2 +75 LDA MPTMPC + BNE #77 + DEC MPTMPC+1 +77 DEC MPTMPC + [ $CMOS + BRA #70 + | + JMP #70 + ] + +80 PLA + STA MPTMPC+1 + PLA + STA MPTMPC + + [ 1=1 ;Attempt map entry merge *** 27/05/86 *** + LDA MPTMPB+2 ;**23/1/87** do not merge if start of cylinder + BEQ #83 + SEC + LDA MAPGEN ;if (MAPGEN-MAPTMP)=MBENTS ; unless first entry + SBC MAPTMP + TAY + LDA MAPGEN+1 + SBC MAPTMP+1 + BNE #81 + CPYIM MBENTS + BEQ #83 +81 SEC + LDA MAPGEN ;then $( MAPGEN-:=ENSZ ; previous entry + PHA + SBCIM :LSB:ENSZ + STA MAPGEN + LDA MAPGEN+1 + PHA + SBCIM :MSB:ENSZ + STA MAPGEN+1 + SEC + LDYIM 0 ; CBSTA:=MPTMPE-SIN(MAPGEN) ; separation of extents + LDA MPTMPE + SBCIY MAPGEN + STA CBSTA + INY + LDA MPTMPE+1 + SBCIY MAPGEN + STA CBSTA+1 + INY + LDA MPTMPE+2 + SBCIY MAPGEN + BNE #82 ; ; (not too long) + INY + LDA CBSTA ; if (CBSTA=LEN(MAPGEN)) ; do extents abut + CMPIY MAPGEN + BNE #82 + INY + LDA CBSTA+1 + CMPIY MAPGEN + BNE #82 + DEY + CLC + LDA MKENVA ; then $( LEN(MAPGEN)+:=MKENVA ; yes, extend previous + ADCIY MAPGEN + STAIY MAPGEN + INY + LDA MKENVA+1 + ADCIY MAPGEN + STAIY MAPGEN + PLA + PLA + [ $CMOS + BRA #84 ; goto #84 $) + | + JMP #84 ; goto #84 $) + ] + +82 PLA ; MAPGEN+:=ENSZ ; else separate extents so make new entry + STA MAPGEN+1 + PLA + STA MAPGEN + ] + +83 LDYIM 0 ;SAVE THE DISC ADDRESS + LDA MPTMPE + STAIY MAPGEN + INY + LDA MPTMPE+1 + STAIY MAPGEN + INY + LDA MPTMPE+2 + STAIY MAPGEN + INY + LDA MKENVA ;SAVE SIZE + STAIY MAPGEN + LDA MKENVA+1 + INY + STAIY MAPGEN +84 LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JSR MBMWT ;MARK BIT MAP WRITTEN TO + LDA MAPTMP + STA CBSTA + LDA MAPTMP+1 + STA CBSTA+1 + JSR MMBWT ;MARK MAP BLOCK WRITTEN + SEC + LDA DIVTMP + SBC MKENVA + STA DIVTMP + LDA DIVTMP+1 + SBC MKENVA+1 + STA DIVTMP+1 + CLC ;FLAG EVERYTHING OK +85 PLA + STA MAPGEN+1 + PLA + STA MAPGEN + RTS + +90 CLC + LDYIM 0 + LDAIY MAPGEN + ADCIM 1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADCIM 0 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADCIM 0 + STAIY MAPGEN + SEC ;NO GOOD + [ $CMOS + BRA #85 + | + BCS #85 + ] + +;ALLOCATE ONE BLOCK +; +; LOOKS IN CURRENT BIT MAP AND RETURNS THE SIN +; OF THE FIRST FREE BLOCK +; +; ON ENTRY +; MPTMPC HOLDS THE CYLINDER NUMBER +; MPSCPT POINTS TO THE CURRENT BIT MAP +; +; ON EXIT +; MPTMPA HOLDS THE SIN OF THE ALLOCATED BLOCK +; +; USES : MPCYPT +; +ALBLK ROUT ;ZERO VARIABLES + [ $CMOS + STZ MPTMPA + STZ MPTMPA+1 + STZ MPTMPA+2 + | + LDAIM 0 + STA MPTMPA + STA MPTMPA+1 + STA MPTMPA+2 + ] + LDA MPSCPT ;COPY POINTER TO USE + STA MPCYPT + LDA MPSCPT+1 + STA MPCYPT+1 +10 LDYIM 0 + LDAIY MPCYPT ;FIND FREE BLOCK + BEQ #30 +20 RORA ;NOW FIND THE SECTOR + BCS #50 ;FOUND WHEN C SET + INC MPTMPA ;KEEP LOOKING + BNE #20 + INC MPTMPA+1 + [ $CMOS + BRA #20 + | + JMP #20 + ] + +30 CLC + LDA MPTMPA ;MOVE TO NEXT BYTE + ADCIM 8 + STA MPTMPA + BCC #35 + INC MPTMPA+1 +35 INC MPCYPT + BNE #10 + INC MPCYPT+1 + [ $CMOS + BRA #10 + | + JMP #10 + ] + +50 PHA ;SAVE TO MARK AS ALLOCATED + LDA MPTMPA + ANDIM 7 + TAX + INX + PLA + CLC +60 ROLA + DEX + BNE #60 + STAIY MPCYPT ;BLOCK MARKED ALLOCATED + LDA MPTMPC + STA MAPTMP + LDA MPTMPC+1 + STA MAPTMP+1 +70 LDA MAPTMP + ORA MAPTMP+1 + BEQ #80 ;GET DISC ADDRESS + LDYIM MPSPCY + CLC + LDA MPTMPA + ADCIY MAPPTR + STA MPTMPA + INY + LDA MPTMPA+1 + ADCIY MAPPTR + STA MPTMPA+1 + BCC #75 + INC MPTMPA+2 +75 LDA MAPTMP ;DECREMENT CYLINDER COUNT + BNE #77 + DEC MAPTMP+1 +77 DEC MAPTMP + [ $CMOS + BRA #70 + | + JMP #70 + ] + +80 LDA MPTMPB ;GET POINTER TO CYLINDER MAP + STA MPCYPT + LDA MPTMPB+1 + STA MPCYPT+1 + LDYIM 0 ;DECREMENT FREE COUNT + SEC + LDAIY MPCYPT + SBCIM 1 + STAIY MPCYPT + INY + LDAIY MPCYPT + SBCIM 0 + STAIY MPCYPT + LDYIM MPCYMP + LDAIY MAPPTR + STA MPCYPT + INY + LDAIY MAPPTR + STA MPCYPT+1 + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JSR MBMWT ;MARK BIT MAP WRITTEN + LDA MPTMPA + ORA MPTMPA+1 + ORA MPTMPA+2 + BNE #90 + LDAIM &FC + JSR INTERR +90 RTS + +; ALLOCATE A SERIES OF BLOCKS +; +; ON ENTRY +; MPCYPT POINTS TO POSITION IN CYLINDER MAP +; DIVTMP HOLDS NUMBER OF SECTORS REQUIRED +; MPSCPT POINTS TO BIT MAP +; MAPPTR POINTS TO MAP TABLE +; MAPTMP POINTS TO MAP BLOCK +; MPTMPC HOLDS CYLINDER NUMBER +; +; ON EXIT +; DIVTMP HOLDS NUMBER OF BLOCKS LEFT +; C SET IF FAILED +; +; USES : MAPGEN +; +ABLKS ROUT + LDYIM MPCYMP + LDAIY MAPPTR ;GET POINTER TO START OF CYLINDER MAP + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 + JSR SIZE ;GET SIZE OF THIS BLOCK + LDA MPTMPD ;MPTMPD HAS SIZE + TAX ;**1/7/88** + CMP DIVTMP ;SEE IF WE NEED THEM ALL + LDA MPTMPD+1 + TAY + SBC DIVTMP+1 + BCC #10 + LDA DIVTMP+2 + BNE #10 ;ABSALL ALLOCATES ALL BLOCKS + LDX DIVTMP + LDY DIVTMP+1 +10 STX MKENVA ;MAKE ENTRY IN MAP BLOCK + STY MKENVA+1 + JSR MKEN + BCS #30 ;ALL DONE SO FINISH + LDA ERRTYP + BNE #30 + LDYIM 0 + SEC + LDAIY MPCYPT + SBC MKENVA + STAIY MPCYPT + INY + LDAIY MPCYPT + SBC MKENVA+1 + STAIY MPCYPT + CMPIM &FF + BNE #20 + DEY + LDAIY MPCYPT + CMPIM &FF + BNE #20 + LDAIM &FA + JSR INTERR +20 CLC + RTS + +30 JSR DAGRP ;NOT ABLE TO MAKE ENTRY + LDYIM 0 + CLC + LDAIY MAPGEN ;INCREASE FREE COUNT + ADC MKENVA + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC MKENVA+1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADCIM 0 + STAIY MAPGEN + SEC ;TO INDICATE FAILURE + RTS + + LNK UADE12A diff --git a/FileServer/SRC/FileServer/Uade12A b/FileServer/SRC/FileServer/Uade12A new file mode 100644 index 0000000..e86fe28 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade12A @@ -0,0 +1,557 @@ + OPT UADE12 ;> Uade12A + TTL File server file UADE12A + +; DEALLOCATE MAP BLOCK +; +; DEALLOCATES THE SPECIFIED MAP BLOCK. OVERWRITES THE SEQUENCE NUBERS +; SO THAT IT WILL NO LONGER APPEAR AS A MAP BLOCK +; +; ON ENTRY +; MPTMPA HOLDS THE SIN OF THE MAP BLOCK +; MPCYPT POINTS TO THE CYLINDER MAP +; +; USES : MPTMPA,MPTMPD,MPTMPC,MPSCPT +; +DAMPBK ROUT + LDYIM MPSPCY + LDAIY MAPPTR + STA TMPSPC + INY + LDAIY MAPPTR + STA TMPSPC+1 + LDA MPTMPA ;DEALLOCATE MAP BLOCK + STA CBSIN + LDA MPTMPA+1 + STA CBSIN+1 + LDA MPTMPA+2 + STA CBSIN+2 + JSR FNDMB ; GNCBPT POINTS TO CURRENT ENTRY + LDYIM CBSA + LDAIY GNCBPT + STA MPSCPT ;SAVE POINTER TO MAP BLOCK + STA CBSTA + INY + LDAIY GNCBPT + STA MPSCPT+1 + STA CBSTA+1 + LDYIM MBSQNO + LDAIM &FF + STAIY MPSCPT ;SAVE INVALID SQ.NO. + CLC + LDA MPSCPT + ADCIM :LSB:LSTSQ + STA MPSCPT + LDA MPSCPT+1 + ADCIM :MSB:LSTSQ + STA MPSCPT+1 + LDAIM 0 + TAY + STAIY MPSCPT + JSR MMBWT + [ $CMOS + STZ MPTMPC ; ZERO VARIABLES + STZ MPTMPC+1 + | + LDAIM 0 + STA MPTMPC ; ZERO VARIABLES + STA MPTMPC+1 + ] +10 SEC + LDA MPTMPA + SBC TMPSPC ; FIND CYLINDER NUMBER + STA MPTMPA + LDA MPTMPA+1 + SBC TMPSPC+1 + STA MPTMPA+1 + LDA MPTMPA+2 + SBCIM 0 + STA MPTMPA+2 + BCC #20 ; CYLINDER FOUND + INC MPTMPC ;INCREMENT CYLINDER COUNT + BNE #10 + INC MPTMPC+1 + [ $CMOS + BRA #10 + | + JMP #10 + ] + +20 JSR RDBTMP ; GET THE RELEVANT BIT MAP TO STORE + CLC + LDA MPTMPA ; GET WHICH BLOCK OF THIS CYLINDER + ADC TMPSPC + STA MPTMPA + LDA MPTMPA+1 + ADC TMPSPC+1 + STA MPTMPA+1 + BCC #25 + INC MPTMPA+2 +25 LDYIM 0 +30 SEC ;GET POSITION IN BIT MAP + LDA MPTMPA + SBCIM 8 + STA MPTMPA + LDA MPTMPA+1 + SBCIM 0 + STA MPTMPA+1 + BCC #40 ; POSITION FOUND IF BRANCH + INY + [ $CMOS + BRA #30 + | + JMP #30 + ] + +40 CLC + LDA MPTMPA ; GET OLD POSITION BACK + ADCIM 8 + STA MPTMPA + BCC #45 + INC MPTMPA+1 +45 LDX MPTMPA + INX + LDAIY MPSCPT ; X HOLDS POSITION IN BYTE A HOLDS THE BYTE +50 RORA ;MOVE TO CORRECT POSITION + DEX + BNE #50 + SEC + LDX MPTMPA ;BLOCK IS FLAGGED FREE AND X HOLDS NUMBER OF SHIFTS + INX +60 ROLA ; UNTIL BACK TO CORRECT POSITION + DEX + BNE #60 + STAIY MPSCPT ; SAVE FLAGS + CLC + LDA MPCYPT ;NOW MAKE COUNTS CORRECT + ADCIM 3 + STA MAPGEN + LDA MPCYPT+1 + ADCIM 0 + STA MAPGEN+1 + LDA MPTMPC + STA MPTMPE + LDA MPTMPC+1 + STA MPTMPE+1 +70 LDA MPTMPE + ORA MPTMPE+1 + BEQ #80 + CLC + LDA MAPGEN + ADCIM 2 + STA MAPGEN + BCC #75 + INC MAPGEN+1 +75 LDA MPTMPE + BNE #77 + DEC MPTMPE+1 +77 DEC MPTMPE + [ $CMOS + BRA #70 + | + JMP #70 + ] + +80 LDYIM 0 + CLC + LDAIY MAPGEN ;INCREMENT FREE BLOCK COUNT + ADCIM 1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADCIM 0 + STAIY MAPGEN + LDYIM 0 + CLC + LDAIY MPCYPT + ADCIM 1 + STAIY MPCYPT + INY + LDAIY MPCYPT + ADCIM 0 + STAIY MPCYPT + INY + LDAIY MPCYPT + ADCIM 0 + STAIY MPCYPT + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JMP MBMWT ; NOW FINISHED +; +; DALLOCATE A GROUP OF BLOCKS +; MARKS THE ENTRIES IN THE SPECIFIED BIT MAP FREE AND INCREASES THE FREE BLOCK COUNT +; +; ON ENTRY +; MPSCPT POINTS TO RELEVANT ENTRY IN MAP BLOCK +; MPCYPT POINTS TO CYLINDER MAP +; MAPTMP POINTS TO MAP BLOCK +; +; USES MPTMPC,MAPGEN,MPTMPD,MAPTMP +; +DAGRP ROUT + LDA MAPTMP + PHA + LDA MAPTMP+1 + PHA + [ $CMOS + STZ MPTMPC ; ZERO VALUES + STZ MPTMPC+1 + | + LDAIM 0 + STA MPTMPC ; ZERO VALUES + STA MPTMPC+1 + ] + LDYIM 0 + LDAIY MPSCPT ; GET SIN + STA MPTMPD + INY + LDAIY MPSCPT + STA MPTMPD+1 + INY + LDAIY MPSCPT + STA MPTMPD+2 + LDA MPSCPT ; SAVE MAP BLOCK POINTER + STA MAPGEN + LDA MPSCPT+1 + STA MAPGEN+1 + +05 LDYIM MPSPCY + SEC ; NOW FIND CYLINDER + LDA MPTMPD + SBCIY MAPPTR + STA MPTMPD + INY + LDA MPTMPD+1 + SBCIY MAPPTR + STA MPTMPD+1 + LDA MPTMPD+2 + SBCIM 0 + STA MPTMPD+2 + BCC #10 ; END FOUND + INC MPTMPC ; COUNT TO NEXT CYLINDER + BNE #05 + INC MPTMPC+1 + [ $CMOS + BRA #05 + | + JMP #05 + ] + +10 LDYIM MPSPCY + CLC + LDA MPTMPD ; RESTORE BLOCK COUNT + ADCIY MAPPTR + STA MPTMPD + INY + LDA MPTMPD+1 + ADCIY MAPPTR + STA MPTMPD+1 + BCC #12 + INC MPTMPD+2 +12 LDA MPTMPC ; SAVE CYLINDER NUMBER + STA MAPTMP + LDA MPTMPC+1 + STA MAPTMP+1 + JSR RDBTMP + LDYIM 0 +15 SEC ; GET POSITION IN BIT MAP + LDA MPTMPD + SBCIM 8 + STA MPTMPD + LDA MPTMPD+1 + SBCIM 0 + STA MPTMPD+1 + LDA MPTMPD+2 + SBCIM 0 + STA MPTMPD+2 + BCC #20 ; WHEN POSITION FOUND + INY + [ $CMOS + BRA #15 + | + JMP #15 + ] + +20 CLC ; GET BIT POSITION BACK + LDA MPTMPD + ADCIM 8 + STA MPTMPD + BCC #22 + INC MPTMPD+1 + BNE #22 + INC MPTMPD+2 +22 LDA MPTMPD + [ $Level3 + STA MPTMPC ; SAVE BIT COUNT + INC MPTMPC + | + INCA + STA MPTMPC ; SAVE BIT COUNT + ] + LDAIY MPSCPT ; GET CORRECT BYTE + LDXIM 9 +25 RORA ; ROTATE TO GET CORRECT POSITION + DEX + DEC MPTMPC + BNE #25 + PHA ;SAVE VALUE + [ $CMOS + PHY ;SAVE POSITION + | + TYA + PHA ;SAVE POSITION + ] + LDYIM 3 + LDAIY MAPGEN ; GET NUMBER OF BLOCKS TO BE DEALLOCATED + STA MPTMPC + INY + LDAIY MAPGEN + STA MPTMPC+1 + [ $CMOS + PLY ; GET POSITION BACK + | + PLA ; GET POSITION BACK + TAY + ] + PLA +30 SEC ;MARK BLOCK FREE + RORA + DEX + BEQ #40 + PHP + PHA ; SAVE VALUE +35 LDA MPTMPC ; DECREMENT COUNT + BNE #37 + DEC MPTMPC+1 +37 DEC MPTMPC + LDA MPTMPC+1 + ORA MPTMPC ; CHECK FOR END + BEQ #45 + PLA ; GET VALUE BACK + PLP + [ $CMOS + BRA #30 ; DEALLOCATE NEXT BLOCK + | + JMP #30 ; DEALLOCATE NEXT BLOCK + ] + +40 STAIY MPSCPT ; SAVE NEW VALUE + INY + LDAIY MPSCPT ; GET NEXT VALUE + RORA ; POSITION CORRECTLY + PHP + PHA + LDXIM 8 ;GIVE X CORRECT VALUE + [ $CMOS + BRA #35 + | + BNE #35 + ] + +45 CPXIM 0 + BEQ #55 ; BRANCH IF POSITION CORRECT + PLA ;BLOCKS HAVE BEEN DEALLOCATED SO CORRECT POSITION + PLP +50 RORA + DEX + BNE #50 ; KEEP GOING UNTIL BACK RIGHT + [ $CMOS + BRA #60 + | + BEQ #60 + ] + +55 PLA + PLP +60 STAIY MPSCPT ;SAVE VALUE + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JSR MBMWT + LDYIM 3 ; NOW CORRECT FREE BLOCK COUNT + LDAIY MAPGEN + STA MPTMPC + INY + LDAIY MAPGEN + STA MPTMPC+1 + LDYIM 0 + CLC ; NOW ADD TO FREE BLOCK COUNT + LDA MPTMPC + ADCIY MPCYPT + STAIY MPCYPT + INY + LDA MPTMPC+1 + ADCIY MPCYPT + STAIY MPCYPT + INY + LDAIM 0 + ADCIY MPCYPT + STAIY MPCYPT + CLC ;NOW GET POSITION IN CYLINDER MAP + LDAIM 3 + ADC MPCYPT + STA MPSCPT + LDAIM 0 + ADC MPCYPT+1 + STA MPSCPT+1 +65 LDA MAPTMP + ORA MAPTMP+1 ; HAVE WE GOT THERE ? + BEQ #70 + CLC ; MOVE TO NEXT ENTRY + LDA MPSCPT + ADCIM 2 + STA MPSCPT + BCC #67 + INC MPSCPT+1 +67 LDA MAPTMP ; DECREMENT CYLINDER COUNT + BNE #68 + DEC MAPTMP+1 +68 DEC MAPTMP + [ $CMOS + BRA #65 + | + JMP #65 + ] + +70 CLC ; NOW DO THE ADD + LDYIM 0 + LDAIY MPSCPT + ADC MPTMPC + STAIY MPSCPT + INY + LDAIY MPSCPT + ADC MPTMPC+1 + STAIY MPSCPT + LDA MAPGEN ; RESTORE SOME VALUES + STA MPSCPT + LDA MAPGEN+1 + STA MPSCPT+1 + LDYIM 0 + TYA + LDXIM 5 +75 STAIY MPSCPT + INY + DEX + BNE #75 + PLA + STA MAPTMP+1 + STA CBSTA+1 + PLA + STA MAPTMP + STA CBSTA + JMP MMBWT + +;CLRBLK +; DEALLOCATES ALL BLOCKS FROM A GIVEN ENTRY. +; THE ORIGINAL MAP BLOCK WILL BE DELETED IF A FLAG IS SET. +; +; ON ENTRY +; MPTMPA HOLDS THE SIN OF THE MAP BLOCK +; MPSCPT HOLDS THE OFFSET IN THE MAP BLOCK +; MPTMPE IF NON-ZERO IMPLIES MAP BLOCK TO BE DELETED +; + +CLRBLK ROUT + LDYIM MPCYMP + LDAIY MAPPTR + STA MPCYPT + INY + LDAIY MAPPTR + STA MPCYPT+1 + CLC + JSR RDMPBK ; MAKE SURE MAP BLOCK IS IN STORE + BNE #20 + CLC + LDA MAPTMP ; GET POINTER TO MAP BLOCK + STA MPMBPT + ADC MPSCPT ; GET CURRENT POSITION + STA MPSCPT + LDA MAPTMP+1 + STA MPMBPT+1 + ADC MPSCPT+1 + STA MPSCPT+1 +10 LDYIM 0 ; CHECK IF END OF BLOCK + LDAIY MPSCPT + INY + ORAIY MPSCPT + INY + ORAIY MPSCPT + BNE #30 ; END OF MAP BLOCK REACHED +15 LDA MPTMPE + BEQ #20 + LDA DNDLTE + BNE #20 + JSR DAMPBK +20 RTS + +30 CLC + LDA MPMBPT + ADCIM :LSB:LSTENT + TAX + LDA MPMBPT+1 + ADCIM :MSB:LSTENT + CPX MPSCPT ; CHECK FOR LAST ENTRY + BNE #60 + CMP MPSCPT+1 + BNE #60 + LDYIM 0 ; GET NEW SIN + LDAIY MPSCPT + STA MPTMPB + INY + LDAIY MPSCPT + STA MPTMPB+1 + INY + LDAIY MPSCPT + STA MPTMPB+2 + + LDYIM 4 + LDAIM 0 +40 STAIY MPSCPT ;clear out this pointer + DEY + BPL #40 ;**14/9/84** + JSR MMBWT ;**8/5/87** mark block written to + + JSR #15 ; CHECK IF THIS BLOCK TO BE DELETED + [ $CMOS + STZ DNDLTE + | + LDAIM 0 + STA DNDLTE + ] + LDAIM 1 + STA MPTMPE + LDA MPTMPB + STA MPTMPA + LDA MPTMPB+1 + STA MPTMPA+1 + LDA MPTMPB+2 + STA MPTMPA+2 + CLC + JSR RDMPBK ; READ IN NEW MAP BLOCK + CLC + LDA MAPTMP ;TRANSFER POINTER + STA MPMBPT + ADCIM :LSB:MBENTS ; GET TO POINT TO START OF ENTRIES + STA MPSCPT + LDA MAPTMP+1 + STA MPMBPT+1 + ADCIM :MSB:MBENTS + STA MPSCPT+1 +60 JSR DAGRP + LDA SAVSC + BNE #70 + INC SAVSC + JSR ENSMB + JSR ULBM +70 CLC ; MOVE TO NEXT ENTRY + LDA MPSCPT + ADCIM :LSB:ENSZ + STA MPSCPT + LDA MPSCPT+1 + ADCIM :MSB:ENSZ + STA MPSCPT+1 + JMP #10 + + LNK UADE13 diff --git a/FileServer/SRC/FileServer/Uade13 b/FileServer/SRC/FileServer/Uade13 new file mode 100644 index 0000000..cebdbb6 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade13 @@ -0,0 +1,1153 @@ + OPT UADE13 ;> Uade13 + TTL File server file UADE13 + +;FNDMAP: +;SEARCHES MAPTB LOOKING FOR DISC NUMBER +;WHICH IS IN ARGB AND ARGC. WHEN +;FOUND LEAVES A POINTER TO THE CORRECT ENTRY IN MAPPTR & MAPENT. +;NOTE THAT MAPENT IS USED BY DSCMAN & SHOULD +;NOT BE ALTERED BY MAPMAN. + +FNDMAP ROUT + [ $CMOS + STZ MPDRVE + STZ DRIVNO + | + LDAIM 0 + STA MPDRVE + STA DRIVNO + ] + LDA MAPTB ;START OF MAP TABLE + STA MAPPTR ;LOOK AT FIRST ENTRY + LDA MAPTB+1 + STA MAPPTR+1 + [ $Level3 + LDXIM 0 ;X HOLDS DRIVE NUMBER + ] +10 LDYIM MPDCNO ;OFFSET TO DISC NUMBER + LDAIY MAPPTR + LDYIM ARGB + CMPIY ARGPTR ;SEE IF ITS CORRECT DISC NUMBER + BNE #20 + LDYIM MPDCNO+1 + LDAIY MAPPTR + LDYIM ARGC + CMPIY ARGPTR + BEQ #30 ;BRANCH IF DISC NUMBER MATCHES +20 INC MPDRVE ; ** 14/06/86 ** drive numbers contiguous + JSR MPADMP ;GET NEXT ENTRY + INC DRIVNO + LDA DRIVNO + CMP DRIVES ;CHECK FOR END + BNE #10 ;BRANCH IF NOT AT END +;IF WE REACH HERE THE DISC WAS NOT FOUND + LDAIM MPERRA + RTS + +30 LDYIM MPNOCY ;Check no leg pull ** 14/06/86 ** + LDAIY MAPPTR + INY + ORAIY MAPPTR ;by non-zero cyl count ** 14/06/86 ** + BEQ #20 + LDA MAPPTR + STA MAPENT + LDA MAPPTR+1 + STA MAPENT+1 ;MAPENT := PTR TO MAPTB ENTRY + LDAIM 0 ;SUCESSFUL SO ZERO RC + RTS + +;CHECK MAP SIZE +; +;CHECKS THAT NEW CYLINDER MAP SIZE IS NOT GREATER THAN OLD +; +;SECTOR TWO INFO POINTED TO BY MPSCPT, +;MAP TABLE ENTRY BY MAPPTR +; +CHMPSZ ROUT + LDYIM MPNOCY+1 + LDAAY MAPTBF + PHA + DEY + LDAAY MAPTBF + PHA ;GET OLD NUMBER OF CYLINDERS + LDYIM MPNOCY ;SECTOR TWO NO. CYLINDERS + PLA + CMPIY MAPPTR + PLA + INY + SBCIY MAPPTR + LDAIM 0 + BCS #10 ;OLD MAP >= NEW MAP + LDAIM MPERRI +10 RTS + + +; +; +;FIND SIZE OF NEW MAP AND SAVE IT +; +; +MPMPSZ ROUT + LDYIM MPSECS ;NO. OF SECTORS ON DISC + LDAIY MAPPTR + STA MPTMPC ;SAVE IT + INY + LDAIY MAPPTR + STA MPTMPC+1 + INY + LDAIY MAPPTR + STA MPTMPC+2 + [ $CMOS + STZ MPTMPA + STZ MPTMPA+1 + STZ MPTMPA+2 + | + LDAIM 0 + STA MPTMPA + STA MPTMPA+1 + STA MPTMPA+2 + ] + LDYIM MPDSCS + LDAIY MAPPTR + TAX +10 CLC + LDA MPTMPA + ADC MPTMPC + STA MPTMPA + LDA MPTMPA+1 + ADC MPTMPC+1 + STA MPTMPA+1 + LDA MPTMPA+2 + ADC MPTMPC+2 + STA MPTMPA+2 + DEX + BNE #10 + LDYIM MPSCTT + LDA MPTMPA + STAIY MAPPTR + INY + LDA MPTMPA+1 + STAIY MAPPTR + INY + LDA MPTMPA+2 + STAIY MAPPTR + RTS +; +;DELETE THE RELEVANT OBJECT +; +MPDLTE LDYIM ARGD ;GET SIN + LDAIY ARGPTR + STA MPTMPA + INY + LDAIY ARGPTR + STA MPTMPA+1 + INY + LDAIY ARGPTR + STA MPTMPA+2 + LDAIM :LSB:MBENTS ;GET OFFSET TO START + STA MPSCPT + LDAIM :MSB:MBENTS + STA MPSCPT+1 + LDAIM 1 ;FLAG CURRENT MAP BLOCK TO BE DELETED + STA MPTMPE + STA SAVSC ;STOP EXTRA WORK + JMP CLRBLK ;REMOVE ALL ENTRIES +; +;INCREMENT MAPPTR TO NEXT MAPTB ENTRY +; + +MPADMP ROUT + CLC + LDAIM MPTBSZ + ADC MAPPTR + STA MAPPTR + BCC #10 + INC MAPPTR+1 +10 RTS + +DIVIDE ROUT + JSR DVDE ;CONVERT TO OLD DIVIDE + SEC + LDA DIVTMP + SBCIM 1 + STA DIVPAR + LDA DIVTMP+1 + SBCIM 0 + STA DIVPAR+1 + LDA DIVTMP+2 + SBCIM 0 + STA DIVPAR+2 + RTS + +;ADD NAME TABLE ENTRY LENGTH TO +;DNMPTR. + +INAMPT ROUT + CLC + LDAIM NTENSZ + ADC DNMPTR + STA DNMPTR + BCC #00 + INC DNMPTR+1 +00 RTS + + +;DIVIDE SECTORS +; +; CALCULATES A CYLINDER NUMBER FROM A SIN +; +;ON ENTRY +; MPTMPA HOLDS THE SIN +; +;ON EXIT +; MPTMPB HOLDS THE CYLINDER +; +;USES MPTMPA +; + [ $CMOS +DIVSEC STZ MPTMPB + STZ MPTMPB+1 ;CLEAR VARIABLE + | +DIVSEC LDAIM 0 + STA MPTMPB + STA MPTMPB+1 ;CLEAR VARIABLE + ] +10 LDYIM MPSPCY + SEC + LDA MPTMPA + SBCIY MAPPTR ;DIVIDE BY SECTORS PER CYLINDER + STA MPTMPA + INY + LDA MPTMPA+1 + SBCIY MAPPTR + STA MPTMPA+1 + LDA MPTMPA+2 + SBCIM 0 + STA MPTMPA+2 + BCC #00 + INC MPTMPB + BNE #10 + INC MPTMPB+1 + [ $CMOS + BRA #10 + | + JMP #10 + ] + + +;TAKE TEXT DISC NAME FROM DNMBUF +;AND PUT IN NAME TABLE ENTRY AT +;DNMPTR. ALSO PUT IN NEW DISC NUMBER +;FROM NXTDNO, AND MARK ENTRY IN USE. +;DISC NO. ALSO PLACED IN MAP TABLE ENTRY +;POINTED TO BY MAPPTR. + +;ALSO INCREMENT NXTDNO !! + +SDSCNM ROUT + LDYIM NTNAME + LDXIM 0 + +10 LDAAX DNMBUF + STAIY DNMPTR + INY + INX + CPXIM DNAMLN + BNE #10 + + LDYIM NTDNO + LDA NXTDNO + PHA + STAIY DNMPTR ;SET DISC NO. LO + INY + LDA NXTDNO+1 + STAIY DNMPTR + + LDYIM MPDCNO+1 + STAIY MAPPTR ;DISC NO. IN MAP TABLE + DEY + PLA + STAIY MAPPTR + + LDYIM NTUSED + LDAIM USED + STAIY DNMPTR + + INC NXTDNO + BNE #20 + INC NXTDNO+1 +20 LDAIM 0 + RTS + +; +;SET UP CYLINDER MAP FOR CURRENT DISC +; +MPSTCY ROUT + LDAIM 1 + STA RSTFLG + LDYIM MPCYMP + CLC + LDAIY MAPPTR + ADCIM 3 ;TO POINT AT ACTUAL ENTRIES + STA MPCYPT + INY + LDAIY MAPPTR + ADCIM 0 + STA MPCYPT+1 + [ $CMOS + STZ MPTMPC + STZ MPTMPC+1 + STZ MPTMPA+2 ;** 21/11/84 ** + | + LDAIM 0 + STA DDRSZE+2 + STA MPTMPC + STA MPTMPC+1 + STA MPTMPA+2 ;** 21/11/84 ** + ] +10 LDYIM MPSCYL + LDA MPTMPC + CMPIY MAPPTR + INY + LDA MPTMPC+1 + SBCIY MAPPTR + BCS #20 + LDAIM 0 + TAY + STAIY MPCYPT + INY + STAIY MPCYPT + CLC + LDA MPCYPT + ADCIM 2 + STA MPCYPT + BCC #15 + INC MPCYPT+1 +15 INC MPTMPC + BNE #10 + INC MPTMPC+1 + [ $CMOS + BRA #10 + | + JMP #10 + ] + +20 STA MPTMPB + STA MPTMPB+1 + STA MPTMPB+2 + [ $CMOS +25 STZ MPTMPA ;LOOP TO READ IN BIT MAPS + STZ MPTMPA+1 + | +25 LDAIM 0 + STA MPTMPA ;LOOP TO READ IN BIT MAPS + STA MPTMPA+1 + ] + + LDA MPTMPA+2 ;check not skipping + BEQ #30 + DEC MPTMPA+2 ;counter for maps to skip + [ $CMOS + BRA #60 + | + JMP #60 + ] + +30 JSR RDBTMP + + LDYIM MP1BIT + LDAIY MAPPTR ;**23/1/87** no valid flag if packed map + BNE #32 + LDYIM MPVAL ;check that subsequent maps are valid + LDAIY MPSCPT ;** 21/11/84 ** + STA MPTMPA+2 ;save this flag [n<>0 => skip n maps] + +32 LDYIM MPSPCY + LDAIY MAPPTR + STA MAPTMP + INY + LDAIY MAPPTR + STA MAPTMP+1 ;SECTORS PER CYCLINDER +35 LDXIM 8 ;EIGHT BITS PER BYTE + LDYIM 0 + LDAIY MPSCPT +40 RORA ;CHECK IF SECTOR FREE + BCC #45 ;CLEAR IF ALLOCATED + INC MPTMPA ;COUNT OF FREE SECTORS + BNE #45 + INC MPTMPA+1 +45 PHA + LDA MAPTMP ;TO CHECK FOR END OF MAP + BNE #47 + DEC MAPTMP+1 +47 DEC MAPTMP + LDA MAPTMP+1 + ORA MAPTMP + BEQ #50 ;BRANCH IF END OF MAP + PLA + DEX ;FOR END OF BYTE + BNE #40 + INC MPSCPT ;INCREMENT POINTER TO BIT MAP + BNE #35 + INC MPSCPT+1 + [ $CMOS + BRA #35 ;TO LOOK AT NEXT BIT + | + JMP #35 ;TO LOOK AT NEXT BIT + ] + +50 PLA ;REMOVE SAVED REG. +60 LDA MPTMPA + STAIY MPCYPT ;SAVE COUNT OF FREE SECTORS + CLC + ADC MPTMPB ;SAVE TOTAL + STA MPTMPB + INY + LDA MPTMPA+1 + STAIY MPCYPT + ADC MPTMPB+1 + STA MPTMPB+1 + BCC #63 + INC MPTMPB+2 +63 CLC ;MOVE POINTER TO NEXT ENTRY + LDA MPCYPT + ADCIM 2 + STA MPCYPT + BCC #66 + INC MPCYPT+1 +66 INC MPTMPC + BNE #70 + INC MPTMPC+1 +70 LDYIM MPNOCY ;CHECK FOR END OF DISC + LDA MPTMPC + CMPIY MAPPTR + INY + LDA MPTMPC+1 + SBCIY MAPPTR + BCS #80 + JMP #25 + +80 LDYIM MPCYMP ;END OF MAPS SO SAVE TOTAL COUNT + LDAIY MAPPTR + STA MPSCPT + INY + LDAIY MAPPTR + STA MPSCPT+1 + LDYIM 0 + LDA MPTMPB + STAIY MPSCPT + INY + LDA MPTMPB+1 + STAIY MPSCPT + INY + LDA MPTMPB+2 + STAIY MPSCPT + LDAIM 0 + STA RSTFLG + RTS + +;FIND SIZE OF OBJECT +; +;ON ENTRY +; MPMBPT POINTS TO MAP BLOCK +; ARGD holds SIN of MAP root +; +;ON EXIT +; MPTMPA HOLDS NUMBER OF BYTES +; MPTMPD HOLDS NUMBER OF BLOCKS +; +; +MPGTSZ ROUT + [ $CMOS + STZ MPTMPD + STZ MPTMPD+1 + STZ MPTMPD+2 ;ZERO BLOCK COUNT + | + LDAIM 0 + STA MPTMPD + STA MPTMPD+1 + STA MPTMPD+2 ;ZERO BLOCK COUNT + ] +10 LDAIM :LSB:MBENTS + STA MPTMPB + LDAIM :MSB:MBENTS + STA MPTMPB+1 ;OFFSET +20 ;ADD UP NEXT ENTRY + CLC + LDA MPMBPT + ADC MPTMPB + STA MPSCPT + LDA MPMBPT+1 + ADC MPTMPB+1 + STA MPSCPT+1 + LDYIM 0 + LDAIY MPSCPT + INY + ORAIY MPSCPT + INY + ORAIY MPSCPT + BEQ #50 + LDA MPTMPB + CMPIM :LSB:LSTENT + LDA MPTMPB+1 + SBCIM :MSB:LSTENT + BCS #30 + LDYIM 3 + CLC + LDA MPTMPD + ADCIY MPSCPT + STA MPTMPD + INY + LDA MPTMPD+1 + ADCIY MPSCPT + STA MPTMPD+1 + BCC #25 + INC MPTMPD+2 +25 CLC + LDA MPTMPB + ADCIM ENSZ + STA MPTMPB + BCC #20 + INC MPTMPB+1 + [ $CMOS + BRA #20 + | + JMP #20 + ] + +30 ;GET NEXT MAP BLOCK + LDYIM 0 + LDAIY MPSCPT + STA MPTMPA + INY + LDAIY MPSCPT + STA MPTMPA+1 + INY + LDAIY MPSCPT + STA MPTMPA+2 + CLC + JSR RDMPBK + BEQ #40 +35 LDAIM MPERRC + RTS + +40 LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + JMP #10 + +50 JSR RDmpbd ;**8/5/87** Read block at ARGD + BNE #35 + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + + ;CALCULATE BYTES FROM BLOCKS + LDA MPTMPD ;NUMBER OF BLOCKS + STA MPTMPB + LDA MPTMPD+1 + STA MPTMPB+1 + LDA MPTMPD+2 + STA MPTMPB+2 + [ $CMOS + STZ MPTMPA ;ZERO BYTE COUNT + STZ MPTMPA+1 + STZ MPTMPA+2 + | + LDAIM 0 + STA MPTMPA ;ZERO BYTE COUNT + STA MPTMPA+1 + STA MPTMPA+2 + ] + LDA MPTMPD + ORA MPTMPD+1 + ORA MPTMPD+2 + BEQ #90 +60 LDA MPTMPB + BNE #62 + LDA MPTMPB+1 + BNE #61 + DEC MPTMPB+2 +61 DEC MPTMPB+1 +62 DEC MPTMPB + LDA MPTMPB+2 + ORA MPTMPB+1 + ORA MPTMPB + BEQ #70 + JSR #95 ; MPTMPA := MPTMPA+BTINBK + [ $CMOS + BRA #60 + | + JMP #60 + ] + +70 ;GET BYTES IN LAST BLOCK + LDYIM BILB + LDAIY MPMBPT + INY + ORAIY MPMBPT + BNE #80 + JSR #95 ;MPTMPA := MPTMPA+BTINBK + [ $CMOS + BRA #90 + | + JMP #90 + ] + +80 LDYIM BILB + CLC + LDA MPTMPA + ADCIY MPMBPT + STA MPTMPA + INY + LDA MPTMPA+1 + ADCIY MPMBPT + STA MPTMPA+1 + BCC #90 + INC MPTMPA+2 +90 LDAIM 0 + RTS + +95 CLC ; MPTMPA := MPTMPA+BTINBK + LDA MPTMPA + ADCIM :LSB:BTINBK + STA MPTMPA + LDA MPTMPA+1 + ADCIM :MSB:BTINBK + STA MPTMPA+1 + BCC #99 + INC MPTMPA+2 +99 RTS + +;CHDNAM + +;LOOK UP DISC NAME IN SECTOR ZERO INFO +;POINTED TO BY MPSCPT. +;IF FOUND, AND ENTRY IN USE -> ERROR +;IF FOUND, ENTRY NOT IN USE, MARK IN USE +;AND SET MAP TABLE ENTRY DISC NO. FROM TABLE +;IF NOT FOUND, CHUCK OUT LRU DISC NO. NOT +;CURRENTLY IN USE, INSERT NEW NAME AND GIVE IT +;A NEW DISC NUMBER (FROM NXTDNO). MARK ENTRY IN USE. +;SET DISC NO. IN MAP TABLE + +;ON ENTRY MAPPTR -> MAP TABLE ENTRY + + +CHDNAM ROUT + JSR FNDDSC ;EXIT WITH DNMPTR POINTING TO ENTRY + BNE #20 ;NOT FOUND, THROW AN ENTRY OUT + +;IF HERE, DISC FOUND. IF IN USE, THEN ERROR +;COZ => TWO DISCS OF SAME NAME IN USE +;ON SAME SYSTEM. IF NOT IN USE, RETURN +;DISC NUMBER. + + LDYIM NTUSED + LDAIY DNMPTR + BNE #10 ;NOT IN USE, OK + + LDAIM MPERRJ + RTS ;ERROR + +10 LDYIM NTDNO + LDAIY DNMPTR + PHA + INY + LDAIY DNMPTR + +;NOW SET MAP TABLE ENTRY + + LDYIM MPDCNO+1 + STAIY MAPPTR + DEY + PLA + STAIY MAPPTR + +;MARK NAME TABLE ENTRY IN USE + + LDYIM NTUSED + LDAIM USED + STAIY DNMPTR + + [ $CMOS + BRA #30 ;FOUND FINISH + | + JMP #30 ;FOUND FINISH + ] + + +20 JSR LRUDSC + +;NOW DNMPTR => LRU NAME ENTRY + + JSR SDSCNM + +30 LDAIM 0 + RTS ;EXIT + + +;MOVE DISC NAME FROM SEC. ZERO +;TO DNMBUF. + +MOVDNM ROUT + LDXIM 0 + LDYIM MPSZNM +10 LDAIY MPSCPT + STAAX DNMBUF + INY + INX + CPXIM DNAMLN + BNE #10 + RTS + + +;FNDDSC + +;ENTRY: MPSCPT -> SECTOR ZERO INFO, INCLUDING DISC NAME + +;EXIT: DNMPTR -> NAME TABLE ENTRY IF FOUND +;Z FLAG SET IF FOUND + +;SIDE EFFECT: DISC NAME MOVED TO DNMBUF + +FNDDSC ROUT + JSR MOVDNM ;MOVE DISC NAME TO DNMBUF + +FNDNAM LDA NAMETB + STA DNMPTR + LDA NAMETB+1 + STA DNMPTR+1 ;SET P.0 POINTER + LDAIM NTSIZE ;NO. OF ENTRIES IN NAMTAB + STA TEMPA + +10 LDYIM NTNAME ;NAMTAB OFFSET + LDXIM 0 +20 LDAIY DNMPTR + EORAX DNMBUF ;Compare + ANDIM &DF ;Force cases + BNE #30 + INX + INY + CPXIM DNAMLN + BNE #20 + RTS + +;IF HERE, NAME FOUND, Z SET. + +30 DEC TEMPA + BEQ #40 ;SEARCH FINISHED, NOT FOUND + JSR INAMPT ;SET DNMPTR TO POINT TO NEXT ENTRY + [ $CMOS + BRA #10 ;DO NEXT ENTRY + | + JMP #10 ;DO NEXT ENTRY + ] + +40 LDAIM MPERRK ;UNSET Z FLAG + RTS + + + +;LRUDSC + +;SEARCH NAME TABLE FOR LRU ENTRY + +;ON EXIT DNMPTR -> LRU ENTRY + +LRUDSC ROUT + LDA NAMETB + STA GENPTR + LDA NAMETB+1 + STA GENPTR+1 + + LDAIM &FF + STA TEMPA ;USED TO KEEP PARTIAL RESULT + LDXIM NTSIZE ;NO. OF ENTRIES + +10 LDYIM NTUSED ;OFFSET OF USE FLAG + LDAIY GENPTR + BEQ #20 ;IN USE -> NO GOOD + + CMP TEMPA + BCS #20 ;TABLE ENTRY>=TEMPA, CONTINUE + + STA TEMPA ;NEW PARTIAL RESULT + LDA GENPTR + STA DNMPTR ;SET POINTER TO PARTIAL RESULT ENTRY + LDA GENPTR+1 + STA DNMPTR+1 + +20 DEX + BEQ #30 ;ALL ENTRIES DONE, FINISH + + CLC + LDAIM NTENSZ + ADC GENPTR + STA GENPTR + BCC #10 + INC GENPTR+1 + [ $CMOS + BRA #10 + | + JMP #10 + ] + +30 RTS + + + +;DDNAME + [ 1=0 +;DELETE DISC NAME POINTED TO BY +;DNMPTR. +;PUT $80 IN FIRST CHAR. OF NAME SO +;IT WON'T BE RECOGNISED AND SET +;USED FLAG TO UNUSED. + +DDNAME ROUT + LDYIM NTNAME + LDAIM &80 + STAIY DNMPTR + LDYIM NTUSED + LDAIM UNUSED + STAIY DNMPTR + RTS + ] + +;FNDDNO +;LOOK UP CURDNO IN NAMETABLE. +;EXIT: NAMTAB -> ENTRY, Z SET IF FOUND + +FNDDNO ROUT + JSR SDNMPT + LDXIM NTSIZE-1 + +10 LDYIM NTDNO + LDA CURDSC + CMPIY DNMPTR + BNE #20 + INY + LDA CURDSC+1 + CMPIY DNMPTR + BEQ #30 ;FOUND, FINISH + +20 JSR INAMPT ;MOVE DNMPTR + DEX + BPL #10 + +30 RTS + + + +;AGENTB +;AGE ALL ENTRIES NOT IN USED IN THE +;DISC NAME TABLE + +AGENTB ROUT + JSR SDNMPT + LDXIM NTSIZE + LDYIM NTUSED +10 LDAIY DNMPTR + BEQ #20 ;IN USE, DON'T AGE + [ $CMOS + DECA ;AGE + | + SEC + SBCIM 1 ;AGE + ] + STAIY DNMPTR +20 JSR INAMPT + DEX + BNE #10 + RTS + + +SDNMPT LDA NAMETB + STA DNMPTR + LDA NAMETB+1 + STA DNMPTR+1 + RTS + + +;CHECK SECTOR ZERO INFO (POINTED TO BY MPSCPT) IS FOR A VALID FS DISC +;If a Winchester, check for suitable company copyright. + +TAGTAB = "AFS0" + +CHKDSC ROUT + [ $CMOS + LDA MPdrve ;**23/1/87** Check if Winnie + CMPIM 4 + BCS #00 ;br if floppy + LDXIM CAcopy + JSR OSrdad ;**23/3/88** find if check to be done + BNE #00 + LDAIM &25 ;check user page A + LDXIM :LSB:CAcorn + LDYIM :MSB:CAcorn + JSR #50 + BNE #30 + LDAIM &26 ;check user page B + LDXIM :LSB:(CAcorn+4) + LDYIM :MSB:(CAcorn+4) + JSR #50 + BNE #30 + ] + +00 LDYIM MPDRNM+3 ;POINTER TO NAME + LDXIM 4 +10 LDAAX TAGTAB-1 + CMPIY MPSCPT + BNE #30 + DEY + DEX + BNE #10 ;IF EQ, DROP THROUGH AND EXIT, Z SET +20 RTS + +30 LDAIM MPERRD + RTS + + [ $CMOS +50 STX Movto ;Save pointer into copyright + STY Movto+1 + LDXIM Cmd+5 ;Zero disc control block +60 STZAX Dsccb + DEX + BPL #60 + STA Dsccb+Cmd+2 ;Set page number + LDA Mpdrve ;**1/8/88** + ASLA + ASLA + ASLA + ASLA + ASLA + STA Dsccb+Cmd+1 + LDAIM &1A ;Mode sense command + STA Dsccb+Cmd + CLC + LDA Mpscpt ;Where to read user pages + STA Dsccb+Tradd + ADCIM 3 + STA Movfrm ; location of block descriptor length + LDA Mpscpt+1 + INCA ;**6/7/88** don't overlay sector zero on restart + STA Dsccb+Tradd+1 + ADCIM 0 + STA Movfrm+1 + LDAIM 20 ;Max length of data area + STA Dsccb+Cmd+4 + JSR Dsccmd + BNE #20 ;exit on any error, Z clear + CLC ;**8/8/87** allow SCSI 4A spec + LDAI Movfrm ; load block descriptor length + ADCIM 6 ; skip block header plus page descriptor + ADC Mpscpt + STA Movfrm + LDA Mpscpt+1 + ADCIM 1 + STA Movfrm+1 ; point to user data + LDXIM 4 + JMP Compar ;go compare text and return + ] + + +;SMAPEN +;MOVE SECTOR ZERO INFO. POINTED TO +;BY MPSCPT INTO MAP TABLE ENTRY +;POINTED TO BY MAPPTR + +SMAPEN ROUT + CLC ;COPY AREA OF STORE + LDA MAPPTR + ADCIM MPNOCY ;MAKE MAPPTR POINT TO START OF AREA + STA MOVTO + LDA MAPPTR+1 + ADCIM 0 + STA MOVTO+1 ;STORE IN POINTER TO COPY + CLC + LDA MPSCPT + ADCIM MPSZNC ;TO POINT TO DISC INFO + STA MOVFRM + LDA MPSCPT+1 + ADCIM 0 + STA MOVFRM+1 ;POINTER FOR MOVING TO + LDXIM MPSZLN + JMP MOVE ;MOVE AND EXIT + +;Zeroes an area of disc. Is a psuedo +;map management routine. +; +;On entry +; OLDSZE = Old size in bytes +; MPTMPA = SIN of object +; +;On exit Z set if sucessful + +ZERDSK ROUT + JSR FNDMAP + BEQ #10 +05 RTS + +10 CLC + JSR RDMPBK ;Requires SIN in MPTMPA + BNE #05 + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + LDA OLDSZE + STA DIVPAR + LDA OLDSZE+1 + STA DIVPAR+1 + LDA OLDSZE+2 + STA DIVPAR+2 + JSR DVDE + BCC #15 + LDAIM &F9 + JSR INTERR +15 LDAIM 2 + LDY OLDSZE + BNE #20 + [ $CMOS + DECA ; now 1 + | + LDAIM 1 + ] +20 STA DIVPAR + SEC + LDA DIVTMP + SBC DIVPAR ;START FROM BLOCK ZERO + STA BREGA + LDA DIVTMP+1 + SBCIM 0 + STA BREGA+1 + LDAIM &FF + STA NBLKS + STA NBLKS+1 + JSR DCENT2 + BEQ #30 + JMP #90 + +;MAPTMP holds SIN of current disc block +;MPTMPD holds count of number in this entry +;Now zero out rest of current block +30 LDA MAPTMP + STA MPTMPA + LDA MAPTMP+1 + STA MPTMPA+1 + LDA MAPTMP+2 + STA MPTMPA+2 + LDA OLDSZE + ORA OLDSZE+1 + ORA OLDSZE+2 + BEQ #40 + LDA OLDSZE + BEQ #60 ;If all of this block used continue +40 CLC + JSR RDMPBK ;Pretend its map block + LDA MAPTMP ;Ignore possible error + STA MPCYPT + LDA MAPTMP+1 + STA MPCYPT+1 + LDY OLDSZE + LDAIM 0 +50 STAIY MPCYPT ;Zero rest of block + INY + BNE #50 + JSR SETMB + JSR CASTWB ;Mark block written + JSR ENSMB ;Write it to disc + JSR SETMB + JSR FNDBLK ;FIND BLOCK TO FLUSH + LDAIM 0 + LDYIM CAFLG + STAIY GNCBPT + LDA MPTMPD + BNE #55 + DEC MPTMPD+1 +55 DEC MPTMPD + INC MPTMPA + BNE #60 + INC MPTMPA+1 + BNE #60 + INC MPTMPA+2 +;Next bit writes 0's to MPTMPD entries until +;none left. +60 + [ $Level3 + JSR SETBM ;Use bit maps + JSR GETFR + LDYIM CBSA + LDAIY GNCBPT + STA MPCYPT + INY + LDAIY GNCBPT + STA MPCYPT+1 + LDYIM 0 + TYA +70 STAIY MPCYPT + INY + BNE #70 ;Area of store zeroed + LDA MPCYPT + STA DCSTAD + LDA MPCYPT+1 + STA DCSTAD+1 + | + STZ DCSTAD ;**29/4/88** zero store address + STZ DCSTAD+1 ;**29/4/88** MOS treats as write zeroes + ] + + LDA MPDRVE + STA DRIVNO +75 LDA MPTMPD + ORA MPTMPD+1 + BEQ #80 + LDA MPTMPA + STA RBDA + LDA MPTMPA+1 + STA RBDA+1 + LDA MPTMPA+2 + STA RBDA+2 + LDAIM &A + STA SAVCOM + [ $Level3 + JSR XFER + LDA MPTMPD + BNE #77 + DEC MPTMPD+1 +77 DEC MPTMPD + INC MPTMPA + BNE #75 + INC MPTMPA+1 + BNE #75 + INC MPTMPA+2 + [ $CMOS + BRA #75 + | + JMP #75 + ] + | + JSR XFERIN ;**29/4/88** + ] + +80 JSR NXTEN + BNE #90 + LDA MAPTMP + STA MPTMPA + LDA MAPTMP+1 + STA MPTMPA+1 + LDA MAPTMP+2 + STA MPTMPA+2 + [ $CMOS + BRA #75 + | + JMP #75 + ] + +90 LDAIM 0 + RTS + + LNK MBBMCM diff --git a/FileServer/SRC/FileServer/Uade14 b/FileServer/SRC/FileServer/Uade14 new file mode 100644 index 0000000..fd70e52 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade14 @@ -0,0 +1,1011 @@ + OPT UADE14 ; > Uade14 + TTL File server file UADE14 + + [ $Level3 +DSCTOP + ORG DSCTOP + ] + +;********************************* +;* D S C M A N * +;********************************* + +;DSCMAN: THE DISC MANAGER +;THIS MODULE READS & WRITES OBJECTS FROM +;AND TO THE DISC. +;NOTE THAT IT USES MANY OF THE POINTERS,VARIABLES, +;AND ROUTINES PROVIDED BY MAPMAN. + + +;ENTRY: +;ARGA = (1=>READ,2=>WRITE) +;ARGB-C DISC NO +;ARGD-F SIN +;ARGG-H START BLOCK NO +;ARGI-J NUMBER OF BLOCKS +;ARGK-L STORE ADDRESS + +;EXIT: ARGA = RC + + + +;********** MAIN ROUTINE ********** + +DSCMAN ROUT + LDXIM 4 + LDAIM MODDSC + JSR ENTRY + [ $Level3 + LDAAX DCRTNS + STA DCJUMP+1 + LDAAX DCRTNS+1 + STA DCJUMP+2 +DCJUMP JMP DCJUMP ;N.B. NO NEED FOR SETFS-NOT CALLING ANY MODULE + | + JMIX DCRTNS ;N.B. NO NEED FOR SETFS-NOT CALLING ANY MODULE + ] +DCRTNS + & DCREAD ;1 => READ + & DCWRIT ;2 => WRITE + & DCIORD ;3 => READ (I/O processor style) + & DCIOWR ;4 => WRITE (I/O processor style) + [ $Level3 +DCEXIT BEQ DCEXEX + LDXIM &FF + STX ODSCMN ;invalidate cache on disc error + STX ODSCMN+1 +DCEXEX JMP PREXIT + | +DCEXIT JMP PREXIT + ] + + +;************ DCREAD ************ + + +;DCREAD: READ AN OBJECT FROM THE DISC. +;NOTE IF A SECTOR HAS NOT BEEN WRITTEN THEN +;THE APPROPRIATE AREA OF STORE IS CLEARED TO ZERO. + + +DCIORD ROUT + [ $Level3 + JSR DCCACH ;check call against last caller + BEQ #40 ;all done !!!!! + + LDXIM &FF ;for I/O side operation + BNE #10 +DCREAD LDXIM 0 +10 STX DSCCB+TRADD+2 + STX DSCCB+TRADD+3 + | +DCREAD LDAIM 8 ;Select MOS read command +00 PHA ;**29/2/88** save function code + ] + + JSR DCINIT ;INITIALISE FOR DSCMAN VARIABLES + + [ $Level3 + BNE #30 + + [ WINCH=0 + LDAIM 8 + | + LDAIM &53 ;DOS READ COMMAND + ] + STA SAVCOM ;SAVCOM := DOS DISC READ COMMAND + +20 JSR SETDSE ;DCSECT := SECTOR NUMBER + + + JSR SETDES ;SETUP DOS DISC DRIVE DESCRIPTOR + + [ DEBUG <> 0 + LDAIM "r" + JSR TRACE + ] + | ; or not level 3 + TAX + PLA + STA SAVCOM ;**29/2/88** restore function code + TXA + BNE #30 + +20 LDA MAPTMP ;DCSECT := MAPTMP (I.E SECTOR NUMBER) + STA DCSECT + STA RBDA + LDA MAPTMP+1 + STA DCSECT+1 + STA RBDA+1 + LDA MAPTMP+2 + STA DCSECT+2 + STA RBDA+2 + + LDA LDRNB ;Set logical drive number + STA DRIVNO + ] + + LDA DCRASH + BNE #40 ;If a disc error occured in NMI task...error. + + JSR XFERIN ;TRANSFER MPTMPD SECTORS + JSR MOVEON ;FIND NEXT SECTORS FROM DISC MAP + BEQ #20 + CMPIM 1 + BNE #30 ;no more to transfer + [ $CMOS + DECA ;set zero + | + LDAIM 0 + ] +30 TAX + LDA DCRASH + BNE #40 ;Check no crash on last BG job + TXA + [ $CMOS +40 BRA DCEXIT + | +40 JMP DCEXIT + ] + + + +;************ DCWRIT ************ + + +;DCWRIT: WRITE AN OBJECT TO DISC +;NOTE THAT IF A SECTOR IS WRITTEN FOR THE FIRST TIME +;IT IS MARKED DIRTY IN THE MAP (IN WHICH CASE +;THE MAP IS MARKED DIRTY). + + + [ $Level3 +DCIOWR ROUT + JSR DCCACF ;copy new stack into variables + LDXIM &FF ;for I/O side operation + BNE #10 +DCWRIT JSR DCSIN ;check invalidation of cache + LDXIM 0 +10 STX DSCCB+TRADD+2 + STX DSCCB+TRADD+3 + JSR DCINIT + BNE #30 + + [ WINCH=0 + LDAIM &0A + | + LDAIM &4B ;DOS DISC WRITE COMMAND + ] + STA SAVCOM ;SAVCOM:=COMMAND TO WRITE +20 JSR SETDSE ;DCSECT:=SECTOR NUMBER + JSR SETDES ;SETUP DRIVE DESCRIPTOR FOR DOS + + [ DEBUG <> 0 + LDAIM "w" + JSR TRACE + ] + + LDA DCRASH + BNE #30 + + JSR XFERIN ;START TRANSFR OF ONE SECTOR + + JSR MOVEON + BEQ #20 + + TAX + LDA DCRASH + BNE #30 + TXA + CMPIM 1 + BNE #30 ;NO MORE SECTORS TO READ + LDAIM 0 +30 JMP DCEXIT + | +DCIOWR +DCWRIT LDAIM &0A ;Select MOS write command + BRA #00 + ] + +;DCINIT: INITIALISE DSCMAN VARIABLES FOR TRANSFER +;0) GET APPROPRIATE DISC MAP LOADED +;1) LDRNB := LOGICAL DRIVE NUMBER (GOT FROM MAPTB ENTRY) +;2) NBLKS := NUMBER OF DISC BLOCKS TO TX +;3) DCSTAD := STORE ADDRESS OF SECTOR +;4) CHECK SIN IS FOR START OF OBJECT +;5) MAPTMP := SIN, MPSCPT:=PTR TO RELEVENT MAP ENTRY +;6) DSCTMP := PTR TO MAP'S DIRTY FLAG + + + +DCINIT ROUT + [ $CMOS + STZ DSCCB+TRADD+2 ;Zero high store addr + STZ DSCCB+TRADD+3 + STZ DCRASH ;Initialise disc error flag + | + LDAIM 0 + STA DCRASH ;Initialise disc error flag + ] + JSR FNDMAP ;MAPPTR & MAPENT PT MAPTB ENTRY + BNE #20 + LDA MPDRVE + STA LDRNB ;LDRNB:= LOGICAL DRIVE NUMBER + +;FIRST CHECK THAT THE SPECIFIED SIN IS SENSIBLE + + LDYIM ARGD + LDAIY ARGPTR + STA MPTMPA + INY + LDAIY ARGPTR + STA MPTMPA+1 ;MPTMPA:=SIN + INY + LDAIY ARGPTR + STA MPTMPA+2 + CLC + JSR RDMPBK + BNE #20 + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + [ $CMOS + STZ NBLKS+1 + | + LDAIM 0 + STA NBLKS+1 + ] + LDYIM ARGI + LDAIY ARGPTR + STA NBLKS ;NBLKS:=NUMBER OF SECTORS TO BE TX + BNE #30 +10 LDAIM DCERRA ;INVALID NUMBER OF BLOCKS +20 RTS + +30 INY + LDAIY ARGPTR + BNE #10 + + LDYIM ARGK + LDAIY ARGPTR + STA DCSTAD + INY + LDAIY ARGPTR + STA DCSTAD+1 ;DCSTAD:=STORE ADDRESS + + +;NOW GET TO THE CORRECT STARTING POINT IN THE OBJECT + + LDYIM ARGG + LDAIY ARGPTR + STA BREGA + INY + LDAIY ARGPTR + STA BREGA+1 ;BREGA:=START BLOCK NUMBER + +DCENT2 LDAIM :LSB:MBENTS + STA MPTMPB + LDAIM :MSB:MBENTS + STA MPTMPB+1 + CLC + LDA MPMBPT + ADC MPTMPB + STA MPSCPT + LDA MPMBPT+1 + ADC MPTMPB+1 + STA MPSCPT+1 +50 SEC + LDYIM 3 + LDA BREGA + SBCIY MPSCPT + STA BREGA + LDA BREGA+1 + INY + SBCIY MPSCPT + STA BREGA+1 + BCC #60 + JSR NXTEN + BEQ #50 + RTS + +60 CLC + LDYIM 3 + LDAIY MPSCPT + ADC BREGA + STA BREGA + INY + LDAIY MPSCPT + ADC BREGA+1 + STA BREGA+1 + LDYIM 0 + CLC + LDAIY MPSCPT + ADC BREGA + STA MAPTMP + INY + LDAIY MPSCPT + ADC BREGA+1 + STA MAPTMP+1 + INY + LDAIY MPSCPT + ADCIM 0 + STA MAPTMP+2 + SEC + INY + LDAIY MPSCPT + SBC BREGA + STA MPTMPD + INY + LDAIY MPSCPT + SBC BREGA+1 + STA MPTMPD+1 + JSR SETSZE + + LDAIM 0 + RTS + +SETSZE ROUT + LDA NBLKS + CMP MPTMPD + LDA NBLKS+1 + SBC MPTMPD+1 + BCS #10 + LDA NBLKS + STA MPTMPD + LDA NBLKS+1 + STA MPTMPD+1 +10 RTS + +NXTEN ROUT + CLC + LDA MPTMPB + ADCIM :LSB:ENSZ + STA MPTMPB + LDA MPTMPB+1 + ADCIM :MSB:ENSZ + STA MPTMPB+1 +10 CLC + LDA MPMBPT + ADC MPTMPB + STA MPSCPT + LDA MPTMPB+1 + ADC MPMBPT+1 + STA MPSCPT+1 + LDYIM 0 + LDAIY MPSCPT + INY + ORAIY MPSCPT + INY + ORAIY MPSCPT + BEQ #30 + LDA MPTMPB + CMPIM :LSB:LSTENT + LDA MPTMPB+1 + SBCIM :MSB:LSTENT + BCC #40 + LDYIM 0 + LDAIY MPSCPT + STA MPTMPA + INY + LDAIY MPSCPT + STA MPTMPA+1 + INY + LDAIY MPSCPT + STA MPTMPA+2 + LDA DSCCB+TRADD+2 + PHA + LDA DCSTAD + PHA + LDA DCSTAD+1 + PHA + LDA SAVCOM + PHA + CLC + JSR RDMPBK + BNE #20 + PLA + STA SAVCOM + PLA + STA DCSTAD+1 + PLA + STA DCSTAD + PLA + STA DSCCB+TRADD+2 + STA DSCCB+TRADD+3 + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + LDAIM :LSB:MBENTS + STA MPTMPB + LDAIM :MSB:MBENTS + STA MPTMPB+1 + [ $CMOS + BRA #10 + | + JMP #10 + ] + +20 TAX + PLA + PLA + PLA + PLA + TXA + RTS + +30 LDAIM DCERRC + RTS + +40 LDYIM 0 + LDAIY MPSCPT + STA MAPTMP + INY + LDAIY MPSCPT + STA MAPTMP+1 + INY + LDAIY MPSCPT + STA MAPTMP+2 + INY + LDAIY MPSCPT + STA MPTMPD + INY + LDAIY MPSCPT + STA MPTMPD+1 + LDAIM 0 + RTS + + + [ $Level3 + +SETDSE LDA MAPTMP ;DCSECT := MAPTMP (I.E SECTOR NUMBER) + STA DCSECT + LDA MAPTMP+1 + STA DCSECT+1 + LDA MAPTMP+2 + STA DCSECT+2 + RTS + + +;SETDES: SETUP DOS'S DISC DRIVE DESCRIPTOR. +;SETUP CORRECT SECTOR NUMBER IN DOS DESCRIPTOR +;AND SELECT APPROPRIATE DRIVE, WHEN ACTUAL DRIVES +;CHANGE. +;A DRIVE MUST BE "DRVSEL" SELECTED & STARTED +;BEFORE TRANSFERS CAN BE INITIATED. +;HOWEVER WE WANT TO AVOID CALLING"DRVSEL" BETWEEN +;THE SECTORS OF A MULTI-SECTOR TRANSFER. + +;ENTRY: OLDFDR = LAST ACTUAL DRIVE NUMBER USED(SETBY SETDES) +;LDRNB = LOGICAL DRIVE NO(I.E. DISC UNIT) +;DCSECT = LOGICAL SECTOR NUMBER +;MAPENT = PTR TO RELEVENT MAPTB ENTRY(MAPMAN/FNDMAP) + +;FUNCTION:- +;SECTSD := NO OF SECTORS ON A SIDE OF THIS DISC; +;IF DCSECT >= SECTSD #NO OF SECTORS ON A SIDE# +;THEN SECTOR NO=SECTDC-SECTSD +;DRIVNO = LDRNB + 2 +;ELSE SECTOR NO=DCSECT; +;DRIVNO := LDRNB +;FI; +;IF DRIVNO <> OLDFDR +;THEN FDRIVE = DRIVE NUMBER +;JSR DRVSEL; +;IF DRIVNO <> othersideof OLDFDR THEN JSR ZTRKSL +;FI; + + +SETDES ROUT + LDA LDRNB + STA DRIVNO + + LDYIM MPSECS + LDAIY MAPENT + STA SECTSD + INY + LDAIY MAPENT + STA SECTSD+1 ;SECTSD:=NUMBER OF SECTORS ON A SIDE + INY + LDAIY MAPENT + STA SECTSD+2 + +10 LDA DCSECT + CMP SECTSD + LDA DCSECT+1 + SBC SECTSD+1 + LDA DCSECT+2 + SBC SECTSD+2 + BCC #20 + +;DCSECT >= SECTSD + + CLC + LDYIM MPDRNC + LDA DRIVNO + ADCIY MAPPTR + STA DRIVNO + SEC + LDA DCSECT + SBC SECTSD + STA DCSECT + STA RBDA + LDA DCSECT+1 + SBC SECTSD+1 ;SUBT NO. OF SECTORS ON A SIDE + STA DCSECT+1 + STA RBDA+1 + LDA DCSECT+2 + SBC SECTSD+2 + STA DCSECT+2 + STA RBDA+2 + JMP #10 + +;DCSECT < SECTSD + +20 + [ WINCH=0 + LDA DCSECT + STA RBDA + LDA DCSECT+1 + STA RBDA+1 + LDA DCSECT+2 + STA RBDA+2 + RTS + | + LDA DCSECT + STA DDRSCT+1 + LDA DCSECT+1 + ANDIM &F + STA DDRSCT ;SECTOR NUMBER + +;WORK OUT TRACK & SECTOR NUMBER + + + LDAIM 0 + STA CTRACK ;START FROM TRACK ZERO +30 LDYIM MPSPCY + SEC ;KEEP SUBTRACTING UNTIL CORRECT TRACK FOUND + LDA DCSECT + SBCIY MAPPTR + STA DCSECT + INY + LDA DCSECT+1 + SBCIY MAPPTR + STA DCSECT+1 + LDA DCSECT+2 + SBCIM 0 + STA DCSECT+2 + BCC #40 + INC CTRACK + JMP #30 + +40 LDYIM MPSPCY + CLC ;GET SECTOR NUMBER BACK + LDA DCSECT + ADCIY MAPPTR + STA DCSECT + STA CSECTR + INY + LDA DCSECT+1 + ADCIY MAPPTR + STA DCSECT+1 + LDA DCSECT+2 + ADCIM 0 + STA DCSECT+2 + RTS + + ] + ] + +;MOVEON: SET NXT SECTOR +;FUNCTION:- NBLKS -:=1 +;DCSTAD +:= BLKSZE +;MAPTMP := NXT SECTOR NUMBER +;MPSCPT := PTR TO NXT MAP ENTRY + +;EXIT: A = 0 => CARRY ON +;A = 1 => NO MORE BLOCKS TO TX +;A > 1 => ERROR + +MOVEON ROUT + SEC + LDA NBLKS + SBC MPTMPD + STA NBLKS + LDA NBLKS+1 + SBC MPTMPD+1 + STA NBLKS+1 + ORA NBLKS + BNE #10 + [ $CMOS + INCA ;RC:=1 if no more blocks + | + LDAIM 1 ;RC:=1 if no more blocks + ] + RTS + +10 CLC;INCREMENT STORE ADDRESS + LDA DCSTAD+1 + ADC MPTMPD + STA DCSTAD+1 + BCC #20 + LDAIM DCERRB ;STORE ADDR GONE ILLEGAL + JSR INTERR +20 JSR NXTEN ;UPDATE MAPTMP & MPSCPT + JMP SETSZE + + +XFER ROUT + LDAIM 1 + STA DDRSZE+1 + [ $CMOS + STZ DDRSZE + BRA #10 + | + LDAIM 0 + JMP #10 + ] + +XFERIN LDA MPTMPD + STA DDRSZE+1 + LDA MPTMPD+1 + [ $Level3 +10 STA DDRSZE + LDA DCSTAD + | + STA DDRSZE +10 LDA DCSTAD + ] + STA DDRSTA + LDA DCSTAD+1 + STA DDRSTA+1 + LDA SAVCOM ;A:=TYPE OF TRANSFER (READ/WRITE) + JSR TRANS + BEQ #40 ;is ok, end NMI + STA DCRASH ;record fault +40 RTS + + +;Block read and write +; On entry:: +; DRIVNO holds the drive number +; DDRSTA holds the start address +; RBDA contains the first sector number +; DDRSZE holds the number of bytes to transfer +; A holds read or write command code + + + [ WINCH=0 + [ $Level3 +BLKRD ROUT + LDAIM &08 ;COMMAND FOR READ + ] +TRANS ROUT + STA DSCCB+CMD + LDA DRIVNO + [ $CMOS + ASLA + ASLA + ASLA + ASLA + ASLA + | + CLC + RORA + RORA + RORA + RORA + ] + ORA RBDA+2 + STA DSCCB+CMD+1 + LDA RBDA+1 + STA DSCCB+CMD+2 + LDA RBDA + STA DSCCB+CMD+3 + +;test for writing to sector zero + + [ $Level3 + LDA RBDA + ] + ORA RBDA+1 + ORA RBDA+2 + BNE #10 + + LDAIM IERRAK ;writing to sector zero + JMP INTERR ;*** + +10 LDA DDRSTA + STA DSCCB+TRADD ; SAVE THE ADDRESS + LDA DDRSTA+1 + STA DSCCB+TRADD+1 + LDA DDRSZE+1 ;CHECK FOR END OF TRANSFER + STA DSCCB+LENGTH+1 + LDA DDRSZE + STA DSCCB+LENGTH+2 + [ $CMOS + STZ DSCCB+LENGTH + STZ DSCCB+LENGTH+3 + STZ DSCCB+CMD+4 + STZ DSCCB+CMD+5 ; FALL INTO DSCCMD *** + | + LDAIM 0 + STA DSCCB + STA DSCCB+LENGTH + STA DSCCB+LENGTH+3 + STA DSCCB+CMD+4 + STA DSCCB+CMD+5 ; FALL INTO DSCCMD *** + JMP DSCCMD ;DO THE TRANSFER + ] + + | ; winchester <> 0 +BLKRD ROUT + LDAIM &53 ;COMMAND FOR READ +TRANS STA DSCCB+CMD + LDA DRIVNO + STA DSCCB ;SAVE THE DRIVE NUMBER + LDA DDRSTA + STA DSCCB+TRADD ; SAVE THE ADDRESS + LDA DDRSTA+1 + STA DSCCB+TRADD+1 + LDAIM 3 ;NUMBER OF PARAMETERS + STA DSCCB+NOPRMS +10 LDA DDRSZE ;CHECK FOR END OF TRANSFER + ORA DDRSZE+1 + BNE #20 +15 RTS + +20 SEC + LDAIM &A ;MAX NUMBER OF SECTORS + SBC CSECTR ;MAX WE CAN TRANSFER + STA DSCCB+PARAMS+2 + LDA DDRSZE ;IF THIS IS NON-ZERO TRANS CANNOT HAVE FINISHED + BNE #30 + LDA DSCCB+PARAMS+2 ;DO WE NEED THIS MANY + CMP DDRSZE+1 + BMI #30 ;SKIP IF NOT + LDA DDRSZE+1 + STA DSCCB+PARAMS+2 ;ONLY TRANSFER AMOUNT REQUIRED +30 LDA CSECTR + STA DSCCB+PARAMS+1 ;SAVE SECTOR NUMBER + LDA CTRACK + STA DSCCB+PARAMS ;SAVE TRACK NUMBER + LDAIM &20 ;256 BYTES PER SECTOR + ORA DSCCB+PARAMS+2 + STA DSCCB+PARAMS+2 + JSR DSCCMD ;DO THE TRANSFER + BNE #15 ;OOPS! FAILED + LDAIM &00 ;FROM NOW ON START AT SECTOR ZERO + STA CSECTR + INC CTRACK ;NEXT TRACK + LDA DSCCB+PARAMS+2 + ANDIM &F ;GET NUMBER OF SECTORS + STA CNTA + SEC + LDA DDRSZE+1 + SBC CNTA ;SUBTRACT FROM TOTAL + STA DDRSZE+1 + LDA DDRSZE + SBCIM 0 + STA DDRSZE + CLC + LDA DSCCB+PARAMS+2 + ANDIM &F + ADC DSCCB+TRADD+1 + STA DSCCB+TRADD+1 +; LDA DSCCB+TRADD+2 ;** 15/2/85 ** dangerous ! +; ADCIM &00 +; STA DSCCB+TRADD+2 + JMP #10 ;GET THE REST + ] + +;DSCCMD - entered with DSCCB prepared. +; Exit A=0 if Ok else FS error code (converted). + + [ WINCH=0 + +DSCCMD ROUT + [ $CMOS + STZ DSCCB ; ZERO CONTROLLER CODE + | + LDAIM 0 + STA DSCCB + ] + LDXIM :LSB:DSCCB + LDYIM :MSB:DSCCB + LDAIM &72 + JSR OSWORD + LDA DSCCB + + [ $Level3 + BEQ #05 ; REPORT DISC ERRORS TO SCREEN 5/6/86 LH + JSR #10 +05 RTS + +10 PHA + LDAIM &73 + LDXIM DSCCB + LDYIM /(DSCCB ) + JSR OSWORD + JSR VSTRIN + = "Disc Error No. " + NOP + LDA DSCCB+3 + JSR WHEX + JSR VSTRIN + = " At Disc Address " + NOP + LDA DSCCB+2 + JSR WHEX + LDA DSCCB+1 + JSR WHEX + LDA DSCCB + JSR WHEX + PLA + RTS + | + BEQ #10 ;Br if ok + CMPIM &FF ;Disc protected? + LDAIM DCERRE ;Code if so + BCS #10 + LDXIM 2 ;**12/7/88** copy disc addr for reports +00 LDAAX DSCCB+CMD+1 + STAAX IEsin + DEX + BPL #00 + LDAIM DCERRF ;Other hard disc fault +10 RTS + ] + + | +;DSCCMD +; SEND A COMMAND TO THE DISC CONTROLLER +; DSCCB IS THE CONTROL BLOCK AND MUST BE SET UP +; TRIES ANY ERROR 10 TIMES +; RETURNS WITH Z SET IF OK +; IF FAILED RETURNS WITH ERROR NUMBER +DSCCMD ROUT + LDAIM &A ;COUNT + STA CNTA +10 LDXIM :LSB:DSCCB + LDYIM :MSB:DSCCB + LDAIM &7F + JSR OSWORD + LDA DSCCB+PARAMS+3 ;LOOK AT REPLY + BEQ #20 + DEC CNTA + BNE #10 ;TRY AGAIN IF ERROR + LDA DSCCB+PARAMS+3 +20 RTS ;RETURN WITH CORRECT ERROR NUMBER + ] + + [ $Level3 +DCCACH ROUT + LDYIM ARGJ ;get MS number of blocks to load + LDAIY ARGPTR + BNE #40 ;exit 'cos its too big + DEY ;get LS number of blocks + LDAIY ARGPTR + CMP IOBSIZ+1 + BEQ #10 + BCS #40 ;overflow here + +DCCACF +10 LDYIM ARGL + LDXIM 10 + LDAIM 0 + STA GENPTR ;spare space + +20 LDAIY ARGPTR + CMPAX ODSCMN ;look against old stack + BEQ #30 + INC GENPTR ;unzero flag +30 STAAX ODSCMN ;save stack + DEY + DEX + BPL #20 ;loop until done + + LDA GENPTR ;load flag +40 RTS + +DCSIN ROUT + LDYIM ARGB + LDXIM 0 +10 LDAIY ARGPTR + CMPAX ODSCMN ;compare against old cache + BNE #20 + INY + INX + CPXIM 5 ;test disc number & SIN + BNE #10 + LDXIM &FF + STX ODSCMN ;invalidate cache + STX ODSCMN+1 +20 RTS ;return to main routine + + | + +; Routines to communicate disc parameters to the MOS. +; DEFDEF defines a set of defaults for numbers of sides, number of cyls +; and number of sectors per track side. +; DEFDSC defines a set of parameters based on those in the current MAPPTR +; table (but it does not have a side count entry). +; MPDRVE contains the drive number in question. + +DEFDEF ROUT + LDAIM FDside + LDXIM FDcyls + LDYIM FDsecs + BRA #20 + +DEFDSC LDYIM MPnocy + LDAIY Mapptr + TAX + LDYIM MPspcy + LDAIY Mapptr + CMPIM FDsecs+2 ;determine if 1/2 sides + BCC #10 + LSRA ; sectors per side now + TAY + LDAIM 2 + BRA #20 + +10 TAY ;1-sided sectors per track + LDAIM 1 + +20 STA Dsccb+Cmd+1 + STY Dsccb+Cmd+2 + STX Dsccb+Cmd+3 + STZ Dsccb+Cmd+4 + STZ Dsccb+Cmd+5 + LDA Mpdrve ; get drive code + LSRA + RORA + RORA + RORA + TSB Dsccb+Cmd+1 + LDAIM &0D ; Define function code + STA Dsccb+Cmd + BRA Dsccmd ; go tell MOS all about disc + + ] + +; Routine to perform 'test drive' function, +; used mainly to determine if write protected +; A on entry is the required drive number + +Testdv ROUT ;**24/2/88** + [ $Level3 + PHA + LDXIM Length+3 + LDAIM 0 +10 STAAX Dsccb + DEX + BPL #10 + PLA + LSRA + RORA + RORA + RORA + STA Dsccb+Cmd+1 + JMP Dsccmd + | + LDXIM Length+3 +10 STZAX Dsccb + DEX + BPL #10 + LSRA + RORA + RORA + RORA + STA Dsccb+Cmd+1 + [ $CMOS + BRA Dsccmd + | + JMP Dsccmd + ] + + ] + + LNK UADE15 diff --git a/FileServer/SRC/FileServer/Uade15 b/FileServer/SRC/FileServer/Uade15 new file mode 100644 index 0000000..b3c6aef --- /dev/null +++ b/FileServer/SRC/FileServer/Uade15 @@ -0,0 +1,1109 @@ + OPT UADE15 ; > Uade15 + TTL File server file UADE15 + + +;* C O M M A N D P R O C E S S O R* + + [ $Level3 +CMND JSR GETBB ;Get big buffer ! + + JSR VSTRIN + = CR,"Starting - " + NOP + + +CLPA LDXIM MONON + STX MONFLG ;Monitor ON to start with + STX OTIME + STX OTIME+1 ;timer timeout + +;SET UP RXCB + + INX + STX EVCHAR ;initialise event flag + STX RIPPLE ;Rxcb counter + + JSR OPENRX ;open CB1 + + LDA &220 + STA OLDEV + LDA &220+1 + STA OLDEV+1 + + LDAIM :LSB:EVENT + STA &220 + LDAIM :MSB:EVENT + STA &220+1 + + LDAIM 14 + LDXIM 2 + JSR OSBYTE ;enable KB event + LDAIM 229 ;disable escape + LDXIM 1 + JSR OSBYTE + + JSR VSTRIN + = "Ready",CR,CR,15 + NOP + + + LDAIM 53 + JSR OSBYTE ;** 13/2/84 ** + ; sever any REMOTE connection now + + LDXIM :LSB:PROT + LDYIM :MSB:PROT + LDAIM &13 ; Net OSWORD + JSR OSWORD ; Set protection mask + +CLPD ;CLPD + +; Poll KB and Rxcb's in the I/O processor + +CPOLL0 + + LDA EVCHAR ;look for event + BEQ COMRTS + LDXIM 0 + STX EVCHAR ;reset the flag + CMPIM ESC + BEQ DOCHDI + ANDIM &DF ;force upper case + CMPIM "M" + BEQ DOMONT ;switch monitor status + CMPIM "Q" + BEQ DOQUIT ;call HALT + +;else fall through .. +;Now poll the control blocks using the MOS + +COMRTS ;come here for new command + + LDX RXTAB ;get number of CB to poll + STX RXCBN ;save this for later use + LDAIM 51 ;poll Rx number (X) + JSR OSBYTE ;result returned in X + TXA + BMI DOCMND ;leap off to deal with the Rx'd packet + JSR PRTIM ;** only call dongle every 30 or so seconds ** + JMP CPOLL0 + +DOCHDI ;DOCHDI + LDAIM &7E + JSR OSBYTE ;acknowledge escape condition here + JSR NOEVNT ;disable events + LDAIM 8 + JSR SETRTN ;ensure free space table + JSR USRMAN + JSR CHDISC ;*** CHANGE DISC ** + JMP CLPA ;back to the start + +DOQUIT ;DOQUIT + JSR NOEVNT ;disable events + LDAIM 8 ;ensure all users free space ** 3/10/84 ** + JSR SETRTN + JSR USRMAN ;no RC from this + JSR FLUSYS + LDXIM :LSB:DOBYE + LDYIM :MSB:DOBYE + JSR OSCLI ;*bye the discs + JMP INITCO ;Back to COMMAND prompt + +DOBYE = "Bye",CR + + +;Switch monitor and go back to loop start. + +DOMONT ROUT + JSR VSTRIN + = CR,"Monitor " + NOP + + LDX MONFLG + CPXIM MONOFF + BEQ #10 + JSR VSTRIN + = "OFF" + NOP + LDAIM MONOFF + JMP #20 + +10 JSR VSTRIN + = "ON" + NOP + LDAIM MONON +20 STA MONFLG + +DBNCEX JSR OSCRLF + JMP CLPD ;Go back to main RX loop + + | +CMND ROUT + +;SET UP RXCB + + STZ RIPPLE ;Rxcb counter + + JSR OPENRX ;open CB1 + +; QPTR is always zero as only one CB is +; read at any time + + STZ QPTR ;standard offset + +;Provide p.0 pointer to control block (used +;in XMIT/REPLY etc.) + + CLC + LDA QPTR + ADCIM :LSB:RXCBV + STA NETCB + LDAIM :MSB:RXCBV + ADCIM 0 + STA NETCB+1 + +;Now poll the control blocks using the MOS + +COMRTS ;come here for new command + + BIT Cmndsw ;ignore door in maintenance modes + BMI #50 + BVS #10 ;br if door open for disc change + + LDAIM 128 ;poll door switch + LDXIM 0 + JSR OSbyte + ANDIM 2 + BEQ #50 ;br unless drive door opened + +; Door has been opened, presumably user wishes to change one or more discs + + LDAIM &40 ;mark door noted open + TSB Cmndsw + LDAIM 137 ;turn on led + LDXIM 1 + JSR OSbyte + LDAIM 8 + JSR Setrtn + JSR Usrman ;USRMAN.QUIT + JSR Flusys ;flush entire system for restart + +; Door is open, flash led from clock until door closed. +; Then restart movable drives only. + +10 JSR Getdte ;get date to find seconds + LDA Date+4 + ANDIM 1 + TAX + LDAIM 137 ;flash led slowly + JSR OSbyte + + LDAIM 128 ;poll door switch + LDXIM 0 + JSR OSbyte + ANDIM 2 + BNE #50 ;until door closed + + LDAIM 137 ;turn off led + LDXIM 0 + JSR OSbyte + + LDA Drives ;restart changeable drives +20 DECA + CMPIM 4 ;(assume drives 4 up are movable) + BCC #30 ;br if all drives restarted + STA Curdrv + LDYIM Argb + STAIY Newarg + LDAIM 9 + JSR Setrtn + JSR Mapman ;*** Restart one drive *** + BEQ #22 + CMPIM DCerrf ;**6/7/88** ignore if disc now unavailable + BNE #25 +22 LDA Curdrv + BRA #20 + +25 JSR Interr ;drive restart failed. What better now? + +30 LDAIM 6 ;Restart AUTMAN + JSR Setrtn ;Ignore any error (no PW file) because + JSR Autman ;There was a PW file earlier + STZ Cmndsw ;Indicate back in user mode + +50 LDX RXTAB ;get number of CB to poll + STX RXCBN ;save this for later use + LDAIM 51 ;poll Rx number (X) + JSR OSBYTE ;result returned in X + TXA + BMI #60 ;leap off to deal with the Rx'd packet + JSR Pollps ;else check printer polling + JMI PRjump ;then go test other printer activity +60 + ] +;Reception has happened, so check +;the function code in the RXbuffer +;and jump to the operation. + + [ $Level3 +DOCMND ROUT + ] + LDA RXCBN ;save CB number + PHA ;altered in OPENRX + JSR OPENRX ;open a new Rxcb + PLA ;RXTAB updated to new CB here + STA RXCBN ;reset CB number + + LDXIM :LSB:RXCBN + LDYIM :MSB:RXCBN + LDAIM &11 ;MOS interface + JSR OSWORD ;read the control block + +; the structure set up in RXCBV is of the form +; CB number (1) ;in RXCBN +; CB data (12) + + [ $Level3 +; Thus QPTR is always zero as only one CB is +; read at any time + + LDAIM &00 + STA QPTR ;standard offset + ] + + SEC + LDA RXCBV+4 ;get low byte of address + SBCIM :LSB:RXBUF ;calculate buffer offset + STA BPTR ;point at the buffer + TAX + + LDAAX RXBUF ;Reply port at top of buffer + STA RPLYPT ;Store reply port + + LDA CBBUF + STA OLDRXB ;STORE OLD BUFFER PTR. + LDA CBBUF+1 + STA OLDRXB+1 + + [ $Level3 +;Provide p.0 pointer to control block (used +;in XMIT/REPLY etc.) + + CLC + LDA QPTR + ADCIM :LSB:RXCBV + STA NETCB + LDAIM :MSB:RXCBV + ADCIM 0 + STA NETCB+1 + + LDAAX RXBUF+1 ;Get fn. code + BEQ #50 ;Don't monitor commands immediately + + PHA + JSR MONITR ;*** Do monitor ** + PLA + + CMPIM FCMAX ;Is < biggest fn. code? + BCC #50 ;Yes => ok + | + LDAAX RXBUF+1 ;Get fn. code + BEQ #80 ;code 0 always allowed + BIT Cmndsw ;Else ensure in user mode + BMI #70 ;Fault if either command mode + BVC #80 ;Ok if user mode door closed +70 JMP Badmod + +80 CMPIM FCMAX ;Is < biggest fn. code? + BCC #90 ;Yes => ok + ] +;Send error return to machine + + LDAIM COERRA + JSR EXTERR + +;Finish command (don't matter if error +;didn't get through). + + JMP COMRTS + + +;FN. code is ok, so get routine entry address +50 +90 ASLA + TAX + LDY BPTR + LDAAY CPUFD ;**20/5/87** set all handles for use + STA UMHUFD ;**20/5/87** by pseudo-directory references + LDAAY CPLIB + STA UMHLIB + LDAAY CPCSD + STA UMHCSD + [ $CMOS + JMIX FNTAB ;Enter routine + | + LDAAX FNTAB + STA GENPTR + LDAAX FNTAB+1 + STA GENPTR+1 + +;ENTER ROUTINE .. + + JMI GENPTR + ] + +;T A B L E S + +CTABA ROUT + +;Initial receive control block +;First 12 bytes - addresses may change + + = RXFLAG + = COPORT ;Command port + = 0 + = 0 ;Set to RX on any station + & RXBUF + = 0,0 + & RXBUF+RXBUFL + = 0,0 + +FNTAB ROUT + +;Addresses of functions + + & CLINE ;Decode command line + & SAVE ;1 + & LOAD ;2 + & EXAMIN ;3 + & CATHDR ;4 + & LOAD ;Load command for execution + & FIND ;6 + & CPSHUT ;7 + & GETBYT ;8 + & PUTBYT ;9 + & GBYTES ;10 + & PBYTES ;11 + & CPRDAR ;=> GETARGS + & CPSTAR ;=> SETARGS + & DISCS ;14 + & CPUSRS ;15 + & CPDATE ;16 + & CPEOF ;17 + & CPINFO ;18 + & CPSTAT ;Set object attributes + & CPDEL ;Delete from fn. code + & USRENV ;21 + & CPSOPT ;Set user option bits + & FCBYE ;Logoff by function code + & CPUINF ;Single user info. + & CPVERN ;25 + & CPSPAC ;26 - returns disc free space + & CDIRFN ;27 - cdir from function code, specify size + & CPSETD ;28 - Set date and time from program + & SAVE ; 29 - Do a 'create', like 'save' but no data + & RDFREE ;30 - read callers free space + & WRFREE ;31 - write users free space + & CPWHO ;32 - return client user name +FNusr2 & CPUSRS ;33 - user list with job/task numbers +FNuin2 & CPUINF ;34 - single user info with job/task number +FCMAX * (.-FNTAB)/2 + +;COMMAND LINE DECODER .... + +;Command table. Verb string; mode mask; and process address. +; Mode mask has &80 (always); &20 if allowed in user mode; +; &40 if allowed in maint. mode 1, &10 if ok in maint. mode 0. + +COMTAB + + [ Lang = English + = "DELETE",&A0 + & DELETE + = "INFO",&A0 + & INFO + = "DIR",&A0 + & SELDIR + = "SDISC",&A0 + & SELDSC + = "CDIR",&A0 + & CDIR + = "ACCESS",&A0 + & SETACC + = "PASS",&A0 + & SETPW + = "I AM",&B0 + & LOGON + = "BYE",&A0 + & USROFF + = "NEWUSER",&A0 + & NEWUSE + = "PRIV",&A0 + & STPRIV + = "LIB",&A0 + & SLIB + = "REMUSER",&A0 + & REMUSE + = "RENAME",&A0 + & RENAME + [ $CMOS ; Filestore only + = "FSREPORT",&E0 + & REPORT + = "PRNAME",&A0 + & PRNAME + = "PRPAGE",&E0 ;**8/2/88** + & PRPAGE + = "FSFORMAT",&C0 + & FMFORM + = "FSVERIFY",&C0 + & VERIFY + = "FSMAXDRIVE",&C0 + & RDMAXD + = "FSMAXUSER",&C0 + & RDMAXU + = "FSSTATION",&C0 + & SETSTN + = "FSMODE",&F0 ;unique code for FSMODE + & FSMODE + = "FSPROT",&C0 + & FSPROT + = "FSUSER",&C0 + & FSUSER + = "FSNAMEDISC",&C0 ;**18/2/88** + & NMDISC + ] + = 0 ;Indicates table end + ] + + [ Lang = Italian + = "CANCELLA",&A0 + & DELETE + = "INFO",&A0 + & INFO + = "DIR",&A0 + & SELDIR + = "SDISC",&A0 + & SELDSC + = "CDIR",&A0 + & CDIR + = "ACCESSO",&A0 + & SETACC + = "PASSA",&A0 + & SETPW + = "I SONO",&B0 + & LOGON + = "CIAO",&A0 + & USROFF + = "NUTENTE",&A0 + & NEWUSE + = "PRIV",&A0 + & STPRIV + = "BIBL",&A0 + & SLIB + = "RIMUT",&A0 + & REMUSE + = "RINOME",&A0 + & RENAME + [ $CMOS ; Filestore only + = "RIPORTA",&E0 + & REPORT + = "NSTAMP",&A0 + & PRNAME + = "PRPAGE",&C0 ;**8/2/88** NOT TRANSLATED TO ITALIAN + & PRPAGE + = "FORMATTA",&C0 + & FMFORM + = "VERIFICA",&C0 + & VERIFY + = "CERTIFICA",&C0 + & CERTIFY + = "DRIVEMAS",&C0 + & RDMAXD + = "UTEMAS",&C0 + & RDMAXU + = "STMEFILE",&C0 + & SETSTN + = "MOMEFILE",&F0 ;unique code for FSMODE + & FSMODE + = "PROTMEFILE",&C0 + & FSPROT + = "UTMEFILE",&C0 + & FSUSER + = "NOMEDISC",&C0 ;**18/2/88** NOT TRANSLATED TO ITALIAN? + &NMDISC + ] + = 0 ;Indicates table end + ] + +CLINE ROUT + [ $Level3 + LDXIM &FF + | + LDAIM :LSB:(Comtab-1) + STA Genptr ;**20/2/87** + LDAIM :MSB:(Comtab-1) + STA Genptr+1 + ] + CLD +10 LDY BPTR + JSR SPACES + DEY +20 INY + [ $Level3 + INX + LDAAX COMTAB + | + JSR Incgpt + LDAI Genptr + ] + BEQ BADCOM ;Last delimiter is zero + BMI #50 ;Check next char after command is non-alpha + EORAY MIDRX ;Compare + ANDIM &DF ;Force cases + BEQ #20 + [ $Level3 + DEX +30 INX + LDAAX COMTAB + | + BRA #35 +30 JSR Incgpt +35 LDAI Genptr + ] + BPL #30 + LDAAY MIDRX + CMPIM "." + BNE #55 + INY + [ $CMOS + BRA #60 + | + JMP #60 + ] + +50 LDAAY MIDRX ;Otherwise check char. after cmnd. is non-alpha + JSR ISCHAR + BCS #60 ;Is non-alpha => end of command + [ $Level3 +55 INX + INX ;Inc. past terminator and address + JMP #10 + +60 LDAAX COMTAB+1 ;Get command processor address + STA Cozero + LDAAX COMTAB+2 + STA Cozero+1 + JMI Cozero ;Enter command processor + | +55 JSR Incgpt + JSR Incgpt ;Inc. past terminator and address + BRA #10 + +60 LDAIM &20 ;check type of command + BIT Cmndsw + BPL #70 + ASLA ;Maintenance mode 1 terminator bit + BVS #70 + LSRA + LSRA ;Maintenance mode 0 terminator bit +70 ANDI Genptr ;Check terminator + BEQ Badmod ;Error if wrong mode command + BIT Cmndsw ;Check if maintenance mode 1 or door open + BVC #80 + LDAIM &F0 ;FSMODE command? + CMPI Genptr + BEQ #80 ;No station check (here) + BIT Cmndsw ;User mode door open? + BPL Badmod ;Yes, say bad mode now + PHY + JSR Fsmody ;Else check locked station + BNE #85 + PLY +80 JSR Incgpt ;Get command processor address + LDAI Genptr + STA Cozero + JSR Incgpt + LDAI Genptr + STA Cozero+1 + JMI Cozero ;Enter command processor + +85 PLY ;reload Y and fall into BADCOM + ] + + +;UNRECOGNISED COMMAND + +BADCOM ROUT + JSR BUFTXT + BNE #30 ;Quotes error + LDXIM 0 ;Now move from TXTBUF to TXBUF +10 LDAAX TXTBUF + STAAX MIDTX + INX + CMPIM CR + BNE #10 + + CPXIM 1 + BNE #20 + LDAIM WOTERR + JSR EXTERR ;Do WHAT? error immediately + [ $CMOS + BRA #30 + | + JMP #30 + ] + +20 TXA + CLC + ADCIM TXHDR ;Message length + LDYIM CCCMND + STY CCODE + JSR REPLYC +30 JMP COMRTS + + [ Lang = English +40 = "Bad command in ",0 + ] + [ Lang = Italian +40 = "Comando errato nel ",0 + ] + + [ $Level3 + +MONITR ROUT + BIT MONFLG + BPL #15 ;bit7=0 -> no monitor + + LDXIM MONTL ;length of the 'monitored' function codes table + +10 CMPAX MONT1 ;look for function match + BEQ #20 ;found one + DEX + BPL #10 ;if fall thru' then exit +15 RTS + +20 STX COTEMP+1 ;save this for later use + JSR PRTMC ;print the machine number + + JSR VSTRIN + = ": " + NOP + + LDYIM 0 + LDX COTEMP+1 + BEQ #65 ;CLI here + +30 LDAAY MONT3 ;read though the text + BEQ #40 ;count the number so far + INY + BNE #30 +40 INY + DEX + BNE #30 + LDX COTEMP+1 + +50 LDAAY MONT3 ;now at the correct operation + BEQ #60 + JSR WRCH ;print ascii chars only + INY ;step thru' + BNE #50 ;stop on zero + +60 JSR MONOUT ;print a space +65 LDAAX MONT2 ;determine objectname offset (if any) + BMI #90 ;none here + + CLC + ADC BPTR + TAY ;Y has offset within the buffer + +70 LDAAY MIDRX ;get chars from Rx buffer + CMPIM CR ;end of name + BEQ #80 + JSR WRCH ;print the name + INY + BNE #70 + +80 JSR MONOUT ;print another space + +90 LDAAX MONT4 ;determine size offset (if any) + BMI #95 + CLC + ADC BPTR + TAY ;Y has offset within the buffer + + LDAAY MIDRX+2 + JSR WHEX + LDAAY MIDRX+1 + JSR WHEX + LDAAY MIDRX + JSR WHEX + +95 JMP OSCRLF + + +WRCH CMPIM &7F + BCS #15 + CMPIM &20 + BCC #15 + JMP OSASCI ;print ascii characters + +MONT1 = 0,1,2,5,20,23,27,29 ;function codes +MONT2 = 0,11,0,0,0,-1,1,11 ;name offsets +MONT3 + = 0 ;CLI here + = "Save",0 + = "Load",0 + = "Run",0 + = "Delete",0 + = "Bye",0 + = "Cdir",0 + = "Create",0 +MONT4 = -1,8,-1,-1,-1,-1,-1,8 ;length offsets +MONTL * MONT2-MONT1-1 + + + +PRTMC ROUT + LDA CBSTID+1 + BEQ #05 + + JSR MKDEC ;make decimal + JSR #30 ;print the network number + LDAIM "." + JSR OSWRCH + JMP #15 + +05 LDXIM 4 +10 LDAIM SPACE + JSR OSWRCH + DEX + BNE #10 ;print spaces + +15 LDA CBSTID + JSR MKDEC ;convert to decimal + JSR #30 + LDXIM 4 + LDA CBFLG + ANDIM MCtask ;**12/6/87** isolate job/task number + BEQ #20 + LSRA + LSRA + LSRA + LSRA + PHA + LDAIM "[" + JSR OSWRCH + PLA + JSR WHEXD + LDAIM "]" + JSR OSWRCH + LDXIM 1 +20 LDAIM SPACE + JSR OSWRCH + DEX + BNE #20 + RTS + +30 LDA COWORK ;msig digit + JSR OSWRCH + LDA COWORK+1 + JSR OSWRCH + LDA COWORK+2 + JMP OSWRCH ;print all three characters in COWORK + + + | +Badmod BIT Cmndsw ;Door open or true wrong mode? + BMI #45 ;Maintenance modes + BVC #45 ;User mode + LDAIM Doorer ;Door open, fail caller + JMP Error + +45 LDXIM 0 ;Special wrong mode error msg +50 LDAAX #40 ;Build base + BEQ #55 + STAAX Midtx + INX + BRA #50 + +55 JSR Setmod ;add mode text + LDAIM Woterr ;fix up message code + STA RTcode + TXA + CLC + ADCIM Txhdr + STZ Ccode + JSR Reply + BRA #30 + ] + +;Convert to decimal + +MKDEC ROUT + TAY + LDAIM &FF + STA TEMPA ;leading zero flag + + LDAIM 100 + JSR #10 + STA COWORK + LDAIM 10 + JSR #10 + STA COWORK+1 + LDAIM 1 + +10 STA COWORK+3 + TYA + LDXIM "0"-1 + SEC + +20 INX + SBC COWORK+3 + BCS #20 + ADC COWORK+3 + + CPXIM "0" + BNE #30 + BIT TEMPA + BPL #30 + LDXIM SPACE + BNE #40 + +30 INC TEMPA ;print zeros +40 TAY ;restore original parameter + TXA + STA COWORK+2 ;save this for now + RTS + + [ $Level3 +;CHDISC +;1) READ DRIVE NUMBER (IF DRIVES>1) +;2) GET DISC NUMBER FOR DRIVE +;3) FLUSH ALL OBJECTS FROM STORE +;4) ENSURE DISC MAP +;5) RESTART (MAPMAN) +;6) RESTART (AUTMAN) + +CHDISC ROUT + LDA DRIVES + SEC + SBCIM 1 + BEQ #10 ;ONE DRIVE, CONTINUE + + JSR RDDRIV + BNE #50 ;IF QUIT TYPED, QUIT ** 13/9/84 + +10 PHA ;STORE DRIVE NO. + JSR CHMSG ;"CHANGING DRIVE - ??" + PLA + STA CURDRV + JSR DRVINF ;GET DISC NO. + + BNE #40 ;ABORT IF ERROR + + LDAIM 8 + JSR SETRTN + JSR STRMAN ;*** FLUSH STORE ** + BNE #40 + + LDAIM 6 + JSR SETRTN + JSR MAPMAN ;*** ENSURE DISC ** + BNE #40 + +20 JSR CHMSGA ;"LOAD NEW DISC" + BNE #50 ;IF ABORT, ABORT ** 13/9/84 ** + + LDA CURDRV + LDYIM ARGB + STAIY NEWARG + LDAIM 9 + JSR SETRTN + JSR MAPMAN ;*** RESTART DRIVE ** + BEQ #30 ;ALL WELL, FINISH + + JSR USRERR ;ERROR, PRINT MESSAGE + JMP #20 + +30 JSR GETPWF ;Restart AUTMAN + JSR VSTRIN + = CR,"Restarting - " + NOP + + RTS + +40 JSR INTERR +50 JSR FLUSYS ;clear out the system + JMP INITCO ;** 13/9/84 ** return to command prompt after abort + + +;READ DRIVE NUMBER FROM CMND. LINE + +RDDRIV ROUT + JSR VSTRIN + = CR,"Drive: " + NOP + + JSR RDLINE + + LDYIM 0 + LDAIY COMPTR + ANDIM &DF ;force upper case + CMPIM ABTCH ;ABORT ?? "Q" + BNE #10 ;** 13/9/84 ** + + LDAIM &FF + BNE #20 ;ABORT ... + +10 JSR GETINT ;GET DRIVE NO. + BNE RDDRIV ;DO AGAIN IF NESC. + + LDA INTEGR+1 + BNE RDDRIV + + LDA INTEGR + CMP DRIVES + BCS RDDRIV ;INTEGR>=DRIVES -> ERROR + + LDXIM 0 ;GIVE Z SET EXIT +20 RTS + + + +CHMSG ROUT + PHA + JSR VSTRIN + = CR,"Changing drive - " + NOP + + PLA + JSR WHEX + JMP OSCRLF + + + +CHMSGA ROUT + JSR VSTRIN + = CR,"Load new disc",CR + NOP + +10 JSR OSECHO ;fudge around ESCAPE problem ** 28/9/84 ** + CMPIM SPACE + BEQ #20 + ANDIM &DF ;force upper case ** 13/9/84 ** + CMPIM ABTCH + BNE #10 + + LDAIM &FF ;GIVE ABORT EXIT +20 RTS + + + +;Call AUTMAN restart and write message +;if PW file not found. + +GETPWF ROUT + LDAIM 6 + LDYIM ARGA + STAIY NEWARG + JSR AUTMAN + BEQ #10 + + JSR VSTRIN + = CR,"WARNING - PW File not found" + NOP + +10 RTS + +EVENT ROUT + PHP ;save status over routine + PHA + CMPIM 2 + BNE #10 + STY EVCHAR + PLA + PLP + RTS + +10 PLA + PLP + JMI OLDEV ;unknown event + +NOEVNT ROUT + LDAIM 15 + LDXIM 0 + JSR OSBYTE ;flush buffer + + LDAIM 13 + LDXIM 2 + JSR OSBYTE ;disable event + LDAIM 229 + LDXIM 0 + JSR OSBYTE ;re-enable escape + + LDA OLDEV + STA &220 + LDA OLDEV+1 + STA &220+1 + + LDX RXCBN ;get CB number + LDAIM 52 + JMP OSBYTE ;delete open CB + ] + +; Routine to open RECEIVE CB + +OPENRX ROUT + LDXIM 11 ;Table offset +10 LDAAX CTABA + STAAX RXCBV ;Set flag, port and stid and bfr addresses. + DEX + BPL #10 + + [ $CMOS + STZ RXCBN ;ready for OSWORD call + | + LDAIM 0 + STA RXCBN ;ready for OSWORD call + ] + +;Now correct buffer pointers if second buffer. +;The one byte gap between the buffers +;is to prevent corruption when a zero is placed +;at the end of received data to prevent +;catastrophe when a bad file name is being +;decoded. + + LDA RIPPLE + INC RIPPLE + LSRA ;flag in carry + + BCC #20 + + LDAIM :LSB:(RXBUF+RXBUFL+1) + STA RXCBV+4 + LDAIM :MSB:(RXBUF+RXBUFL+1) + STA RXCBV+5 + + LDAIM :LSB:(RXBUF+RXBUFL+RXBUFL+1) + STA RXCBV+8 + LDAIM :MSB:(RXBUF+RXBUFL+RXBUFL+1) + STA RXCBV+9 + +;At this point, previous CB is set to receive. + +20 LDXIM :LSB:RXCBN + LDYIM :MSB:RXCBN + LDAIM &11 + JSR OSWORD ;do OPENRX + + LDA RXCBN + STA RXTAB ;save CB number + BNE #30 + + LDAIM IERRAI ;unable to open Rxcb + JMP INTERR + +30 RTS + + LNK UADE15A diff --git a/FileStore/SRC/FileStore/Uade15A.6502 b/FileServer/SRC/FileServer/Uade15A similarity index 73% rename from FileStore/SRC/FileStore/Uade15A.6502 rename to FileServer/SRC/FileServer/Uade15A index 0bbd7cd..4da4acf 100644 --- a/FileStore/SRC/FileStore/Uade15A.6502 +++ b/FileServer/SRC/FileServer/Uade15A @@ -1,6 +1,9 @@ OPT UADE15 ; > Uade15A TTL File server file UADE15A +; whole file is Filstore + [ $CMOS + ; FSREPORT command tells authorised user only of last internal error. Repmes ROUT @@ -23,49 +26,44 @@ Repmes ROUT ] 40 = "XX" 50 = "XX" - -;v1.31 -; = " SIN=" -;60 = "XX" -;70 = "XX" -;80 = "XX" + = " SIN=" +60 = "XX" +70 = "XX" +80 = "XX" = CR,&80 Repend - = &F + Reptab -; = #10-Repmes + = #10-Repmes = #20-Repmes = #30-Repmes = #50-Repmes = #40-Repmes - = &25 -; = #60-Repmes -; = #70-Repmes -; = #80-Repmes + = #60-Repmes + = #70-Repmes + = #80-Repmes Report ROUT - -;v1.31 -; JSR Spaces ;**1/6/88** look for arguments -; ANDIM &DF -; CMPIM "R" -; BNE #20 -; BIT Cmndsw ;**1/6/88** must be maint mode 1 for reset -; BMI #00 ;**7/7/88** or user mode -; JSR Getusr ;**1/6/88** and privileged user -; BNE #20 -; LDYIM Utpriv -; LDAIY Ustptr -; ANDIM Systpv -; BEQ #20 -;00 LDXIM IEaddr -;10 LDAIM 0 -; PHX -; JSR OSwrad ;**1/6/88** Reset reports to zero -; PLX -; INX -; CPXIM IEaddr+8 -; BCC #10 + JSR Spaces ;**1/6/88** look for arguments + ANDIM &DF + CMPIM "R" + BNE #20 + BIT Cmndsw ;**1/6/88** must be maint mode 1 for reset + BMI #00 ;**7/7/88** or user mode + JSR Getusr ;**1/6/88** and privileged user + BNE #20 + LDYIM Utpriv + LDAIY Ustptr + ANDIM Systpv + BEQ #20 +00 LDXIM IEaddr +10 LDAIM 0 + PHX + JSR OSwrad ;**1/6/88** Reset reports to zero + PLX + INX + CPXIM IEaddr+8 + BCC #10 20 LDXIM 0 30 LDAAX Repmes ;copy base message @@ -78,20 +76,16 @@ Report ROUT 40 JSR OSrdad ;read next byte of error logout PHX TAY - LDAAX Reptab-IEaddr-1 ;msg offset + LDAAX Reptab-IEaddr ;msg offset TAX TYA JSR Wrterr ;place hex in msg PLX INX - CPXIM IEaddr+5 + CPXIM IEaddr+8 BCC #40 ;continue till all done - -;v1.23 - LDAAX Reptab-IEaddr-1 - -;v1.31 -; LDAIX Repend-Repmes ;get msg length + + LDAIM Repend-Repmes ;get msg length Datour CLC @@ -160,7 +154,7 @@ SETSTN 55 LDAIM 0 ;send null reply for success JMP Datous -60 LDAIM WOTERR +60 LDAIM Numerr JMP Error 70 JMP Comrts ;message already sent @@ -293,7 +287,7 @@ Setmod JSR Flusys ;ensure discs PLA BEQ #90 ;br if ok - JSR USRERR ;else report problem + JSR Interr ;else report problem 90 RTS FSmody @@ -396,96 +390,94 @@ FSUSER ROUT 50 LDAIM Aterrg 60 JMP Error -;v1.31 -; -;; FSNAMEDISC <n> <title> renames a disc. Maintenance mode 1 only. -;; Reads both descriptor sectors for the disc and replaces the name -;; with that specified. -; -;NMDISC JSR NMdisr ;**22/3/88** Read arguments -; JSR Rddata ;Read first descriptor sector -;70 BNE #50 -; LDYIM MPsznm -;80 LDAAY Txtbuf-MPsznm ;Copy in new disc name -; STAIY Mpcypt -; INY -; CPYIM MPsznm+Dnamln -; BCC #80 -; LDAIM &0A ;Write code -; STA Dsccb+Cmd -; JSR Dsccmd ;Write back sector -; BNE #60 -; LDA RBda ;First or second done? -; BNE #35 ;Second done -; INC RBda ;Set second now -; LDA MPdrve -; -;;v1.31 -;; JSR RDstwx -; BRA #70 -; -;; Subroutine, read disc number followed by disc name. -;; Exit: A=Disc number, TXTBUF=disc name. -;; Syntax errors pop link and take error actions. -; -;NMDISR ROUT -; JSR Spaces ;**18/2/88** Find disc number -; CMPIM "0" -; BCC #85 -; CMPIM "6" -; BCS #85 -; ANDIM 7 -; STA Mpdrve ;Set variables for RDDATA routine in MAPMAN -; INY ;(Maybe should make this a MAPMAN function) -; JSR Rdtitl ;Read disc name -; BNE #80 -; LDXIM &FF -;60 INX -; LDAAX Txtbuf ;Check and find end of name -; CMPIM "A" -; BCC #61 -; CMPIM "Z"+1 -; BCC #60 -;61 CMPIM "a" -; BCC #62 -; CMPIM "z"+1 -; BCC #60 -;62 CPXIM 0 ;first char? -; BEQ #63 -; CMPIM "-" -; BEQ #60 -; CMPIM "_" -; BEQ #60 -; CMPIM "0" -; BCC #63 -; CMPIM "9"+1 -; BCC #60 -;63 CMPIM CR -; BNE #90 -; CPXIM 0 -; BEQ #90 -; CPXIM Dnamln+1 -; BCS #90 -; LDAIM Space -;65 STAAX Txtbuf -; INX -; CPXIM Dnamln -; BCC #65 -; LDA Mpdrve -; RTS -; -;80 PLA ;**22/3/88** unstack link -; PLA -; JMP Comrts -; -;85 PLA ;**4/4/88** unstack link -; PLA -; LDAIM Numerr -; JMP Error -; -;90 PLA ;**22/3/88** unstack link -; PLA -; LDAIM Synerr -; JMP Error +; FSNAMEDISC <n> <title> renames a disc. Maintenance mode 1 only. +; Reads both descriptor sectors for the disc and replaces the name +; with that specified. +NMDISC JSR NMdisr ;**22/3/88** Read arguments + JSR Rddata ;Read first descriptor sector +70 BNE #50 + LDYIM MPsznm +80 LDAAY Txtbuf-MPsznm ;Copy in new disc name + STAIY Mpcypt + INY + CPYIM MPsznm+Dnamln + BCC #80 + LDAIM &0A ;Write code + STA Dsccb+Cmd + JSR Dsccmd ;Write back sector + BNE #60 + LDA RBda ;First or second done? + BNE #35 ;Second done + INC RBda ;Set second now + LDA MPdrve + JSR RDstwx + BRA #70 + +; Subroutine, read disc number followed by disc name. +; Exit: A=Disc number, TXTBUF=disc name. +; Syntax errors pop link and take error actions. + +NMDISR ROUT + JSR Spaces ;**18/2/88** Find disc number + CMPIM "0" + BCC #85 + CMPIM "6" + BCS #85 + ANDIM 7 + STA Mpdrve ;Set variables for RDDATA routine in MAPMAN + INY ;(Maybe should make this a MAPMAN function) + JSR Rdtitl ;Read disc name + BNE #80 + LDXIM &FF +60 INX + LDAAX Txtbuf ;Check and find end of name + CMPIM "A" + BCC #61 + CMPIM "Z"+1 + BCC #60 +61 CMPIM "a" + BCC #62 + CMPIM "z"+1 + BCC #60 +62 CPXIM 0 ;first char? + BEQ #63 + CMPIM "-" + BEQ #60 + CMPIM "_" + BEQ #60 + CMPIM "0" + BCC #63 + CMPIM "9"+1 + BCC #60 +63 CMPIM CR + BNE #90 + CPXIM 0 + BEQ #90 + CPXIM Dnamln+1 + BCS #90 + LDAIM Space +65 STAAX Txtbuf + INX + CPXIM Dnamln + BCC #65 + LDA Mpdrve + RTS + +80 PLA ;**22/3/88** unstack link + PLA + JMP Comrts + +85 PLA ;**4/4/88** unstack link + PLA + LDAIM Numerr + JMP Error + +90 PLA ;**22/3/88** unstack link + PLA + LDAIM Synerr + JMP Error + + ] ; whole file was filestore + LNK UADE16 diff --git a/FileStore/SRC/FileStore/Uade16.6502 b/FileServer/SRC/FileServer/Uade16 similarity index 77% rename from FileStore/SRC/FileStore/Uade16.6502 rename to FileServer/SRC/FileServer/Uade16 index 22e61e5..923e623 100644 --- a/FileStore/SRC/FileStore/Uade16.6502 +++ b/FileServer/SRC/FileServer/Uade16 @@ -23,103 +23,28 @@ ;9) Possibly DELETE previous file from map, ;flush from store and ensure map. -SAVE ROUT ;DOSAVE +;**8/2/88** Command level code deleted -;Command decoding entry point - -;Y -> next char in command line - - JSR BUFTXT - BNE DSVRTS - LDXIM COZERO - JSR RDNUM ;Read four byte Load addr. - BEQ DSVERR - LDXIM COZERO + 8 - JSR RDNUM ;End address +1 - BEQ DSVERR - -;Get file length before reading -;exec address. - - LDXIM 0 - SEC - PHP -DSVLPA PLP - LDAAX COZERO + 8 - SBCAX COZERO - STAAX MIDTX + 8 - PHP - INX - CPXIM 3 - BNE DSVLPA - PLP ;Restore stack - LDAAX COZERO + 8 - SBCAX COZERO - BEQ DSVONB ;Not too big .... - LDAIM SAERRC ;Too big - BRA DSVERA - - -DSVONB LDXIM COZERO + 4 - JSR RDNUM ;Get exec. address - BNE DSVONA - LDXIM 3 -DSVLPB LDAAX COZERO - STAAX COZERO + 4 ;Exec = Save addr. - DEX - BPL DSVLPB - -DSVONA JSR COMEND - BNE DSVRTS - - LDXIM 8 -;v1.23 *** FIX *** -;DSVLPC LDAAX COZERO -; STAAX MIDTX -DSVLPC LDAAX COZERO-1 - STAAX MIDTX-1 - DEX - BNE DSVLPC - -DSVLPD LDAAX TXTBUF - STAAX MIDTX +&B ;Store file title - INX - CMPIM CR - BNE DSVLPD - - TXA ;File title length - CLC - ADCIM &E ;Add load/exec/length size + Header length - - - LDXIM CCSAVE ;Save command code - STX CCODE - JSR REPLYC ;Return code -DSVRTS JMP COMRTS ;Finish +SAVE ROUT ; Also entered here for a CREATE 11/6/84 BC + JSR STKUSE ;Set m/c no. and call FINDMC + BNE #22 ;Fail, return -DSVERR LDAIM WOTERR -DSVERA JMP ERROR + LDAIM 13 ;DIRMAN.CHECKPRES + JSR #95 ;**23/3/88** see if preserve will work + BNE #23 -SAVONA - JSR STKUSE ;Set m/c no. and call FINDMC - BNE DSVRTS - LDAIM SAVFTO - JSR SETFTP LDAIM &A ;File title -> disc number JSR SETRTN - - [ Pseudods = Yes - LDYIM UTHUFD ;**1/7/87** fix up user root handle - LDAIY USTPTR - STA UMHUFD - ] - - LDYIM ARGF + JSR STKUSA + LDAIM SAVFTO + JSR SETFTP + INY LDAIM &80 ;no wild cards in last name STAIY NEWARG - JSR DIRMAN ;Disc number on stack - BNE DSVERA + JSR DIRMAN ;Disc number on stack + BNE #23 ;**9/6/87** + LDX BPTR LDYIM ARGD @@ -133,14 +58,14 @@ SAVONA CPYIM ARGD+3 BNE #10 + DEY ;pass info @ ARGG,H + JSR SETUSE ;put userinfo on stack + LDAIM 1 JSR SETRTN - LDYIM 8 - JSR SETUSE ;put userinfo on stack - JSR MAPMAN ;** CREATE SPACE ** - BNE DSVERA + BNE #23 LDXIM 4 LDYIM ARGF @@ -155,9 +80,18 @@ SAVONA LDAAX FCODE EORIM FCCRET ; The function code for create BNE #25 + [ $CMOS STZ CCODE ; Blat the command return code + | + LDAIM 0 + STA CCODE ; Blat the command return code + ] JMP #70 +22 JMP COMRTS ;Finish + +23 JMP ERROR + 25 LDAIM PSAVD STA MIDTX ;Save data port @@ -166,7 +100,12 @@ SAVONA LDAIM :MSB:BUFSZ ;** 6/2/84 ** STA MIDTX+2 ;Size of save buffer hi + [ $CMOS STZ RTCODE + | + LDAIM 0 + STA RTCODE + ] LDAIM 3 ;offset in buffer of name STA CCODE @@ -181,10 +120,18 @@ SAVONA ;If we get here, ready to receive ;data, so set up for receive loop. + [ $CMOS STZ DATAIN STZ DATAIN+1 STZ DATAIN+2 ;DATAIN -> no. of bytes received STZ DSCERR ;Error flag + | + LDAIM 0 + STA DATAIN + STA DATAIN+1 + STA DATAIN+2 ;DATAIN -> no. of bytes received + STA DSCERR ;Error flag + ] LDX BPTR LDAAX MIDRX+8 ;Check if zero length file ORAAX MIDRX+9 @@ -201,6 +148,19 @@ SAVONA ;Set buffer pointers in control block 40 LDY QPTR + [ $Level3 + LDA IOBUF + STAAY CBBUF + LDA IOBUF+1 ;Buffer (hi) + STAAY CBBUF+1 + + LDA IOEND + STAAY CBBUFE ;Buffer end (lo) + LDA IOEND+1 + STAAY CBBUFE+1 ;Buffer end (hi) + + LDAIM &FF + | LDA BBUF STAAY CBBUF LDA BBUF+1 ;Buffer (hi) @@ -212,6 +172,8 @@ SAVONA STAAY CBBUFE+1 ;Buffer end (hi) LDAIM &00 + ] + STAAY CBBUF+2 STAAY CBBUF+3 STAAY CBBUFE+2 @@ -236,11 +198,15 @@ SAVONA LDAAY CBBUFE+1 SBCAY CBBUF+1 STA DIVPAR+1 + [ $CMOS STZ DIVPAR+2 ;Top byte always 0 - + | + LDAIM 0 + STA DIVPAR+2 ;Top byte always 0 + ] + ;Add no. received to total no. of ;bytes received. - CLC LDA DIVPAR ADC DATAIN @@ -268,10 +234,17 @@ SAVONA LDA DIVPAR+1 STAIY NEWARG ;No. of blocks to write INY + [ $Level3 + LDA IOBUF + STAIY NEWARG ;Address of data to write + INY + LDA IOBUF+1 + | LDA BBUF STAIY NEWARG ;Address of data to write INY LDA BBUF+1 + ] STAIY NEWARG ;As above (hi) LDYIM ARGB @@ -351,51 +324,8 @@ SAVONA ;Now prepare to do PRESERVE to ;keep the data on disc. -70 LDYIM ARGO ;SIN GOES IN ARGQ->ARGS (!) - -;Now prepare to do PRESERVE to -;keep the data on disc. - - JSR SINDSC ;Get SIN/DISC to stack - JSR STKUSA - - LDAIM SAVFTO - JSR SETFTP - -;Move load/exec addresses from -;receive message buffer to stack - - LDX BPTR - LDYIM ARGF -75 LDAAX MIDRX - STAIY NEWARG - INX - INY - CPYIM ARGF + 8 - BNE #75 - - LDAIM ACCDEF ;Access default - STA MIDTX ;Store for final reply - STAIY NEWARG - JSR GETDTE ;Read time chip if present - - LDYIM ARGO - LDA DATE - STA MIDTX + 1 ;Store for final reply - STAIY NEWARG - INY - LDA DATE + 1 - STA MIDTX + 2 ;Store for final reply - STAIY NEWARG - - LDAIM DRPRS - JSR SETRTN - - LDYIM ARGT - LDAIM &80 - STAIY NEWARG ;wild card flag - - JSR DIRMAN ;*** DO PRESERVE ** +70 LDAIM DRPRS + JSR #95 BNE #85 LDYIM ARGG ;** 4/8/83 ** @@ -408,8 +338,8 @@ SAVONA BNE #85 ;**** 17/3/83 **** 80 JMP COMRTS ;Finished ... exit -85 JSR EXTERR ;Send error to client +85 JSR EXTERR ;Send error to client ;Abort exit ... clear entry from ;map of created space using FREESTORE, @@ -425,7 +355,61 @@ SAVONA JSR MAPMAN ;** Free space ** BEQ #80 - JSR USRERR + JSR INTERR + +;Routine to DIRMAN.DRPRS or DIRMAN.CHECKPRES +;DIRMAN code in A on entry + +95 JSR SETRTN + + LDYIM ARGO ;SIN GOES IN ARGQ->ARGS (!) + JSR SINDSC ;Get SIN/DISC to stack + LDAIM &80 + STAIY NEWARG ;ARGT = wild card flag + + JSR STKUSA + + LDAIM SAVFTO + JSR SETFTP + + [ Pseudods = Yes + LDYIM UTHUFD ;**1/7/87** fix up user root handle + LDAIY USTPTR + STA UMHUFD + ] + +;Move load/exec addresses from +;receive message buffer to stack + + LDX BPTR + LDYIM ARGF +97 LDAAX MIDRX + STAIY NEWARG + INX + INY + CPYIM ARGF+8 + BNE #97 + + LDAIM ACCDEF ;Access default + STA MIDTX ;Store for final reply + STAIY NEWARG + + [ $Level3 + [ 1=0 + JSR SETDAT ;Read time chip if present + ] + | + JSR GETDTE ;Read date & time + ] + LDYIM ARGO + LDA DATE + STA MIDTX+1 ;Store for final reply + STAIY NEWARG + INY + LDA DATE+1 + STA MIDTX+2 ;Store for final reply + STAIY NEWARG + + JMP DIRMAN ;*** DO PRESERVE ** - LNK UADE16A diff --git a/FileStore/SRC/FileStore/Uade16A.6502 b/FileServer/SRC/FileServer/Uade16A similarity index 89% rename from FileStore/SRC/FileStore/Uade16A.6502 rename to FileServer/SRC/FileServer/Uade16A index 1c7063c..5549dc1 100644 --- a/FileStore/SRC/FileStore/Uade16A.6502 +++ b/FileServer/SRC/FileServer/Uade16A @@ -18,46 +18,11 @@ ;to pad out data until loop end. ;5) Return code reply. +;**8/2/88* Command level code deleted -DOLOAD ROUT ;DOLOAD - -;CLI type entry - - JSR BUFTXT ;Read file title - BNE DLORTS - - STZ MIDTX + 4 ;Use load address flag - - LDXIM COZERO - JSR RDNUM - BEQ DLOONA ;Load address not present - - LDXIM 3 -DLOLPA LDAAX COZERO ;Load addr. present, move to TXBUF - STAAX MIDTX - DEX - BPL DLOLPA - DEC MIDTX + 4 ;Use given address -DLOONA JSR COMEND - BNE DLORTS - LDXIM 0 -DLOLPB LDAAX TXTBUF - STAAX MIDTX + 5 - INX - CMPIM CR - BNE DLOLPB - TXA ;Get file title length - CLC - ADCIM 7 ;Add load addr. etc. + TXHDR - - LDXIM CCLOAD ;Command code for load - STX CCODE - JSR REPLYC ;Send reply -DLORTS JMP COMRTS ;Finish !!! - - -LOAD JSR GETUSE ;Get user info. using FINDMC - BNE DLORTS ;Fail, exit +LOAD ROUT + JSR GETUSE ;Get user info. using FINDMC + BNE #17 ;Fail, exit [ Pseudods = Yes LDYIM UTHUFD ;**1/7/87** fix up user root handle @@ -86,20 +51,29 @@ LOAD JSR GETUSE ;Get user info. using FINDMC 10 LDAIM WOTERR 15 JMP ERROR +17 JMP COMRTS ;Finish !!! + 20 LDYIM ARGB LDAIM TYPDIR ;Directory type ANDIY NEWARG ;0 => is file BEQ #25 ;OK, carry on - LDAIM LODERA ;Not ok, external error + [ $CMOS BRA #15 - + | + BNE #15 + ] + 25 LDAIM READAC ANDIY NEWARG BNE #30 ;Read access => OK LDAIM LODERB ;Not ok, external error + [ $CMOS BRA #15 - + | + BNE #15 + ] + 30 LDA DETDIS STA DANDS ;Store Disc. no. LDA DETDIS+1 @@ -122,13 +96,15 @@ LOAD JSR GETUSE ;Get user info. using FINDMC ANDIM &02 ;test bit 1 (write bit) BEQ #40 LDAIM DRERRI ;object in use + [ $CMOS BRA #15 + | + BNE #15 + ] ;Move load/exec info. from COWORK to transmit buffer ;Note CPYLXS copies date and access as well - - 40 LDXIM 0 ;Offset from MIDTX JSR CPYLXS ;Note corrupts COTEMP @@ -149,7 +125,12 @@ LOAD JSR GETUSE ;Get user info. using FINDMC DEX BPL #50 + [ $CMOS STZ RTCODE + | + LDAIM 0 + STA RTCODE + ] LDAIM 14 ;offset of name string in buffer STA CCODE @@ -158,11 +139,19 @@ LOAD JSR GETUSE ;Get user info. using FINDMC BEQ #55 JMP #95 ;Reply failed + [ $CMOS 55 STZ DSCERR ;Set disc error flag STZ FINFLG ;Set finish flag STZ CURBLK STZ CURBLK+1 - + | +55 LDAIM 0 + STA DSCERR ;Set disc error flag + STA FINFLG ;Set finish flag + STA CURBLK + STA CURBLK+1 + ] + ;Loop round sending data to client ;in blocks of size BBSIZE. TOSEND ;is the amount left to send, decremented @@ -178,10 +167,18 @@ LOAD JSR GETUSE ;Get user info. using FINDMC 60 SEC LDA TOSEND + [ $Level3 + SBC IOBSIZ + | SBC BBSIZE + ] STA COWORK LDA TOSEND+1 + [ $Level3 + SBC IOBSIZ+1 + | SBC BBSIZE+1 + ] STA COWORK+1 LDA TOSEND+2 @@ -209,13 +206,24 @@ LOAD JSR GETUSE ;Get user info. using FINDMC DEC FINFLG ;Set loop finish flag=#FF ORA TOSEND BEQ #90 ;Zero length file => send final reply only + [ $CMOS BRA #75 - + | + BNE #75 + ] + + [ $Level3 +70 LDA IOBSIZ + STA OUTBSZ + LDA IOBSIZ+1 + STA OUTBSZ+1 + | 70 LDA BBSIZE STA OUTBSZ LDA BBSIZE+1 STA OUTBSZ+1 - + ] + ;The size of the block to send (in ;bytes) is now in OUTBSZ. So divide ;by disc block size to get number @@ -225,7 +233,12 @@ LOAD JSR GETUSE ;Get user info. using FINDMC STA DIVPAR LDA OUTBSZ+1 STA DIVPAR+1 + [ $CMOS STZ DIVPAR+2 ;3 byte arg. + | + LDAIM 0 + STA DIVPAR+2 ;3 byte arg. + ] JSR DIVIDE LDYIM ARGB JSR SINDSC ;Set disc/SIN on stack @@ -239,7 +252,11 @@ LOAD JSR GETUSE ;Get user info. using FINDMC 80 LDY BPTR LDAAY CPUFD ;Get data port sent from client + [ $Level3 + JSR SENDIO ;Send big block + | JSR SENDBC ;Send big block + ] BNE #95 ;Otherwise, contact lost with client, so give up. ;At end of loop, test finish flag, @@ -275,6 +292,7 @@ LOAD JSR GETUSE ;Get user info. using FINDMC 95 JMP COMRTS + ;*************** ;* D E L E T E * ;*************** @@ -342,8 +360,12 @@ CATHDR ROUT ANDIM OWNER BEQ #10 LDAIM "O" + [ $CMOS BRA #20 - + | + BNE #20 + ] + 10 LDAIM "P" ;PUBLIC OR OWNER ACCESS 20 STA MIDTX+&B LDAIM SPACE @@ -368,33 +390,7 @@ CATHDR ROUT 40 JMP ERROR -;***************** -;* C A T * -;***************** - -CAT ROUT ;CAT -;Get dir. title and return it - - JSR BUFTXT - BNE #20 - JSR COMEND - BNE #20 - - LDXIM 0 -10 LDAAX TXTBUF - STAAX MIDTX - INX - CMPIM CR - BNE #10 - LDAIM 3 - STA CCODE - TXA ;Get length - CLC - ADCIM 2 - JSR REPLYC ;Send reply -20 - JMP COMRTS ;Finish ;***************** ;* E X A M I N E * @@ -406,7 +402,7 @@ CAT ROUT ;CAT EXAMIN JSR STKUSE ;CALL FINDMC AND SET USTPTR ON STACK - BNE #20 + BNE #30 LDAIM EXAFTO JSR SETFTP ;SET FILE TITLE POINTER ON STACK @@ -447,9 +443,7 @@ EXAMIN STAIY NEWARG ;pass parameter JSR DIRMAN ;*** DIRECTORY MANAGER CALL ** - BEQ #40 - JMP Error -40 + BNE #40 LDA BBUF STA GENPTR LDA BBUF+1 diff --git a/FileServer/SRC/FileServer/Uade17 b/FileServer/SRC/FileServer/Uade17 new file mode 100644 index 0000000..8702587 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade17 @@ -0,0 +1,608 @@ + OPT UADE17 ;FILE > Uade17 + TTL File server file UADE17 + +;INFO/LOGON/PRIV. OPERATIONS ETC. + + +;Get info in m/c readable format, depending on +;argument. + +;1 = creation date +;2 = load/execution addresses +;3 = size +;4 = type/access +;5 = all above 4 in order load/execute/size/access/date +; +;6 = get access, cycle (sequence) number, and last +; component of dir. title for dir. name. NOTE +; does not use retrieve, and does not trap "NOT +; FOUND" error. + +CPINFO ROUT + JSR GETUSE + BNE #50 + + LDX BPTR + LDAAX MIDRX + BEQ #05 ;Zero arg => error + CMPIM 6 + BEQ #70 ;=> do directory information + BCC #10 ;Otherwise, is valid arg. + +05 LDAIM INFERA + [ $CMOS + BRA #60 ;Abort with err. msg. + | + BNE #60 ;Abort with err. msg. + ] + + [ $CMOS +10 STZ MIDTX ;Set existence flag to "does not exist" + | +10 LDAIM 0 + STA MIDTX ;Set existence flag to "does not exist" + ] + LDAIM INFFTO + JSR CPRETR ;Retrieve details + BEQ #15 ;Ok, continue + CMPIM DRERRC ;If not found, alter existence flag + BNE #60 ;Not "not found" => error + LDXIM 1 ;Length of reply + [ $CMOS + BRA #45 ;Exit, sending reply + | + BNE #45 ;Exit, sending reply + ] + +15 INC MIDTX ;Set flag to "is a file" + LDX BPTR + LDAAX MIDRX ;Check arg. + LDXIM 1 ;Offset for COCOPY + CMPIM 5 ;Is "all args" ? + BNE #20 ;Nope, continue + + JSR CPYLXS ;Yep, copy all args + BEQ #30 ;Always jump + +20 JSR COCOPY ;Copy relevant amount of stuff COWORK->MIDTX + +30 LDYIM ARGB ;check for OWNER/PUBLIC + LDAIY NEWARG + ANDIM OWNER + BEQ #35 + LDAIM &FF +35 EORIM &FF ;invert byte [Owner => 0] + STAAX MIDTX ;put this at the end of the information + INX + +40 LDYIM INFACC + LDAAY COWORK + ANDIM TYPDIR ;Check if is a directory + BEQ #45 ;Is not -> continue + INC MIDTX ;Is => set flag to 2 => directory +45 TXA ;Length of information transfered + JMP Datous ;Go send msg + +50 JMP COMRTS + +60 JMP ERROR + +70 JSR STKUSA ;Set user info. on stack + LDAIM 3 + STA COZERO ;Offset for dir. name result + LDAIM HDRLEN+1 ;Offset of dir. name arg. + LDXIM &C1 ;force directory here + JSR DIRIN2 ;Get dir. infomation + BNE #60 + + LDYIM ARGD ;Now set access & sequence number + [ $CMOS + STZ MIDTX+NAMLNT+3 ;Zero => owner, $FF => public + STZ MIDTX+1 + | + LDAIM 0 + STA MIDTX+NAMLNT+3 ;Zero => owner, $FF => public + STA MIDTX+1 + ] + LDAIM OWNER + ANDIY NEWARG ;Check access to dir. + BNE #80 ;Is owner, continue + DEC MIDTX+NAMLNT+3 ;Otherwise, give $FF +80 INY + LDAIY NEWARG + STA MIDTX+NAMLNT+4 ;Set sequence number of dir. + LDAIM NAMLNT + STA MIDTX+2 ;Set length of dir. name + LDXIM NAMLNT+5 ;Length of message - TXHDR + [ $CMOS + BRA #40 ;Exit with reply (Note MIDTX undefined) + | + BNE #40 ;Exit with reply (Note MIDTX undefined) + ] + +CPIXTB = 2 ;Table of length of data + = 8 + = 3 + = 1 + +CPIATB = INFDTE ;Offset of data in COWORK + = INFLOA + = INFSZE + = INFACC + + +;Copy load/exec/size/access/date into MIDTX + +CPYLXS ROUT + LDAIM 2 + JSR COCOPY ;Load/exec + LDAIM 3 + JSR COCOPY ;Size + LDAIM 4 + JSR COCOPY ;access + LDAIM 1 ;creation date + +;Fall through into last call of COCOPY + +COCOPY + +;Copy some object attribute from COWORK into MIDTX +;offset by X. Attribute length and value is determined +;by A on entry which indexes into two tables + + TAY + LDAAY CPIXTB-1 + STA COTEMP ;Set length to copy + LDAAY CPIATB-1 + TAY ;Get offset in COWORK +10 LDAAY COWORK + STAAX MIDTX + INY + INX + DEC COTEMP + BNE #10 + RTS ;Note assumed elsewhere always exit EQ + + + + +;Set object attributes according to arg. + +;1 => set load/execute/access +;2 => set load address +;3 => set execute address +;4 => set access byte +;5 => set date bytes ** 5/9/84 ** + +;Basically just a call to DIRMAN.SETATTRIBS + +CPSTAT ROUT + JSR STKUSE + BNE #50 + + LDX BPTR + LDAAX MIDRX + BEQ #10 + CMPIM 6 ;** 5/9/84 ** + BCC #20 ;Arg ok, continue + +10 LDAIM INFERA ;Error in arg. + JMP ERROR + +20 TAY + LDAAY DRSAT2-1 ;Note uses table in DIRMAN to get data length + BEQ #40 ;If setting zero number of bytes, exit + + CLC + ADCIM HDRLEN+1 ;Get offset of file title in RX buffer + LDYIM ARGC + JSR SETFTP ;Set pointer to file title + + INY ;ARGF here + LDAIM &C0 + STAIY NEWARG ;wild card flag + + LDX BPTR +30 INY + LDAAX MIDRX ;Load arg. to DIRMAN.SETATTRIBS + STAIY NEWARG + INX + CPYIM ARGH+9 + BNE #30 + +;Stack now all set, call DIRMAN.SETATTRIBS + + LDAIM 4 + JSR SETRTN + JSR DIRMAN +40 JSR RCODE +50 JMP COMRTS + + +;Non-command line call to delete object, and return +;object information after deletion. + +CPDEL ROUT + JSR STKUSE + BNE #20 + LDAIM HDRLEN ;Offset of file title + JSR CPRETR ;Retrieve details of object to delete + BNE #10 ;No good, error + + JSR STKUSA ;Reset user pointer on stack + LDAIM HDRLEN ;File title offset + JSR SETFTP ;Set file title pointer + LDAIM 3 + JSR SETRTN + + LDYIM ARGG + LDAIM &80 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;** Call DIRMAN.DELETE ** + BNE #10 ;Error + + LDXIM 0 ;Set offset from MIDTX for file details + JSR CPYLXS ;Copy the whole lot over + CLC + TXA + ADCIM TXHDR ;Length of message + STA Cozero ;**1/7/87** save length + JSR OBJCLR ;Clear object out of map + BEQ #25 ;error returned here +10 JSR RCODE ;Send error return +20 JMP COMRTS ;And finish + +25 LDA Cozero ;**1/7/87** load reply length + [ $CMOS + BRA #30 + | + BNE #30 + ] + + + +;Return user environment information. +; 1) Call DIRMAN.EXAMINE to get dir. name, and disc +; number of CSD. +; 3) Call MAPMAN.DISCNAME to get name of disc with +; given disc number. +; 4) Call DIRMAN.EXAMINE to get title of LIB. + +USRENV + JSR GETUSE + BNE #20 + + LDX BPTR + LDAIM TERMIN + STAAX MIDRX ;Fool DIRINF into getting CSD info. + + LDAIM 17 ;Offset from MIDTX for dir. title + JSR DIRINF ;Read dir. information + BNE #40 ;Error -> bomb out + + LDAIM 1 ;Offset from MIDTX for disc name + JSR CPDNAM ;Read disc name (note assumes disc no. on stack) + BNE #40 + + LDX BPTR + LDAAX CPLIB ;Read library handle + LDYIM UTHSLD + STAIY USTPTR ;Set as CSD of user + + LDAIM 27 ;Offset from MIDTX of LIB name + JSR DIRINF ;Entry point not changing CSD handle + BNE #40 + + LDAIM DNAMLN ;Disc name length + STA MIDTX + [ $CMOS + STZ CCODE + | + LDAIM 0 + STA CCODE + ] + LDAIM TXHDR+37 ;Message length +30 JSR REPLYC + JMP COMRTS + +40 JMP ERROR + + + +;************* +;* L O G O N * +;************* + + +LOGON ROUT + + JSR SPACES +10 LDAAY MIDRX ;Step past station if present + CMPIM "." ;Network number terminator - special case + BEQ #20 + CMPIM "0" + BCC #30 ;On if <0 + CMPIM ":" ;On if >9 + BCS #30 +20 INY + BNE #10 + +30 JSR BUFTXT ;Read User + BNE #50 + INX ;Step past CR between userid & pw + JSR BTXTA + BNE #50 + JSR COMEND ;Check to end of C.line + BNE #50 + + LDYIM ARGB + LDX QPTR + LDAAX CBSTID + STAIY NEWARG + STA MCNUMB ;** 31/08/86 ** + INY + LDAAX CBSTID+1 + STAIY NEWARG + STA MCNUMB+1 ;** 31/08/86 ** + INY + LDAAX CBflg ;**25/12/86** Get control byte + ANDIM MCtask ;**25/12/86** Isolate task no + STAIY NEWARG ;pass station id + STA MCnumb+2 + + [ $CMOS + BIT Cmndsw ;Command mode logon? ** 31/08/86 ** + BMI #70 ;Br for special process if so + ] + + JSR SBUFPT ;pointer to TXTBUF + + LDAIM 1 + JSR SETRTN + JSR USRMAN ;attempt logon + BNE #60 ;failed + + [ $Level3 + LDYIM ARGH ;test for priv'd logon + LDAIY NEWARG + BNE #32 ;no monitor for priv'd users + + BIT MONFLG + BPL #32 ;skip if monitor off anyway + + LDY QPTR + JSR PRTMC ;output mc number + JSR VSTRIN + = ": I am " + NOP + + LDXIM 0 +31 LDAAX TXTBUF + INX + JSR OSASCI ;print the user name + CMPIM CR + BNE #31 + +32 + ] + LDYIM ARGG + LDXIM 3 +40 LDAIY NEWARG ;Get UFD/CSD/LIB handles + option byte + STAAX MIDTX + DEY + DEX + BPL #40 + +45 LDAIM CCLGON + STA CCODE + LDAIM TXHDR+4 ;Message length + JSR REPLYC ;Send handles etc. back + +50 JMP COMRTS ;FINISH + +60 JMP ERROR + + [ $CMOS + +; Command mode 0 logon to command mode 1. +; No PASSWORDS file, instead there is the possibility +; of a system id stored (checksummed) in CMOS RAM. +; If this is not consistent then we fallback onto a +; fixed and known ID. There is no password in either +; case (though one may be typed if wished). + +65 = "SYST",CR ;Fallback command mode userid + +70 STZ TEMPA ;Zero checksum + LDXIM FSusid ;Extract CMOS RAM system userid +75 JSR OSrdad ;Read next byte + TAY ;Test it + BMI #90 ;invalid if -ve + BEQ #90 ;invalid if zero + STAAX Cozero-FSusid ;save in workspace + CLC + ADC TEMPA ;Accumulate checksum + BCC #77 + INCA ;With end-round carry +77 STA TEMPA + INX + CPXIM FSusie-1 ;Last byte next? + BCC #75 ;No, read on normally + JSR OSrdad ;Extract checksum (no sign checks) + CMP TEMPA ;Check checksum + BNE #90 ;Wrong, use fallback + LDXIM :LSB:Cozero ;Good, use value read out + LDYIM :MSB:Cozero +80 STX Genptr + STY Genptr+1 + LDXIM 0 + LDYIM 0 +85 LDAAX Txtbuf ;Compare with supplied value + JSR Ischar ;C set unless alpha + EORIY Genptr + BCS #86 + ANDIM &DF ;Caseless alpha match +86 BNE #95 + LDAIY Genptr ;Matched, was it terminator? + INX + INY + CMPIM CR + BNE #85 ;No, continue scan + LDAIM &C0 ;OK, set command mode 1 + STA Cmndsw ;(note, caller station in MCNUMB) + STZ Midtx ;zero handles + option byte + STZ Midtx+1 + STZ Midtx+2 + STZ Midtx+3 + BRA #45 ;Complete logon + +90 LDXIM :LSB:#65 ;Use fallback system userid + LDYIM :MSB:#65 + BRA #80 + +95 LDAIM ATERRB ;Userid not valid in this mode + BRA #60 + + ] + +;*************** +;* L O G O F F * +;*************** + + +USROFF ROUT + +;(LABEL USROFF TO AVOID NAME CLASH +;WITH USRMAN ROUTINE) + +;SET UP ARGS FOR LOGOFF (DELETE USER) +;IN USERMAN, CALL, AND SEND APPROPRIATE +;MESSAGE BACK TO CLIENT. + + JSR COMEND + BNE #30 + +FCBYE + + [ $CMOS + BIT Cmndsw ;Check if command mode + BMI #05 ;Just exit quietly if so + ] + +;nice if this returns no error if not logged on ** 5/9/84 ** + + JSR GETUSR ;23/1/76** + BEQ #10 ;check for logged on user here + +05 LDAIM 0 + [ $CMOS + BRA #20 ;exit ok + | + BEQ #20 ;exit ok + ] + +10 JSR STKUSE ;Entry by function code + BNE #30 + + LDAIM 2 ;LOGOFF ROUTINE NUMBER + JSR SETRTN + JSR USRMAN +20 JSR RCODE +30 JMP COMRTS + + + +CPSOPT ROUT + +;Set USER OPTION in pw file +;Just call appropriate AUTMAN routine + + JSR STKUSE + BNE #20 + LDAAX MIDRX ;Note assumes X is BPTR here + CMPIM &10 ;Check option <16 + BCS #30 + INY + STAIY NEWARG + LDYIM UTPRIV ; check not low-priv user *** 25/5/86 *** + LDAIY USTPTR ; *** 25/5/86 *** + ANDIM LOPRIV ; *** 25/5/86 *** + BNE #40 ; error if so *** 25/5/86 *** + LDAIM 7 + JSR SETRTN + JSR AUTMAN ;Call AUTMAN.USEROPTION +10 JSR RCODE +20 JMP COMRTS + +30 LDAIM INFERA ;Bad arg + [ $CMOS + BRA #10 + | + BNE #10 + ] + +40 LDAIM ATERRD ; Insufficient privilege *** 25/5/86 *** + [ $CMOS + BRA #10 + | + BNE #10 + ] + + +;************************ +;* S E L E C T D I S C * +;************************ + + +SELDSC ROUT ;SELDSC + +;ALL WORK DONE IN USRMAN. + + JSR RDTITL ;GET DISC NAME ON STACK + BNE #20 + + LDAIM &A + JSR SETRTN + JSR SBUFPT + JSR MAPMAN ;*** GET DISC NO FOR NAME ** + BNE #30 + + LDYIM ARGB + LDAIY NEWARG + PHA + INY + LDAIY NEWARG + INY + INY + STAIY NEWARG ;MOVE DISC. NO. UP TO MAKE WAY FOR USRPTR + DEY + PLA + STAIY NEWARG + JSR STKUSE ;SET USER POINTER + BNE #20 + LDYIM ARGF + JSR STKHND ;PUT 3 HANDLES ON STACK + + LDAIM 3 + JSR SETRTN + JSR USRMAN ;*** SELECT DISC ** + BNE #30 + + LDYIM ARGD + LDXIM 2 +10 LDAIY NEWARG + STAAX MIDTX + DEY + DEX + BPL #10 + + LDAIM CCSDIS + STA CCODE + LDAIM TXHDR+3 ;MESSAGE LENGTH + JSR REPLYC +20 JMP COMRTS + +30 JMP ERROR + + LNK UADE17A diff --git a/FileServer/SRC/FileServer/Uade17A b/FileServer/SRC/FileServer/Uade17A new file mode 100644 index 0000000..06d3428 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade17A @@ -0,0 +1,656 @@ + OPT UADE17 ;FILE > Uade17A + TTL File server file UADE17A + +;********************** +;* S E L E C T D I R * +;********************** + +SELDIR ROUT ;SELDIR + +;ALL WORK DONE BY USERMAN AGAIN. + + JSR RDTITL + BNE #10 + JSR STKUSE + BNE #10 + + JSR SBUFPT ;** 5/9/84 ** + LDYIM ARGF + JSR STKHND ;Handles -> stack + JSR SELHAN + BNE #20 ;error in allocation + + LDAIM CCSDIR +00 STA CCODE + LDAIM TXHDR+1 ;Message length + JSR REPLYC +10 JMP COMRTS + +20 JMP ERROR + + +SELHAN LDAIM 5 ;ROUTINE NUMBER + JSR SETRTN + JSR USRMAN ;*** SELECT DIR. ** + BNE #30 ;exit if fail + + LDYIM ARGB + LDAIY NEWARG + STA MIDTX ;New s.dir + LDAIM 0 +30 RTS + +;****************************** +;* S E L E C T L I B R A R Y * +;****************************** + +;as for DIR but null filename is illegal +;if RETRIEVE ok then call USRMAN with LIB as CSD + +SLIB JSR RDTITL + BNE #10 + JSR STKUSE + BNE #10 + JSR SBUFPT + JSR SCOWPT ;Set pointer to COWORK on stack + LDAIM 2 ;Dirman retrieve + JSR SETRTN + + LDYIM ARGH + LDAIM &C0 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;*** RETRIEVE ** + BNE #20 + + JSR STKUSE + BNE #10 + JSR SBUFPT + JSR SCOWPT ;Set pointer to COWORK on stack + + LDYIM ARGF + JSR STKHND ;handles -> stack + + LDYIM ARGH + LDAIY NEWARG + DEY + STAIY NEWARG ;LIB->CSD + + JSR SELHAN ;** 5/9/84 ** + BNE #20 ;error in allocation + + LDAIM CCSLIB + [ $CMOS + BRA #00 + | + BNE #00 + ] + + +;********************* +;* S E T A C C E S S * +;********************* + + +SETACC ROUT + +;1) PUT USER INFO. POINTER AND FILE TITLE +;POINTER ON STACK. +;2) INTERPRET STRING SENT FROM CLIENT INTO +;AN ACCESS BYTE AND STICK ON STACK. +;3) CALL SETATTRIBS IN DIRMAN +;4) REPLY TO CLIENT + + + JSR BUFTXT ;Get file name + BNE #40 + STY COWORK ;Store cmnd. line ptr. + JSR STKUSE + BNE #40 + + JSR SBUFPT + + LDY COWORK ;Restore cmnd. line ptr. + JSR SPACES + + [ $CMOS + STZ COZERO ;Partial result + | + LDAIM 0 + STA COZERO ;Partial result + ] + DEY +10 INY + LDXIM 2 ;Offset into access tables + JSR CMPACC ;Compare letter at Y with access tables + BEQ #10 ;Access letter found + CMPIM "/" ;Owner access delimiter + BEQ #20 + JSR SPACER ;skip trailing spaces ** 25/5/83 ** + CMPIM CR + BNE #50 ;Invalid character => error + DEY ;Point to CR so will exit after rotating COZERO + +20 ASL COZERO ;Rotate access bits to owner position + ASL COZERO + +30 INY ;Increment past '/' delimiter + LDXIM 1 + JSR CMPACC + BEQ #30 + JSR SPACER ;skip trailing spaces ** 25/5/83 ** + CMPIM CR + BNE #50 ;If here, CR has terminated string => set access + + LDYIM ARGF + LDAIM &C0 + STAIY NEWARG ;wild cards flag + LDAIM 4 + INY ;Set arg to SETATTRIBS => SETACCESS + STAIY NEWARG + INY + LDA COZERO ;Restore access byte + STAIY NEWARG ;SET ACCESS BITS + LDAIM 4 ;SETACC ROUTINE NO. + JSR SETRTN + JSR DIRMAN ;*** SET ACCESS ** + JSR RCODE ;SEND REPLY +40 JMP COMRTS ;FINISH + +50 LDAIM SAERRA + JMP ERROR + + +OWNTAB + = "R" + = "W" + = "L" + +POWNTB = 1 ;OWNER READ + = 2 ;OWNER WRITE + = 4 + +CMPACC ROUT + LDAAY MIDRX + EORAX OWNTAB + ANDIM &DF ;Compare with cases forced + BEQ #10 + DEX + BPL CMPACC + LDAAY MIDRX ;Exit, A = char, Z unset + RTS + +10 LDAAX POWNTB + [ $CMOS + TSB COZERO ;Update partial result + | + ORA COZERO + STA COZERO ;Update partial result + ] + LDXIM 0 ;Set Z flag; note A corrupted + RTS + + + +;****************** +;* N E W U S E R * +;****************** + + +NEWUSE ROUT + +;ALL WORK DONE IN AUTMAN, ROUTINE NO. 1 + + JSR RDTITL ;Get user name + BNE #10 + JSR STKUSE ;Stack caller's user info + BNE #10 + JSR SBUFPT ;Stack new user ptr. + + LDAIM 1 +DOUSE JSR SETRTN ;SET ROUTINE NUMBER + JSR AUTMAN ;DO NEW USER + JSR RCODE ;SEND RETURN CODE +RUEXIT ;Shared with REMUSE +SPWEXT ;Shared with SETPW +10 JMP COMRTS ;FINISH + + + +;************************ +;* R E M O V E U S E R * +;************************ + +REMUSE ROUT + +;REMARKABLY SIMILAR TO NEWUSER + + JSR RDTITL + BNE RUEXIT + JSR STKUSE + BNE RUEXIT + JSR SBUFPT + + LDAIM 4 + [ $CMOS + BRA DOUSE ;Always jump + | + BNE DOUSE ;Always jump + ] + + +;************************** +;* S E T P A S S W O R D * +;************************** + + +SETPW ROUT + +;GET USER INFO AND CALL ROUTINE IN AUTMAN +;TO DO WORK. + + JSR BUFTXT ;Buffer old pw + BNE SPWEXT + INX ;Ptr. to next free spot in TXTBUF + JSR BTXTA ;Buffer new pw + BNE SPWEXT + JSR COMEND + BNE SPWEXT + + [ $Level3 + BIT MONFLG ;Do monitor message specially to avoid PW + BPL #00 ;No monitor -> carry on + LDY QPTR ;Point to RX control block + JSR PRTMC ;Print machine number + JSR VSTRIN + = ": Pass",CR + NOP +00 + ] + JSR STKUSE + BNE SPWEXT + JSR SBUFPT + + LDYIM UTPRIV ; check low-privilege *** 25/5/86 *** + LDAIY USTPTR ; *** 25/5/86 *** + ANDIM LOPRIV ; *** 25/5/86 *** + BNE #10 ; br if password not allowed *** 25/5/86 *** + + LDAIM 3 ;ROUTINE NUMBER + [ $CMOS + BRA DOUSE ;Always jump + | + BNE DOUSE ;Always jump + ] + +10 LDAIM ATERRD ; Insufficient privilege *** 25/5/86 *** + JMP ERROR ; *** 25/5/86 *** + + +;********************** +;* C R E A T E D I R * +;********************** + + +CDIRFN ROUT + JSR Stkuse ; Check logged-on first + BNE #20 ; *** 31/10/86 *** + LDY BPTR + INY + JSR RDTITL + BNE #20 + LDY BPTR + LDAAY MIDRX + BEQ #30 ;zero is a silly number + CMPIM (:MSB:MAXDIR)+1 + BCS #30 + [ $CMOS + BRA #10 ;check for overflow + | + BCC #10 ;check for overflow + ] + +CDIR ;CDIR + +;PASS USER INFO AND DIRECTORY NAME +;TO DIRMAN. THEN CLEAN UP IF NECCESSARY. + + JSR RDTITL + BNE #20 + LDAIM 2 ;size of directory + +10 CMP CACHSZ+1 ;** 31/1/85 + BCS #30 + LDYIM ARGF + STAIY NEWARG + INY + LDAIM &80 ;** 11/10/84 ** + STAIY NEWARG ;wild card flag + JSR STKUSE + BNE #20 + + JSR SBUFPT + LDAIM 5 ;CREATE DIR. FUNCTION CODE + JSR SETRTN + JSR DIRMAN ;*** DO DIR. CREATE ** + BNE #15 + JSR OBJCLR ;CLEAR OLD OBJECT +15 JSR RCODE ;store RC + +SPEXIT ;Shared with SETPRIV +20 JMP COMRTS + +30 LDAIM DRERRP + JMP ERROR + + +;****************** +;* S E T P R I V * +;****************** + + +STPRIV ROUT + +;MOST WORK DONE BY AUTMAN + + JSR BUFTXT ;MOVE USER ID. + BNE SPEXIT + STY COWORK + JSR STKUSE + BNE SPEXIT + JSR SBUFPT + + LDY COWORK + JSR SPACES + ANDIM &DF ;Force upper case + CMPIM "S" ;SYSTEM USER ??? + BEQ #10 + CMPIM "L" ;ow-privilege user? *** 25/5/86 *** + BEQ #50 ; *** 25/5/86 *** + CMPIM CR ;NON-SYSTEM USER ?? + BNE #30 + LDAIM 0 ;NON-SYST. USER + [ $CMOS + BRA #20 + | + BEQ #20 + ] + +10 INY + JSR COMEND + BNE SPEXIT + LDAIM 1 ;SYSTEM USER ! +20 LDYIM ARGF + STAIY NEWARG ;Set user's priv. flag + LDAIM 5 ;SET PRIV. + JMP DOUSE + +30 LDAIM SPERRA +40 JMP ERROR + +50 INY ; *** 25/5/86 *** + JSR COMEND ; *** 25/5/86 *** + BNE SPEXIT ; *** 25/5/86 *** + LDAIM 2 ;Low-privilege user *** 25/5/86 *** + [ $CMOS + BRA #20 ; *** 25/5/86 *** + | + BNE #20 ; *** 25/5/86 *** + ] + +;************* +;* D I S C S * +;************* + +DISCS ROUT + +;Provide list of discs currently on system. + +;User supplies entry (drive) number, and +;number of drives. For each drive he is interested in, +;call MAPMAN once to get disc number +;and again to get disc name. + + [ $CMOS + STZ COZERO ;No. of drives found + | + LDAIM 0 + STA COZERO ;No. of drives found + ] + LDA BBUF + CLC + ADCIM TXHDR+1 ;Result buffer + STA COZERO+1 + LDA BBUF+1 + ADCIM 0 + STA COZERO+2 +10 LDX BPTR + LDAAX MIDRX + CMP DRIVES + BCS #30 ;User drive >= drives + + [ $CMOS + STAI COZERO+1 ;Store probable drive number + | + LDYIM 0 + STAIY COZERO+1 ;Store probable drive number + ] + LDYIM ARGB + STAIY NEWARG + LDAIM 8 ;Drive -> disc no. + JSR SETRTN + JSR MAPMAN + BNE #28 ;Abort + LDAIM &B ;Disc no. -> name + JSR SETRTN + JSR MAPMAN + BNE #40 + INC COZERO+1 + BNE #20 + INC COZERO+2 +20 LDA COZERO+1 + STA MOVTO + LDA COZERO+2 + STA MOVTO+1 + + LDYIM ARGB + LDAIY NEWARG ;Ptr. to name + STA MOVFRM + INY + LDAIY NEWARG + STA MOVFRM+1 + LDXIM DNAMLN + JSR MOVE ;Move name to result + CLC + LDA COZERO+1 + ADCIM DNAMLN + STA COZERO+1 + BCC #25 + INC COZERO+2 +25 INC COZERO ;No. of drives dealt with +28 LDX BPTR ;**14/06/86** + INCAX MIDRX ;Next drive to do + LDA Cozero ;**1/5/87** loop until requested drives done + CMPAX Midrx+1 ;**1/5/87** + BCC #10 ;**1/5/87** + +30 LDYIM ARGB + LDA COZERO ;Set args to LSTPRY + STAIY NEWARG + INY + LDA COZERO+1 + STAIY NEWARG + INY + LDA COZERO+2 + STAIY NEWARG + LDAIM CCDSCS + JSR LSTRPY ;Reply to client +35 JMP COMRTS +40 JSR EXTERR + [ $CMOS + BRA #35 + | + JMP #35 + ] + +;************* +;* U S E R S * +;************* + +CPUSRS ROUT + + JSR STKLST + + JSR GETUSR ;Get current user (16/1/86) + BNE #15 ;***31/10/86*** + LDYIM UTPRIV + LDAIY USTPTR + ANDIM SYSTPV ;Stack privilege for USRMAN +05 LDYIM ARGF + STAIY NEWARG + LDX BPTR + LDAAX RXBUF+1 ;**20/5/87** check function code + EORIM (FNusr2-FNtab)/2 ;**20/5/87** zero if job/task nos + INY + STAIY NEWARG + + LDAIM 7 + JSR SETRTN + JSR USRMAN + BNE #10 + LDAIM CCUSRS + JSR LSTRPY + JMP COMRTS + +10 JMP ERROR + +15 LDAIM 0 ;not logged on, hide priv users + [ $CMOS + BRA #05 + | + BEQ #05 + ] + +;*********** +;* D A T E * +;*********** + + +CPSETD ROUT ;Set the date ** 20/9/83 ** + JSR Getuse ;***Check caller logged on*** + BNE #20 + LDYIM Utpriv ;***and system priv*** + LDAIY Ustptr + ANDIM Systpv + BEQ #30 ;***31/10/86*** + LDA DATE + PHA + LDA DATE+1 + PHA ;SAVE DATE IN CASE WE NEED IT! + LDY BPTR ;check flag + LDAAY MIDRX + STA DATE + LDAAY MIDRX+1 + STA DATE+1 + JSR CHKDTE + BNE #10 + LDY BPTR + LDAAY MIDRX+2 + CMPIM 24 + BCS #10 + STA HRS + LDAAY MIDRX+3 + CMPIM 60 + BCS #10 + STA MINS + LDAAY MIDRX+4 + CMPIM 60 + BCS #10 + STA SECS + [ $Level3 + JSR SETTME + JSR PRDTE ;Display new date + | + JSR SETDTE ;Set date & time + ] + PLA + PLA ;REMOVE SAVED DATE + LDAIM TXHDR ;Rx header only + [ $CMOS + BRA DATOUT + | + BNE DATOUT + ] + +10 PLA + STA DATE+1 + PLA + STA DATE + LDAIM DTERR + JSR RCODE +20 JMP COMRTS + +30 LDAIM ATerrd ;Insufficient privilege *** 31/10/86 *** + JMP Error ;*** 31/10/86 *** + +CPDATE ROUT + +;No user check since doesn't involve +;files. + + [ $Level3 + JSR PRTIM + | + JSR GETDTE ;Get the date & time + ] + LDA DATE ;read date + STA MIDTX + LDA DATE+1 + STA MIDTX+1 + LDA HRS + STA MIDTX+2 + LDA MINS + STA MIDTX+3 + LDA SECS + STA MIDTX+4 ;Time = zero if clock not present + LDAIM TXHDR+5 ;Message length + [ $CMOS + BRA Datout + | + BNE Datout + ] + + +;***************** +;* V E R S I O N * +;***************** + + [ $CMOS +VERSN = "FileStore " + = "0"+VERLA, ".", "0"+VERLB/10, "0"+VERLB-VERLB/10*10, CR, 6 + ] + +CPVERN ROUT + LDYIM 0 +10 LDAAY VERSN + STAAY MIDTX + INY + CMPIM 6 ;end of version number character + BNE #10 + + TYA +Datous ;Entry with text length in A + CLC + ADCIM TXHDR +Datout ;Entry with msg length in A + [ $CMOS + STZ CCODE ;0 command code + | + LDXIM 0 + STX CCODE ;0 command code + ] + JSR REPLYC ;Message length in A here +Datoux ;Here to just exit + JMP COMRTS + + LNK UADE18 diff --git a/FileServer/SRC/FileServer/Uade18 b/FileServer/SRC/FileServer/Uade18 new file mode 100644 index 0000000..e03b9c3 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade18 @@ -0,0 +1,937 @@ + OPT UADE18 ;FILE > Uade18 + TTL File server file UADE18 + +;Random access and RENAME & User Info + + +;*************** +;* R E N A M E * +;*************** + +;Rename file <A> as <B> +; +;1) Buffer both file names, call DIRMAN.CHECKDISCNOS +;2) Retrieve A. Check owner access, is a file, is unlocked +;3) Preserve name B with details of A +;4) If old SINofB = SINofA, renaming same file -> return +;5) Else, clear oldB from map, and delete A from dir (not map!) + +RENAME ROUT + STY COTEMP + JSR GETUSE + BNE Datoux + + LDY COTEMP ;pointer into MIDRX + JSR BUFTXT ;Buffer name A + BNE #10 ;Exit via extra jump + INX + STX COTEMP ;Store offset of B in TXTBUF + JSR BTXTA ;Buffer name B + BNE #10 ;Exit via extra jump + JSR COMEND ;Check to end of command line + BNE #10 ;Exit via extra jump + +;** 24/9/84 ** + +;Substantial rewrite to allow renaming of directories +;The actual mechanics are identical to renaming files +;but lots of checking for loops in directories needs to be +;done, which means that full pathname expansion is called for + + LDA BBUF + STA PTR + LDA BBUF+1 + STA PTR+1 + + [ $CMOS + STZ REXIST ;full wild card lookup + LDAIM 0 + | + LDAIM 0 + STA REXIST ;full wild card lookup + ] + JSR RNAMLK ;do the checking for existence etc. + BNE #10 ;fail + + STX RTYPE ;type of object that we've found + CLC + LDA PTR + STA PTR1 + ADCIM :LSB:INFNXT + STA PTR + + LDA PTR+1 + STA PTR1+1 + ADCIM :MSB:INFNXT + STA PTR+1 ;new result area + +;PTR =lastname and info <B> +;PTR1=lastname and info <A> + + LDA COTEMP ;offset of name <B> + JSR RNAMLK ;similar checking as for <A> + BEQ #15 ;all succeeded [but may not be ok !] + + LDXIM 0 ;no object returned so no type either + CMPIM DRERRC ;'not found' in final part of name +10 BNE #45 ;failed for some serious reason + ROR REXIST ;object <B> done NOT exist (=>&80) + [ 1=0 ; removed, INFDIS set if B does not exist ** 14/10/86 ** + BMI #20 ;if so then skip disc number check + ] + +;now look for rename across discs + +15 LDYIM INFDIS + LDAIY PTR + CMPIY PTR1 + BNE #40 ;failed here + INY + LDAIY PTR + CMPIY PTR1 + BNE #40 ;failed here too + +20 LDA RTYPE ;look for file/dir + ANDIM TYPDIR + BEQ #55 ;file so ok + +;now look for loops in directories + + LDYIM 0 ;from the beginning + STY LAST + STY NAME + LDX COTEMP ;starts with "$" ? + LDAAY TXTBUF + JSR RNAMPD ;**20/5/87** check root or pseudo directory + BNE #25 + STA NAME ;**20/5/87** store root or pseudo directory name + LDAAY TXTBUF+1 + JSR RNAMPT ;**20/5/87** check separator/terminator + BNE #25 + INC LAST +25 LDAAX TXTBUF + JSR RNAMPD ;**20/5/87** check root or pseudo directory + BNE #28 + EOR NAME ;**20/5/87** zero if same root or pseudo directory as A? + STA NAME + LDAAX TXTBUF+1 + JSR RNAMPT ;**20/5/87** check separator/terminator + BNE #28 + DEC LAST +28 ;X=0 or fail here + LDA LAST ;test for mismatch + BNE #40 ;bad rename + LDA NAME ;**20/5/87** A & B must be in same or no pseudo directory + BNE #40 + +30 LDAAY TXTBUF + JSR ISCHAR + BCS #32 + ANDIM &DF ;force upper case +32 CMPIM TERMIN + BEQ #50 ;bad, LEFT$<B>=$<A> unless $<A>=$<B> + STA NAME + LDAAX TXTBUF ;mismatch in names is essential + JSR ISCHAR ;force case on both chars + BCS #35 + ANDIM &DF +35 CMP NAME ;match against other name + BNE #37 + INX + INY + BNE #30 + +37 BIT REXIST ;different names so <B> must NOT exist + BMI #55 + +40 LDAIM RNAMQQ ;bad rename error string +45 JMP ERROR + +50 LDAAX TXTBUF ;check for subdirectory here + CMPIM SEPART ;** 27/3/85 ** + BEQ #40 +55 JSR STKUSE ;Set up PRESERVE call for A details, named B + LDA COTEMP + JSR SETTXP ;put name to stack + + INY + STY NAME + LDAIM INFLOA + STA ONAME ;counters + LDXIM 17 + +60 LDY ONAME + LDAIY PTR1 + LDY NAME + STAIY NEWARG + INC ONAME + INC NAME + DEX + BNE #60 + + LDAIM 12 + JSR SETRTN ;Do DIRMAN.PRESERVE (without DELCHK) + + LDYIM ARGT + LDAIM &80 ;enable wildcards + STAIY NEWARG ;wild card flag + + JSR DIRMAN + BNE #45 + + BIT REXIST ;did <B> exist + BMI #80 ; .. no .. + + LDXIM 3 + LDYIM INFSIN+2 +65 LDAIY PTR + CMPIY PTR1 + BNE #70 + DEY + DEX + BNE #65 + +70 TXA + BEQ #85 ;if identical then NOP + +75 JSR OBJCLR ;Clear old B from map (if SIN <> zero) + BNE #45 ;Error exit + +;Then finally delete name A from directory + +80 JSR STKUSE + JSR SBUFPT ;Set pointer to TXTBUF + LDAIM 11 ;** 24/9/84 ** + JSR SETRTN + + LDYIM ARGG + LDAIM &C0 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;Delete A +85 JSR RCODE ;Return success/failure and exit + +90 JMP COMRTS + + +RNAMLK ROUT ;A=offset in TXTBUF of pathname for object +;PTR=results area + +;retrieves object in TXTBUF, expanding pathname into !PTR +;checks object existence, pathname completeness, +;object owned, unlocked, not open + + PHA + JSR STKUSE ;prepare for retrieve call + PLA + JSR SETTXP ;point to the name + + LDYIM ARGF + LDA PTR + STAIY NEWARG + INY + LDA PTR+1 + STAIY NEWARG ;pointer to results area + INY + LDAIM 0 ;no wildcards + STAIY NEWARG + + LDAIM 2 + JSR SETRTN + JSR DIRMAN ;call retrieve + BNE #40 ;DIRMAN call failed + + LDYIM ARGB + LDAIY NEWARG + TAY + + ANDIM OWNER + BNE #10 + LDAIM DRERRE ;'insufficient priv' + RTS + +10 TYA + ANDIM LOCKED + BEQ #20 + LDAIM DRERRG ;'entry locked' + RTS + +20 STY LAST ;preserve Type & access + +;now check that it isn't open + + LDAIM ARGB + STA NAME + LDYIM INFDIS + STY ONAME + LDXIM 2 + JSR #50 ;copy disc no. + + LDAIM INFSIN + STA ONAME + LDXIM 3 + JSR #50 ;copy SIN + + LDAIM 2 + JSR SETRTN + JSR RNDMAN ;ask for info + PHA + LDX LAST + PLA + BNE #30 ;RC=0 if open + LDAIM RDERRH ;'already open' + RTS + +30 LDAIM 0 +40 RTS ;*** the end ** + + +50 LDY ONAME + LDAIY PTR + LDY NAME + STAIY NEWARG + INC NAME + INC ONAME + DEX + BNE #50 + RTS + +RNAMPD ROUT ;**20/5/87** check name for root or pseudo directory + CMPIM ROOT + BEQ #10 + JMP Testpd + +RNAMPT ;**20/5/87** check separator or terminator + CMPIM SEPART + BEQ #10 + CMPIM TERMIN +10 RTS + + +;************** +;* USER INFO * +;************** + + +CPUINF ROUT + + JSR STKUSE + BNE #30 ;Who are you + + LDAIM HDRLEN ;Offset of user name + JSR SETFTP ;Set ptr. to user name + + LDAIM 6 ;USRMAN.USERINFO + JSR SETRTN + + JSR USRMAN + BNE #40 + + LDYIM ARGB + LDAIY NEWARG + [ 1=0 + LDXIM 0 ;calculate privilege value ; *** 25/5/86 *** + BITIM SYSTPV + BEQ #10 + LDXIM 1 +10 BITIM LOPRIV + BEQ #20 + LDXIM 2 +20 STX MIDTX + | + ANDIM SYSTPV ;calculate privilege value ;**31/10/86** + STA MIDTX + ] + INY ;copy station address + LDAIY NEWARG + STA MIDTX+1 + INY + LDAIY NEWARG + STA MIDTX+2 + INY + LDAIY NEWARG ;**20/5/87** return job (task) number + LSRA ;**20/5/87** position job (task) number + LSRA + LSRA + STA MIDTX+3 ;**20/5/87** assume extended format + + LDX BPTR + LDAAX RXBUF+1 ;**20/5/87** check function code + CMPIM (FNuin2-FNtab)/2 ;**20/5/87** C set if extended function + LDAIM TXHDR+3 ;Message length + BCC #20 + [ $Level3 + LDAIM TXHDR+4 + | + INCA + ] +20 JSR REPLYC ;Return message +Cpuinx +30 JMP COMRTS + +40 JSR RCODE ;Send error + [ $CMOS + BRA #30 + | + JMP #30 + ] + + + +;************* +;* C L O S E * +;************* + +CPSHUT JSR STKUSE + BNE #30 + LDX BPTR + LDAAX MIDRX ;Get old handle + BEQ #50 ;Handle=0 => close all files for machine + + INY + STAIY NEWARG + LDAIM 3 ;"Close handle" + [ $CMOS + BRA #60 + | + BNE #60 + ] + +50 LDAIM &D ;"Close all files" +60 JSR SETRTN + JSR RNDMAN + [ $CMOS + BRA #40 + | + JMP #40 + ] + +;******** +;* FIND * +;******** + +;Open a file for reading or update, +;or open a directory + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +FIND ROUT + [ $CMOS + STZ COTEMP ;** 15/11/84 ** used to build access byte + | + LDAIM 0 + STA COTEMP ;** 15/11/84 ** used to build access byte + ] + + JSR GETUSE ;Set mc no. and call FINDMC + BNE Cpuinx ;Fail, exit + +;USTPTR now points to user info. +;Check if need to create a new file +;or if existing one will do. Then either create or retrieve +;new or existing file. + + LDX BPTR + LDAAX MIDRX+1 + BNE #30 ;Not opening for update + LDAAX MIDRX + BNE #30 ;File must exist => don't create + + JSR FICRFL ;Otherwise, create file and forge retrieve info. + BNE #45 ;Error + + LDAIM FILEJC ;Set "just created" flag in mode + [ $CMOS + TSB COTEMP + BRA #40 ;Skip round retrieve since we have all info. already + | + ORA COTEMP + STA COTEMP + BNE #40 ;Skip round retrieve since we have all info. already + ] + +30 JSR FIRETR ;Retrieve details of existing file + BNE #45 + +40 LDYIM ARGB + LDAIY NEWARG ;Get access allowed and type + TAX + ANDIM RDWRAC+TYPE + BNE #50 ;File, no read or write access + + LDAIM DRERRE +45 JMP Error ;insufficient access + +50 LDYIM ARGE + TXA + STAIY NEWARG ;Set up for RNDMAN call + PHA ;save access byte + + LDAIM 1 ;RNDMAN.OPEN + JSR SETUSA ;Copy USTPTR onto stack + +;Mode so far is in COTEMP - may need write +;access bit setting. + + PLA ;restore access byte + LDX BPTR + LDYAX MIDRX+1 ;Get read flag from client + BNE #60 ;Jump if set + + ANDIM 3 ;supply just the public access bits + [ $CMOS + BRA #65 ;fall thru' IS ok here + | + JMP #65 ;fall thru' IS ok here + ] + +; ORAIM RDWRAC ;Set Read/Write access + +60 LDAIM READAC +65 ORA COTEMP + LDYIM ARGD + STAIY NEWARG ;Put mode on stack + + INY ;Y := ARGE + JSR SCOWPT ;Put COWORK ptr on stack + + JSR RNDMAN ;*** Call RNDMAN.OPEN ** + BNE #90 ;Open failed + +;Open worked - return handle + + LDYIM ARGB + LDAIY NEWARG + STA MIDTX ;Store handle in TX buffer + + LDA COTEMP + ANDIM FILEJC ;DATE ALREADY SET IF JUST CREATED + BNE #70 + LDY BPTR + LDAAY MIDRX+1 ;updating file ? + BNE #70 + [ $Level3 + | + JSR GETDTE ;Ensure current date stored + ] + LDA DATE ;Check date and skip update if unchanged + CMP COTEMP+INFDTE + BNE #67 + LDA DATE+1 + CMP COTEMP+INFDTE+1 + BEQ #70 +67 LDAIM 4 ;DIRMAN.SET ATTRIBUTES + JSR SETUSA ;USER INFO + LDAIM FNDFTO ;POINTER TI FILE TITLE + JSR SETFTP ;FILE TITLE POINTER TO STACK + INY + LDAIM &C0 ;** 19/11/84 ** only updates one entry + STAIY NEWARG ;SET WILD CARD FLAG + INY + LDAIM 5 ;SET DATE FUNCTION + STAIY NEWARG + INY + LDA DATE + STAIY NEWARG ;PUT IN CURRENT DATE + INY + LDA DATE+1 + STAIY NEWARG + JSR DIRMAN ;SET TODAYS DATE ON OBJECT + BNE #90 ;SHOULDN'T FAIL!!! + +70 LDAIM TXHDR+1 ;Message length + JSR REPLYC ;Send handle back + +80 JMP COMRTS ;Return + +90 JSR EXTERR ;Send error code + [ $CMOS + BRA #80 ;exit + | + JMP #80 ;exit + ] + + +;*** FIRETR *** + +;Called from FIND to retrieve file details. +;Calls DIRMAN.RETRIEVE + +;Entry: USTPTR points to USERTB entry +;File title stil in RX buffer + +;Exit: A: return code +;COWORK buffer: file details +;ARGB on NEWARG: max access allowed + +FIRETR ROUT + LDAIM DRRTR ;DIRMAN.RETRIEVE + JSR SETUSA ;Put user info on NEWARG stack + + LDAIM FNDFTO ;File title offset + JSR SETFTP ;Set file title pointer + + JSR SCOWPT + + LDYIM ARGH + LDAIM &C0 + STAIY NEWARG ;wild card flag + + JMP DIRMAN ;*** Call DIRMAN.RETRIEVE and return ** + + +;*** FICRFL *** + +;Called to create new file in FIND. +;File is created with standard size of FIFLSZ bytes. + +;Entry: USTPTR points to user info +;File title in request buffer + +;Exit: A = return code +;COWORK buffer: file details as if from +;DIRMAN.RETRIEVE + +FICRFL ROUT + LDAIM 10 ;=> get disc number for this file + JSR SETUSA + LDAIM FNDFTO + JSR SETFTP ;Set pointer to file title + + LDYIM ARGK + LDAIM &80 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;DIRMAN.FILETITLETODISCNUMBER + BNE #10 + +;Correct disc number now on stack + + LDYIM ARGD ;Set file size to manifest FIFLSZ + LDAIM :LSB:FIFLSZ + STAIY NEWARG ;LS byte + INY + LDAIM :MSB:FIFLSZ + STAIY NEWARG ;CS byte + INY + LDAIM 0 ;MS byte zero + STAIY NEWARG + + JSR SETUSE ;pass userinfo @ ARGG,H ** 3/10/84 ** + + LDAIM MAPCS ;MAPMAN.CREATESPACE + JSR SETRTN + + JSR MAPMAN ;*** MAPMAN.CREATSPACE ** + BEQ #20 +10 RTS ;Exit if failed + +;Disc number and SIN on stack. +;Save them in COWORK (=DETRAM) buffer in +;DIRMAN.RETRIEVE format. + +20 LDYIM ARGB + LDAIY NEWARG ;Disc no. (LS) + STA DETDIS + INY + LDAIY NEWARG ;Disc no. (MS) + STA DETDIS+1 + + LDYIM ARGD + LDAIY NEWARG ;SIN (LS) + STA DETSIN + INY + LDAIY NEWARG ;SIN (CS) + STA DETSIN+1 + INY + LDAIY NEWARG ;SIN (MS) + STA DETSIN+2 + +;zero the new space + + LDYIM ARGG + LDAIM 0 ;old size + STAIY NEWARG + INY + STAIY NEWARG + INY + STAIY NEWARG + + LDAIM 13 + JSR SETRTN + JSR MAPMAN + BNE #10 ;exit if error + + [ $Level3 + | + JSR GETDTE ;Ensure date and time accurate + ] + + +;Preserve the newly created file + + LDAIM DRPRS ;DIRMAN.PRESERVE + JSR SETUSA ;Set user info on NEWARG stack + + LDAIM FNDFTO ;Offset of file title + JSR SETFTP ;Set pointer to title + + LDAIM &FF ;Clear load & exec addresses to $FF + +30 INY + STAIY NEWARG + CPYIM ARGM ;ARGM is end of exec address + BNE #30 ;Loop + + LDAIM ACCDEF+TYPFIL ;Default access; Type = file + INY + STAIY NEWARG ;Set type & access + + INY ;Set creation date + LDA DATE + STAIY NEWARG + INY + LDA DATE+1 + STAIY NEWARG + +;Copy SIN from COWORK (=DETRAM) to NEWARG stack + + LDA DETSIN ;SIN (LS) + INY + STAIY NEWARG + LDA DETSIN+1 ;SIN (CS) + INY + STAIY NEWARG + LDA DETSIN+2 ;SIN (MS) + INY + STAIY NEWARG + + LDYIM ARGT + LDAIM &80 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;*** Call DIRMAN.PRESERVE ** + BNE #40 ;Failed + JSR OBJCLR ;Clear old object out of map & cache if nesc. + BNE #40 ;**** 17/3/83 **** + +;Have created file: fabricate DIRMAN.RETRIEVE info +;in DETRAM buffer (disc no. and SIN already there) +;and on NEWARG stack. Need to include only access +;info and size. + + LDAIM ACCDEF ;Default access + STA DETACC + + LDAIM :LSB:FIFLSZ ;Size (LS) + STA DETSZ + LDAIM :MSB:FIFLSZ ;Size (CS) + STA DETSZ+1 + [ $CMOS + STZ DETSZ+2 ;Size (MS) + | + LDAIM 0 + STA DETSZ+2 ;Size (MS) + ] + +;Need to put type of object & max access +;allowed on NEWARG stack at ARGB (because +;DIRMAN.RETRIEVE does). + + LDAIM RDWRAC+TYPFIL ;Read/write access; Type = file + LDYIM ARGB + STAIY NEWARG + + LDAIM 0 ;return code + RTS + +;Failed to do preserve - must free space + +40 STA COTEMP+1 ;Save RC + + JSR FIDSIN ;Disc no. & SIN to stack + + LDYIM ARGF + JSR SETUSE ;pass pointer to user info ** 3/10/84 ** + + LDAIM MAPFS ;MAPMAN.FREESPACE + JSR SETRTN + + JSR MAPMAN ;*** MAPMAN.FREESPACE ** + BEQ #50 ;OK + JSR INTERR ;Never happens? + +50 LDA COTEMP+1 ;Get back RC from Preserve + RTS + + +;*** FIDSIN *** + +;Copy disc no. and SIN from DETRAM (=COWORK) buffer +;to NEWARG stack + +FIDSIN ROUT + LDYIM ARGB + LDA DETDIS ;Disc no (LS) + STAIY NEWARG + LDA DETDIS+1 ;Disc no (MS) + INY + STAIY NEWARG + + LDA DETSIN ;SIN (LS) + INY + STAIY NEWARG + LDA DETSIN+1 ;SIN (CS) + INY + STAIY NEWARG + LDA DETSIN+2 ;SIN (MS) + INY + STAIY NEWARG + RTS + + + +;*********** +;* E O F * +;*********** + +CPEOF ROUT + +;Calls RDEOF and returns $FF if HWM<=SFP, zero +;otherwise. + + JSR STKUSE + BNE #05 ;User not valid + + LDX BPTR + LDAAX MIDRX + INY + STAIY NEWARG ;Set handle of file + LDAIM &F + JSR SETRTN + JSR RNDMAN ;Do End of File call + BNE #06 ;Error -> pass on + LDYIM ARGB + LDAIY NEWARG ;Get result from randman + STA MIDTX + LDAIM TXHDR+1 + JSR REPLYC +05 JMP COMRTS + +06 JSR RCODE ;Return error + [ $CMOS + BRA #05 + | + JMP COMRTS + ] + +;***************************** +;* Return free space on disc * +;***************************** + +CPSPAC + JSR RDTITL + BNE #05 ;syntax error ? + + LDAIM 10 + JSR SETRTN + JSR SBUFPT ;put pointer on stack + + JSR MAPMAN ;name -> number + BNE #20 ;skip on error + +;returns: +;ARGB = LS disc number +;ARGC = MS disc number + + LDAIM 12 ;new entry point 21/3/83 + JSR SETRTN + + JSR MAPMAN + BNE #20 ;skip on error + + LDXIM 5 + LDYIM ARGG ;ready to copy data back +10 LDAIY NEWARG + STAAX MIDTX + DEY + DEX + BPL #10 ;return three bytes + + LDAIM TXHDR+6 ;message length + JMP Datout ;send back result + +20 JMP Error + + +;return callers free space + +RDFREE ROUT + JSR STKUSE + BNE #70 + + LDYIM ARGC + LDX BPTR + LDAAX MIDRX + CMPIM CR + BNE #20 ;no argument + + LDA USTPTR + CLC + ADCIM UTUSID + STA USTPTR + BCC #10 + INC USTPTR+1 +10 JSR SETUSE ;set the user pointer on stack + [ $CMOS + BRA #30 + | + JMP #30 + ] + +20 LDAIM HDRLEN+0 + JSR SETFTP ;point to user name + +30 LDAIM 9 + JSR SETRTN + JSR AUTMAN + BNE #50 + + LDXIM 3 + LDYIM ARGB+3 +40 LDAIY NEWARG + STAAX MIDTX + DEY + DEX + BPL #40 + LDAIM HDRLEN+4 + JMP Datout + +50 JMP ERROR + +;set user free space + +WRFREE JSR STKUSE + BNE #70 + + LDYIM ARGC + LDAIM HDRLEN+4 ;offset of name + JSR SETFTP ;pointer to name + + LDX BPTR + LDYIM ARGF +60 LDAAX MIDRX + STAIY NEWARG + INX + INY + CPYIM ARGF+4 + BNE #60 + + LDAIM 10 + JSR SETRTN + JSR AUTMAN + JSR RCODE ;reply with zero RC +70 JMP COMRTS ;else all ok + + LNK UADE19 diff --git a/FileServer/SRC/FileServer/Uade19 b/FileServer/SRC/FileServer/Uade19 new file mode 100644 index 0000000..2a9d5c5 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade19 @@ -0,0 +1,817 @@ + OPT UADE19 ;File > Uade19 + TTL File server file UADE19 + + +;********** +;* GETBYT * +;********** + +;Read single byte from file. +;All work done by RNDMAN. + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +GETBYT ROUT + JSR STKUSE ;Put user info ptr on stack + BNE #10 + + JSR #30 + + LDAIM 7 ;RNDMAN.RDCH + JSR SETRTN + JSR RNDMAN ;*** Call RNDMAN.RDCH ** + BNE #20 ;Failed + + LDYIM ARGB + LDAIY NEWARG ;Get byte read + STA MIDTX ;Put in TX buffer + + INY + LDAIY NEWARG ;Get EOF flag + STA MIDTX+1 ;Put in TX buffer + LDAIM TXHDR+2 ;Message length + +;Note that sequence no. is still in control block + + JSR REPLYC ;Send reply + +10 JMP COMRTS ;exit + +20 JMP ERROR + +30 LDX BPTR + LDAAX RXBUF+2 ;Get file handle + LDYIM ARGD + STAIY NEWARG + + LDX QPTR ;Get seq no. from control block + LDAAX RXCBV + ANDIM 1 ;Mask out reception flag + INY + STAIY NEWARG + RTS + + +;********** +;* PUTBYT * +;********** + +;Write single byte to file. +;All work done by RNDMAN. + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +PUTBYT + JSR STKUSE ;Put user info ptr on stack + BNE #10 + + JSR #30 + + LDX BPTR + LDAAX RXBUF+3 ;Get byte to be written + INY + STAIY NEWARG ;Put on call stack + + LDAIM 8 ;RNDMAN.WRCH + JSR SETRTN + JSR RNDMAN ;*** Call RNDMAN.WRCH ** + +;Note that sequence no. is still in control block + + JSR RCODE ;Send return code + [ $CMOS + BRA #10 ;Exit + | + JMP COMRTS ;exit + ] + + +;* CPRDAR * + +;Read specified part of file info + +;Most work done in RNDMAN. + +CPRDAR ROUT + JSR GETUSE ;USTPTR := USERTB entry + BNE #60 + JSR SETUSR ;Copy user info to NEWARG stack + LDX BPTR ;Offset of request buffer + LDAAX MIDRX ;Get handle + LDYIM ARGD + STAIY NEWARG ;Put handle on NEWARG stack + + LDAIM &B ;RNDMAN.RDAR + JSR SETRTN + JSR RNDMAN ;*** Call RNDMAN.RDAR ** + BNE #40 ;Not OK, send error code and exit + +;Have now got sequential file ptr, file hwm, +;and file size on NEWARG stack. +;The one to be sent back is determined by +;arg in request block. +;Arg is 0,1,2 resp. to get the above. + +;Set Y to appropriate offset on NEWARG stack + + LDX BPTR ;Offset of request buffer + LDAAX MIDRX+1 ;Arg from request + BNE #10 ;Not 0 + + LDYIM ARGB ;Offset of file ptr + [ $CMOS + BRA #50 + | + BNE #50 + ] + +10 CMPIM 1 ;Test arg + BNE #20 ;Not 0 or 1 + + LDYIM ARGE ;Offset of file HWM + [ $CMOS + BRA #50 + | + BNE #50 + ] + +20 CMPIM 2 ;Test arg + BNE #30 ;Not 0, 2, or 1 + + LDYIM ARGH ;Offset of file size + [ $CMOS + BRA #50 + | + BNE #50 + ] + +;Invalid arg in request + +30 LDAIM ARGERR ;"Bad arg to RDAR" +40 JMP ERROR ;Send error and exit + +;Y now contains the offset on NEWARG +;of the required 3 bytes. + +50 LDAIY NEWARG ;LS byte + STA MIDTX ;Put in TX buffer + INY + LDAIY NEWARG ;CS byte + STA MIDTX+1 + INY + LDAIY NEWARG ;MS byte + STA MIDTX+2 + LDAIM TXHDR+3 ;Mesage length + JSR REPLYC ;Send reply + +60 JMP COMRTS ;Exit + + + +;* CPSTAR * + +;Set sequential file pointer + +CPSTAR ROUT + JSR GETUSE ;USTPTR := ptr to user info + BNE #10 ;error + JSR SETUSR ;Copy user info to stack + LDX BPTR ;Offset of request buffer + LDAAX MIDRX ;Get handle + LDYIM ARGD + STAIY NEWARG ;Put handle on stack + +;Put arg saying what to set on stack + + LDAAX MIDRX+1 + INY + STAIY NEWARG + +;Put value to be set on stack + + LDAAX MIDRX+2 ;value (LS) + INY + STAIY NEWARG + LDAAX MIDRX+3 ;value (CS) + INY + STAIY NEWARG + LDAAX MIDRX+4 ;value (MS) + INY + STAIY NEWARG + LDAAX MIDRX+5 ;Some vals have 4 bytes + INY + STAIY NEWARG + + LDAIM &C ;RNDMAN.STAR + JSR SETRTN + JSR RNDMAN ;*** Call RNDMAN.STAR ** + JSR RCODE ;Transmit reply + +10 JMP COMRTS ;Exit + + + +;************ +;* PUTBYTES * +;************ + +;Write several bytes to specified file offset. + +;1) Set up pointer to user info +;2) (abolished) +;3) Send first reply, giving data port +;and max. blocksize. +;4) LOOP: receive block into big buffer +;5) LOOP: write to disc (RNDMAN.PUTBYTES) +;unless disc error flag set +;6) LOOP: If disc error, then set flag but +;continue to receive. +;7) LOOP: If more to receive, adjust OFFSET +;and loop to 4). +;8) Send final RC (disc error flag) + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +PBYTES ROUT + JSR GETUSE ;USTPTR := ptr to user info + BNE #10 ;not logged on ** 6/9/84 ** + + JSR RMSUBO ;Prepare for some PUTBYTES calls + BEQ #15 + +05 JSR EXTERR ;Not OK, send RC +10 JMP COMRTS ;Exit + +;Send first reply, giving data port and max blocksize + +15 LDAIM PSAVD ;Use same data port as SAVE + STA MIDTX + + LDAIM :LSB:BUFSZ ;Big buffer size (2 bytes) + STA MIDTX+1 + LDAIM :MSB:BUFSZ + STA MIDTX+2 + + [ $CMOS + STZ RTCODE ;RTCODE := CCODE := 0 + STZ CCODE + | + LDAIM 0 + STA RTCODE ;RTCODE := CCODE := 0 + STA CCODE + ] + + LDAIM TXHDR+3 ;Message length + + JSR REPLY ;Send message + BNE #10 ;Lost contact - abort + +;Ready to receive data, so set up for +;reception loop. + + [ $CMOS + STZ DATAIN ;DATAIN := 0 (3 bytes) + STZ DATAIN+1 + STZ DATAIN+2 + STZ DSCERR ;Clear disc err flag + STZ FINFLG ;Clear end-of-transfer flag + | + LDAIM 0 + STA DATAIN ;DATAIN := 0 (3 bytes) + STA DATAIN+1 + STA DATAIN+2 + STA DSCERR ;Clear disc err flag + STA FINFLG ;Clear end-of-transfer flag + ] + +;Test specially for transfer of zero bytes, +;to prevent 64K net control block being +;set up! Jump straight to final reply. + + LDX BPTR + LDAAX MIDRX+2 ;Ls byte of size + ORAAX MIDRX+3 ;CS + ORAAX MIDRX+4 ;MS + BNE #20 ;Not zero bytes + JMP #70 ;Jump straight to final reply + +;Loop which receives data and writes it to disc +;Set buffer pointers in RX control block + +20 LDY QPTR ;Buffer start = BBUF + LDA BBUF + STAAY CBBUF + LDA BBUF+1 + STAAY CBBUF+1 + + LDA BBEND ;Buffer end = BBEND + STAAY CBBUFE + LDA BBEND+1 + STAAY CBBUFE+1 + + LDAIM PSAVD ;Set data port + STAAY CBPORT + +;Station already set from first reception + + JSR WAIT ;Wait for reception + BNE #10 ;No contact => abort + +;Now subtract buffer limits to see how +;much data was received. + + LDY QPTR + SEC ;COWORK := CBBUFE-CBBUF + LDAAY CBBUFE + SBCAY CBBUF + STA COWORK ;LS byte + LDAAY CBBUFE+1 + SBCAY CBBUF+1 + STA COWORK+1 ;MS byte + +;Add amount received to total number of bytes +;received. + + CLC ;DATAIN +:= COWORK + LDA COWORK ;LS byte + ADC DATAIN + STA DATAIN + LDA COWORK+1 ;CS byte + ADC DATAIN+1 + STA DATAIN+1 + BCC #25 ;MS byte of received length always 0 + INC DATAIN+2 +25 + +;Compare total amount received (in DATAIN) +;with total number of bytes to be written. +;(in original message buffer). +;Set FINFLG if exactly the right amount +;has been received. +;If too much has been received, then send +;a return code. + + LDX BPTR + SEC + LDAAX MIDRX+2 ;LS byte of size + SBC DATAIN + STA BREGA ;Use BREGA as workspace + LDAAX MIDRX+3 ;CS byte of size + SBC DATAIN+1 + STA BREGA+1 + LDAAX MIDRX+4 ;MS byte + SBC DATAIN+2 + +;Carry set if received <= size + + ORA BREGA ;OR 3 bytes of result + ORA BREGA+1 ;for zero test + BEQ #30 ;Equal => last block + BCS #40 ;Recd < size => carry on + +;Client sent too much data. +;Send error code and stop. + + LDAIM PBERRA ;Error code + JMP #05 ;Send RC and exit + +30 LDAIM &FF ;Last block; set FINFLG + STA FINFLG + +;If disc error flag set, ignore received data, +;and jump round disc write. + +40 LDA DSCERR ;Disc error flag + BNE #50 ;Jump if error + +;Set up for call of RNDMAN + + + LDX BPTR + LDAAX MIDRX ;Get file handle + LDYIM ARGD + STAIY NEWARG ;Put on call stack + + LDA BBUF ;Buffer addr (Big Buffer) + INY + STAIY NEWARG + LDA BBUF+1 + INY + STAIY NEWARG + + LDA COWORK ;No. of bytes (calculated above) + INY + STAIY NEWARG ;LS byte + LDA COWORK+1 + INY + STAIY NEWARG ;MS byte + + LDAIM &A ;RNDMAN.PUTBYTES + JSR SETUSA ;Stack user info + + JSR RNDMAN ;*** RNDMAN.PUTBYTES ** + BEQ #50 ;OK, continue + STA DSCERR ;Store error code + +;If FINFLG is set, then we have just written +;the last block. +;Otherwise, adjust the file offset and carry on. + +50 LDA FINFLG ;Finished? + BNE #70 ;Exit from loop if yes + +;Send ack to client's ack port + + LDY BPTR + LDXAY CPUFD ;Ack port + LDAIM 1 ;Message length + JSR REPLYB ;Send byte (random contents) + BNE #80 ;Contact lost => abort + +60 JMP #20 ;Round loop again + +;Have received all the data. +;Final RC is in DSCERR. +;If RC is zero, send back amount xferred (always amount requested +;if no error). If non-zero, send error. + +70 LDA DSCERR + STA RTCODE + BNE #90 ;RC <> 0 => error + STA CCODE ;Set command code = 0 + STA MIDTX+4 ;send 32 bit number + LDX BPTR + LDAAX MIDRX+2 + STA MIDTX+1 + LDAAX MIDRX+3 + STA MIDTX+2 + LDAAX MIDRX+4 ;Move length of data to MIDTX + STA MIDTX+3 + LDAIM TXHDR+5 + JSR REPLYC ;Send reply (note MIDTX undefined) + +80 JMP COMRTS ;Exit from command + +90 JSR RCODE ;Send error reply + [ $CMOS + BRA #80 + | + JMP #80 + ] + + + +;************ +;* GETBYTES * +;************ + +;Read several bytes from specified file offset. + +;1) Set up pointer to user info +;2) Save size of transfer. +;SEND first RC to client +;3) LOOP: read chunk into big buffer (RNDMAN.GETBYTES) +;unless disc error flag set +;4) LOOP: If disc error, then set flag but +;continue to send data. +;5) LOOP: send to client +;6) LOOP: If more to send, adjust OFFSET +;and loop to 3). +;7) Send final RC (disc error flag) + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +GBYTES ROUT + [ $CMOS + STZ GBBXFD ;GBBXFD := 0 + STZ GBBXFD+1 + STZ GBBXFD+2 + STZ GBEFLG ;GBEFLG := 0 + | + LDAIM 0 + STA GBBXFD ;GBBXFD := 0 + STA GBBXFD+1 + STA GBBXFD+2 + STA GBEFLG ;GBEFLG := 0 + ] + + JSR GETUSE ;USTPTR := ptr to user info + BNE #10 ;OK, continue ** 6/9/84 ** + + JSR RMSUBO ;Set up RNDMAN for GETBYTES calls + BEQ #15 + +05 JSR EXTERR ;Not OK, send RC +10 JMP COMRTS ;Exit + +15 LDYIM ARGB ;**23/3/88** check mode of access for file + LDAIY NEWARG + ANDIM READAC + BNE #16 + LDAIM RDERRO + [ $CMOS + BRA #05 + | + BNE #05 + ] + +16 + [ 1=0 + LDX BPTR ;**23/3/88** check if GETBYTES or GETPUTBYTES + LDAAX RXBUF+1 + EORIM 35 + BNE #17 + JSR #99 ;**23/3/88** zero sequence number + LDAIM &E ;**23/3/88** GETPUTBYTES, prepare put also + JSR SETUSA + LDAAX MIDRX+1 + JSR RMSUBP + BNE #05 + JSR #99 ;**23/3/88** zero sequence number + BRA #20 + +17 + ] + LDAIM 0 + JSR RCODE ;Send "OK" rc + BNE #10 ;lost contect so ABORT + +;TOSEND := size of transfer + +20 LDX BPTR + LDAAX MIDRX+2 ;Size (LS) + STA TOSEND + LDAAX MIDRX+3 ;Size (CS) + STA TOSEND+1 + LDAAX MIDRX+4 ;Size (MS) + STA TOSEND+2 + +;Use the big buffer. +;Read from disc chunks of size BUFSZ, and transmit +;them to the client. +;Note that, in general, each chunk will be badly +;aligned with respect to disc blocks. RNDMAN tries +;to be efficient about this for each chunk. +;It may be worth adding extra optimization here if +;very large (> BUFSZ) transfers are common. + + [ $CMOS + STZ DSCERR ;No disc error yet + STZ FINFLG ;Not finished yet + | + LDAIM 0 + STA DSCERR ;No disc error yet + STA FINFLG ;Not finished yet + ] + +;Test specially for transfer of zero +;bytes to prevent 64K net control +;block being set up! + + LDA TOSEND ;Size (LS) + ORA TOSEND+1 ;CS + ORA TOSEND+2 ;MS + BNE #25 ;OK - not zero bytes + JMP #70 ;Jump straight to final reply + + +;Loop, sending data to client in blocks of +;size BUFSZ. TOSEND is the amount left to +;send, OFFSET the current file position. +;If an error occurs, the error code is put +;in DSCERR and the loop continues, padding +;out the transmission until the right +;amount of data has been sent. +;FINFLG gets set on the last time round +;the loop. + +25 SEC ;COWORK := TOSEND - BUFSZ + LDA TOSEND + SBCIM :LSB:BUFSZ + STA COWORK + LDA TOSEND+1 + SBCIM :MSB:BUFSZ + STA COWORK+1 + LDA TOSEND+2 + + SBCIM 0 + STA COWORK+2 + + ORA COWORK ;OR 3 bytes for zero test + ORA COWORK+1 + BEQ #30 ;TOSEND = BUFSZ + BCS #35 ;TOSEND < BUFSZ + +;BUFSZ >= TOSEND: send remaining data +;and set finish flag. + +30 LDA TOSEND ;OUTBSZ := TOSEND + STA OUTBSZ + LDA TOSEND+1 + STA OUTBSZ+1 + DEC FINFLG ;Set loop finish flag to $FF + [ $CMOS + BRA #40 + | + BNE #40 + ] + +35 LDAIM :LSB:BUFSZ ;OUTBSZ := BUFSZ + STA OUTBSZ + LDAIM :MSB:BUFSZ + STA OUTBSZ+1 + +;The size of the block to send is in OUTBSZ. +;Call RNDMAN.GETBYTES to get the data into +;the big buffer. + +40 LDX BPTR + LDAAX MIDRX ;Get file handle + LDXIM 9 ;**23/3/88** RNDMAN.GETBYTES + JSR RMSUBR + +;Add number of bytes actually read to +;GBBXFD, and OR end-of-file flag +;into GBEFLG. + + CLC + LDYIM ARGB + LDAIY NEWARG ;Bytes xferred (LS) + ADC GBBXFD + STA GBBXFD ;LS total + INY + LDAIY NEWARG + ADC GBBXFD+1 + STA GBBXFD+1 ;CS total + BCC #60 ;Only 2 bytes from RNDMAN + INC GBBXFD+2 ;MS total +60 INY + LDAIY NEWARG ;EOF flag + [ $CMOS + TSB GBEFLG ;OR with flag so far + | + ORA GBEFLG ;OR with flag so far + STA GBEFLG + ] + + LDY BPTR + [ 1=0 + LDAAY RXBUF+1 ;**23/3/88** GETBYTES or GETPUTBYTES + EORIM 35 + BNE #65 + LDA DSCERR ;**23/3/88** GETPUTBYTES + BNE #67 + LDAAY MIDRX+1 + LDXIM &A ;**23/3/88** RNDMAN.PUTBYTES + JSR RMSUBR + [ $CMOS + BRA #67 + | + JMP #67 + ] + +65 + ] + LDAAY CPUFD ;Get client's data port + JSR SENDBB ;Send big block (size in OUTBSZ) + BNE #90 ;Contact lost with client; give up + +;End of loop. Test finish flag, and set +;TOSEND from COWORK. + +67 BIT FINFLG ;Test finish flag + BMI #70 ;Exit from loop if finished + + LDA COWORK ;TOSEND := COWORK + STA TOSEND + LDA COWORK+1 + STA TOSEND+1 + LDA COWORK+2 + STA TOSEND+2 + + JMP #25 ;Loop return + +;Exit from GBLOOP: RC in DSCERR + +70 LDA DSCERR + BNE #80 ;Jump if error + +;Send back end-of-file flag and +;count of bytes actually read. + + LDA GBEFLG ;EOF flag + STA MIDTX ;Put in TX buffer + LDA GBBXFD ;Bytes xferred (LS) + STA MIDTX+1 + LDA GBBXFD+1 + STA MIDTX+2 ;CS + LDA GBBXFD+2 + STA MIDTX+3 ;MS + [ $CMOS + STZ MIDTX+4 ;send 32 bit number ** 26/2/85 ** + | + LDAIM 0 + STA MIDTX+4 ;send 32 bit number ** 26/2/85 ** + ] + LDAIM TXHDR+5 ;Message length + JMP Datout ;Send reply + +80 JSR RCODE ;Send return code + +90 JMP COMRTS ;Exit from command + + [ 1=0 +99 LDYIM RTINUS ;**23/3/88** fudge to keep sequence number + LDAIY RTEPTR ;**23/3/88** safely at zero as it cannot be + ANDIM &FE ;**23/3/88** used by GETPUTBYTES + STAIY RTEPTR + RTS + ] + +;*** Call RNDMAN to set up bytes operation + +RMSUBO ROUT + LDAIM &E ;**** RNDMAN.SUBO *** + JSR SETUSA + LDX BPTR + LDAAX MIDRX+0 ;Get file handle +RMSUBP INY + STAIY NEWARG + + LDX QPTR ;Get seq no from control block + LDAAX RXCBV + ANDIM 1 ;Get just seq bit + INY + STAIY NEWARG + +;The flag, no of bytes, and offset +;are in the correct order in rx block + + LDX BPTR +10 LDAAX MIDRX+1 + INY + STAIY NEWARG + INX + CPYIM ARGL + BNE #10 ;More to copy + + JMP RNDMAN ;**** Call RNDMAN.SUBO & return *** + +;Routine to call RNDMAN.GETBYTES or .PUTBYTES. +;Entry: A=Handle; X=RNDMAN code + +RMSUBR ROUT + LDYIM ARGD + STAIY NEWARG ;Put handle on stack + + LDA BBUF ;Put buffer address on stack + INY + STAIY NEWARG + LDA BBUF+1 + INY + STAIY NEWARG + + LDA OUTBSZ ;Put no. of bytes on stack + INY + STAIY NEWARG + LDA OUTBSZ+1 + INY + STAIY NEWARG + + TXA ;RNDMAN function code + JSR SETUSA + + JSR RNDMAN ;*** Call RNDMAN ** + BEQ #50 ;OK, continue + STA DSCERR ;Otherwise set error code +50 RTS + + +;Yet another interface - this one allows an application +;to determine the userid under which it is logged-on + +;This is probably most useful for MAILing type progs + +CPWHO ROUT ;** 19/3/85 ** + JSR GETUSE + BNE #20 ;nb this will deal with the error + + LDXIM 0 + LDYIM UTUSID +10 LDAIY USTPTR ;copy the user name + STAAX MIDTX + INY + INX + CMPIM CR ;copy only upto CR (pw follows - dont want that) + BNE #10 + + TXA + JMP Datous ;return the answer with zero RC + +20 JMP COMRTS + + LNK UADE20 diff --git a/FileServer/SRC/FileServer/Uade20 b/FileServer/SRC/FileServer/Uade20 new file mode 100644 index 0000000..a982e1a --- /dev/null +++ b/FileServer/SRC/FileServer/Uade20 @@ -0,0 +1,446 @@ + OPT UADE20 ;FILE > Uade20 + TTL File server file UADE20 + + +;C O M M A N D P R O C E S S O R + +;U T I L I T I E S + + +RCODE ROUT + +;Check return code in A. If 0, send +;3 byte message. If not, go to error +;routine +;Command code always set 0. + + [ $CMOS + STZ CCODE + | + LDXIM 0 + STX CCODE + ] + TAY + BEQ REPLYA + JMP EXTERR + + +;Sends a zero return code to client. +;Sets RC into TXBUF and drops through into +;REPLY, passing a the header length as message length + +REPLYA LDAIM TXHDR + [ $CMOS +REPLYC STZ RTCODE ;Set R.code + | +REPLYC LDXIM 0 + STX RTCODE ;Set R.code + ] + +;Sends a message of length A to client +;on the reply port (in var RPLYPT). + +REPLY LDX RPLYPT + +;Sends a message of length A on port X +;to client. + +REPLYB LDY QPTR ;Get CB pointer + CLC + ADCIM :LSB:TXBUF + STAAY CBBUFE ;Buffer end ptr. (lo) + LDAIM 0 ;Assumed msg. length < 255 + + STAAY CBBUF+2 + STAAY CBBUF+3 ;hi order addresses + STAAY CBBUFE+2 + STAAY CBBUFE+3 ;from 2nd processor + + ADCIM :MSB:TXBUF + STAAY CBBUFE+1 ;Buffer end ptr (hi) + + LDAIM :LSB:TXBUF + STAAY CBBUF ;Buffer ptr lo + LDAIM :MSB:TXBUF + STAAY CBBUF+1 ;Buffer ptr hi + TXA ;Set port + STAAY CBPORT + + +;Entry point used when CB set up elsewhere +;(e.g. LOAD/EXAMINE). Assumed all is +;set but TX flag. + +SEND ROUT + LDAIM TXFLAG + ORAAY CBFLG + STAAY CBFLG +SENDX + LDAIM TXRPT + LDYIM TXDLY ;Delay between tries + +;A = no. of times to try transmit +;Y = delay between tries +;NETCB = page zero pointer to control block + + STA TXJ + STY TXD + [ $CMOS + LDAI NETCB + | + LDYIM 0 + LDAIY NETCB + ] + STA TXF ;flag byte +10 LDX NETCB ;Pointers to CBlock + LDY NETCB+1 + LDAIM &10 + JSR OSWORD ;call Tx + + [ $CMOS + LDAI NETCB ;check for Tx on Tx + | + LDYIM 0 + LDAIY NETCB ;check for Tx on Tx + ] + BNE #20 + LDA TXF + [ $CMOS + STAI NETCB + BRA #10 ;restore flag byte and try again + | + STAIY NETCB + BNE #10 ;restore flag byte and try again + ] + +20 LDAIM 50 + JSR OSBYTE + TXA + BMI #20 ;poll 'til done + BEQ #40 ;Yes => success => exit + DEC TXJ ;No. of times decrement + BEQ #30 ;All done => failure + LDY TXD ;Delay time + JSR MSDELY ;Do delay + [ $CMOS + BRA #10 ;Do again + | + JMP #10 ;Do again + ] + +30 TXA ;Return flag in A +40 RTS + + +;Wait to receive from client. +;Control block pointed by QPTR, wait +;is a constant (WAITCL) no. of msecs. + +WAIT ROUT + LDAIM RXFLAG + STA CBFLG ;CB is ammended for Rx, so open it + + [ $CMOS + STZ RXCBN + | + LDXIM 0 + STX RXCBN + ] + LDAIM &11 + LDXIM :LSB:RXCBN + LDYIM :MSB:RXCBN + JSR OSWORD + + LDXIM 50 +WaitX + STX TIMER2 + LDXIM WAITCL + STX TIMER1 +10 LDAIM ONEMS ;One msec loop + STA TIMER ;(2cycles) +20 LDX RXCBN ;(4usecs) + LDAIM 51 + JSR OSBYTE ;poll Rx + TXA + BMI #30 ;(2) + DEC TIMER ;(5) timer not p.0 + BNE #20 ;(3) + DEC TIMER1 ;(2) + BNE #10 ;(3) + DEC TIMER2 + BNE #10 + +;Total inner loop time = 14 cycles +;So ONEMS = 71 (decimal) + +30 LDXIM :LSB:RXCBN + LDYIM :MSB:RXCBN + LDAIM &11 + JSR OSWORD ;read the control block + + LDAIM 0 + BIT RXCBN+1 ;read flag byte + BMI #40 + LDAIM WAITER ;timeout + +40 RTS + + +ERROR ROUT + JSR EXTERR + JMP COMRTS + + +;Puts error code in A into TXBUF +02. +;Looks A up in ERRTAB and if found, puts text into +;message. +;If not found, uses text F.S. ERROR xx (xx is A +;in hex). +;Message then send to client using REPLY. +;CCODE always set to zero in LOOKER + +EXTERR ROUT + PHA + JSR LOOKER ;Find error in table etc. + PLA ;** 17/9/84 ** + CMPIM RDERRH + BNE #30 + LDA MCopat+1 ;Details of where object open + BEQ #10 ;net number + + JSR #40 ;write into the buffer + LDAIM "." + STAAX MIDTX ;add separator + INX + +10 LDA MCopat ;station number + JSR #40 ;append to end of message + LDAIM "(" + STAAX MIDTX ;lest job (task) number present + LDA MCopat+2 + BEQ #20 + INX + JSR #40 ;write into the buffer + LDAIM ")" + STAAX MIDTX + INX + +20 LDAIM CR + STAAX MIDTX + +30 TXA ;Message length for REPLY + SEC ;Set carry to add 1 for CR + ADCIM TXHDR ;Add header length to message length + JMP REPLY ;Send and return + +40 STX COTEMP + JSR MKDEC ;convert to decimal + LDYIM :LSB:-3 + LDX COTEMP ;restore X value +50 LDAAY COWORK-:LSB:-3 ;get results from MKDEC + CMPIM SPACE + BEQ #60 + STAAX MIDTX ;put text in buffer + INX +60 INY + BNE #50 + RTS + + +;Look error in A up and put relevant message +;at MIDTX. + +LOOKER ROUT + STA RTCODE + PHA + + LDAIM :LSB:ERRTAB + STA GENPTR + LDAIM :MSB:ERRTAB + STA GENPTR+1 + LDYIM 0 + STY CCODE ;Set command code to zero +10 PLA + CMPIY GENPTR ;Check error number + BEQ #60 ;Found + + PHA + LDAIM CR +20 INY + BNE #30 + INC GENPTR+1 +30 CMPIY GENPTR ;Move to end of this text + BNE #20 + INY + BNE #40 + INC GENPTR+1 +40 LDAIY GENPTR + BNE #10 ;Non-zero => not end of table + +;If here, number not found, so construct +;default error message. + + LDXIM 0 +45 LDAAX ERRMSG ;Load error text + BMI #50 ;Terminated by NOP + STAAX MIDTX ;Store in transmit buffer + INX + BNE #45 + +50 PLA ;Get error number back + JSR WRTERR ;Put A in hex in message at X + LDAIM CR + STAAX MIDTX ;Terminate message + RTS + +60 LDXIM &FF ;Error found, move text to message +65 INX + INY + BNE #70 + INC GENPTR+1 +70 LDAIY GENPTR + STAAX MIDTX + CMPIM CR + BNE #65 + RTS ;Complete, exit X - length-1 + + +WRTERR ROUT + PHA + LSRA + LSRA + LSRA + LSRA + JSR #10 ;TOP NIBBLE + PLA +10 ANDIM &F + CMPIM &A + BCC #20 + ADCIM 6 +20 ADCIM &30 + STAAX MIDTX + INX + RTS + + + [ Lang = English +ERRMSG = "F.S. Error " + ] + [ Lang = Italian +ERRMSG = "Errore mefile " + ] + NOP + + +;Send big block on port in A. +;Size of message is in OUTBSZ, +;assumes station already set. + +SENDBB ROUT +SENDBC LDY QPTR + STAAY CBPORT + CLC + LDA BBUF ;Buffer address + STAAY CBBUF + ADC OUTBSZ + STAAY CBBUFE + LDA BBUF+1 + STAAY CBBUF+1 + ADC OUTBSZ+1 + STAAY CBBUFE+1 + JMP SEND ;Send message ... + + [ $Level3 + +SENDIO ROUT + LDY QPTR ;routine to send the IO side buffer + STAAY CBPORT ;in byte-size chunks ** 19/1/84 ** + + CLC + LDA IOBUF + STA COTEMP + ADC OUTBSZ + STA OUTBSZ + LDA IOBUF+1 + STA COTEMP+1 + ADC OUTBSZ+1 + STA OUTBSZ+1 ;COTEMP is low end of buffer + + LDAIM &FF + STAAY CBBUF+2 + STAAY CBBUF+3 + STAAY CBBUFE+2 + STAAY CBBUFE+3 ;initialise top bytes + +10 LDY QPTR + CLC + + LDA COTEMP + STAAY CBBUF + ADCIM BUFSZ + STAAY CBBUFE + STA COTEMP + + LDA COTEMP+1 + STAAY CBBUF+1 + ADCIM :MSB:BUFSZ + STAAY CBBUFE+1 + STA COTEMP+1 ;buffer pointers set, new COTEMP set + + LDAAY CBBUFE + CMP OUTBSZ + LDAAY CBBUFE+1 + SBC OUTBSZ+1 + BCC #20 ;C=1 if cbbufe>= outbsz + + LDA OUTBSZ + STAAY CBBUFE + LDA OUTBSZ+1 + STAAY CBBUFE+1 ;setup last transmission + +20 PHP + JSR SEND ;do transmit + PLP ;restore carry + TAX + BNE #30 ;bad transmit + BCC #10 +30 RTS + ] + +MSDELY ROUT + CPYIM 0 + BEQ #30 ;If no delay, Exit + PHA ;Keep Acc. + [ $CMOS + PHX ;Keep X + PHY + | + TXA + PHA ;Keep X + TYA + PHA + ] + LDXIM 0 +; TYA ;Keep delay time (in msecs) +; SEC +; SBCIM 30 ;subtract 30 ys for polling loop +; CMPIM &E3 +; BCS #20 ;skip , ok +; TAY +10 DEX + BNE #10 ;1msec loop + DEY + BNE #10 ;Outer loop + [ $CMOS +20 PLY ;Reset delay time + PLX ;Reset X + | + PLA + TAY ;Reset delay time + PLA + TAX ;Reset X + ] + PLA ;Reset A +30 RTS + + LNK UADE20A diff --git a/FileServer/SRC/FileServer/Uade20A b/FileServer/SRC/FileServer/Uade20A new file mode 100644 index 0000000..4e22551 --- /dev/null +++ b/FileServer/SRC/FileServer/Uade20A @@ -0,0 +1,765 @@ + OPT UADE20 ;FILE > Uade20A + TTL File server file UADE20A + +;*** NON - NET UTILITIES *** + + +CPDNAM ROUT + +;Read disc name of disc number at ARGF on stack +;into MIDTX offset by A. + + PHA ;Push MIDTX offset + + LDYIM ARGF + LDAIY NEWARG ;GET DISC NO. + PHA + INY + LDAIY NEWARG ;SET ON STACK AT ARGB + LDYIM ARGC + STAIY NEWARG + DEY + PLA + STAIY NEWARG + LDAIM &B ;MAPMAN ENTRY PT. + JSR SETRTN + JSR MAPMAN + BNE #20 + + LDYIM ARGB + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 ;SET PTR. TO DISC NAME + + [ $CMOS + PLX ; Offset from MIDTX + | + PLA + TAX ; Offset from MIDTX + ] + LDYIM 0 +10 LDAIY GENPTR + STAAX MIDTX + INX + INY + CPYIM DNAMLN + BNE #10 +20 RTS + + +DIRIND ROUT + STA COZERO + JSR STKUSA ;Stack user info at ARGA + LDXIM &C1 + [ $CMOS + BRA #10 + | + BNE #10 + ] + +;Call DIRMAN.EXAMINE to get last component of +;file title (may be CR) and disc number and cycle +;number of directory. +;On entry, A is offset from MIDTX to put dir. name +;Dir. name arg. is assumed at MIDRX + +DIRINF STA COZERO + JSR STKUSA ;Stack user info at ARGA + LDXIM &C0 +10 LDAIM HDRLEN +DIRIN2 ;Entry point from CPINFO + STX COZERO+1 ;save parameter for DIRMAN + JSR SETFTP ;MOVE FILE TITLE PTR. TO STACK + INY + LDA COZERO ;Load offset + CLC + ADCIM :LSB:MIDTX + STAIY NEWARG ;SET RESULT AREA FOR EXAMINE + LDAIM :MSB:MIDTX + ADCIM 0 + INY + STAIY NEWARG + INY + LDAIM 4 + STAIY NEWARG ;ARG. FOR EXAMINE => GET TITLE + LDAIM 7 + JSR SETRTN + + LDYIM ARGK + LDA COZERO+1 ;passed parameter + STAIY NEWARG ;wild card flag + + JMP DIRMAN ;GET INFO. and return + + +;Copy SIN/Disc no. from DANDS to +;stack. Y already set as stack ptr. + +SINDSC ROUT + LDXIM 0 +10 LDAAX DANDS + STAIY NEWARG + INY + INX + CPXIM 5 + BNE #10 + RTS + + +;Copy disc block information to stack, starting +;at Y. + +;Info is: +;1) Current disc block start (CURBLK) +;2) No. of blocks to read/write (DIVPAR) +;3) Address to read/write to/from (BBUF) + +IBLOCK ROUT + LDA CURBLK + STAIY NEWARG + INY + LDA CURBLK+1 + STAIY NEWARG + + INY + LDA DIVPAR + STAIY NEWARG + INY + LDA DIVPAR+1 + STAIY NEWARG + + INY + [ $Level3 + LDA IOBUF + | + LDA BBUF + ] + STAIY NEWARG + INY + [ $Level3 + LDA IOBUF + 1 + | + LDA BBUF+1 + ] + STAIY NEWARG + + RTS + + + +;Set pointer on stack pointing to +;text buffer. +;Also set 0 in byte after receive buffer +;Offset in A on entry to SETTXP + +SBUFPT ROUT + LDAIM 0 + +SETTXP INY + CLC + ADCIM :LSB:TXTBUF + STAIY NEWARG + LDAIM :MSB:TXTBUF +10 INY + ADCIM 0 + STAIY NEWARG + [ $CMOS + PHX + | + TXA + PHA + ] + LDX BPTR + [ $CMOS + STZAX RXBUF+RXBUFL ;**22/3/88** + PLX + | + LDAIM 0 + STAAX RXBUF+RXBUFL ;**22/3/88** + PLA + TAX + ] + RTS + +;Sets file title pointer to stack +;at Y. +;On entry, A is offset of file title +;in RX buffer. + +;This routine also puts 0 in the byte +;after the receive buffer so that +;analysis of the file title doesn't +;get carried away. + +SETFTP INY + CLC + ADC BPTR ;Add file title offset to buffer offset + ADCIM :LSB:RXBUF + STAIY NEWARG + LDAIM :MSB:RXBUF + [ $CMOS + BRA #10 + | + BNE #10 + ] + +;Returns the last component of the pathname handed to save +;in MIDTX [3:13] + +SAVNAM ROUT + LDX BPTR +10 INX + LDAAX MIDRX+11 + CMPIM CR + BNE #10 ;look for CR +20 DEX + LDAAX MIDRX+11 + CMPIM "." + BEQ #30 + CPX BPTR ;maybe just one component here + BNE #20 + DEX +30 INX + LDYIM 0 +40 LDAAX MIDRX+11 + CMPIM CR + BEQ #50 + STAAY MIDTX+3 + INX + INY + BNE #40 +50 LDAIM &20 +60 CPYIM 12 + BCS #70 + STAAY MIDTX+3 + INY + [ $CMOS + BRA #60 + | + BNE #60 + ] + +70 LDAIM &80 + STAAY MIDTX+3 + RTS ;terminate with CR + + +;Call FINDMC using machine number +;in net control block. + +;Then set CSD handle from RX block into +;user table. + +GETUSE ROUT ;Entry generating EXTERR if error + JSR GETUSR + BEQ #10 + JSR EXTERR + LDAIM &FF ;Indicate unsuccessful exit + RTS + +GETUSR LDY QPTR ;Entry not generating error + LDAAY CBSTID + STA MCNUMB + LDAAY CBSTID+1 + STA MCNUMB+1 + LDAAY CBflg ;**25/12/86** + ANDIM MCtask + STA MCnumb+2 + + JSR FINDMC + BNE #10 + + LDX BPTR + LDAAX CPCSD ;GET CSD SENT FROM CLIENT + LDYIM UTHSLD + STAIY USTPTR ;SET CSD + LDAIM 0 ;Indicate successful exit +10 RTS + + + +;Move user info. pointer in USTPTR +;to stack. +SETUSE ROUT + INY + LDA USTPTR + STAIY NEWARG + LDA USTPTR+1 + INY + STAIY NEWARG + RTS + + +;GET USER INFO AND PUT ON STACK AT ARGB + +STKUSE ROUT + JSR GETUSE + BNE #10 +STKUSA LDYIM ARGA + JSR SETUSE ;NOTE SETUSE DOES INY FIRST, SO ARGA CORRECT + LDAIM 0 +10 RTS + +;PUT THREE HANDLES FROM RX BUFFER +;ON STACK AT Y. + +STKHND ROUT + LDX BPTR + LDAAX CPUFD + STAIY NEWARG + INY + LDAAX CPCSD + STAIY NEWARG + INY + LDAAX CPLIB + STAIY NEWARG + RTS + +SETRTN ROUT + LDYIM ARGA + STAIY NEWARG + RTS + + +;Set pointer to COWORK on stack + +SCOWPT ROUT + INY + LDAIM :LSB:COWORK + STAIY NEWARG + INY + LDAIM :MSB:COWORK + STAIY NEWARG + RTS + + + +;SIN/disc no. of object are on +;stack (usually just after a call +;of PRESERVE). + +;assumes that GETUSE result is valid ** 3/10/84 ** + +;If SIN <> 0 ... + +;1) Clear object from store. +;2) Delete object from map +;3) Ensure map. + +OBJCLR ROUT + JSR SINZED ;Check SIN is zero (also used in RENAME) + BEQ #30 ;If zero, exit + + LDAIM 5 ;STRALL function + JSR SETRTN + JSR STRMAN ;Flush from store + BNE SETRTN ;put it on the stack if error + + LDYIM ARGF + JSR SETUSE ;pass pointer to user info ** 3/10/84 ** + + LDAIM MAPFS ;Map free store + JSR SETRTN + JSR MAPMAN ;Delete from map + BNE #20 ;No good => abort + + LDAIM MAPENS ;Map ensure fn. + JSR SETRTN + JSR MAPMAN ;Ensure map + BEQ #30 ;OK => exit + +20 JSR INTERR ;Not ok => stop + +30 RTS + + +SINZED LDYIM ARGD + LDAIY NEWARG + INY + ORAIY NEWARG + INY + ORAIY NEWARG + RTS + + +;Gets entry point, no. of entries and a pointer +;to BIGBFR +1 onto stack. Used by DISCS and USERS + +STKLST ROUT + TYA + TAX ;pointer into MIDRX + LDYIM ARGB + LDAAX MIDRX + STAIY NEWARG ;Start point in list + INY + LDAAX MIDRX+1 + STAIY NEWARG ;Number of entries + INY + LDA BBUF + CLC + ADCIM TXHDR+1 ;Result area + STAIY NEWARG + INY + LDA BBUF+1 + ADCIM 0 + STAIY NEWARG + RTS + + + +;Given no. of entries found and ptr. to +;end of result area on stack, sends off the +;result of DISC/USERS in big buffer. +;On entry A = continue code. + +LSTRPY ROUT + STA TEMPA + LDYIM ARGB + LDAIY NEWARG + PHA ;Number of entries found + LDA BBUF + STA GENPTR + LDA BBUF+1 + STA GENPTR+1 + LDYIM 0 + LDA TEMPA ;Continue code + STAIY GENPTR + TYA ;Return code (0) + INY + STAIY GENPTR + PLA + INY + STAIY GENPTR ;Number of entries found + +;Set control block for reply + + LDA RPLYPT + LDX QPTR + STAAX CBPORT + LDA BBUF + STAAX CBBUF ;Ptr. to message + LDA BBUF+1 + STAAX CBBUF+1 + LDYIM ARGC + LDAIY NEWARG ;End of result buffer + STAAX CBBUFE + INY + LDAIY NEWARG + STAAX CBBUFE+1 + LDY QPTR ;Arg to SEND + JMP SEND ;Send reply and exit + + + +;Set stack and call DIRMAN retrieve +;to put details into COWORK buffer. +;On entry A = offset in RXCB of file name + +LDRETR ROUT + LDAIM LODFTO + +CPRETR PHA + LDAIM DRRTR ;Dirman retreive + JSR SETUSA ;PLACE ADDR OF USERINFO ONTO NEWARG STACK + PLA ;Pull f.t. offset + JSR SETFTP ;Set file title pointer + JSR SCOWPT + LDAIM &C0 ;allow wild cards in LOAD + LDYIM ARGH + STAIY NEWARG ;wild card flag + + JMP DIRMAN ;Get info. to COWORK and return + + + + [ 1=0 +RNAMDQ ROUT + TAY + LDAIM &C0 ;wild card flag + PHA + TYA + BNE #10 + +RNAMDM + +;Call DIRMAN with function code in A, file title offset +;from TXTBUF in X. Used from RENAME. + + TAY + LDAIM 0 + PHA + TYA +10 JSR SETUSA + TXA ;Get offset of file name in TXTBUF + JSR SETTXP + PLA + JMP CPRET1 ;Set pointer to COWORK, and call DIRMAN + + + +;Check access/type byte for RENAME +;Must be an unlocked file with OWNER access + +CHEKTB = DRERRG ;Is locked + = LODERA ;Is a directory + = DRERRE ;Insufficient access + +CHEKRN ROUT + LDXIM 3 + LDYIM ARGB + LDAIY NEWARG + EORIM OWNER ;Flip the OWNER bit + ASLA +10 ASLA + BCS #20 + DEX + BNE #10 + + TXA ;Zero RC + RTS + +20 LDAAX CHEKTB-1 + RTS + + ] + + +;COMMAND LINE UTILS + + +;Get string (possibly quoted) from +;CLI string (at MIDRX) and transfer +;to TXTBUF offset by X (normally zero) +;NOTE - ACKS and NACKS ignored here !! + +BUFTXT ROUT + LDXIM 0 + [ $CMOS +BTXTA STZ QUOTED ;Quoted flag + | +BTXTA LDAIM 0 + STA QUOTED ;Quoted flag + ] + + JSR SPACES + CMPIM """" + BNE #30 + DEC QUOTED ;Quoted flag on + DEX + +20 INX +25 INY +30 LDAAY MIDRX +35 STAAX TXTBUF + + CMPIM ACK + BEQ #25 ;Inc. string ptr., but not buffer + CMPIM NACK + BEQ #25 + + CMPIM CR + BEQ #60 + CMPIM SPACE + BNE #50 + BIT QUOTED + BMI #20 ;Spaces OK in quoted string + +40 LDAIM CR ;Finish with CR as terminator in destn. + [ $CMOS + BRA #35 + | + BNE #35 + ] + +50 CMPIM """" + BNE #20 + INY ;Step C.line ptr. past final delimiter + INC QUOTED ;Switch off quoted flag + [ $CMOS + BRA #40 ;Exit, with CR terminator + | + BEQ #40 ;Exit, with CR terminator + ] + +60 LDA QUOTED ;Error in quoted string + BEQ #70 ;Otherwise exit, Z set + +BUFERR LDAIM NAMERR + PHP + JSR EXTERR ;Send error message + PLP +70 RTS ;Give Z unset exit + + [ 1=0 +;Read hex number (up to 4 bytes) +;into 4-byte p.0 area at X. NOTE +;uses 1 extra byte at X. + +RDNUM ROUT + STZAX 0 + STZAX 1 + STZAX 2 + STZAX 3 + STZAX 4 + JSR SPACES +10 LDAAY MIDRX + CMPIM "0" + BCC #40 + CMPIM &3A + BCC #20 + SBCIM 7 + BCC #40 + CMPIM &40 + BCS #40 + +20 ASLA + ASLA + ASLA + ASLA + STYZX 4 + LDYIM 4 +30 ASLA + ROLZX 0 + ROLZX 1 + ROLZX 2 + ROLZX 3 + DEY + BNE #30 + LDYZX 4 + INY + BNE #10 + +40 LDAZX 4 + RTS + ] + +SPACER DEY +50 INY +SPACES LDAAY MIDRX + CMPIM SPACE + BEQ #50 + RTS + + +;Move file title into TXTBUF and +;check to end of line for syntax. + +RDTITL ROUT + JSR BUFTXT + BNE #10 ;**20/5/87** fall into COMEND + +COMEND JSR SPACES + CMPIM CR + BEQ #10 + LDAIM SYNERR + JSR EXTERR + LDAIM SYNERR ;Give non-zero exit +10 RTS + +;** E R R O R T A B L E ** + +ERRTAB + + [ Lang = English + = URERRA,"Who are you?",CR + = WOTERR,"Bad Command",CR + = SYNERR,"Syntax",CR + = NAMERR,"Bad string",CR + = NUMERR,"Bad number",CR + = DRERRA,"Bad file name",CR + = DRERRB,"Broken dir",CR + = DRERRC,"Not found",CR + = DRERRD,"Not a directory",CR + = DRERRE,"Insufficient access",CR + = DRERRG,"Entry locked",CR + = ATERRB,"User not known",CR + = ATERRC,"Wrong password",CR + = ATERRE,"Bad password",CR + = MPERRB,"Disc full",CR + = MPERRA,"Disc changed",CR + = SAERRA,"Bad attribute",CR + = ATERRA,"PW file not found",CR + [ $Level3 + = &54,"Insert a Fileserver disc",CR + ] + = RDERRB,"Channel",CR + = RDERRJ,"EOF",CR + = RDERRL,"Outside file",CR + = RDERRH,"Already open at station ",CR + = RDERRN,"File read only",CR + = DCERRE,"Disc read only",CR + = DCERRF,"Disc fault",CR + = MPERRL,"Map fault",CR + = RDERRC,"Too many open files",CR + = URERRB,"Too many users",CR + = LODERA,"Is a directory",CR + = &BA,"Insufficient privilege",CR ;** 13/4/83 ** + = DRERRJ,"Dir. not empty",CR + = DRERRM,"Dir. full",CR + = ATERRF,"Already a user",CR + = RNAMQQ,"Bad Rename",CR + = DRERRK,"Types don't match",CR + = URERRE,"Not logged on",CR + = ATERRG,"Bad user name",CR + = RDERRO,"Write only",CR ;** 16/11/84 + = MPERRN,"Insufficient space",CR + = SPERRA,"Bad privilege letter",CR ;** 6/11/86 ** + [ $CMOS + = DOORER,"Drive door open",CR + ] + = 0 ;Table terminator + ] + + [ Lang = Italian + = URERRA,"Chi sei?",CR + = WOTERR,"Comando Errato",CR + = SYNERR,"Syntax",CR ; ************************************ + = NAMERR,"Sequenza errata",CR + = NUMERR,"Numero errata",CR ; ************************************ + = DRERRA,"Nome file errato",CR + = DRERRB,"Dir rotto",CR + = DRERRC,"Non trovato",CR + = DRERRD,"Non e' un directory",CR + = DRERRE,"Accesso insufficiente",CR + = DRERRG,"Entrata bloccata",CR + = ATERRB,"Utente Sconosciuto",CR + = ATERRC,"P.o. Errata",CR + = ATERRE,"P.o. incorretta",CR + = MPERRB,"Disco pieno",CR + = MPERRA,"Disco changed",CR ; ********************************** + = SAERRA,"Attributo Errato",CR + = ATERRA,"P.o. file non trovato",CR + [ $Level3 + = &54,"Inserire un disco Fileserver",CR + ] + = RDERRB,"Canale",CR + = RDERRJ,"FDF",CR + = RDERRL,"Fuori file",CR + = RDERRH,"Gia' aperto alla stazione ",CR + = RDERRN,"File solo lettura",CR + = DCERRE,"Disco solo lettura",CR + = DCERRF,"Disco difettoso",CR + = MPERRL,"Mappa difettoso",CR + = RDERRC,"Troppi file aperti",CR + = URERRB,"Troppi utenti",CR + = LODERA,"E' gia' un directory",CR + = &BA,"Privilegio insufficiente",CR ;** 13/4/83 ** + = DRERRJ,"Dir non vuoto",CR + = DRERRM,"Dir pieno",CR + = ATERRF,"Gia' in uso",CR + = RNAMQQ,"Rinome errata",CR + = DRERRK,"Tipi non coincidono",CR + = URERRE,"Non acceso",CR + = ATERRG,"Nome utente errato",CR + = RDERRO,"Solo scrittura",CR ;** 16/11/84 + = MPERRN,"Spazio insufficiente",CR + = SPERRA,"Privilegio lettera errato",CR ;** 6/11/86 ** + [ $CMOS + = DOORER,"Drive aperto",CR + ] + = 0 ;Table terminator + ] + + LNK PRINT0 diff --git a/FileServer/SRC/GO b/FileServer/SRC/GO new file mode 100644 index 0000000..2382959 --- /dev/null +++ b/FileServer/SRC/GO @@ -0,0 +1,7 @@ +*ADFS +*LIB ADFS::0.$.LIBRARY +*65ARTHURT +*DIR ADFS::0.$ +*CB +CH."START" + diff --git a/FileServer/SRC/GO.INF b/FileServer/SRC/GO.INF new file mode 100644 index 0000000..16108ad --- /dev/null +++ b/FileServer/SRC/GO.INF @@ -0,0 +1 @@ +GO FFFFD652 6E0D379E 0000004D 19 diff --git a/FileServer/SRC/L3ASM b/FileServer/SRC/L3ASM new file mode 100644 index 0000000..9387cc6 --- /dev/null +++ b/FileServer/SRC/L3ASM @@ -0,0 +1 @@ +*|Assembly sequence for Wini FS > L3Asm *|By Jes 3/9/84, Updated by Glenn 8/5/85 *|Updated by Mark Usher 7/4/21 *DIR $.FileServer *LIB $.LIBRARY *TurMasm *OPT 1 1 STOP ON ASM Level3 *CB CH."$.LOADER" \ No newline at end of file diff --git a/FileServer/SRC/L3ASM.inf b/FileServer/SRC/L3ASM.inf new file mode 100644 index 0000000..9701bbf --- /dev/null +++ b/FileServer/SRC/L3ASM.inf @@ -0,0 +1 @@ +$.L3ASM 00000000 00000000 000000CA 19 A548 1E380A A24D 331315 diff --git a/FileStore/SRC/LIBRARY/65ARTHURT b/FileServer/SRC/LIBRARY/65ARTHURT similarity index 100% rename from FileStore/SRC/LIBRARY/65ARTHURT rename to FileServer/SRC/LIBRARY/65ARTHURT diff --git a/FileServer/SRC/LIBRARY/65ARTHURT.INF b/FileServer/SRC/LIBRARY/65ARTHURT.INF new file mode 100644 index 0000000..5d95e8d --- /dev/null +++ b/FileServer/SRC/LIBRARY/65ARTHURT.INF @@ -0,0 +1 @@ +65ARTHURT FFFFFA40 9444A542 0000A0C4 19 diff --git a/FileStore/SRC/LIBRARY/CB b/FileServer/SRC/LIBRARY/CB similarity index 100% rename from FileStore/SRC/LIBRARY/CB rename to FileServer/SRC/LIBRARY/CB diff --git a/FileServer/SRC/LIBRARY/CB.INF b/FileServer/SRC/LIBRARY/CB.INF new file mode 100644 index 0000000..adb1b5e --- /dev/null +++ b/FileServer/SRC/LIBRARY/CB.INF @@ -0,0 +1 @@ +CB 0000B800 0000B800 00004000 19 diff --git a/FileStore/SRC/LIBRARY/TURMASM b/FileServer/SRC/LIBRARY/TurMasm similarity index 100% rename from FileStore/SRC/LIBRARY/TURMASM rename to FileServer/SRC/LIBRARY/TurMasm diff --git a/FileServer/SRC/LIBRARY/TurMasm.INF b/FileServer/SRC/LIBRARY/TurMasm.INF new file mode 100644 index 0000000..eed193e --- /dev/null +++ b/FileServer/SRC/LIBRARY/TurMasm.INF @@ -0,0 +1 @@ +TurMasm 0000B000 0000B000 00004800 19 diff --git a/FileServer/SRC/LOADER b/FileServer/SRC/LOADER new file mode 100644 index 0000000..ff64e20 Binary files /dev/null and b/FileServer/SRC/LOADER differ diff --git a/FileServer/SRC/LOADER.INF b/FileServer/SRC/LOADER.INF new file mode 100644 index 0000000..a6b2c61 --- /dev/null +++ b/FileServer/SRC/LOADER.INF @@ -0,0 +1 @@ +LOADER 00000800 00008023 0000031C 19 CRC32=EDEE2AAA \ No newline at end of file diff --git a/FileServer/SRC/README b/FileServer/SRC/README new file mode 100644 index 0000000..5206f61 --- /dev/null +++ b/FileServer/SRC/README @@ -0,0 +1,604 @@ +Level 3 / Filestore File Server v1.31 +===================================== + +This disc contains the completed shared source code for the Acorn Level 3 +file server and the Filestore FS ROM. + + +Assembling the File Server Source Code +====================================== + +The source code will assemble on either a BBC with an Acorn Turbo (256K) +6502 Co-Processor and ADFS or on Arthur/RISC OS using the 6502 Turbo +Co-Processor emulator which is included here. +To assemble on a BBC, use SHIFT-BREAK or *EXEC !BOOT. On RISC OS, double +clicking the file GO will start the process. The assembled file "FS" will be +placed in the root directory. The assembly process is significantly faster +when a hard drive is used instead of a floppy. + +Files +===== + +\ $ + !BOOT - BBC Routine to set library and call L3ASM +* GO - RISC OS Routine to set library, load emulator and call L3ASM + README - This file + L3ASM - Loads TurboMasm and starts the assembly process + LOADER - BASIC program to put together the assembled parts and create the + Level3 binary "FS" + +\ LIBRARY +* 65ARTHURT - The Turbo Co-processor emulator for RISC OS + CB - BASIC for the Turbo Co-processor + TURMASM - Turbo version of MASM assembler + +\ FileServer + The shared L3 & FileStore source code files + +\ FileServer\X + Location for the assembled parts. Do not delete or the assembler will fail. + +* The files marked * are only on the 800K RISC PC version of this disk. + + +Version 1.31 +============ + +Date - estimated July 1988. Dates in change comments since v1.24 include +4/29 April 1988, 22 May 1988, 1 Jun 1988 and 1/7/20 July 1988. + +Comments +======== +This is the original and unchanged source code. Since just before v1.20 the +FileStore had become an Acorn product which used the same code base as the Level3 file server. The original code was 3 directories + - L3 containing the Level3 file server code + - FileStore with the Filestore file server code for the new E01 Filestore + - FileServer which appears to be an unfinished or incomplete set of code that + merges the Level3 file server and FileStore file server code base. + +The merged code was based on 2 switches, Level3 (representing Level3 +file server) and CMOS (for the FileStore which used the 65C102 processor). The +work to merge the code bases has now been completed. As no Level3 binaries +after v1.31 are known, the code changes in the FileStore file server code can +now be applied to Level3 file server using the shared code base "FileServer". + +When assembling the Filestore code, please also read the README file on the +Filestore FS source code disk. + +Warning: There appear to be changes made to the file system handling over +previous versions. It has been found that hard drives from previous versions +are not fully compatible with v1.31 - both L3 and FileStore. + +Changes (from v1.24) (L3 source files) +==================== + +HEADER FILE 1 + Uade01 Line 0064 VERLA, version changed from 2 to 3 +20/07/88 Uade01 Line 0065 VERLB, version changed from 4 to 1 + Uade01 Line 0194 SYNERR changed from &FE to &DC + +UTILITIES + Uade03 Line 0012 (C) date changed from 1987 to 1988 + +24/02/88 Uade04 Line 0243 changes made to date evaluation code + Uade04 Line 0244 ensuring day is not >31 + Uade04 Line 0256 + Uade04 Line 0274 + Uade04 Line 0275 + +FILE SERVER INITIALISATION + +24/03/88 Uade04 Line 0685 include the century in the date calculation +[typo 24/02/88?] to 0687 +24/02/88 Uade04 Line 0692 + Uade04 Line 0699 + to 0701 + Uade04 Line 0703 + Uade04 Line 0705 + Uade04 Line 0708 +24/02/88 Uade04 Line 0759 +24/02/88 to 0761 + Uade04 Line 0763 + Uade04 Line 0805 + Uade04 Line 0811 + to 0814 +24/02/88 Uade04 Line 0838 + to 0840 + Uade04 Line 0845 + Uade04 Line 0882 + Uade04 Line 0889 Leap year check + to 0891 + Uade04 Line 0926 Use carry flag to display leading 0 for hours + 0931 Use carry flag to display leading 0 for minutes +24/02/88 Uade04 Line 1012 + to 1015 + +24/02/88 Uade04 Line 0287 changes made to printing decimal numbers + Uade04 Line 0294 ensuring flag to print leading zeros is not lost + Uade04 Line 0297 + Uade04 Line 0304 + +USRMAN + Uade06 Line 0979 close down routine "LOGOFF" +01/06/88 to 0983 + Uade06 Line 0987 + Uade06 Line 0989 + Uade06 Line 0990 + Uade06 Line 0992 + Uade06 Line 0993 +01/06/88 Uade06 Line 0999 + + Uade06 Line 1073 routine GETUFD. change made to the how the root + Uade06 Line 1076 dir is created +07/07/88 to 1077 + Uade06 Line 1091 routine RTROOT + Uade06 Line 1093 + Uade06 Line 1114 store the users disc number in a variable instead + Uade06 Line 1116 of on the stack + Uade06 Line 1120 and use UMHLIB instead of USTEMP + to 1122 + Uade06 Line 1138 + Uade06 Line 1140 + Uade06 Line 1143 comment change to retrieve root again without + to 1144 checking if it already has been + Uade06 Line 1146 Clean up before doing the retrieve + Uade06 Line 1157 retrieve the previous user disc number + Uade06 Line 1159 +RNDMAN +29/04/88 Rman02 Line 0160 Change file size. code moved to a subroutine + Rman02 Line 0161 RDEXSZ in Rman04 to extend the file +29/04/88 Rman02 Line 0163 + Rman02 Line 0164 + +01/06/88 Rman02 Line 0383 bugfix: High water mark not increased when setting + the sequential file pointer, if it exceeded + the high existing high water mark + +23/03/88 Rman03 Line 0250 bugfix for the access mode for Putbytes/Getbytes + to 0254 operations + +29/04/88 Rman04 Line 0183 Set new file size and call the new subroutine + Rman04 Line 0184 RDEXSZ to extend the file +29/04/88 Rman04 Line 0215 Subroutine RDEXSZ + Rman04 Line 0253 + +DIRMAN +23/03/88 Uade0C Line 0021 New function 13 added. Check if object will preserve + Uade0C Line 0023 Increase the number of functions + Uade0C Line 0046 add routine to table +04/04/88 Uade0C Line 0127 call as a subroutine + Uade0C Line 0128 and use the DIRMAN exit function +04/04/88 Uade0C Line 0154 Routine DRRET2 set up the name, root character and 9 + to 0158 spaces + Uade0C Line 0171 add check for directory type and the locked bit + Uade0C Line 0172 + Uade0C Line 0174 + Uade0C Line 0175 + Uade0C Line 0177 + Uade0C Line 0178 + Uade0C Line 0181 +04/04/88 Uade0C Line 0256 Change to RTS as a subroutine exit + +04/04/88 Uade0C Line 0890 DRINFO most of the routine changed + to 0930 + + Uade0D Line 0153 check for : character removed as it was there twice +01/06/88 Uade0D Line 0580 compatibility for "^" ? + Uade0D Line 0581 + Uade0D Line 0584 + + Uade0D Line 0858 Code for RETPAR changed around in order of + Uade0D Line 0861 execution. + Uade0D Line 0865 + to 0912 + + Uade0E Line 0380 OUTZRO routine removed +24/02/88 Uade0E Line 0472 ensure only the day of the month is output + Uade0E Line 0473 + Uade0E Line 0479 + Uade0E Line 0480 set the value for the year + to 0483 + Uade0E Line 0494 +24/02/88 Uade0E Line 0501 ensure year 20xx compatable + to 0504 + Uade0E Line 0524 code optimised for character conversion + +01/06/88 Uade0E Line 0723 bugfix when outputting the access byte + Uade0E Line 0747 + to 0763 + +AUTMAN +22/03/88 Uade10 Line 0092 code moved to subroutine ATOPWF + Uade10 Line 0094 + to 0096 comments added +22/05/88 Uade10 Line 0189 new subroutine ATOPWF + to 0210 +22/03/88 Uade10 Line 0337 changed to use new open password file routine +22/03/88 Uade10 Line 0369 changed to use new open password file routine + + Uade10 Line 0814 check for alternative return code &FF instead of end + of file removed +01/06/88 Uade10 Line 0943 round up if part sector and skip check for page + to 0947 boundary at which was at 0978 (removed) + Uade10 Line 0979 remove unnecessary branch label +01/06/88 Uade10 Line 0982 check if password file is too big +01/06/88 Uade10 Line 0986 + to 0988 flush the now unwanted segment + + Uade10 Line 1027 code optimised to check for end of PW file + to 1036 + +01/06/88 Uade10 Line 1068 check if the password file will be too big before + to 1074 trying to enlarge it + +MAPMAN +24/02/88 Uade10 Line 0106 check added for write protect + to 0108 + + Uade10 Line 0705 code optimisation. keep a copy of the map block + 0709 pointer on the stack. +01/07/88 Uade10 Line 0721 and use it instead of making the calculation again + to 0724 + + Uade10 Line 0864 Code optimised to save having to get the drive + Uade10 Line 0869 number twice + Uade10 Line 0879 + Uade10 Line 0873 Comments reinstated + Uade10 Line 0875 + Uade10 Line 0877 + +05/03/88 Uade10 Line 0882 some checks and then.. + to 0891 code moved to a new subroutine MPRESZ +05/03/88 Uade10 Line 0918 new subroutine MPRESZ from previous code + to 0944 + +MAPMAN UTILITIES +06/07/88 Uade11 Line 0072 exit if Sector zero not retrieved +05/03/88 Uade11 Line 0092 code optimised to use the new routine MPRESZ +01/07/88 Uade11 Line 0498 code replaced by subroutine SETMB +01/07/88 Uade11 Line 0700 ?? + Uade11 Line 0703 + Uade11 Line 0711 + Uade11 Line 0719 branch labels changed + to 0756 + +MAPMAN UTILITIES II +01/07/88 Uade12 Line 0285 code optimised + to 0286 + Uade12 Line 0605 code optimised + to 0617 + +DSCMAN +24/02/88 Uade14 Line 0826 routine Testdv, mainly to check for write protect + to 0843 + +COMMAND PROCESSOR +23/03/88 Uade16 Line 0032 implement check for DIRMAN CHECKPRES (function 13) + Uade16 Line 0287 DRPRES routine moved and now shared with CHECKPRES + Uade16 Line 0288 + Uade16 Line 0320 Routine for CHECKPRES and DRPRES + to 0367 + + Uade16 Line 0039 ?? + to 0042 + + Uade16 Line 0061 code optimised + 0062 + + Uade19 Line 0019 code optimised + Uade19 Line 0043 + Uade19 Line 0053 + to 0070 + Uade19 Line 0085 label removed. no longer required + +23/03/88 Uade19 Line 0473 Check mode of access for file + Uade19 Line 0495 Ensure 0 returned if ok + +23/03/88 Uade19 Line 0580 Code optimised. Moved to new subroutine RMSUBR shared + Uade19 Line 0581 by Putbytes and Getbytes + Uade19 Line 0587 label removed. no longer required + Uade19 Line 0692 code moved to new subroutine RMSUBR + to 0719 + Uade20 Line 0088 Bugfix. Y not initialised to 0 when checking for a tx + on tx + +22/03/88 Uade20 Line 0544 code optimised. + Uade20 Line 0547 because of code reuse ensure X is preserved + Uade20 Line 0551 + to 0553 + Uade20 Line 0548 + Uade20 Line 0571 + Uade20 Line 0572 + + Uade20 Line 1022 New errors. SYNERR "Syntax" + Uade20 Line 1024 NUMERR "Bad Number" + Uade20 Line 1067 repeated for Italian language + Uade20 Line 1069 + +From the Filestore source code. + +Changes (from v1.23) (FileServer) +================================= + +The Filestore software has a big buffer cache option introduced for replies +which is enabled in this version. + +Support for Pseudo directory symbols is no longer present, but kept as an +optional assembler directive. The same for the MOS ROM debug code. +Command line changes: +Old Version New command and syntax +*FORMAT *FSFORMAT <4|5> <NAME> +*FSMODE *FSMODE <U|M> +*VERIFY *FSVERIFY d +*FSSTN *FSSTATION sss +*MAXDRIVE *FSMAXDRIVE d +*FSUSER *FSUSER <name> +*FSPROT *FSPROT <ON|OFF> +*REPORT *FSREPORT + +New Commands are +*PRPAGE <Y|N> +*FSNAMEDISC <name> + +Commands removed are +*CAT +*LOAD +*SAVE +*CERTIFY + +Form Feed suppression option (*PRPAGE). Bypass flag in CMOS for the Acorn copyright hard drive check. SIN added to disc error report strings. +Year 20xx compatable, bugfix enlarging the password file. Support for multiple +hard drives and E40S, E60S. Reset CMOS to default values if they are corrupt. +A revised version of the AFS0 disk format is used to optimise use of the larger +hard drives. Disks and floppies with the older AFS0 format will have issues. + +HEADER FILE 1 +20/07/88 Uade01 Line 0059 VERLB, version changed from 23 to 31 +18/02/88 Uade01 Line 0065 Pseudo directory (%, &, @) switch added - default off + Uade01 Line 0267 Size of IEaddr changed to 8 bytes for better error reporting +08/02/88 Uade01 Line 0273 Flag added for the supression of print Form Feed +23/03/88 Uade01 Line 0274 Flag added to bypass hard drive ACORN copyright check +05/03/88 Uade01 Line 0275 variable CMinen added for CMOS table length + +HEADER FILE 2 + Uade02 Line 0117 Pseudo directory (%, &, @) switch + to 0119 ] +08/02/88 Uade02 Line 0239 Receive buffer length extended from 80 to 127 bytes +01/05/86 Uade02 Line 0261 Mask for task number in control byte changed from &1E to &78 +08/02/88 Uade02 Line 0399 size of MIDRX changed to calculated length +08/02/88 Uade02 Line 0418 File title buffer made always the same size as RXBUFL + Uade02 Line 0450 variable added for SIN of last disc error +08/02/88 Uade02 Line 0465 Flag for printing no trailer FormFeed + +ERROR HANDLING +29/04/88 Uade03 Line 0051 reporting added for the SIN of last disc error +29/04/88 Uade03 Line 0092 cancel any pending receive control blocks after error + +FILE SERVER INITIALISATION + Uade04 Line 0036 INTERR changed to USRERR +05/03/88 Uade04 Line 0046 Table of default values for initialsing CMOS RAM added +05/03/88 Uaed04 Line 0066 Initialise CMOS RAM if not initialised +24/02/88 Uade04 Line 0204 Code optimisation for date sanity check + to 0205 " + Uade04 Line 0216 " + Uade04 Line 0228 " + Uade04 Line 0233 " + to 0236 " + +USRMAN + Uade06A Line 0307 Pseudo directory (%, &, @) switch + to 0310 ] +01/06/88 Uade06A Line 0372 Routine LOGOFF + to 0379 +07/07/88 Uade06A Line 0454 Routine GETUFD, add SETUID + to 0458 and code optimzation reusing RTROOT +07/07/88 Uade06A Line 0494 Routine GETLBH, to retrieve file "LIBRARY" + to 0539 + +RNDMAN +29/04/88 Rman02 Line 0160 Change file size. code moved to a subroutine + to 0163 RDEXSZ in Rman04 to extend the file +29/04/88 Uade19 Line 0188 use RXEXSZ + to 0189 +01/06/88 Rman02 Line 0382 bugfix: High water mark not increased when setting + the sequential file pointer, if it exceeded + the high existing high water mark +23/03/88 Rman03 Line 0247 bugfix for the access mode for Putbytes/Getbytes + to 0250 operations +29/04/88 Rman04 Line 0182 Set new file size and call the new subroutine + to 0187 RDEXSZ to extend the file +29/04/88 Rman04 Line 0219 Subroutine RDEXSZ added + Rman04 Line 0252 + +DIRMAN +23/03/88 Uade0C Line 0021 New function 13 added. Check if object will preserve + to 0022 Increase the number of functions + Uade0C Line 0041 add routine to table +04/04/88 Uade0C Line 0122 call as a subroutine + to 0126 and use the DIRMAN exit function +04/04/88 Uade0C Line 0150 Routine DRRET2 set up the name, root character and 9 + to 0154 spaces +04/04/88 Uade0C Line 0167 add check for directory type and the locked bit + to 0178 + Uade0C Line 0206 + to 0209 + Uade0C Line 0212 Pseudo directory (%, &, @) switch + to 0227 | + to 0229 ] + Uade0C Line 0223 + to 0226 + Uade0C Line 0533 Pseudo directory (%, &, @) switch + to 0540 ] +04/04/88 Uade0C Line 0260 Change to RTS as a subroutine exit + Uade0CA Line 0032 INTERR changed to USRERR +04/04/88 Uade0CA Line 0303 DRINFO most of the routine changed + to 0335 + Uade0D Line 0152 check for : character removed as it was there twice + Uade0D Line 0152 check for : character removed as it was there twice + Uade0D Line 0415 Pseudo directory (%, &, @) switch + to 0420 ] + Uade0D Line 0517 Pseudo directory (%, &, @) switch + to 0523 ] + Uade0D Line 0535 Pseudo directory (%, &, @) switch + to 0540 ] +01/06/88 Uade0D Line 0573 compatibility for "^" ? +01/06/88 Uade0D Line 0577 code optimisation, no longer required + + Uade0DA Line 0145 Code for RETPAR changed around in order of + Uade0DA to 0191 execution. + Uade0DA Line 0535 Pseudo directory (%, &, @) switch + to 0540 ] + Uade0DA Line 0865 + to 0912 + + Uade0E Line 0377 OUTZRO routine removed +24/02/88 Uade0E Line 0460 ensure only the day of the month is output + Uade0E Line 0461 + Uade0E Line 0467 + Uade0E Line 0468 set the value for the year + to 0471 + Uade0E Line 0482 +24/02/88 Uade0E Line 0489 ensure year 20xx compatable + to 0492 + Uade0E Line 0512 code optimised for character conversion + Uade0E Line 0526 Jump label OUTACA removed + Uade0E Line 0576 Jump label OUTSZA removed + +01/06/88 Uade0EA Line 0082 check entry code and update header +01/06/88 Uade0EA Line 0106 Check if preserve only, update header + to 0122 routine + +AUTMAN +22/03/88 Uade0F Line 0084 code moved to subroutine ATOPWF +22/03/88 Uade0F Line 0181 new subroutine ATOPWF + to 0206 +22/03/88 Uade0F Line 0334 use subroutine ATOPWF to check PW file +22/03/88 Uade0F Line 0534 use subroutine ATOPWF to check PW file + + Uade0FA Line 0213 RTS added + Uade0FA Line 0282 check removed for alternative RC + to 0288 +01/06/88 Uade0FA Line 0413 + to 0417 +01/06/88 Uade0FA Line 0448 code to look for runnimg over page boundary removed +01/06/88 Uade0FA Line 0455 check if the password file will be too big before + to 0457 trying to enlarge it +01/06/88 Uade0FA Line 0478 add test for end of file + to 0483 + Uade0FA Line 0504 code optimised to check for end of PW file + to 0509 +01/06/88 Uade0FA Line 0543 check if the password file will be too big before + to 0549 trying to enlarge it + Line 0572 + +MAPMAN +24/02/88 Uade10 Line 0101 check added for write protect + to 0102 + +01/07/88 Uade10A Line 0418 code optimisation. keep a copy of the map block + Line 0422 pointer on the stack +01/07/88 Uade10A Line 0434 and use it instead of making the calculation again + to 0437 + Uade10A Line 0533 Code optimised with temp variables no longer being + zero'ed + + Uade10A Line 0568 Code optimised to save having to get the drive + Uade10A Line 0573 number twice +05/03/88 Uade10A Line 0597 code moved to a new subroutine MPRESZ +05/03/88 Uade10A Line 0621 new subroutine MPRESZ from previous code + to 0646 + +MAPMAN UTILITIES +06/07/88 Uade11 Line 0069 check if disc needs to be mounted + to 0076 +05/03/88 Uade11 Line 0094 code optimised to use the new routine MPRESZ +06/07/88 Uade11 Line 0125 + to 0129 +06/07/88 Uade11 Line 0408 JSR USRERR replaced by JSR INTERR +01/07/88 Uade11 Line 0499 code replaced by subroutine SETMB +01/07/88 Uade11A Line 0072 Get Cylinder Map position routine chnaged + to 0081 + +MAPMAN UTILITIES II + Uade12 Line 0051 + Uade12 Line 0058 code optimised. Setting command 8 moved up to here + to 0059 + Uade12 Line 0070 + to 0072 + Uade12 Line 0098 + Uade12 Line 0265 bugfix: ensure carry is cleared +01/07/88 Uade12 Line 0584 optimise ABLKS + to 0595 + Uade12 Line 0636 routine ABSALL removed as is now in routine ABLKS + + Uade13 Line 0018 optimise code. No need to clear drive number in X +23/03/88 Uade13 Line 0789 Bypass (C)Acorn hard drive check + to 0791 +01/08/88 Uade13 Line 0829 Set drive number + Line 0833 Use different memory area + Line 0837 Use different memory area +06/07/88 Uade13 Line 0838 bugfix: don't overlay sector zero on restart + Uade13 Line 0849 Use different memory area + to 0853 + Uade13 Line 0912 Use INTERR instead of USRERR +29/04/88 Uade13 Line 0978 Remove code and zero DCSTAD + to 0998 +29/04/88 Uade13 Line 1013 Remove code + to 1024 + +DSCMAN +29/02/88 Uade14 Line 0053 optimise code. use stack + to 0058 +12/07/88 Uade14 Line 0457 copy disc address for error reporting + to 0461 +24/02/88 Uade14 Line 0508 routine Testdv, mainly to check for write protect + to 0522 + +COMMAND PROCESSOR +06/07/88 Uade15 Line 0088 Ignore error if removable disc is unavailable + to 0094 Use INTERR instead of USRERR +08/02/88 Uade15 Line 0332 comment added PRPAGE NOT TRANSLATED TO ITALIAN +08/02/88 Uade15 Line 0352 comment added NOMEDISC NOT TRANSLATED TO ITALIAN? + Uade15A Line 0026 add error reporting string SIN= + to 0029 +01/06/88 Uade15A Line 0044 add support to reset the error report +07/07/88 to 0049 & in user mode +01/06/88 to 0064 in maintenance mode for privileged user + Uade15A Line 0085 support change in message length +22/03/88 Uade15A Line 0390 add support to rename a disc in maintenance mode + to 0476 + +08/02/88 Uade16 Line 0028 SAVE Routine changes + to 0088 + Uade16 Line 0331 Pseudo directory (%, &, @) switch + to 0335 ] + Uade16A Line 0027 Pseudo directory (%, &, @) switch + to 0031 ] + Uade19 Line 0591 code optimisation and moved to RMSUBR + to 0592 + Uade19 Line 0705 new subroutine RMSUBR + to 0732 + +22/03/88 Uade20A Line 0153 bugfix. + +PRINT +08/02/88 PRINT0 Line 0040 check for trailer banner suppress state + to 0043 +20/05/87 PRINT0 Line 0269 + to 0271 +08/02/88 PRINT0 Line 0495 add option for a single Form Feed as a trailer banner + to 0522 + +FORMAT + FORM00 Line 0029 multiple lines of code removed + FORM00 Line 0048 JMP COMRTS removed + FORM00 Line 0245 image format changes + FORM00 Line 0257 + FORM00 Line 0260 + FORM00 Line 0265 + FORM00 Line 0269 + to 0280 + FORM00 Line 0283 + FORM00 Line 0303 + FORM00 Line 0402 + to 0406 diff --git a/FileServer/SRC/README.inf b/FileServer/SRC/README.inf new file mode 100644 index 0000000..848f0d1 --- /dev/null +++ b/FileServer/SRC/README.inf @@ -0,0 +1 @@ +README FFFFFF59 18948126 00 19 \ No newline at end of file diff --git a/FileServer/SRC/START b/FileServer/SRC/START new file mode 100644 index 0000000..d0e0b98 Binary files /dev/null and b/FileServer/SRC/START differ diff --git a/FileServer/SRC/START.INF b/FileServer/SRC/START.INF new file mode 100644 index 0000000..a28d3d8 --- /dev/null +++ b/FileServer/SRC/START.INF @@ -0,0 +1 @@ +$.START 00000800 00008023 00000141 33 A54C 373B11 A242 0C3913 diff --git a/FileServer/adfs/FS-131bin.adl b/FileServer/adfs/FS-131bin.adl new file mode 100644 index 0000000..70fbdfc Binary files /dev/null and b/FileServer/adfs/FS-131bin.adl differ diff --git a/FileServer/adfs/FS-131src-BBC.adl b/FileServer/adfs/FS-131src-BBC.adl new file mode 100644 index 0000000..5014eb1 Binary files /dev/null and b/FileServer/adfs/FS-131src-BBC.adl differ diff --git a/FileServer/adfs/FS-131src-RISC.adf b/FileServer/adfs/FS-131src-RISC.adf new file mode 100644 index 0000000..5d790a4 Binary files /dev/null and b/FileServer/adfs/FS-131src-RISC.adf differ diff --git a/FileStore/Binary Files/E01S-131 b/FileStore/Binary Files/E01S-131 new file mode 100644 index 0000000..b385b57 Binary files /dev/null and b/FileStore/Binary Files/E01S-131 differ diff --git a/FileStore/Binary Files/E01S-131p b/FileStore/Binary Files/E01S-131p new file mode 100644 index 0000000..1d3edac Binary files /dev/null and b/FileStore/Binary Files/E01S-131p differ diff --git a/FileStore/Binary Files/FSR-131 b/FileStore/Binary Files/FSR-131 new file mode 100644 index 0000000..008c927 Binary files /dev/null and b/FileStore/Binary Files/FSR-131 differ diff --git a/FileStore/Binary Files/FSR-131p b/FileStore/Binary Files/FSR-131p new file mode 100644 index 0000000..7505561 Binary files /dev/null and b/FileStore/Binary Files/FSR-131p differ diff --git a/FileStore/Binary Files/FSrom b/FileStore/Binary Files/FSrom deleted file mode 100644 index 7d3214d..0000000 Binary files a/FileStore/Binary Files/FSrom and /dev/null differ diff --git a/FileStore/Binary Files/FSrom.inf b/FileStore/Binary Files/FSrom.inf deleted file mode 100644 index ea56de9..0000000 --- a/FileStore/Binary Files/FSrom.inf +++ /dev/null @@ -1 +0,0 @@ -$.FSrom 00000000 00000000 00007E00 33 diff --git a/FileStore/Binary Files/Original Binary/E01 v1.23 MOS 0254-205-03 MOS33C.rom b/FileStore/Binary Files/MOS-33F similarity index 84% rename from FileStore/Binary Files/Original Binary/E01 v1.23 MOS 0254-205-03 MOS33C.rom rename to FileStore/Binary Files/MOS-33F index dd9648c..6142aa1 100644 --- a/FileStore/Binary Files/Original Binary/E01 v1.23 MOS 0254-205-03 MOS33C.rom +++ b/FileStore/Binary Files/MOS-33F @@ -1,41 +1,39 @@ -ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…�†„º†,$ü©€ü¢�½��½��½��½��½��½��½��½� � ½� +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,$ü©€ü¢�½��½��½��½��½��½��½��½� � ½� � -½� � ½� � ½� � ½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½� � ½�!�!½�"�"½�#�#½�$�$½�%�%½�&�&½�'�'½�(�(½�)�)½�*�*½�+�+½�,�,½�-�-½�.�.½�/�/½�0�0½�1�1½�2�2½�3�3½�4�4½�5�5½�6�6½�7�7½�8�8½�9�9½�:�:½�;�;½�<�<½�=�=½�>�>½�?�?½�@�@½�A�A½�B�B½�C�C½�D�D½�E�E½�F�F½�G�G½�H�H½�I�I½�J�J½�K�K½�L�L½�M�M½�N�N½�O�O½�P�P½�Q�Q½�R�R½�S�S½�T�T½�U�U½�V�V½�W�W½�X�X½�Y�Y½�Z�Z½�[�[½�\�\½�]�]½�^�^½�_�_½�`�`½�a�a½�b�b½�c�c½�d�d½�e�e½�f�f½�g�g½�h�h½�i�i½�j�j½�k�k½�l�l½�m�m½�n�n½�o�o½�p�p½�q�q½�r�r½�s�s½�t�t½�u�u½�v�v½�w�w½�x�x½�y�y½�z�z½�{�{½�|�|½�}�}½�~�~½��½�è�è½�é�é½�ê�ê½�ë�ë½�ì�ì½�í�í½�î�î½�ï�ï½�ð�ð½�ñ�ñ½�ò�ò½�ó�ó½�ô�ô½�õ�õ½�ö�ö½�÷�÷½�ø�ø½�ù�ù½�ú�ú½�û�û½�ý�ý½�þ�þ½�ÿ�ÿÊðLè,ü½���â½��ã½�æ�ä½�ç�åÊÐå©Àüÿ©ëýÿ,$üxØ¢ÿš©ˆü© -�ü©&ü© �ü©ü©�ü­ü…Ô©�ü­ü¢€Žü8eÔð©þ…ÔdÕœüœü©üü õì Ýì¢�ž�æž�çž�ÊÐô©>…©€…œ¥Ômç¢Ø©ˆæÊÐú©î… ©ð…¡©(…©ü…©*…¢©í…£©àü©Àü©:Ðý©à…¤ü, ü©P…ù…ú…ï…ð©…í…î©…ñ…ò,(üX¢�½íð îÿèÐõd ­Ôì÷ÿ¢ÚŽøÿ¢ìŽùÿÍ�ð"d­fçj¥¤) €…¤ü¥ ðë ×ìd ¥ž…€à­hçÉùL�l ææ `©Á ü©#üœ!ü©‚ ü©g!ü`©à ü©2:Ðý­!ü‰ ð -­ü) Àü`Î�,$ü, ü HZl �„¡… zhl¢�, üî�Ò@Î�,$ü`î�Ò`H­ü…­1ü…©@,üð$ÚZüü¥…ž®æà ° … ~í¥ Ð¥ž…zú µï Ùíh@|*ô �<Ú®oçìnçÐ H­üjjh°òpç ÑíŽoç­üjj°'ìnçð"©ÿü­ü)ð -ü©ü©‚ü®nç½pçüú`èà¢�`Ú©,üðî,üðélç®nç ÑíŽnçìoçÐÒüü€Ð†Ð„ÑÉÐy$œ0©�’Ð`¢À �†¨„©  ±Ð‘¨ˆù©€ÀLOô²ÐÉÐQ©À �…¨„©i…Ä„Å…È„ÉdÌdÍdÏdÁ ±Ð…ÂȱЅÃȱÐð%É ð!$œü…΢�©……ÀÚZ Oôzú¥À0üðÞHhÐûèÐç`Éð¤ÉÐK²ÐªÐ1©‰ æ…΄Ïè²ÎðÉЊ’ÐæÐÐæÑ  ±Ð‘Έù`© eÎ…ÎÛæÏ€× qðð �±ÎÈ‘ÐÀ ÷©’Î`ÉÐE �±ÐÈÉбЅ`ÉÐé±Ðmç¢ 6ðIÿè 6ð`ÉÐ ²Ðªx +ðX ‘Ð`ÉÐòЪ ±Ðx 6ðX`ÉrÐ%Lf÷ÉÐ  �¹gç‘ÐÈÀö`ÉР�±Ð™gçÈÀö`ÉðUÉÐÖx¢ +ð € 6ð �±Ð¢ 6ðȱÐJJJJiQ¢ 6ð±Ð)Ê 6ðȱТ 6ðȱТ 6ðȱТ� 6ð¢ +ð)  6ðX`­fçH �¹bç‘ÐÈÀöhÍfçÐê`Ú¢ +ð…j©îÅ Ðd©ðÅ¡Ð^Z �¢ +ð™bçÈ¢ +ð8éQ +½� � ½� � ½� � ½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½� � ½�!�!½�"�"½�#�#½�$�$½�%�%½�&�&½�'�'½�(�(½�)�)½�*�*½�+�+½�,�,½�-�-½�.�.½�/�/½�0�0½�1�1½�2�2½�3�3½�4�4½�5�5½�6�6½�7�7½�8�8½�9�9½�:�:½�;�;½�<�<½�=�=½�>�>½�?�?½�@�@½�A�A½�B�B½�C�C½�D�D½�E�E½�F�F½�G�G½�H�H½�I�I½�J�J½�K�K½�L�L½�M�M½�N�N½�O�O½�P�P½�Q�Q½�R�R½�S�S½�T�T½�U�U½�V�V½�W�W½�X�X½�Y�Y½�Z�Z½�[�[½�\�\½�]�]½�^�^½�_�_½�`�`½�a�a½�b�b½�c�c½�d�d½�e�e½�f�f½�g�g½�h�h½�i�i½�j�j½�k�k½�l�l½�m�m½�n�n½�o�o½�p�p½�q�q½�r�r½�s�s½�t�t½�u�u½�v�v½�w�w½�x�x½�y�y½�z�z½�{�{½�|�|½�}�}½�~�~½��½�è�è½�é�é½�ê�ê½�ë�ë½�ì�ì½�í�í½�î�î½�ï�ï½�ð�ð½�ñ�ñ½�ò�ò½�ó�ó½�ô�ô½�õ�õ½�ö�ö½�÷�÷½�ø�ø½�ù�ù½�ú�ú½�û�û½�ý�ý½�þ�þ½�ÿ�ÿÊðL +è,ü©›üÿ©ëýÿ,$üxØ¢ÿš©ˆü© +�ü©&ü© �ü©ü©�ü­ü…Ô©�ü­ü¢€Žü8eÔð©þ…ÔdÕœüœü©üü Íì µì¢�ž�æž�çÊÐ÷©>…©€…œ¥Ômç¢Ø©ˆæÊÐú©À… ©ð…¡©(…©ü…©…¢©í…£©àü©Àü©:Ðý©à…¤ü, ü©P…ù…ú…ï…ð©…í…î©…ñ…ò,(üX¢�½Oíð îÿèÐõd ­¬ì÷ÿ¢²Žøÿ¢ìŽùÿÍ�ð"d­fçj¥¤) €…¤ü¥ ðë ¯ìd ¥ž…€à­hçÉùL�l ææ `©Á ü©#üœ!ü©‚ ü©g!ü`©à ü©2:Ðý­!ü‰ ð +­ü) Àü`Î�,$ü, ü HZl �„¡… zhl¢�, üî�Ò@Î�,$ü`î�Ò`H©@,üð$ÚZüü¥…ž®æà ° … Lí¥ Ð¥ž…zú …ï §íh@|øó �?Ú®oçìnçÐ H­üjjh°òpç ŸíŽoç­üjj°'ìnçð"©ÿü­ü)ð +ü©ü©‚ü®nç½pçüú`èà¢�`Ú©,üðî,üðélç®nç ŸíŽnçìoçÐÒüü€Ð†Ð„ÑÉÐy$œ0©�’Ð`¢À �†¨„©  ±Ð‘¨ˆù©€ÀLô²ÐÉÐQ©À �…¨„©i…Ä„Å…È„ÉdÌdÍdÏdÁ ±Ð…ÂȱЅÃȱÐð%É ð!$œü…΢�©……ÀÚZ ôzú¥À0üðÞHhÐûèÐç`Éð¤ÉÐC²ÐªÐ)©‰ æ…΄Ïè²ÎðÉЊ’ÐæÐÐæÑ  ±Ð‘Έù` ´ð€ß Aðð �±ÎÈ‘ÐÀ ÷©’Î`ÉÐE �±ÐÈÉбЅ`ÉÐé±Ðmç¢ ðIÿè ð`ÉÐ ²Ðªx ûïX ‘Ð`ÉÐòЪ ±Ðx ðX`ÉrÐ%L$÷ÉÐ  �¹gç‘ÐÈÀö`ÉР�±Ð™gçÈÀö`ÉðcÉÐÖx¢ ûï € ð �±Ð)à… ±Ð)¢ ðȱÐJJJ J8é°id¢ ð±Ð)Ê ðȱТ ðȱТ ðȱТ� ð¢ ûï)  ðX`®fç ¹bç‘ЈøìfçÐî`Ú¢ ûïl©ÀÅ Ðf©ðÅ¡Ð`¢ ûïbç¢ ûï8éQ°id +… - -™bçÊ +ðbç™bçÈ¢ +ð™bçÈ¢ +ð™bçÈ¢� +ð™bçz­gçidgçîhçÐ îiçÐîjçÐîkçú` NðŽ�ü­ü€ NðŽ�üüH¥¤)÷ü…¤ :íh`H 3í¥¤ ü…¤h`É2Ð ÿì �±¨ª`É3Ð! ÿ쩉 æ…΄ϲÎðÊЪ`© eÎ…ÎîæÏ€êÉ4Ð - qðð©’Î`É€Ð0ŠÐ ©�,,ü0P `àüÐç­lçð­nç8íoçÐ ­üjj©�°iª`ɄТ� æ`ɉЊj¥¤) €ü…¤`dœ©,!üð9­"üÅÔð ÉÿЩ@�æ© ñL!í,!ü­"üð Iÿð ©¢ üL;ó�æ…ª©.L#퀭!ü)ð õì ÝìL;óL8󤪭!üæ­"ü™�È­!ü0Э"ü™�ÈÀ ð -„ª­!üÐÞL%íœ ü©„!ü©,!üð´²­"ü™�©D ü¥“ÐLqó,�æP©!ü©‰ æ…®„¯ �±®ð,ÉÐȱ®ðÅ“Ðȱ®ðÅРȱ®ðÅ‘ð¥®i …®Ò毀΀R C÷,�æPLKó©è ñL¦ò©‚ ü©òL#í©,!üð/­"üÅÔÐ(© òL!í,!ü­"üÐ, ü0©L#í,!ü­"ü­"ü€­�æL*÷ ÝìL8ó, ü0©B òL!í¤ª­!ü-­"ü‘¬ÈÐæ­Æ«ðÑ­!ü0Э"ü‘¬È„ªÐæ­Æ«ð­!üÐÔL%íœ ü©„!ü„ª©,!ü𡥫ð›­"ü¤ª‘¬æªÐæ­­�æL&÷©þ òæŒæ©D ü©§!ü¥, üP>"ü¥‘"ü¥Ô, ü0 ©Ó òL!í¥Ô, üP!"ü©�,�æ0 /Œ!ü#ü­æ¬æL!í"üLröL(ò¥“Ð ¤’À‚ðLô¥ªe¬æ­ ‘®È¥­‘®¥“𥑠‘®ˆ¥‘®ˆ¥“‘®ˆ¥’ €‘® êì­mç…Ô©€…œ©î ðL!íÚ¢¤ªµ‘¬ÈÐæ­Æ«ð -脪à Ðìú€¤æªà ð÷úL(ò¤’À÷À‰°óÀ‡° ˜8騥jˆü°¬Ú¥’*ª|“óâóÄó¥ó¥ó¥óòóòóÐó©‚…ª©…«©‰…¬©å…­ ¹”�™æˆ÷úLáñ©…®©�…¯úLÖñ©…«©ü…ª©†…¬©ì…­€ ©…®©�…¯ C÷©€ �æú©D ü©§!ü© ôL¦ò¥ªi€æ¥ 楑 -楒*æ©Àüü©üœüL8ó:ô=ô=ô>ôJôlæ`©ŸÐX$ŸÐü`©Ÿ`dœÚ ±¨…Òȱ¨…Ó �±¨0Lõô…֪ȱ¨…×Ð3àƒ°8 ±¨ˆˆˆˆ(ñ¨™Ø�ÈÈÈÈÈÀ ê(àbà‰°^  ±¨™Ì�ÈÀö© ,!üÐX©þ…¥©æœæd¦d§ ç©x 3í,!üð­ ü©g!ü©, üÐ:…­ ü…­!ü… :í(æ§ÐÑæ¦ÐÍæ¥ÐÉ€©D€©!ü©@€ ÿì©C �‘¨©€…œú`Œ!ü¢DŽ ü¢’ õ† „¡ :í¥×Ð9¥Ö -ª½2÷�æ½1÷æ|9õKõKõ„õ„õ„õõõ„õ  ¹Ð�(q¨™Ð�ÈÀñ(€#¥Ò%ÓÉÿЩæ©@�æ ±¨™Ô�ÈÀ ö€œ�楨…®¥©…¯ C÷(ú`¬æ, üP"¹Ò�"üȹÒ�ÈŒæ"üÌæ°, ü0ãL%í©B€©g!ü©A¤ÔHhÈÐûL,÷©?!ü©×L#í©‚ ü,�æPL&÷©,�æðLÏöL*÷©öL#í©,!üð»­"üÅÔÐê©  öL!í,!üÞ­"üÐÙ, ü0©L#í,!üÊ­"üÅÒÐí"üÅÓм©,!ü𵩧!ü©D ü©Ï öæŒæ¥Ò, üP0"ü¥Ó"ü©c öL!í¥Ô, üP"ü©�"ü©y öL!í¤ªÐ¥«ð+, üPA±¬"üÈÐÆ«ðæ­±¬"üÈ„ªÐÆ«ð -æ­, ü0ÛL%í©?!ü­�æ©»L#íL8ó­æ¬æL!í­�æ^L8ó©‚ ü©Û öL!í©,!üðH­"üÅÔÐA©îL#í,!ü7­"üÐ2, ü0© ÷L!í,!ü!­"üÅÒЭ"üÅÓЭ�æL6ò©,!üð©�€©A �‘¨L8ó� +cç¥ )à bçÊ ûï cç¢ ûïdç¢ ûïeç¢� ûïfç­gçidgçîhçÐ îiçÐîjçÐîkçú` ðŽ�ü­ü€ ðŽ�üüH¥¤)÷ü…¤ íh`H í¥¤ ü…¤h`É2Ð ×ì �±¨ª`É3Ð ×쩉 æ…΄ϲÎðÊЪ` ´ð€òÉ4Ð + Aðð©’Î`É€Ð.ŠÐ ,,ü0P `àüÐé­lçð­nç8íoçÐ ­üjj©�°iª`ɄТ� æ`ɉЊj¥¤) €ü…¤`© eÎ…ÎæÏ`dœ©,!üð7­"üÅÔð ÉÿЩ@�æ©ÞLûì,!ü­"üð Iÿð ©¢ üL ó�æ…ª©þLû쀭!ü)ð Íì µìL óL󤪭!üæ­"ü™�È­!ü0Э"ü™�ÈÀ ð +„ª­!üÐÞLýìœ ü©„!ü©,!üð´²­"ü™�©D ü¥“ÐL?ó,�æP©!ü©‰ æ…®„¯ �±®ð,ÉÐȱ®ðÅ“Ðȱ®ðÅРȱ®ðÅ‘ð¥®i …®Ò毀΀P ÷,�æPL󩸠ñLtò©‚ ü©ÂLûì©,!üð-­"üÅÔÐ&©ÕLûì,!ü­"üÐ, ü0©éLûì,!ü­"ü­"ü€­�æLèö µìLó, ü0© òLù줪­!ü-­"ü‘¬ÈÐæ­Æ«ðÑ­!ü0Э"ü‘¬È„ªÐæ­Æ«ð­!üÐÔLýìœ ü©„!ü„ª©,!ü𡥫ð›­"ü¤ª‘¬æªÐæ­­�æLäö©Ì òæŒæ©D ü©§!ü¥, üP>"ü¥‘"ü¥Ô, ü0 ©¡ òLùì¥Ô, üP!"ü©�,�æ0 /Œ!ü#ü­æ¬æLùì"üL2öLöñ¥“Ð ¤’À‚ðLÒó¥ªe¬æ­ ‘®È¥­‘®¥“𥑠‘®ˆ¥‘®ˆ¥“‘®ˆ¥’ €‘® Âì­mç…Ô©€…œ©À ðLùìÚ¢¤ªµ‘¬ÈÐæ­Æ«ð +脪à Ðìú€¤æªà ð÷úLöñ¤’À÷À‰°óÀ‡° ˜8騥jˆü°¬Ú¥’*ª|aó°ó’ósósósóÀóÀóžó©‚…ª©…«©‰…¬©å…­ ¹”�™æˆ÷úL±ñ©…®©�…¯úL¦ñ©…«©ü…ª©T…¬©ì…­€ ©…®©�…¯ ÷©€ �æú©D ü©§!ü©ä óLtò¥ªi€æ¥ 楑 +楒*æ©Àüü©üœüLóô ô ô ôôlæ`©ŸÐX$ŸÐü`©Ÿ`dœÚ ±¨…Òȱ¨…Ó �±¨0L·ô…֪ȱ¨…×Ð3àƒ°8 ±¨ˆˆˆˆ(ñ¨™Ø�ÈÈÈÈÈÀ ê(àVà‰°R  ±¨™Ì�ÈÀö© ,!üÐL©þ…¥©æœæd¦d§ ç©x í,!üð­ ü©g!ü©, üÐ. í(æ§ÐÝæ¦ÐÙæ¥ÐÕ€©D€©!ü©@€ ×ì©C �‘¨©€…œú`Œ!ü¢DŽ ü¢T õ† „¡ í¥×Ð9¥Ö +ª½ðö�æ½ïöæ|ûô õ õFõFõFõQõQõFõ  ¹Ð�(q¨™Ð�ÈÀñ(€#¥Ò%ÓÉÿЩæ©@�æ ±¨™Ô�ÈÀ ö€œ�楨…®¥©…¯ ÷(ú`¬æ, üP"¹Ò�"üȹÒ�ÈŒæ"üÌæ°, ü0ãLýì©B€©g!ü©A¤ÔHhÈÐûLêö©?!ü©™Lûì©‚ ü,�æPLäö©,�æðLöLèö©¸Lûì©,!üð»­"üÅÔÐê©ËLûì,!üà­"üÐÛ, ü0©ßLûì,!üÌ­"üÅÒÐÅ­"üÅÓо©,!ü𷩧!ü©D ü© öæŒæ¥Ò, üP0"ü¥Ó"ü©# öLùì¥Ô, üP"ü©�"ü©9 öLù줪Ð¥«ð+, üPA±¬"üÈÐÆ«ðæ­±¬"üÈ„ªÐÆ«ð +æ­, ü0ÛLýì©?!ü­�æ©{LûìLó­æ¬æLùì­�æ\Ló©‚ ü©› öLùì©,!üðF­"üÅÔÐ?©®Lûì,!ü5­"üÐ0, ü0©ÂLûì,!ü!­"üÅÒЭ"üÅÓЭ�æLò©,!üð©�€©A �‘¨Ló� � � � - ±® 8ñ®…ª ±®é�…­ ±®…¬  ±®8å­…«`†à„á �±àð ©e’à¢à �` ±àJJJJJÉ°êé…øª ±àÉðBÉ -ð>É -É°)à°Ñ ±à)ð•íÉ°ȱà•ñȱà•ï ±àɱð -LýŠ0©`€£LKþLøù  -±àÐí  ±à…õÐ: ±àÐ߈±àÐÚˆ±à…õˆ±àðæõðÌÚª ±àøÈ±à  qàøžÿÿèÐúú  ¥õ‘àŠ0² ±à)…÷ȱà…öȱà…ü �¦øµíjµñ° -…ûÈ¥ü8åû…ü¥öé�…ö¥÷é�…÷°êˆ¥üeû…ü˜Õï©aLr÷ Âù”ù ±à…öȱà…÷©îÅ Ðú©ðÅ¡Ðô© -…ýµùü©¢™ ø(ðLüþSÆýðO¢‡ ø©€í¦øµùÍ üÐÑ© -…ý¥÷ˆùxù¥ö‡ùwù¥ü¦øÕñõñüÍüÐø ±àÉ -Щ¢¢€ ù€©Ð ü £ùLp÷€¬©‚¢m ùH ˜ùdû¦ø¥üÕñæûh H éù¢� „ìh ü…ÿ­hçÍhçð¿Äìð÷ £ù­ üj°ú -…þ‰Љ@Љð -Æýª ±ùLr÷Æõðæü¦øµíjµñ° -ÅüÐdüöùæ÷L©ø`HÌ üÐ ­üÿÿèÐdìh@HÌ üÐö½ÿÿèüðí­ üÉÐæh@x 3íŽúÿŒûÿ`¢ íŽúÿŒûÿXL:í‰ð©P`‰@ð©ÿ`©H`¦ø¥¤)è�ý…¤ü­ üj©Ð üÐýµù üÍ üÐî`¦û¥¤)ûý…¤ü`© -…ý­0üÍ1üÐÍ2üÐ -Í3üЩeLr÷ 9úðøÉ%ðòÉeðîÉРHh:ÐûÊÐøˆÐõ©ÆýÜ€× ëúȱà…öȱà…÷ ±à °úȱà)à…øˆÈ±à °ú ûPó ±à)ýIð# ûP8 � û0J°±ö0ü€­0ü‘öÈÐêæ÷€æ � û0.p ±ö0üÈÐøæ÷€í­0ü‘öÈÐøæ÷€á ûp 0ü© -éÐü©�`hh û­0ü û¨ û)ðò˜®0üðŠ - - - -Ъ)ðŠ)` �©H û)Ðùh0ü2ü û)ðù`­1ü…þ­1üÅþÐô(`H û) ðùh$þ`X©�…ø Âù �¥ ü¦ø•ù© üˆÐý­ üj°ú*…þ‰ð©€é¥ Í üÐÕ© „û¢ û ˜ù¢� ©à ü˜Ðý­ ü…þ,ü©Ð üÐýL£ù­ü� èÐî„û­ üj@­ü �@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�� Âù©¬…â©ÿ…ã ±à…äȱà…åµñ°ÿ©ÊÿµñÉðœÊÿÉð ©`Lr÷ÆèÐ ÿ…èªð&¥â…æ¥ã…ç¥æ…â¥ç…ã ÿ¨ðÞ ÿ’äæäÐæåˆÐõ€ê ÿ…ô ÿ…ó ÿ…õ ÿ…ö ÿ…÷¦øtùdû¥ô bÿ´ñµù’ä qÿˆÐö¥ó bÿ´ñ¥û’ä qÿˆÐö¥õ bÿ´ñ¢�˜J…銒äÅé°eé€åéª qÿˆÐë© -…ý éùŠÐ©X¦ø´ùЩ¢é ýLüþ©e°@$œü¢Õ þ ˜ù¢� ±àÛþȱàÜþ©…ì ôŒ ü„ÿÅìðü £ù­ ü…þ‰ÐˉÀð -Æýà ±ùLr÷¥û¦øÕí°…ûL‰ýdûµùÕï°•ù€ð Âùtù©¢Y þLüþ©e°udû¦øµù ü éùdü©…ý¥üü¢ñ þ ˜ù¦û½ý ‚¨¢�©…ìŒ ü„ÿÅìðüÚ £ùhÐ3­ ü‰ÐωØð ÆýÇ ±ù€%æü¥ü¦øÕñ¸æû¥ûÕí§µùÕï° -•ù©X€†©P€©�Lr÷Í üмÿÿèÐîÜþŒü¬ üÀÐ@dì@Í üÐø,üè€ê†ê„ëdì® ü†þ¢B ÿ 3톢„£…ÿ ü©ª¨:ÐÊÐ ˆÐ ©Ð ü©¿…ììðê :í(°$þ ˆÿlê�H­ üj°*‰ð…þÆì€æì©*…¢©í…£hL-í qà…äȱài�…å`¥öeä…ä¥÷eå…å`²âæâÐæã`¢©8¬hçÈÈÈÌhçð, üðöÌhçð , üÐöÊÐé` N� �õþª÷N �õûþÿû�÷,N�úNúNúN–N��012hÿÉ Ð© - îÿ© L†íLÿíL]ð���í�è@í \ No newline at end of file + ±® 8ñ®…ª ±®é�…­ ±®…¬  ±®8å­…«`†à„á �±àð ©e’à¢à �` ±àJJJJJÉ°êé…øª ±àðOÉðKÉ +ðGÉ -É°)à°Ï ±à)ð•íÉ°ȱà•ñȱà•ï ±àɯð +LýŠ0©`€¡LGþLöù¦øµ + ¨ù€’  +±àÐä  ±à…õÐ: ±àÐÖˆ±àÐш±à…õˆ±àðæõðÃÚª ±àÚ÷È±à  qàÛ÷žÿÿèÐúú  ¥õ‘àŠ0© ±àð¦È±à)…÷ȱà…öȱà…ü �¦øµíjµñ° +…ûÈ¥ü8åû…ü¥öé�…ö¥÷é�…÷°êˆ¥üeû…ü˜Õï©aL0÷ Àù”ù ±à…öȱà…÷©ÀÅ Ðú©ðÅ¡Ðô© +…ýµùü©¢g ø(ðLöþkÆýðg¢U ø©€í¦øµùÍ üÐÑ© +…ý©½}ù¥÷Щ©}ù©�~ù©êù€ùoù¥ö~ùnù¥ü¦øÕñõñüÍüÐø ±àÉ +Щ¢¢w ù€©Ð ü šùL.÷€”©‚¢d ùH ùdû¦ø¥üÕñæûh H çù¢� „ìh ü©d¥d¦…§ Yùð¿Äìð÷ šù Yùð³­ üj°õ +‰І‰@Љð +Æý§ ¨ùL0÷Æõð'æü¦øµíjµñ° +ÅüÐdüöù¥÷ðæ÷LwøÆ¥ÐƦÐƧ`HÌ üÐ ­üÿÿèÐdìh@HÌ üÐö½ÿÿèüðí­ üÉÐæh@x íŽúÿŒûÿ`¢é ìŽúÿŒûÿXLí‰ð©P`‰@ð©ÿ`‰ð©H`©�`¦ø¥¤)è�ý…¤ü­ üj©Ð üÐýµù üÍ üÐî`¦û¥¤)ûý…¤ü`© +…ý©S0üœ3üÍ0üÐ ©¥0üœ3üÍ0üð©eL0÷ ?úðøÉ%ðòÉeðîÉРHh:ÐûÊÐøˆÐõ©ÆýÜ€× nûȱà…öȱà…÷ ±à Ñúȱà)€ȱà Ñú ¶ûPó ±à)ýIð# ¶ûP8 � ¶û0f°±ö0ü€­0ü‘öÈÐêæ÷€æ �¥÷ð% §û) ðù$þ0@p ±ö0üÈÐøæ÷€ç­0ü‘öÈÐøæ÷€Û §û) ðù$þ0pçœ0ü€î ¶ûp 0ü©@:Ðý(©�`hh ¶û­0üêê ¶û¨ §û)ð¥þ)ð瘮0üÐ ª)ÉðŠ)`©ÿ€ù¢�ÊÐý nû© Ñú Ñú Ñú Ñú© Ñú Ñúª ¶û0­0üà à Ð +¢�É�Ð¥ä•âè€ã ±à)àã ¶û¦â­0ü ¶û¬0üШ)ФŠ€ž ±àJJJJJ¨¹£ûH §û)ð,0ü€ôh0ü2ü � §û)ð �`ˆÐóhh©e`­1ü…þ­1üÅþÐô(`H §û) Ð¥þ)Ðóh$þ`ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�� Àù©§…â©ÿ…ã ±à…äȱà…åµñ«ÿ©ÅÿµñÉðœÅÿÉð ©`L0÷ÆèÐ zÿ…èªð&¥â…æ¥ã…ç¥æ…â¥ç…ã zÿ¨ðÞ zÿ’äæäÐæåˆÐõ€ê zÿ…ô zÿ…ó zÿ…õ zÿ…ö zÿ…÷¦øtùdû¥ô ]ÿ´ñµù’ä lÿˆÐö¥ó ]ÿ´ñ¥û’ä lÿˆÐö¥õ ]ÿ´ñ¢�˜J…銒äÅé°eé€åéª lÿˆÐë© +…ý çùŠÐ©X¦ø´ùЩ¢é ýLöþ©e°<$œü¢Ï þ ù¢� ±àÕþȱàÖþ©…ì ôŒ üÅìðü šù­ ü‰ÐωÀð +ÆýÇ ¨ùL0÷¥û¦øÕí°…ûL‰ýdûµùÕï°•ù€ð Àùtù©¢U þLöþ©e°sdû¦øµù ü çùdü©…ý¥üü¢ë þ ù¦û½ý ‚¨¢�©…ìŒ üÅìðüÚ šùhÐ3­ ü‰ÐщØð ÆýÉ ¨ù€%æü¥ü¦øÕñºæû¥ûÕí©µùÕï° +•ù©X€ˆ©P€©�L0÷Í üмÿÿèÐîÖþŒü¬ üÀÐ@dì@Í üÐø,üè€ê†ê„ëdì® ü†þ¢: ÿ 톢„£ ü©ª¨:ÐÊÐ ˆÐ ©Ð ü©¿…ììðê í(°$þ ƒÿlê�H­ üj°*¤ø™ +�‰ðÆì€æì©…¢©í…£hLí qà…äȱài�…å`¥öeä…ä¥÷eå…å`²âæâÐæã`¢©8¬hçÈÈÈÌhçð, üðöÌhçð , üÐöÊÐé` N� �õþª÷N �õûþÿû�÷,N�úNúNúN–N��012hÿÿÿÿÿÿÉ Ð© + îÿ© LTíLÍíL-ð���éì�èí \ No newline at end of file diff --git a/FileStore/Binary Files/MOS-33Fp b/FileStore/Binary Files/MOS-33Fp new file mode 100644 index 0000000..16079ec --- /dev/null +++ b/FileStore/Binary Files/MOS-33Fp @@ -0,0 +1,39 @@ +±V…‰ÎeÎf¥‰Ð ¥ˆe¥‡f€º ¶Vк­fmcc­embbîaæ‡ÐæˆÆ‰€Ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,$ü©€ü¢�½��½��½��½��½��½��½��½� � ½� +� +½� � ½� � ½� � ½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½��½� � ½�!�!½�"�"½�#�#½�$�$½�%�%½�&�&½�'�'½�(�(½�)�)½�*�*½�+�+½�,�,½�-�-½�.�.½�/�/½�0�0½�1�1½�2�2½�3�3½�4�4½�5�5½�6�6½�7�7½�8�8½�9�9½�:�:½�;�;½�<�<½�=�=½�>�>½�?�?½�@�@½�A�A½�B�B½�C�C½�D�D½�E�E½�F�F½�G�G½�H�H½�I�I½�J�J½�K�K½�L�L½�M�M½�N�N½�O�O½�P�P½�Q�Q½�R�R½�S�S½�T�T½�U�U½�V�V½�W�W½�X�X½�Y�Y½�Z�Z½�[�[½�\�\½�]�]½�^�^½�_�_½�`�`½�a�a½�b�b½�c�c½�d�d½�e�e½�f�f½�g�g½�h�h½�i�i½�j�j½�k�k½�l�l½�m�m½�n�n½�o�o½�p�p½�q�q½�r�r½�s�s½�t�t½�u�u½�v�v½�w�w½�x�x½�y�y½�z�z½�{�{½�|�|½�}�}½�~�~½��½�è�è½�é�é½�ê�ê½�ë�ë½�ì�ì½�í�í½�î�î½�ï�ï½�ð�ð½�ñ�ñ½�ò�ò½�ó�ó½�ô�ô½�õ�õ½�ö�ö½�÷�÷½�ø�ø½�ù�ù½�ú�ú½�û�û½�ý�ý½�þ�þ½�ÿ�ÿÊðL +è,ü©›üÿ©ëýÿ,$üxØ¢ÿš©ˆü© +�ü©&ü© �ü©ü©�ü­ü…Ô©�ü­ü¢€Žü8eÔð©þ…ÔdÕœüœü©üü Íì µì¢�ž�æž�çÊÐ÷©>…©€…œ¥Ômç¢Ø©ˆæÊÐú©À… ©ð…¡©(…©ü…©…¢©í…£©àü©Àü©:Ðý©à…¤ü, ü©P…ù…ú…ï…ð©…í…î©…ñ…ò,(üX¢�½Oíð îÿèÐõd ­¬ì÷ÿ¢²Žøÿ¢ìŽùÿÍ�ð"d­fçj¥¤) €…¤ü¥ ðë ¯ìd ¥ž…€à­hçÉùL�l ææ `©Á ü©#üœ!ü©‚ ü©g!ü`©à ü©2:Ðý­!ü‰ ð +­ü) Àü`Î�,$ü, ü HZl �„¡… zhl¢�, üî�Ò@Î�,$ü`î�Ò`H©@,üð$ÚZüü¥…ž®æà ° … Lí¥ Ð¥ž…zú …ï §íh@|øó �?Ú®oçìnçÐ H­üjjh°òpç ŸíŽoç­üjj°'ìnçð"©ÿü­ü)ð +ü©ü©‚ü®nç½pçüú`èà¢�`Ú©,üðî,üðélç®nç ŸíŽnçìoçÐÒüü€Ð†Ð„ÑÉÐy$œ0©�’Ð`¢À �†¨„©  ±Ð‘¨ˆù©€ÀLô²ÐÉÐQ©À �…¨„©i…Ä„Å…È„ÉdÌdÍdÏdÁ ±Ð…ÂȱЅÃȱÐð%É ð!$œü…΢�©……ÀÚZ ôzú¥À0üðÞHhÐûèÐç`Éð¤ÉÐC²ÐªÐ)©‰ æ…΄Ïè²ÎðÉЊ’ÐæÐÐæÑ  ±Ð‘Έù` ´ð€ß Aðð �±ÎÈ‘ÐÀ ÷©’Î`ÉÐE �±ÐÈÉбЅ`ÉÐé±Ðmç¢ ðIÿè ð`ÉÐ ²Ðªx ûïX ‘Ð`ÉÐòЪ ±Ðx ðX`ÉrÐ%L$÷ÉÐ  �¹gç‘ÐÈÀö`ÉР�±Ð™gçÈÀö`ÉðcÉÐÖx¢ ûï € ð �±Ð)à… ±Ð)¢ ðȱÐJJJ J8é°id¢ ð±Ð)Ê ðȱТ ðȱТ ðȱТ� ð¢ ûï)  ðX`®fç ¹bç‘ЈøìfçÐî`Ú¢ ûïl©ÀÅ Ðf©ðÅ¡Ð`¢ ûïbç¢ ûï8éQ°id +… + + +cç¥ )à bçÊ ûï cç¢ ûïdç¢ ûïeç¢� ûïfç­gçidgçîhçÐ îiçÐîjçÐîkçú` ðŽ�ü­ü€ ðŽ�üüH¥¤)÷ü…¤ íh`H í¥¤ ü…¤h`É2Ð ×ì �±¨ª`É3Ð ×쩉 æ…΄ϲÎðÊЪ` ´ð€òÉ4Ð + Aðð©’Î`É€Ð.ŠÐ ,,ü0P `àüÐé­lçð­nç8íoçÐ ­üjj©�°iª`ɄТ� æ`ɉЊj¥¤) €ü…¤`© eÎ…ÎæÏ`dœ©,!üð7­"üÅÔð ÉÿЩ@�æ©ÞLûì,!ü­"üð Iÿð ©¢ üL ó�æ…ª©þLû쀭!ü)ð Íì µìL óL󤪭!üæ­"ü™�È­!ü0Э"ü™�ÈÀ ð +„ª­!üÐÞLýìœ ü©„!ü©,!üð´²­"ü™�©D ü¥“ÐL?ó,�æP©!ü©‰ æ…®„¯ �±®ð,ÉÐȱ®ðÅ“Ðȱ®ðÅРȱ®ðÅ‘ð¥®i …®Ò毀΀P ÷,�æPL󩸠ñLtò©‚ ü©ÂLûì©,!üð-­"üÅÔÐ&©ÕLûì,!ü­"üÐ, ü0©éLûì,!ü­"ü­"ü€­�æLèö µìLó, ü0© òLù줪­!ü-­"ü‘¬ÈÐæ­Æ«ðÑ­!ü0Э"ü‘¬È„ªÐæ­Æ«ð­!üÐÔLýìœ ü©„!ü„ª©,!ü𡥫ð›­"ü¤ª‘¬æªÐæ­­�æLäö©Ì òæŒæ©D ü©§!ü¥, üP>"ü¥‘"ü¥Ô, ü0 ©¡ òLùì¥Ô, üP!"ü©�,�æ0 /Œ!ü#ü­æ¬æLùì"üL2öLöñ¥“Ð ¤’À‚ðLÒó¥ªe¬æ­ ‘®È¥­‘®¥“𥑠‘®ˆ¥‘®ˆ¥“‘®ˆ¥’ €‘® Âì­mç…Ô©€…œ©À ðLùìÚ¢¤ªµ‘¬ÈÐæ­Æ«ð +脪à Ðìú€¤æªà ð÷úLöñ¤’À÷À‰°óÀ‡° ˜8騥jˆü°¬Ú¥’*ª|aó°ó’ósósósóÀóÀóžó©‚…ª©…«©‰…¬©å…­ ¹”�™æˆ÷úL±ñ©…®©�…¯úL¦ñ©…«©ü…ª©T…¬©ì…­€ ©…®©�…¯ ÷©€ �æú©D ü©§!ü©ä óLtò¥ªi€æ¥ 楑 +楒*æ©Àüü©üœüLóô ô ô ôôlæ`©ŸÐX$ŸÐü`©Ÿ`dœÚ ±¨…Òȱ¨…Ó �±¨0L·ô…֪ȱ¨…×Ð3àƒ°8 ±¨ˆˆˆˆ(ñ¨™Ø�ÈÈÈÈÈÀ ê(àVà‰°R  ±¨™Ì�ÈÀö© ,!üÐL©þ…¥©æœæd¦d§ ç©x í,!üð­ ü©g!ü©, üÐ. í(æ§ÐÝæ¦ÐÙæ¥ÐÕ€©D€©!ü©@€ ×ì©C �‘¨©€…œú`Œ!ü¢DŽ ü¢T õ† „¡ í¥×Ð9¥Ö +ª½ðö�æ½ïöæ|ûô õ õFõFõFõQõQõFõ  ¹Ð�(q¨™Ð�ÈÀñ(€#¥Ò%ÓÉÿЩæ©@�æ ±¨™Ô�ÈÀ ö€œ�楨…®¥©…¯ ÷(ú`¬æ, üP"¹Ò�"üȹÒ�ÈŒæ"üÌæ°, ü0ãLýì©B€©g!ü©A¤ÔHhÈÐûLêö©?!ü©™Lûì©‚ ü,�æPLäö©,�æðLöLèö©¸Lûì©,!üð»­"üÅÔÐê©ËLûì,!üà­"üÐÛ, ü0©ßLûì,!üÌ­"üÅÒÐÅ­"üÅÓо©,!ü𷩧!ü©D ü© öæŒæ¥Ò, üP0"ü¥Ó"ü©# öLùì¥Ô, üP"ü©�"ü©9 öLù줪Ð¥«ð+, üPA±¬"üÈÐÆ«ðæ­±¬"üÈ„ªÐÆ«ð +æ­, ü0ÛLýì©?!ü­�æ©{LûìLó­æ¬æLùì­�æ\Ló©‚ ü©› öLùì©,!üðF­"üÅÔÐ?©®Lûì,!ü5­"üÐ0, ü0©ÂLûì,!ü!­"üÅÒЭ"üÅÓЭ�æLò©,!üð©�€©A �‘¨Ló� +� +� +� + ±® 8ñ®…ª ±®é�…­ ±®…¬  ±®8å­…«`†à„á �±àð ©e’à¢à �` ±àJJJJJÉ°êé…øª ±àðOÉðKÉ +ðGÉ -É°)à°Ï ±à)ð•íÉ°ȱà•ñȱà•ï ±àɯð +LýŠ0©`€¡LGþLöù¦øµ + ¨ù€’  +±àÐä  ±à…õÐ: ±àÐÖˆ±àÐш±à…õˆ±àðæõðÃÚª ±àÚ÷È±à  qàÛ÷žÿÿèÐúú  ¥õ‘àŠ0© ±àð¦È±à)…÷ȱà…öȱà…ü �¦øµíjµñ° +…ûÈ¥ü8åû…ü¥öé�…ö¥÷é�…÷°êˆ¥üeû…ü˜Õï©aL0÷ Àù”ù ±à…öȱà…÷©ÀÅ Ðú©ðÅ¡Ðô© +…ýµùü©¢g ø(ðLöþkÆýðg¢U ø©€í¦øµùÍ üÐÑ© +…ý©½}ù¥÷Щ©}ù©�~ù©êù€ùoù¥ö~ùnù¥ü¦øÕñõñüÍüÐø ±àÉ +Щ¢¢w ù€©Ð ü šùL.÷€”©‚¢d ùH ùdû¦ø¥üÕñæûh H çù¢� „ìh ü©d¥d¦…§ Yùð¿Äìð÷ šù Yùð³­ üj°õ +‰І‰@Љð +Æý§ ¨ùL0÷Æõð'æü¦øµíjµñ° +ÅüÐdüöù¥÷ðæ÷LwøÆ¥ÐƦÐƧ`HÌ üÐ ­üÿÿèÐdìh@HÌ üÐö½ÿÿèüðí­ üÉÐæh@x íŽúÿŒûÿ`¢é ìŽúÿŒûÿXLí‰ð©P`‰@ð©ÿ`‰ð©H`©�`¦ø¥¤)è�ý…¤ü­ üj©Ð üÐýµù üÍ üÐî`¦û¥¤)ûý…¤ü`© +…ý©S0üœ3üÍ0üÐ ©¥0üœ3üÍ0üð©eL0÷ ?úðøÉ%ðòÉeðîÉРHh:ÐûÊÐøˆÐõ©ÆýÜ€× nûȱà…öȱà…÷ ±à Ñúȱà)€ȱà Ñú ¶ûPó ±à)ýIð# ¶ûP8 � ¶û0f°±ö0ü€­0ü‘öÈÐêæ÷€æ �¥÷ð% §û) ðù$þ0@p ±ö0üÈÐøæ÷€ç­0ü‘öÈÐøæ÷€Û §û) ðù$þ0pçœ0ü€î ¶ûp 0ü©@:Ðý(©�`hh ¶û­0üêê ¶û¨ §û)ð¥þ)ð瘮0üÐ ª)ÉðŠ)`©ÿ€ù¢�ÊÐý nû© Ñú Ñú Ñú Ñú© Ñú Ñúª ¶û0­0üà à Ð +¢�É�Ð¥ä•âè€ã ±à)àã ¶û¦â­0ü ¶û¬0üШ)ФŠ€ž ±àJJJJJ¨¹£ûH §û)ð,0ü€ôh0ü2ü � §û)ð �`ˆÐóhh©e`­1ü…þ­1üÅþÐô(`H §û) Ð¥þ)Ðóh$þ`ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�� Àù©§…â©ÿ…ã ±à…äȱà…åµñ«ÿ©ÅÿµñÉðœÅÿÉð ©`L0÷ÆèÐ zÿ…èªð&¥â…æ¥ã…ç¥æ…â¥ç…ã zÿ¨ðÞ zÿ’äæäÐæåˆÐõ€ê zÿ…ô zÿ…ó zÿ…õ zÿ…ö zÿ…÷¦øtùdû¥ô ]ÿ´ñµù’ä lÿˆÐö¥ó ]ÿ´ñ¥û’ä lÿˆÐö¥õ ]ÿ´ñ¢�˜J…銒äÅé°eé€åéª lÿˆÐë© +…ý çùŠÐ©X¦ø´ùЩ¢é ýLöþ©e°<$œü¢Ï þ ù¢� ±àÕþȱàÖþ©…ì ôŒ üÅìðü šù­ ü‰ÐωÀð +ÆýÇ ¨ùL0÷¥û¦øÕí°…ûL‰ýdûµùÕï°•ù€ð Àùtù©¢U þLöþ©e°sdû¦øµù ü çùdü©…ý¥üü¢ë þ ù¦û½ý ‚¨¢�©…ìŒ üÅìðüÚ šùhÐ3­ ü‰ÐщØð ÆýÉ ¨ù€%æü¥ü¦øÕñºæû¥ûÕí©µùÕï° +•ù©X€ˆ©P€©�L0÷Í üмÿÿèÐîÖþŒü¬ üÀÐ@dì@Í üÐø,üè€ê†ê„ëdì® ü†þ¢: ÿ 톢„£ ü©ª¨:ÐÊÐ ˆÐ ©Ð ü©¿…ììðê í(°$þ ƒÿlê�H­ üj°*¤ø™ +�‰ðÆì€æì©…¢©í…£hLí qà…äȱài�…å`¥öeä…ä¥÷eå…å`²âæâÐæã`¢©8¬hçÈÈÈÌhçð, üðöÌhçð , üÐöÊÐé` N� �õþª÷N �õûþÿû�÷,N�úNúNúN–N��012hÿÿÿÿÿÿÉ Ð© + îÿ© LTíLÍíL-ð���éì�èí \ No newline at end of file diff --git a/FileStore/Binary Files/Original Binary/E01 v1.23 FS 0254-205-04.rom b/FileStore/Binary Files/Original Binary/E01 v1.23 FS 0254-205-04.rom deleted file mode 100644 index cbfc604..0000000 Binary files a/FileStore/Binary Files/Original Binary/E01 v1.23 FS 0254-205-04.rom and /dev/null differ diff --git a/FileStore/Binary Files/Original Binary/labels.jpeg b/FileStore/Binary Files/Original Binary/labels.jpeg deleted file mode 100644 index ef62899..0000000 Binary files a/FileStore/Binary Files/Original Binary/labels.jpeg and /dev/null differ diff --git a/FileStore/SRC/!BOOT b/FileStore/SRC/!BOOT deleted file mode 100644 index 48ed794..0000000 --- a/FileStore/SRC/!BOOT +++ /dev/null @@ -1 +0,0 @@ -MODE0 *LIB $.LIBRARY *DIR FILESTORE *E. FSASM \ No newline at end of file diff --git a/FileStore/SRC/!BOOT.inf b/FileStore/SRC/!BOOT.inf deleted file mode 100644 index 2deb692..0000000 --- a/FileStore/SRC/!BOOT.inf +++ /dev/null @@ -1 +0,0 @@ -$.!BOOT 00000000 00000000 0000002E 33 diff --git a/FileStore/SRC/FS/!BOOT b/FileStore/SRC/FS/!BOOT new file mode 100644 index 0000000..b3a539c --- /dev/null +++ b/FileStore/SRC/FS/!BOOT @@ -0,0 +1 @@ +MODE0 *DIR $ *LIB LIBRARY *EXEC FSASM \ No newline at end of file diff --git a/FileStore/SRC/FS/!BOOT.inf b/FileStore/SRC/FS/!BOOT.inf new file mode 100644 index 0000000..b5aa9cc --- /dev/null +++ b/FileStore/SRC/FS/!BOOT.inf @@ -0,0 +1 @@ +$.!BOOT 00000000 00000000 00000026 19 A341 271B11 A341 271B0F diff --git a/FileStore/SRC/FS/FSASM b/FileStore/SRC/FS/FSASM new file mode 100644 index 0000000..f221712 --- /dev/null +++ b/FileStore/SRC/FS/FSASM @@ -0,0 +1 @@ +*|Assembly sequence for FileStore FS > FSAsm *|By Jes 3/9/84, Updated by Glenn 8/5/85 *|Updated by Mark Usher 7/4/21 *DIR $.FileStore *LIB $.LIBRARY *TurMasm *OPT 1 1 STOP ON ASM UADE01 *CB CH."FSmake" \ No newline at end of file diff --git a/FileStore/SRC/FS/FSASM.inf b/FileStore/SRC/FS/FSASM.inf new file mode 100644 index 0000000..a6508cd --- /dev/null +++ b/FileStore/SRC/FS/FSASM.inf @@ -0,0 +1 @@ +$.FSASM 00000000 00000000 000000CC 19 A341 271B11 A341 271B0F diff --git a/FileStore/SRC/FS/FileStore/FSmake b/FileStore/SRC/FS/FileStore/FSmake new file mode 100644 index 0000000..f2a0825 Binary files /dev/null and b/FileStore/SRC/FS/FileStore/FSmake differ diff --git a/FileStore/SRC/FS/FileStore/FSmake.inf b/FileStore/SRC/FS/FileStore/FSmake.inf new file mode 100644 index 0000000..7dfb973 --- /dev/null +++ b/FileStore/SRC/FS/FileStore/FSmake.inf @@ -0,0 +1 @@ +$.FSmake 00000800 0000B823 00000675 33 A548 2B0C0C A24D 331317 diff --git a/FileStore/SRC/FS/FileStore/Form00 b/FileStore/SRC/FS/FileStore/Form00 new file mode 100644 index 0000000..9b97190 --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Form00 @@ -0,0 +1,607 @@ + OPT Form00 ;File > Form00 + TTL File server file FORM00 + +;********** +;* FORMAT * +;********** + +; FORMAT <discnumber> <discname> command (Command mode 1 only) +; formats a floppy disc as an empty fileserver disc. + +Fimptr * Mpscpt ;Reuse normal workspace +Fgpptr * Mpmbpt +Fgprpt * Mapent + +FMform ROUT + JSR NMdisr ;**22/5/88** read disc no & name + CMPIM 4 ;First allowed disc number (one digit) + BCC #03 + STA Drivno ;Save for later + LSRA ;Put drive number into dscb + RORA + RORA + RORA + STA Dsccb+Cmd+1 + + JSR FMackn ;reply to caller now, lest he time out + + LDAIM &0F ;Format command + STA Dsccb+Cmd + LDAIM FDside ;Disc manifests - number of sides + TSB Dsccb+Cmd+1 + LDAIM FDsecs + STA Dsccb+Cmd+2 + LDAIM FDcyls + STA Dsccb+Cmd+3 + STZ Dsccb+Cmd+4 + STZ Dsccb+Cmd+5 + JSR Dsccmd ;Format disc + BEQ #05 ;Br if Ok so far + JMP #50 ;Else report error + +03 LDAIM Numerr ;Bad disc number + JMP Error + + +; Now have the disc in the state where every sector looks like the bitmap +; for an empty track. Only the first sector of each cylinder is actually +; used for this purpose however. Next we write a number of other sector +; images to initialise the disc as a AFS0 disc. It is also made to look like +; a full and rather small ADFS disc lest it ever be put in the wrong drives. + +; The required sector images are held at FMmaps in a compacted format: +; +; <number of sectors in next image - zero indicates all done> +; <sector number (two bytes)> +; +; <-ve count -1 - -128 is group repeat> | followed by grp as below +; | omitted unless grp used +; +; <number of bytes of data following 1-127> | +; <data bytes as just specified> | +; +; <offset to next data group> | +; +; <length zero terminates> + +05 LDXIM :LSB:FMmaps ;set up to process list of compacted sector images + LDYIM :MSB:FMmaps + STX Fimptr + STY Fimptr+1 + JSR Getdte ;Read date/time + LDA Date + STA FMdat1 + STA FMdat2 + STA FMdat3 + LDA Date+1 + STA FMdat1+1 + STA FMdat2+1 + STA FMdat3+1 + LDXIM Dnamln-1 ;Now build disc names +06 LDAAX Txtbuf + STAAX FMdnm1 + STAAX FMdnm2 + DEX + BPL #06 +10 LDX Freptr ;get address of work buffer + LDY Freptr+1 + STX Fgpptr ;set up to build next sector group + STY Fgpptr+1 + STX DSCCB+TRadd ;save in DSCB + STY DSCCB+TRadd+1 + STZ DSCCB+TRadd+2 + STZ DSCCB+TRadd+3 + JSR #95 ;get number of sectors + BEQ #24 ;go exit if all done + STA DSCCB+CMD+4 ;else set sector count in DSCB +12 PHA + LDXIM 0 + LDAIM 0 ;zero out sector group initially +15 JSR #90 + DEX + BNE #15 + PLA + DECA + BNE #12 + LDX Freptr ;restore start pointer + STX Fgpptr + LDY Freptr+1 + STY Fgpptr+1 + JSR #95 ;get sector address + STA DSCCB+CMD+3 + JSR #95 + STA DSCCB+CMD+2 + LDA Drivno + ASLA + ASLA + ASLA + ASLA + ASLA + STA DSCCB+CMD+1 ;drive number +20 LDYIM :LSB:-1 ;default group repeat +22 JSR #95 ;next string length + TAX + BEQ #35 ;br if end of sector group + BPL #25 ;br unless repeat group item + TAY ;save (-ve) group repeat count + LDA Fimptr ;prepare to reread group + STA Fgprpt + LDA Fimptr+1 + STA Fgprpt+1 + BRA #22 + +24 BRA FMvok ;done, go say OK + +25 JSR #95 ;copy string to sector image + JSR #90 + DEX + BNE #25 + INY + BEQ #30 ;br if no more group repeat + LDA Fgprpt ;yes, reset source ptr + STA Fimptr + LDA Fgprpt+1 + STA Fimptr+1 + BRA #22 + +30 JSR #95 ;get offset to next string + CLC + ADC Fgpptr + STA Fgpptr + BCC #20 ;br unless wraps sector + INC Fgpptr+1 + BRA #20 + +35 LDAIM &0A ;write function code + STA DSCCB+CMD + STZ DSCCB+CMD+5 + JSR Dsccmd + BNE #50 + JMP #10 ;if ok, onto next sector group + +FMVerr +50 JSR Looker ;put error msg at MIDTX +55 LDA CBstid ;copy caller station + STA Txbuf + LDA CBstid+1 ;and net + STA Txbuf+1 + LDA TXbuf-1 ;borrow a byte + PHA + LDAIM 1 + STA TXbuf-1 + LDXIM :LSB:(Txbuf-1) + LDYIM :MSB:(Txbuf-1) + LDAIM &14 + JSR OSword ;NOTIFY caller of error + PLA + STA TXbuf-1 ;restore borrowed byte + JMP Comrts ;'cos original request long since timed out + +FMVok + LDAIM "O" + STA Midtx + LDAIM "K" + STA Midtx+1 + LDAIM CR + STA Midtx+2 + LDA Drivno ;seek disc to home + JSR Rddata ;(a good a way as any - ignore errors) + BRA #55 + +; Routine to store value in constructed image & step ptr + +90 STAI Fgpptr ;store value in image + INC Fgpptr ;and increment pointer + BNE #92 + INC Fgpptr+1 +92 RTS + +; Routine to get value from compacted image & step ptr + +95 LDAI Fimptr ;get value from compacted image + INC Fimptr ;and increment pointer + BNE #99 + INC Fimptr+1 +99 CMPIM 0 ;reset cc from A + RTS + +; Routine to acknowledge good syntax at least to caller. Can't keep +; him waiting until command complete, because the ECOnet request will +; time out. +; +; Side effect - set store address in disc CB. + +FMackm = "Please wait...",CR,&80 + +FMackn ROUT + LDXIM 0 ;copy text +10 LDAAX FMackm + STAAX Midtx + INX + CMPIM &80 + BNE #10 + TXA + CLC + ADCIM Txhdr + LDXIM CCinf ;reply as no-error text + STX Ccode + JSR Replyc + + LDA Freptr ;Set store address to free store + STA Dsccb+Tradd + LDA Freptr+1 + STA Dsccb+Tradd+1 + STZ Dsccb+Tradd+2 + STZ Dsccb+Tradd+3 + RTS + +; Compacted sector images + +FMmaps ROUT + = 1 + & 0 ;cylinder 0 sector 0 has first disc info ptr; also ADFS free map + = 1, FDsecs*FDside ;ADFS free space - cylinder 1 + = Szoff-1 ;offset + = 1, FDsecs*FDside-2 ;first disc info sector + = 5 ;offset to 252 + = 1, FDsecs*FDside ;ADFS disc size (1 cylinder!) + = 2 ;offset to checksum + = 1, FDsecs*FDside+FDsecs*FDside-2+FDsecs*FDside ;checksum + = 0,0 ;end sector + + = 1 + & 1 ;cylinder 0 sector 1 has second disc info ptr; also ADFS free sizes + [ FDside = 1 + = 1,FDsecs-9 ;ADFS free length + | + = 1,FDsecs-7 ;ADFS free length + ] + = Szoff-1 ;offset + = 1, FDsecs*FDside-1 ;second disc info sector + = 8 ;offset + [ FDside = 1 + = 1, FDsecs*FDside-9+FDsecs*FDside-1 ;checksum + | + = 1, FDsecs*FDside-7+FDsecs*FDside-1 ;checksum + ] + = 0,0 ;end sector + + = 5 + & 2 ;cylinder 0 sectors 2-6 have ADFS root directory + = 5,0,"Hugo" ;Master sequence + dir id + = 250,1,0 ;5-&FF + = 255,1,0 ;&100-&1FF + = 255,1,0 ;&200-&2FF + = 255,1,0 ;&300-&3FF + = &CC,2,"$",CR ;Directory name + = 9,1,2 ;Parent pointer + = 3,2,"$",CR ;Directory title + = 32,4,"Hugo" ;Dir id + = 0,0 ;end sectors + + = 1 + & FDsecs*FDside-2 ;cylinder 0 sector last-2 has 1st disc info + = #20-#10 ;length of all next guff +10 = "AFS0" +FMdnm1 = "Fileserver disc0" ;overwritten by users name + & FDcyls ;cylinders per disc + & FDsecs*FDside*FDcyls ;sectors per disc + = 0 ;... continued + = 1 ;number of discs +FMsecs & FDsecs*FDside ;sectors per cylinder + = 2 ;size of bitmap in sectors per cylinder + = 1 ;addition for next physical drive + = 1 ;increment for next logical drive + & FDsecs*FDside+2 ;sin of root directory ... + = 0 ;...continued +FMdat1 & 0 ;overwritten by date of root + & 1 ;first cylinder of free space + = (FDsecs*FDside+7)/8 ;bytes per cylinder bitmap +20 = 0,0 ;end sector + + = 1 + & FDsecs*FDside-1 ;cylinder 0 sector last-1 has 2nd disc info + = #40-#30 ;length of all next guff +30 = "AFS0" +FMdnm2 = "Fileserver disc0" ;overwritten by users name + & FDcyls ;cylinders per disc + & FDsecs*FDside*FDcyls ;sectors per disc + = 0 ;... continued + = 1 ;number of discs + & FDsecs*FDside ;sectors per cylinder + = 2 ;size of bitmap in sectors per cylinder + = 1 ;addition for next physical drive + = 1 ;increment for next logical drive + & FDsecs*FDside+2 ;sin of root directory ... + = 0 ;...continued +FMdat2 & 0 ;overwritten by date of root + & 1 ;first cylinder of free space + = (FDsecs*FDside+7)/8 ;bytes per cylinder bitmap +40 = 0,0 ;end sector + + + = 2 + & FDsecs*FDside ;cylinder 1 sectors 0-1 have bit map + GBLA $Mbend ;bitmap in last byte + GBLA $Mbens ;max packed maps per sector + GBLA $Mbits ;map counter + GBLA $Mbyte ;bytes per cylinder bitmap + GBLA $Mbcnt ;packed maps in current sector + GBLA $Mbsec ;sector sizer + GBLA $Mbtot ;total packed maps to go +$Mbyte SETA (FDsecs*FDside+7)/8 ;bytes per cylinder bitmap +$Mbtot SETA FDcyls + WHILE $Mbtot > 0 ;loop to fill all sectors +$Mbsec SETA 256 +$Mbens SETA 256/$Mbyte ;max bitmap sets per sector + [ $Mbtot = FDcyls ;if first sector + = $Mbyte*2 ;special for first two cylinders +$Mbits SETA $Mbyte + WHILE $Mbits > 0 + = &00 +$Mbits SETA $Mbits-1 + WEND + = &80 ;first seven sectors used +$Mbits SETA FDside*FDsecs-8 + WHILE $Mbits > 7 + = &FF ;all sectors free +$Mbits SETA $Mbits-8 + WEND +$Mbend SETA 0 + WHILE $Mbits > 0 +$Mbend SETA $Mbend+$Mbend+1 ;calculate any final map byte +$Mbits SETA $Mbits-1 + WEND + [ $Mbend > 0 + = $Mbend ;last few sectors on cylinder + ] + = 0 ;offset to main group +$Mbens SETA $Mbens-2 +$Mbsec SETA $Mbsec-$Mbyte-$Mbyte +$Mbtot SETA $Mbtot-2 + ] +$Mbcnt SETA $Mbtot + [ $Mbcnt > $Mbens +$Mbcnt SETA $Mbens ;calculate bitmap blocks in this cylinder + ] + = -$Mbcnt ;group repeat count + = $Mbyte ;group length +$Mbits SETA FDside*FDsecs + WHILE $Mbits > 7 + = &FF ;all sectors free +$Mbits SETA $Mbits-8 + WEND + [ $Mbend > 0 + = $Mbend ;last few sectors on cylinder + ] + = $Mbsec-($Mbcnt*$Mbyte) ;offset to end of sector +$Mbtot SETA $Mbtot-$Mbcnt + WEND + = 0 ;end sector + + = 1 + & FDsecs*FDside+2 ;cylinder 1 sector 2 has root directory map + = #60-#50 ;length of all next guff +50 = "JesMap" + = 0,0 + & 0 ;bytes in last block + & FDsecs*FDside+3 ;sin of first text block + = 0 ;... continued + & 2 ;number of blocks allocated +60 = 0,0 ;end sector + + = 2 + & FDsecs*FDside+3 ;cylinder 1 sectors 2-3 have root directory + = #80-#70 +70 & &1E5 ;ptr to first entry + = 0 ;first sequence number + = "$ " ;root directory name + & &1CB ;first free entry + & 1 ;number of entries in use + + = &ff, &ff +80 + = 21, 2 + & &22 + = 27, 2 +; +; And then the existing source continues +; + & &2B + = 24,2 + & &45 + = 24,2 + & &5F + = 24,2 + & &79 + = 24,2 + & &93 + = 24,2 + & &AD + = 24,2 + & &C7 + = 24,2 + & &E1 + = 24,2 + & &FB + = 24,2 + & &115 + = 24,2 + & &12F + = 24,2 + & &149 + = 24,2 + & &163 + = 24,2 + & &17D + = 24,2 + & &197 + = 24,2 + & &1B1 + = 24,2 + & 0 ;end of used entries + = 0,10 + = "Passwords " ;name of entry + = 9,5 ;offset past la, ea, acc +FMdat3 & 0 ;to be filled in + & FDsecs*FDside+5 ;sin of Passwords file + = 0 ;... continued + = 0,0 ;end sector + + = 1 + & FDsecs*FDside+5 ;cylinder 1 sector 5 has password file map + = #95-#90 ;length +90 = "JesMap" + = 0,0 + & 0 ;bytes in last block + & FDsecs*FDside+6 ;sin of first text block + = 0 ;... continued + & 1 ;number of blocks allocated +95 = 0,0 ;end sector + + = 1 + & FDsecs*FDside+6 ;cylinder 1 sector 6 has passwords file + = 5,"Syst",13 ;Define one privileged identifier + = Maxunm-1-5 + = 1,13 ;null password + = Maxpw-1 + = 5,4,4,4,0,&C0 ;free space, system privilege flag + = 0,0 ;end sector + + = 0 ;end of all sectors + + +; ************ +; * FSVERIFY * +; ************ + +; FSVERIFY <discnumber> command (command mode 1 only) +; verifies a disc is a fileserver disc and that all +; the sectors are readable without error. + +VERIFY ROUT + LDAIM &2F ;Winchester verify command code + STA Tempa ;preset command + JSR Spaces ;find arguments + CMPIM "0" ;first is disc number (one digit) + BCC #20 + CMPIM "6" + BCS #20 + ANDIM 7 ;isolate drive number + STA Drivno ;save for later + STA Mpdrve + INY + JSR Comend ;check end of command + BNE #40 + LDA Drivno + JSR Rddata ;read disc sector 0 + BNE #30 + LDA Dsccb+Tradd ;set store address + STA MPscpt + LDA Dsccb+Tradd+1 + STA MPscpt+1 + JSR Chkdsc ;check disc is FS disc + BNE #30 + + JSR FMackn ;reply to caller now, lest he time out + + LDXIM 9 ;zero (extended) disc CB +05 STZAX Dsccb+Cmd + DEX + BNE #05 + + LDA Drivno + LSRA + RORA + RORA + RORA + STA Dsccb+Cmd+1 + CMPIM 4*&20 ;Winchester or floppy? + BCC #50 ;Br if Winnie + + LDAIM &0E ;VERIFY command code + STA Dsccb+Cmd + INC Dsccb+Cmd+1 ;Assume one-sided disc + LDYIM Mpszsc ;Get sectors per track + LDAIY Mpscpt + CMPIM FDsecs+2 ;See if 1/2 sided disc + BCC #10 + LSRA + INC Dsccb+Cmd+1 ;Set 2 sided disc +10 STA Dsccb+Cmd+2 ;Sectors per side + LDYIM Mpsznc ;extract drive parameters + LDAIY Mpscpt + STA Dsccb+Cmd+3 +15 JSR Dsccmd ;Perform Verify + BEQ #35 ;OK, end now +18 JMP FMVerr ;else go send error + +20 LDAIM Woterr ;General syntax error +25 JMP Error + +30 LDAIM Dcerrf ;Disc fault + BRA #25 + +35 JMP FMVok ;say OK + +40 JMP Comrts + +50 LDA Tempa ;Winnie + STA Dsccb+Cmd ;set command now + CMPIM &E2 ;br if Certify + BEQ #15 ;fall through if Verify + LDYIM Mpszns ;set number of sectors + LDAIY Mpscpt + STA Brega + INY + LDAIY Mpscpt + STA Brega+1 + INY + LDAIY Mpscpt + STA Brega+2 ;will need multiple operations + DEC Dsccb+Cmd+7 ;max is &FFFF + DEC Dsccb+Cmd+8 + LDA Brega+2 +60 BNE #70 ;br if not final section + LDA Brega+1 ;final pass, do remnant + STA Dsccb+Cmd+7 + LDA Brega + STA Dsccb+Cmd+8 + BRA #15 + +70 JSR Dsccmd ;do part verify + BNE #18 ;br if in error + CLC + LDA Dsccb+Cmd+8 ;update start block + ADC Dsccb+Cmd+5 + STA Dsccb+Cmd+5 + LDA Dsccb+Cmd+7 + ADC Dsccb+Cmd+4 + STA Dsccb+Cmd+4 + BCC #75 + INC Dsccb+Cmd+3 +75 INC Brega ;update count remaining + BNE #80 + INC Brega+1 +80 DEC Brega+2 + BRA #60 + +FNSH +LEFT * FRESTR-. ;get free store + [ LEFT > 0 ;must not overflow workspace + | + ! 0,"FRESTR incorrect" + ] + +; The original ROM has some junk at the end. +; but don't add if Psuedo = Yes + [ Pseudods = No + = &87, &D0, &02, &E6, &88, &C6 + = &89, &80, &CB, &D0, &02, &E6, &88, &C6 + = &89, &80, &CB, &80, &CB, &90, &03, &EE + = &60, &81, &E6, &87, &D0, &02, &E6, &88 + = &C6, &89, &80, &CB, &14, &3F, &A5, &B4 + ] + +;** T H E E N D *** + END diff --git a/FileStore/SRC/FileStore/Mbbmcm.6502 b/FileStore/SRC/FS/FileStore/Mbbmcm similarity index 100% rename from FileStore/SRC/FileStore/Mbbmcm.6502 rename to FileStore/SRC/FS/FileStore/Mbbmcm diff --git a/FileStore/SRC/FileStore/Print0.6502 b/FileStore/SRC/FS/FileStore/Print0 similarity index 90% rename from FileStore/SRC/FileStore/Print0.6502 rename to FileStore/SRC/FS/FileStore/Print0 index 7457e17..4a8b89b 100644 --- a/FileStore/SRC/FileStore/Print0.6502 +++ b/FileStore/SRC/FS/FileStore/Print0 @@ -37,17 +37,12 @@ Pstart ROUT INX CPXIM Praddr+6 BCC #00 - -;v1.31 -; LDXIM PRnoFF ;**8/2/88** read trailer banner suppress state -; JSR OSrdad -; STA PRnotb - -; LDAIM :LSB:#10 ;prime initial entry from commutator - LDAIM &B4 + LDXIM PRnoFF ;**8/2/88** read trailer banner suppress state + JSR OSrdad + STA PRnotb + LDAIM :LSB:#10 ;prime initial entry from commutator STA Prjump -; LDAIM :MSB:#10 - LDAIM &78 + LDAIM :MSB:#10 STA Prjump+1 RTS ;finished init @@ -131,21 +126,15 @@ Pstart ROUT 64 LDA Lastin ;**1/6/87** if previous station unterminated BEQ #65 JSR PRfoot ;**1/6/87** print footer now -65 - INC Prxcb+9 - BNE #70 - INC Prxcb+&A -70 LDAIM 0 - -; LDA Prxcb+5 ;Prepare to return CB as acknowledge -; CLC -; ADCIM 1 - STAI Prxcb+9 -; LDA Prxcb+6 -; ADCIM 0 -; STA Prxcb+10 ;Make one byte length -; LDAIM 0 -; STAI Prxcb+5 ;and send one zero byte +65 LDA Prxcb+5 ;Prepare to return CB as acknowledge + CLC + ADCIM 1 + STA Prxcb+9 + LDA Prxcb+6 + ADCIM 0 + STA Prxcb+10 ;Make one byte length + LDAIM 0 + STAI Prxcb+5 ;and send one zero byte LDA Prxcb+1 ;save control byte STA Lastct STZ Pretry ;zero retry count @@ -174,6 +163,9 @@ Pstart ROUT STA Lastin LDA Prxcb+4 STA Lastin+1 + LDA Prxcb+1 ;**20/5/87** + ANDIM MCtask + STA Lastin+2 JSR Pconnt ;refresh timeout JSR Prxcbi ;Then reissue receive STA Prxcb ;save CB number (or zero) @@ -274,10 +266,9 @@ Pollps ROUT ;here every main idle cycle STA Lastin LDA CBstid+1 STA Lastin+1 -;v1.31 -; LDA CBflg ;**20/5/87** -; ANDIM MCtask -; STA Lastin+2 + LDA CBflg ;**20/5/87** + ANDIM MCtask + STA Lastin+2 JSR Pconnt ;refresh timer LDAIM Prbusy ;and mark busy TSB Pstate @@ -324,6 +315,8 @@ Pconnt ROUT ; Print page footer PRfoot ROUT + LDA PRnotb ;**8/2/88** See if trailer suppressed + BNE #10 LDAIM &0C ;and send formfeed FOOTER (may get worse) CMP Lastch ;unless already done in data stream BEQ #10 @@ -418,6 +411,9 @@ Prchks ROUT LDA Prxcb+4 CMP Lastin+1 BNE #10 ;**20/5/87** + LDA Prxcb+1 + ANDIM MCtask + CMP Lastin+2 10 RTS ; Check if new buffer is a "start print" buffer. Returns Z set if so. @@ -496,34 +492,33 @@ Prname ROUT JSR Rcode ;Null reply 70 JMP Comrts -;v1.31 ; PRPAGE Y/N permits or suppresses the trailer banner ; which is currently a single FF -;PRPAGE ;**8/2/88** command added -; BIT Cmndsw ;Maintenance mode is ok -; BMI #80 -; STY Bptr -; JSR Getuse ;get user details -; BNE #70 -; LDYIM Utpriv -; LDAIY Ustptr ;this guy better be privileged -; ANDIM Systpv -; BEQ #15 ;else reject command -; LDY Bptr -;80 JSR Spaces ;find argument -; ANDIM &DF -; CMPIM "N" -; BEQ #90 -; CMPIM "Y" -; BNE #95 -; LDAIM 0 -;90 STA PRnotb ;set local flag -; LDXIM PRnoFF ;and stash in non-volatile storage -; JSR OSwrad -; BRA #60 -; -;95 LDAIM Woterr ;argument not Y or N -; JMP Error +PRPAGE ;**8/2/88** command added + BIT Cmndsw ;Maintenance mode is ok + BMI #80 + STY Bptr + JSR Getuse ;get user details + BNE #70 + LDYIM Utpriv + LDAIY Ustptr ;this guy better be privileged + ANDIM Systpv + BEQ #15 ;else reject command + LDY Bptr +80 JSR Spaces ;find argument + ANDIM &DF + CMPIM "N" + BEQ #90 + CMPIM "Y" + BNE #95 + LDAIM 0 +90 STA PRnotb ;set local flag + LDXIM PRnoFF ;and stash in non-volatile storage + JSR OSwrad + BRA #60 + +95 LDAIM Woterr ;argument not Y or N + JMP Error LNK FORM00 diff --git a/FileStore/SRC/FileStore/Rman01.6502 b/FileStore/SRC/FS/FileStore/Rman01 similarity index 100% rename from FileStore/SRC/FileStore/Rman01.6502 rename to FileStore/SRC/FS/FileStore/Rman01 diff --git a/FileStore/SRC/FileStore/Rman02.6502 b/FileStore/SRC/FS/FileStore/Rman02 similarity index 95% rename from FileStore/SRC/FileStore/Rman02.6502 rename to FileStore/SRC/FS/FileStore/Rman02 index 864357b..86c564c 100644 --- a/FileStore/SRC/FileStore/Rman02.6502 +++ b/FileStore/SRC/FS/FileStore/Rman02 @@ -157,26 +157,10 @@ RDWRCH ROUT ;Must extend file ;Allocate another block (1K bytes) -;v1.24 -20 STZ NEWFSZ ;Ls byte of new size - LDAIM 4 ;Add 1K to 3-byte size - CLC - LDYIM RTFSZE + 1 ;CS byte of size - ADCIY RTEPTR - STA NEWFSZ + 1 - INY - LDAIM 0 - ADCIY RTEPTR ;MS byte - STA NEWFSZ+2 - JSR RDCHSZ ; Change file size - - -;v1.31 -;20 LDAIM 1 ;Ls byte of new size -; STA NEWFSZ ;**29/4/88** central subroutine -; STZ NEWFSZ+1 -; JSR RDEXSZ ;**29/4/** Change file size - +20 LDAIM 1 ;Ls byte of new size + STA NEWFSZ ;**29/4/88** central subroutine + STZ NEWFSZ+1 + JSR RDEXSZ ;**29/4/** Change file size BNE #40 ;Error 30 JSR RDGBLK ;Get required block into cache @@ -386,7 +370,6 @@ RDSTAR ROUT STA NEWFSZ JSR RDCHSZ ;Change size of file BNE #40 ;Error => exit - JSR #88 ;Copy SFP into RANDTB @@ -396,9 +379,7 @@ RDSTAR ROUT JSR #90 ;Set current seq. ptr. LDAIM RTOSFP ;Set old seq. ptr. as well JSR #90 - -;v1.31 -; JSR RDSHWM ;**1/6/88** set HWM if SFP > old HWM + JSR RDSHWM ;**1/6/88** set HWM if SFP > old HWM 37 LDAIM 0 ;Return code 40 JMP RDEXIT ;Return - RC in A diff --git a/FileStore/SRC/FileStore/Rman02A.6502 b/FileStore/SRC/FS/FileStore/Rman02A similarity index 100% rename from FileStore/SRC/FileStore/Rman02A.6502 rename to FileStore/SRC/FS/FileStore/Rman02A diff --git a/FileStore/SRC/FileStore/Rman03.6502 b/FileStore/SRC/FS/FileStore/Rman03 similarity index 97% rename from FileStore/SRC/FileStore/Rman03.6502 rename to FileStore/SRC/FS/FileStore/Rman03 index 4aefdc7..32bce06 100644 --- a/FileStore/SRC/FileStore/Rman03.6502 +++ b/FileStore/SRC/FS/FileStore/Rman03 @@ -244,13 +244,10 @@ RDSUBO ROUT LDYIM RTCSFP+2 STAIY RTEPTR ;MS byte -20 - -;v1.31 -;20 LDYIM HTMODE ;**23/3/88** return access mode - ;LDAIY HNDPTR - ;LDYIM ARGB - ;STAIY ARGPTR +20 LDYIM HTMODE ;**23/3/88** return access mode + LDAIY HNDPTR + LDYIM ARGB + STAIY ARGPTR JSR RDCKSP ;Check SFP inside file BEQ #30 ;SFP inside file diff --git a/FileStore/SRC/FileStore/Rman04.6502 b/FileStore/SRC/FS/FileStore/Rman04 similarity index 90% rename from FileStore/SRC/FileStore/Rman04.6502 rename to FileStore/SRC/FS/FileStore/Rman04 index 7740045..3bc1890 100644 --- a/FileStore/SRC/FileStore/Rman04.6502 +++ b/FileStore/SRC/FS/FileStore/Rman04 @@ -177,50 +177,15 @@ RDPBTS ROUT LDA EOFFLG ;Get end-of-file flag BEQ #30 ;Not end of file - - -;v1.23 ;Must call MAPMAN to extend file - CLC - LDYIM RTCSFP ;NEWFSZ := SFP + xfer size -;rounded up modulo 256 (whole block) - LDAIY RTEPTR ;SFP LS byte - LDYIM ARGG - ADCIY ARGPTR ;xfer size (LS) + + LDYIM ARGG ;**29/4/88** + LDAIY ARGPTR STA NEWFSZ INY LDAIY ARGPTR - LDYIM RTCSFP + 1 - ADCIY RTEPTR - STA NEWFSZ + 1 ;CS - INY - LDAIY RTEPTR - ADCIM 0 - STA NEWFSZ + 2 ;MS - - CLC - LDAIM &FF ;Add 255 to round up - ADC NEWFSZ ;Don't want LS byte - LDAIM 4 ;Add extra 1K - ADC NEWFSZ + 1 - STA NEWFSZ + 1 - BCC #25 - INC NEWFSZ + 2 -25 STZ NEWFSZ ;Clear LS byte - - -;v1.31 -;Must call MAPMAN to extend file - -; LDYIM ARGG ;**29/4/88** -; LDAIY ARGPTR -; STA NEWFSZ -; INY -; LDAIY ARGPTR -; STA NEWFSZ+1 - - - JSR RDCHSZ ;**29/4/88** Extend file + STA NEWFSZ+1 + JSR RDEXSZ ;**29/4/88** Extend file BNE #40 ;Failed 30 LDYIM ARGG ;BTSLFT := xfer size @@ -247,45 +212,44 @@ RDPBTS ROUT LDAIM 0 ;=> successful return 40 JMP RDEXIT ;EXIT: RC IN A -;v1.31 -;; Routine to extend file. Called with amount required -;; in NEWFSZ, NEWFSZ+1. Adds 4K to round up. -;; Exit Z set if OK, else error code in A. -; -;RDEXSZ ROUT ;**29/4/88** -; CLC -; LDYIM RTCSFP ;NEWFSZ := SFP + xfer size -; LDAIY RTEPTR ;SFP LS byte -; ADC NEWFSZ ;xfer size (LS) -; STA NEWFSZ -; INY -; LDAIY RTEPTR -; ADC NEWFSZ+1 -; STA NEWFSZ+1 ;CS -; INY -; LDAIY RTEPTR -; ADCIM 0 -; STA NEWFSZ+2 ;MS -; LDAIM &8A -; BCS #40 ;**29/4/88** Error if overflowed -; -; LDAIM &FF ;Add 255 to round up -; CMP NEWFSZ+2 ;**29/4/88** Unless reaching 24 bits -; BEQ #50 -; CLC -; ADC NEWFSZ ;Don't want LS byte -; LDAIM 4 ;Add extra 1K -; ADC NEWFSZ+1 -; STA NEWFSZ+1 -; BCC #25 -; INC NEWFSZ+2 -;25 STZ NEWFSZ ;Clear LS byte -;30 JSR RDCHSZ ;**29/4/88** call change size routine -;40 RTS - -;50 STA NEWFSZ ;**29/4/88** getting near max, -; STA NEWFSZ+1 ;**29/4/88** round up now to max -; BRA #30 +; Routine to extend file. Called with amount required +; in NEWFSZ, NEWFSZ+1. Adds 4K to round up. +; Exit Z set if OK, else error code in A. + +RDEXSZ ROUT ;**29/4/88** + CLC + LDYIM RTCSFP ;NEWFSZ := SFP + xfer size + LDAIY RTEPTR ;SFP LS byte + ADC NEWFSZ ;xfer size (LS) + STA NEWFSZ + INY + LDAIY RTEPTR + ADC NEWFSZ+1 + STA NEWFSZ+1 ;CS + INY + LDAIY RTEPTR + ADCIM 0 + STA NEWFSZ+2 ;MS + LDAIM &8A + BCS #40 ;**29/4/88** Error if overflowed + + LDAIM &FF ;Add 255 to round up + CMP NEWFSZ+2 ;**29/4/88** Unless reaching 24 bits + BEQ #50 + CLC + ADC NEWFSZ ;Don't want LS byte + LDAIM 4 ;Add extra 1K + ADC NEWFSZ+1 + STA NEWFSZ+1 + BCC #25 + INC NEWFSZ+2 +25 STZ NEWFSZ ;Clear LS byte +30 JSR RDCHSZ ;**29/4/88** call change size routine +40 RTS + +50 STA NEWFSZ ;**29/4/88** getting near max, + STA NEWFSZ+1 ;**29/4/88** round up now to max + BRA #30 diff --git a/FileStore/SRC/FileStore/Rman05.6502 b/FileStore/SRC/FS/FileStore/Rman05 similarity index 100% rename from FileStore/SRC/FileStore/Rman05.6502 rename to FileStore/SRC/FS/FileStore/Rman05 diff --git a/FileStore/SRC/FileStore/Uade01.6502 b/FileStore/SRC/FS/FileStore/Uade01 similarity index 97% rename from FileStore/SRC/FileStore/Uade01.6502 rename to FileStore/SRC/FS/FileStore/Uade01 index 5e37e95..4750c54 100644 --- a/FileStore/SRC/FileStore/Uade01.6502 +++ b/FileStore/SRC/FS/FileStore/Uade01 @@ -56,7 +56,7 @@ English * 0 Italian * 1 ; **18/2/87** Verla * 1 ;Version number & level -Verlb * 23 ;Range 0-99 20/7/88 +Verlb * 31 ;Range 0-99 20/7/88 Lang * English Mask * &3F ;protection state (&3F for service system) Yes * 0 @@ -264,19 +264,15 @@ Prtimo * 30 ;Printer timeout in seconds (3-650) CMinst # 0 ;**5/3/88** start of area to init Stnids # 2 ;ECOnet station id # 4 ;spares for MOS use -IEaddr # 5 ;INTERR Log out area - -;v1.31 -;IEaddr # 8 ;INTERR Log out area - +IEaddr # 8 ;INTERR Log out area MUaddr # 1 ;MAXUSR storage area MDaddr # 1 ;MAXDRV storage area Praddr # 6 ;POLLPS name address FSusid # 12 ;Stored command mode system id FSusie # 0 ;End of system id space -;PRnoFF # 1 ;**8/2/88** Non-zero to suppress FF -;CAcopy # 1 ;**23/3/88** Non-zero if no ACORN copyright check -;CMinen # 0 ;**5/3/88** End of area to init +PRnoFF # 1 ;**8/2/88** Non-zero to suppress FF +CAcopy # 1 ;**23/3/88** Non-zero if no ACORN copyright check +CMinen # 0 ;**5/3/88** End of area to init ACK * 6 NACK * &15 diff --git a/FileStore/SRC/FileStore/Uade02.6502 b/FileStore/SRC/FS/FileStore/Uade02 similarity index 96% rename from FileStore/SRC/FileStore/Uade02.6502 rename to FileStore/SRC/FS/FileStore/Uade02 index ab8ad9d..cbf77ee 100644 --- a/FileStore/SRC/FileStore/Uade02.6502 +++ b/FileStore/SRC/FS/FileStore/Uade02 @@ -165,10 +165,7 @@ MPSCYL # 2 ;START CYLINDER MP1BIT # 1 ;Non-zero if packed map, gives bytes/cyl MPSZLN * @ ;End of part copied from sector zero MPSCTT # 3 ;TOTAL NUMBER OF SECTORS -;v1.23 -PADDD1 # 3 ; temporary to line up the variables correctly. MPCYMP # 2 ;STORE ADDRESS OF CYLINDER MAP -PADDD2 # 1 ; temporary to line up the variables correctly. MPTBSZ * @ ;SIZE OF MAPTB ENTRY ;** SECTOR ZERO INFO ** @@ -239,11 +236,7 @@ NTENSZ * @ ;SIZE OF ENTRY ;*** COMMAND PROC. MANIFESTS *** ;CONSTANTS - -;v1.23 -RXBUFL * &50 ;Receive buffer length -;v1.31 -; RXBUFL * 127 ;**8/2/88** Receive buffer length (<=127) +RXBUFL * 127 ;**8/2/88** Receive buffer length (<=127) COPORT * &99 FIFLSZ * &400 ;Initial size of file created by FIND BUFSZ * &500 ;TX BUFFER SIZE @@ -265,10 +258,7 @@ DOT * "." FCCMND * 5 ;To recognise a command FCCRET * 29 ; The create command 11/6/84 BC HDRLEN * 5 ;Header of INCOMING message -;v1.23 *** FIX -MCTASK * &1E -;MCTASK * &78 ;Mask for task number in control byte **1/5/86** - +MCTASK * &78 ;Mask for task number in control byte **1/5/86** TXHDR * 2 ;Header length of OUTGOING message CLIDLM * CR ;Delimiter in CLI table SAVFTO * HDRLEN+&B @@ -283,7 +273,12 @@ FNDFTO * HDRLEN+2 ;File find, not dir. find ?? ;STORE POINTERS + [ Pseudods = No ^ &8000 + | + ^ &8100 + ] + FRESTR # 0 FREPTR # 2 ;PTR TO FREE STORE (GETVEC) ENDPTR # 2 ;PTR TO END OF FREE STORE (GETVEC) @@ -326,7 +321,6 @@ EOFFLG # 1 ;End-of-file flag (RNDMAN) HTENTS # 1 ;NO. OF HAND. TBL. ENTRIES RTNENT # 1 ;No. of RANDTB entries GVWRKA # 2 ;GETVEC WORK VARIABLE -ENWRKA # 2 ;ENTRY WORK VAR MCNUMB # 3 ;MC/NO LOOKED UP IN USERTB(USRMAN-FINDMC) **25/12/86** DATE # 5 ;Date and time values HRS * DATE+2 @@ -407,7 +401,6 @@ FCODE # 1 ;FN. code CPUFD # 1 CPCSD # 1 CPLIB # 1 -;MIDRX * &A1 MIDRX # RXBUFL+RXBUFL+1-(MIDRX-RXBUF) ;**8/2/88** RXBUFT # 1 TXBUF # 0 @@ -459,9 +452,7 @@ MPNWFR # UTFRLN ;user free space calculation Oswork # 5 ;OS control block MPscor # 2 ;Bitmap sector origin (MAPMAN) MCopat # 3 ;"Already open at station m.n" - -;v1.31 -;IEsin # 3 ;SIN of last disc error +IEsin # 3 ;SIN of last disc error [ Cachesw=Yes ODSCMN # 11 ] @@ -476,9 +467,7 @@ Prpoll # 1 ;Receive CB number, or zero if none Prwork # 8 ;Workspace for reading POLLPS packets Pretry # 1 ;Retry counter for POLLPS replies Prdata # Prlong+1 ;Printer data buffer - -;v1.31 -;PRnotb # 1 ;**8/2/88** Non-zero if no trailer FF +PRnotb # 1 ;**8/2/88** Non-zero if no trailer FF DYNSTA * @ ;START OF DYNAMICALLY ALLOCATED STORE diff --git a/FileStore/SRC/FileStore/Uade03.6502 b/FileStore/SRC/FS/FileStore/Uade03 similarity index 96% rename from FileStore/SRC/FileStore/Uade03.6502 rename to FileStore/SRC/FS/FileStore/Uade03 index 12e107c..fdf13ee 100644 --- a/FileStore/SRC/FileStore/Uade03.6502 +++ b/FileStore/SRC/FS/FileStore/Uade03 @@ -7,7 +7,7 @@ START JMP STRTFS ; .. here we go .. -CACORN = "(C)Acorn 1987" +CACORN = "(C)Acorn 1988" ;I N P U T - O U T O U T R O U T I N E S @@ -48,15 +48,14 @@ INTERR ROUT CPXIM IEaddr+5 BCC #10 ;Copy A, X, Y, JSR address -;v1.31 -;15 LDAAX IEsin-IEaddr-5 ;write last SIN -; JSR OSwrad -; INX -; CPXIM IEaddr+8 -; BCC #15 -; -; LDAIM 0 ;**29/4/88** temporary? deprotect store -; JSR Doprot ;**29/4/88** to allow for taking dumps +15 LDAAX IEsin-IEaddr-5 ;write last SIN + JSR OSwrad + INX + CPXIM IEaddr+8 + BCC #15 + + LDAIM 0 ;**29/4/88** temporary? deprotect store + JSR Doprot ;**29/4/88** to allow for taking dumps LDXIM 0 ;start flashing led PHX ;save marker to check door opened @@ -90,13 +89,10 @@ INTERR ROUT 50 LDXIM &FF ;Reset stack ptr - delayed for debugging TXS - -; v1.31 -; LDX RXTAB ;**29/4/88** cancel any pending RX CBs -; BEQ #60 -; LDAIM &34 -; JSR OSBYTE - + LDX RXTAB ;**29/4/88** cancel any pending RX CBs + BEQ #60 + LDAIM &34 + JSR OSBYTE 60 LDAIM 0 ;Indicate start in user mode required JMP Strtf1 ;then start all over again @@ -442,10 +438,9 @@ ENTRY ROUT LDAIY ARGPTR LDYIM ENTRES STAIY ARGPTR ;COPY OF ARGA (THE ENTRY REASON) - STA ENWRKA ;ENWRKA:=[ARGPTR+ARGA] - DEC ENWRKA ;ENWRKA -:= 1 - ASL ENWRKA ;ENWRKA *:= 2 - LDX ENWRKA ;X := JUMP TABLE OFFSET + DECA ;CODE -:= 1 + ASLA ;CODE *:= 2 + TAX ;X := JUMP TABLE OFFSET LDAIM &FF STA NEWARG STA NEWARG+1 ;NEWARG := $FFFF diff --git a/FileStore/SRC/FileStore/Uade04.6502 b/FileStore/SRC/FS/FileStore/Uade04 similarity index 77% rename from FileStore/SRC/FileStore/Uade04.6502 rename to FileStore/SRC/FS/FileStore/Uade04 index a3844c3..2b21f2e 100644 --- a/FileStore/SRC/FileStore/Uade04.6502 +++ b/FileStore/SRC/FS/FileStore/Uade04 @@ -33,33 +33,29 @@ INIT ROUT JSR AUTMAN ;AUTMAN.RESTART BEQ #20 10 PHA - - JSR INTERR -;v1.31 -; JSR USRERR - + JSR USRERR PLA 20 RTS + ;Main start point ;Resets ENDPTR, FREPTR and re-allocates all tables. ;STRTF1 Entry with door state in A -;v1.31 -;CMintb ;**5/3/88** table for initialising CMOS RAM -; = &FE,&01 ;Set station id + complement -; = 0,0,0,0 ;Reserved -; = 0,0,0,0,0 ;Error logout -; = 0,0,0 ;SIN of last disc access on error -; = 80 ;Max users -; = 6 ;Max drives -; = "PRINT " ;printer name -; = "SYST",CR ;maintenance userid -; = 0,0,0,0,0,0 ;...continued -; = :LSB:("S"+"Y"+"S"+"T"+&0D)+:MSB:("S"+"Y"+"S"+"T"+&0D) -; = 0 ;printer page flag -; = 0 ;ACORN copyright check flag +CMintb ;**5/3/88** table for initialising CMOS RAM + = &FE,&01 ;Set station id + complement + = 0,0,0,0 ;Reserved + = 0,0,0,0,0 ;Error logout + = 0,0,0 ;SIN of last disc access on error + = 80 ;Max users + = 6 ;Max drives + = "PRINT " ;printer name + = "SYST",CR ;maintenance userid + = 0,0,0,0,0,0 ;...continued + = :LSB:("S"+"Y"+"S"+"T"+&0D)+:MSB:("S"+"Y"+"S"+"T"+&0D) + = 0 ;printer page flag + = 0 ;ACORN copyright check flag Strtfs ROUT LDXIM 1 ;Turn on LED during tests @@ -67,27 +63,24 @@ Strtfs ROUT JSR OSbyte JSR MEMTST ;Test memory - comes back only if OK -;v1.31 -; LDXIM Stnids ;**5/3/88** find if CMOS initialised -; JSR OSrdad -; STA Cozero -; LDXIM Stnids+1 -; JSR OSrdad -; SEC -; ADC Cozero ;if station ids checksum -; BEQ #20 ;then assume initialised -; LDXIM CMinst -;10 LDAAX CMintb-Stnids -; PHX -; JSR OSwrad -; PLX -; INX -; CPXIM CMinen -; BCC #10 - -;20 - - JSR Pstart ;Now start the printserver + LDXIM Stnids ;**5/3/88** find if CMOS initialised + JSR OSrdad + STA Cozero + LDXIM Stnids+1 + JSR OSrdad + SEC + ADC Cozero ;if station ids checksum + BEQ #20 ;then assume initialised + LDXIM CMinst +10 LDAAX CMintb-Stnids + PHX + JSR OSwrad + PLX + INX + CPXIM CMinen + BCC #10 + +20 JSR Pstart ;Now start the printserver LDAIM 128 ;read user switches LDXIM 0 @@ -208,11 +201,8 @@ MW30D = 4,6,9,11 CHKDTE ROUT LDA DATE - -;v1.31 -; ANDIM 31 ;**24/2/88** isolate day of month -; TAX - + ANDIM 31 ;**24/2/88** isolate day of month + TAX BEQ #40 CMPIM 32 BCS #40 @@ -223,13 +213,7 @@ CHKDTE ROUT BCS #40 CMPIM 2 BEQ #20 ; br to check leap year - -;v1.23 - LDA DATE - -;v1.31 -; TXA - + TXA CMPIM 31 BCC #30 LDXIM 4 @@ -241,30 +225,14 @@ CHKDTE ROUT BNE #10 BRA #30 -;v1.23 -20 LDA DATE - -;v1.31 -;20 TXA - +20 TXA CMPIM 29 BCC #30 CMPIM 30 BCS #40 - -;v1.23 LDA DATE+1 - LSRA - LSRA - LSRA - LSRA - ADCIM 81 - ANDIM 3 - -;v1.31 -; LDA DATE+1 -; ADCIM :LSB:(BASEYR*16) -; ANDIM 3*16 + ADCIM :LSB:(BASEYR*16) + ANDIM 3*16 BNE #40 30 LDAIM 0 RTS diff --git a/FileStore/SRC/FileStore/Uade05.6502 b/FileStore/SRC/FS/FileStore/Uade05 similarity index 100% rename from FileStore/SRC/FileStore/Uade05.6502 rename to FileStore/SRC/FS/FileStore/Uade05 diff --git a/FileStore/SRC/FileStore/Uade06.6502 b/FileStore/SRC/FS/FileStore/Uade06 similarity index 100% rename from FileStore/SRC/FileStore/Uade06.6502 rename to FileStore/SRC/FS/FileStore/Uade06 diff --git a/FileStore/SRC/FileStore/Uade06A.6502 b/FileStore/SRC/FS/FileStore/Uade06A similarity index 78% rename from FileStore/SRC/FileStore/Uade06A.6502 rename to FileStore/SRC/FS/FileStore/Uade06A index 7b18d49..55b4ca2 100644 --- a/FileStore/SRC/FileStore/Uade06A.6502 +++ b/FileStore/SRC/FS/FileStore/Uade06A @@ -367,55 +367,30 @@ LOGOFF ROUT LDAIM 6 JSR SETUSA JSR RNDMAN ;*** CLOSE ALL ENTRIES ** + BEQ #10 + PLY ;**1/6/88** stack bad return code + PHA + +;NOW CLEAR USERTB ENTRY TO ZERO -;v1.23 +10 JSR USENS ;update all free space entries BEQ #20 -10 PLY - TAY - RTS -20 JSR USENS ;update all free space entries - BNE #10 - LDYIM UTPRIV ;check for priv'd user + PLY ;**1/6/88** stack bad return code ** + PHA +20 LDYIM UTPRIV ;check for priv'd user LDAIY USTPTR ;** 27/9/84 ** ANDIM SYSTPV BEQ #30 ;not priv'd DEC USSYS ;decrement counter 30 LDAIM 0 - TAY - LDXIM "#" + LDYIM UTENSZ-1 ;**1/6/88** 40 STAIY USTPTR - INY - DEX - BNE #40 + DEY + BPL #40 PLA RTS -;v1.31 -; BEQ #10 -; PLY ;**1/6/88** stack bad return code -; PHA - -;;NOW CLEAR USERTB ENTRY TO ZERO - -;10 JSR USENS ;update all free space entries -; BEQ #20 -; PLY ;**1/6/88** stack bad return code ** -; PHA -;20 LDYIM UTPRIV ;check for priv'd user -; LDAIY USTPTR ;** 27/9/84 ** -; ANDIM SYSTPV -; BEQ #30 ;not priv'd -; DEC USSYS ;decrement counter -;30 LDAIM 0 -; LDYIM UTENSZ-1 ;**1/6/88** -;40 STAIY USTPTR -; DEY -; BPL #40 -; PLA -; RTS - - USENS CLC ;** 2/10/84 ** LDYIM ARGD LDA USTPTR @@ -458,8 +433,7 @@ CLUFDR ROUT 10 RTS -CLSLDR - LDA UMHCSD +CLSLDR LDA UMHCSD BEQ #10 JSR CLOSE STZ UMHCSD @@ -477,32 +451,12 @@ CLSLDR GETUFD ROUT - -;v1.24 - LDAIM ROOT - STA USRROT - LDAIM SEPART - STA USRSEP - JSR SETUID + JSR SETUID ;COPY USERID INTO USRUFD LDAIM TERMIN STA USRTER - LDAIM :LSB:USRROT - STA TITPTR - LDAIM :MSB:USRROT - STA TITPTR+1 - - LDAIM 0 ;no wild cards here - JSR RETRV ;RETRIEVE ROOT DIR + LDAIM SEPART + JSR #20 ;**7/7/88** complete name & retrieve BNE #10 - -;v1.31 -; JSR SETUID ;COPY USERID INTO USRUFD -; LDAIM TERMIN -; STA USRTER -; LDAIM SEPART -; JSR #20 ;**7/7/88** complete name & retrieve -; BNE #10 - LDAIM OWNER TSB USRACC ;OWNER ACCESS TO UFD BRA #00 ;Common code @@ -514,11 +468,10 @@ GTROOT JSR RTROOT JSR GETLBH ;LOOK FOR LIB FILE 10 RTS -RTROOT +RTROOT LDAIM TERMIN +20 STA USRSEP LDAIM ROOT STA USRROT - LDAIM TERMIN - STA USRSEP LDAIM :LSB:USRROT STA TITPTR LDAIM :MSB:USRROT @@ -527,6 +480,7 @@ RTROOT JMP RETRV ;RETRIEVE ROOT DIR + ;TRY TO RETRIEVE FILE "LIBRARY". ;IF FOUND, OPEN AND PUT HANDLE ;IN LIB. LOCATION. IF NOT, OPEN @@ -537,16 +491,14 @@ RTROOT GETLBH ROUT LDYIM UTDISC LDAIY USTPTR - - PHA + STA USDISC ;**7/7/88** INY LDAIY USTPTR - PHA ;save users disc number - LDA USTEMP - PHA ;save - STZ USTEMP -10 LDA USTEMP - JSR DRVINF ;drive exists ; 20 04 11 + STA USDISC+1 ;save users disc number + + STZ UMHLIB ;spare counter +10 LDA UMHLIB + JSR DRVINF ;drive exists ? BNE #20 ;no JSR SUSRDI @@ -562,21 +514,16 @@ GETLBH ROUT CMPIM DRERRC BNE #50 ;IF ERROR NOT "NOT FOUND", ABORT -20 INC USTEMP - LDA USTEMP - CMP DRIVES +20 INC UMHLIB + LDA UMHLIB ;**14/06/86** + CMP DRIVES ;**14/06/86** BCC #10 ;loop until all drives tried -;NOW CHECK IF ROOT ALREADY RETRIEVED -;(IF USING ROOT AS CSD FOR EXAMPLE), -;AND IF NOT, RETRIEVE. THEN OPEN AND RETURN -;HANDLE FOR LIB. +;Now retrieve root. Then open and return +;handle for lib. - LDYIM INFNAM - LDAAY USRINF - CMPIM ROOT - BEQ #30 - JSR RTROOT ;Otherwise, retrieve + JSR #40 ;**7/7/88** must reset drive first + JSR RTROOT ; retrieve BNE #50 30 JSR OPEN @@ -585,73 +532,14 @@ GETLBH ROUT LDAIM 0 ;GIVE Z SET 40 TAX - PLA - STA USTEMP - LDYIM UTDISC + 1 ;restore the old values - PLA + LDYIM UTDISC+1 ;restore the old values + LDA USDISC+1 STAIY USTPTR DEY - PLA + LDA USDISC STAIY USTPTR TXA ;restore return code RTS - -;v1.31 -; STA USDISC ;**7/7/88** -; INY -; LDAIY USTPTR -; STA USDISC+1 ;save users disc number - -; STZ UMHLIB ;spare counter -;10 LDA UMHLIB -; JSR DRVINF ;drive exists ? -; BNE #20 ;no -; JSR SUSRDI -; -; LDAIM :LSB:DEFLIB ;PTR. TO LIB. TITLE -; STA TITPTR -; LDAIM :MSB:DEFLIB -; STA TITPTR+1 -; -; LDAIM 0 ;no wild cards here -; JSR RETRV -; -; BEQ #30 ;OK, FOUND SO OPEN -; CMPIM DRERRC -; BNE #50 ;IF ERROR NOT "NOT FOUND", ABORT -; -;20 INC UMHLIB -; LDA UMHLIB ;**14/06/86** -; CMP DRIVES ;**14/06/86** -; BCC #10 ;loop until all drives tried -; -;;Now retrieve root. Then open and return -;;handle for lib. -; -; JSR #40 ;**7/7/88** must reset drive first -; JSR RTROOT ; retrieve -; BNE #50 -; -;30 JSR OPEN -; BNE #50 ;ABORT IF ERROR -; STA UMHLIB ;STORE HANDLE -; LDAIM 0 ;GIVE Z SET -;40 TAX -; PLA -; STA USTEMP -; LDYIM UTDISC + 1 ;restore the old values -; PLA -; STAIY USTPTR -; DEY -; PLA -; LDYIM UTDISC+1 ;restore the old values -; LDA USDISC+1 -; STAIY USTPTR -; DEY -; LDA USDISC -; STAIY USTPTR -; TXA ;restore return code -; RTS 50 PHA JSR CLUFDR diff --git a/FileStore/SRC/FileStore/Uade0A.6502 b/FileStore/SRC/FS/FileStore/Uade0A similarity index 100% rename from FileStore/SRC/FileStore/Uade0A.6502 rename to FileStore/SRC/FS/FileStore/Uade0A diff --git a/FileStore/SRC/FileStore/Uade0B.6502 b/FileStore/SRC/FS/FileStore/Uade0B similarity index 100% rename from FileStore/SRC/FileStore/Uade0B.6502 rename to FileStore/SRC/FS/FileStore/Uade0B diff --git a/FileStore/SRC/FileStore/Uade0C.6502 b/FileStore/SRC/FS/FileStore/Uade0C similarity index 93% rename from FileStore/SRC/FileStore/Uade0C.6502 rename to FileStore/SRC/FS/FileStore/Uade0C index 1b284d0..2134569 100644 --- a/FileStore/SRC/FileStore/Uade0C.6502 +++ b/FileStore/SRC/FS/FileStore/Uade0C @@ -19,13 +19,7 @@ ;11) Remove a directory ** 24/9/84 ** ;12) Preserve object (without DELCHK) ** 25/9/84 ** ;13) Check if object will preserve **23/3/88** - -;v1.23 -DIRMAN LDXIM 12 - -;v1.31 -;DIRMAN LDXIM 13 - +DIRMAN LDXIM 13 LDAIM MODDIR JSR ENTRY LDAIM &19 @@ -44,8 +38,7 @@ DRRTNS & DRFTDN ;10 => FILE TITLE -> DISC NO. & DRDELT ;11 => Remove a directory & DRPRES ;12 => Preserve object without delchk -;v1.31 -; & DRPRES ;13 => Check if object will preserve + & DRPRES ;13 => Check if object will preserve DREXIT JMP PREXIT ;**25/12/86** ;*********** DRPRES *********** @@ -126,14 +119,11 @@ DRPRES ROUT DRRETR ROUT + JSR DRRET2 ;**4/4/88** call as subroutine + BRA DREXIT -;v1.31 -; JSR DRRET2 ;**4/4/88** call as subroutine -; BRA DREXIT -;DRRET2 - - LDYIM ARGH +DRRET2 LDYIM ARGH LDAIY ARGPTR ORAIM &02 ;**2/6/87** "^" allowed at end STA DIRWC ;get wild card flag @@ -157,12 +147,11 @@ DRRETR ROUT ;SUPPLY DETAILS OF ROOT DIR -;v1.31 -; LDAIM ROOT ;**4/4/88** Set up name -; JSR OUTCH -; LDXIM 9 -; JSR OUTSPS -; JSR SETINF ;Reset INFPTR + LDAIM ROOT ;**4/4/88** Set up name + JSR OUTCH + LDXIM 9 + JSR OUTSPS + JSR SETINF ;Reset INFPTR 05 LDYIM INFLOA LDXIM 8 @@ -175,32 +164,17 @@ DRRETR ROUT LDA DIRACC LDYIM ARGB STAIY ARGPTR ;ACCESS TO ROOT DIR - -;v1.23 - LDYIM INFDTE - LDA TDATE + LDYIM INFACC + LDAIM TYPDIR+LOCKED STAIY INFPTR - LDA TDATE+1 + INY + LDA TDATE ;(DATE OF CREATION ROOT) STAIY INFPTR - LDYIM INFACC - LDAIM TYPDIR + INY + LDA TDATE+1 STAIY INFPTR LDA DIRSIN - LDYIM INFSIN - -;v1.31 -; LDYIM INFACC -; LDAIM TYPDIR+LOCKED -; STAIY INFPTR -; INY -; LDA TDATE ;(DATE OF CREATION ROOT) -; STAIY INFPTR -; INY -; LDA TDATE+1 -; STAIY INFPTR -; LDA DIRSIN -; INY - + INY STAIY INFPTR LDA DIRSIN+1 INY @@ -229,12 +203,10 @@ DRRETR ROUT STAIY INFPTR DEY BPL #22 - -;v1.31 -; LDA DATE ;set date to today (????????) -; STA TDATE -; LDA DATE+1 -; STA TDATE+1 + LDA DATE ;set date to today (????????) + STA TDATE + LDA DATE+1 + STA TDATE+1 BRA #05 ;**23/1/87** complete info entry a la root [ Pseudods = Yes @@ -248,12 +220,10 @@ DRRETR ROUT BNE #27 JSR LOADDR ;**20/5/87** load directory BNE #60 - -;v1.31 -; LDA DATE ;set date to today (????????) -; STA TDATE -; LDA DATE+1 -; STA TDATE+1 + LDA DATE ;set date to today (????????) + STA TDATE + LDA DATE+1 + STA TDATE+1 | 25 BRA #27 ] @@ -287,12 +257,7 @@ DRRETR ROUT BNE #60 ;Error 50 LDAIM 0 ;RC:=0 - -;v1.23 -60 JMP DREXIT - -;v1.31 -;60 RTS ;**4/4/88** +60 RTS ;**4/4/88** ;MAKE INFPTR POINT TO DETAILS AREA diff --git a/FileStore/SRC/FS/FileStore/Uade0CA b/FileStore/SRC/FS/FileStore/Uade0CA new file mode 100644 index 0000000..c38e065 --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Uade0CA @@ -0,0 +1,457 @@ + OPT UADE0C ;FILE > Uade0CA + TTL File server file UADE0CA + +;************ DRCHSZ ************ + +;DRCHSZ: CHANGE SIZE OF A FILE + +;ENTRY: ARGB = LS +;ARGC = MS(PTR TO USERINFO) +;ARGD = LS +;ARGE = MS(PTR TO FILE TITLE) +;ARGF = LS +;ARGG = CS +;ARGH = MS(NEW SIZE) + +;EXIT : ARGA = RC + +;FUNCTION:- +;REMOVE ALL OF THE OBJECT FROM THE CACHE; +;IF TYPE OF OBJECT = FILE +;THEN CHECK FOR WRITE ACCESS; +;CHECK THAT FILE IS NOT OPEN; +;CHANGE SIZE; +;ENSURE OBJECT MAP UPTO DATE ON DISC +;ELIF TYPE OF OBJECT = DIR +;THEN RC:=WRONG TYPE #AUTOMATICALLY DONE IN RETAIN# +;FI + +DRCHSZ ROUT + [ 1=1 + LDAIM IERRAC ;Not used in FileStore ** 29/09/86 ** + JMP INTERR + | + LDYIM ARGI + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV + BNE #40 + +;RETRIEVE DIR ENTRY + + JSR RETENT + BNE #40 + + JSR CRNSIN ;OBJSIN := SIN OF CURRENT DIR ENTRY + JSR MAXACC ;OBJACC := TYPE & ACCESS HELD FOR OBJECT + JSR UNLOCK ;UNLOCK DIR + JSR REMOVE ;REMOVE OBJSIN FROM THE CACHE + BNE #40 ;error trap **** 17/3/83 **** + LDA OBJACC + ANDIM TYPE + CMPIM TYPDIR + BNE #10 + LDAIM DRERRF ;WRONG TYPE + BRA #40 + +;DEAL WITH A FILE + +10 LDA OBJACC + ANDIM WRITAC + BNE #20 + LDAIM DRERRL ;NO WRITE ACCESS ! + BRA #40 + +;CHECK THAT THE FILE IS NOT OPEN + +20 LDAIM 2 ;RNDMAN.INFO + JSR SETDSA ;PLACE ARG, OBJECT DISC NO & SIN ONTO NEWARG STACK + JSR RNDMAN + BNE #30 + LDAIM DRERRI + BRA #40 + +;NOW CALL MAPMAN TO HAVE THE SIZE CHANGED + +30 LDAIM 3 + JSR SETDSA + LDYIM ARGF + LDAIY ARGPTR + LDYIM ARGB + STAIY NEWARG ;LS(NEW SIZE) + LDYIM ARGG + LDAIY ARGPTR + LDYIM ARGC + STAIY NEWARG ;CS(NEW SIZE) + LDYIM ARGH + LDAIY ARGPTR + LDYIM ARGD + STAIY NEWARG ;MS(NEW SIZE) + + JSR JUSINF ;** 3/10/84 pass userinfo ptr + + JSR MAPMAN + BNE #40 + JSR ENSOMP ;ENSURE OBJECT MAP + +40 JMP DREXIT + ] + +;******** EXAMINE ROUTINE ******** + +;DREXAM : GIVE DETAILS OF ENTRY(S) IN A DIR. +;ENTRY: +;ARGB/C PTR TO USER INFO +;ARGD/E PTR TO FILE TITL +;ARGF/G ADDRESS OF STORE FOR RESULT +;ARGH = TYPE OF RESULT REQURIED +;0 => ALL INFO, M/C READABLE +;1 => ALL INFO, CHAR STRING +;2 => FILE TITLE + FILE NAME LENGTH, M/C +;3 => ACCESS+FILE TITLE, CHAR STRING +;4 => GIVE LAST COMPONENT F.T. ONLY +;ARGI = ENTRY POINT TO DIR. +;ARGJ = NO. OF ENTRIES (0=> ALL DIR.) +;ARGK = wild card flag + +;EXIT : +;ARGB/C PTR TO BYTE AFTER RESULT END +;ARGD = NO. OF ENTRIES +;ARGE = SEQ. NO. OF DIRECTORY BEING EXAMINED + +;WHEN ARGH IS 4, ARGD IS MAX. ACCESS TO DIR, +;ARGE IS SEQUENCE NUMBER OF DIR., AND +;ARGF/G ARE DISC. NO LO/HI + +;TABLE OF EXAMINE ROUTINE ENTRY POINTS + +DEXTAB & EXRTNA + & EXRTNB + & EXRTNC + & EXRTND + +DREXAM ROUT + STZ DIRFLG + LDYIM ARGK + LDAIY ARGPTR + ORAIM &02 ;**2/6/87** "^" allowed at end of name + STA DIRWC ;get wild card flag + RORA ;look at bit0 + BCC #10 + LDAIM &80 + STA DIRFLG +10 JSR INITDV + BNE #20 + + JSR SETINF ;STORE RESULT PTR. + + LDAIY ARGPTR + CMPIM 5 + BCC #15 ;IF <5, OK + LDAIM DRERRO ;BAD ARG. TO EXAMINE + BRA #20 + +15 STA EXARG ;TYPE OF RESULT + INY + LDAIY ARGPTR + STA EXENTR ;ENTRY TO DIR. + INY + LDAIY ARGPTR + JSR CHKENS + BCC #25 ;OK + LDAIM DRERRN ;TOO MANY ENTRIES REQUESTED +20 JMP #75 + +25 STA EXENTS ;NO. OF ENTRIES + JSR GETDRD ;LOAD APPROPRIATE DIR + BNE #20 + LDAIM 4 + CMP EXARG + BNE #35 + +;IF HERE, COPY FILE NAME FROM DIRECTORY +;INTO RESULT AREA. + + LDYIM DRNAME ;OFFSET IN DIR. +30 LDAIY DPTRLD + STAI INFPTR + INY + JSR INCIPT + CPYIM DRFREE + BNE #30 + + LDYIM DRSQNO + LDAIY DPTRLD ;Read dir. sequence number + PHA ;Store for later use + + LDA DIRACC + LDYIM ARGD + STAIY ARGPTR + PLA ;Pull sequence number + INY + STAIY ARGPTR + LDA DRDISC + INY + STAIY ARGPTR + INY + LDA DRDISC+1 + STAIY ARGPTR + BRA #70 + +35 JSR INTPRE ;PREVEN := DIRSTA + +;FOR I=0 TO EXENTR DO +;$( SET CURRENT := NEXT(PREV. ENTRY) +;IF END OF DIR...EXIT WITH RC SET +;PREVENTRY := CURRENT ENTRY +;$) + +40 JSR SETCRN + BEQ #60 ;Zero => end of dir => exit + LDA EXENTR + DEC EXENTR + TAX + BEQ #45 ;LOOP FINISHED + JSR MOVCRN ;PREVEN := CRNTEN + BRA #40 + +;SET ROUTINE TO BE USED, DEPENDING +;ON EXARG. +;EXRTN := JMP <examine routine> + +45 LDA EXARG + ASLA + TAX + LDAAX DEXTAB + STA EXRTN+1 + LDAAX DEXTAB+1 + STA EXRTN+2 + LDAIM JMPINS + STA EXRTN + LDAIM 0 ;NO. OF ENTRIES + +;LOOP ROUND EXAMINE ROUTINE, DECREMENTING +;EXENTS, AND CHAINING THROUGH DIR. + +50 PHA ;STORE NO. OF ENTRIES + JSR EXRTN ; call routine + BEQ #55 + PLX ;Restore stack + JSR UNLOCK + BRA #75 ;Error -> exit [always jump] + +55 PLA + INCA ;ADD NO. OF ENTS. + PHA + LDA CRNTEN + STA PREVEN + LDA CRNTEN+1 + STA PREVEN+1 + JSR SETCRN ;CURRENT := NEXT(PREV) + BEQ #65 ;NOT OK, FINISH LOOP + PLA + CMP EXENTS + BNE #50 + +;FINALLY, SET END OF BLOCK INDICATOR. +60 PHA +65 LDAIM EXTERM + STAI INFPTR + JSR INCIPT ;INCREMENT POINTER TO END OF BLOCK (USED IN TXCB). + LDYIM ARGB + LDA INFPTR + STAIY ARGPTR + INY + LDA INFPTR+1 + STAIY ARGPTR + INY + PLA ;GET NO. OF ENTRIES + STAIY ARGPTR + + LDYIM DRSQNO + LDAIY DPTRLD ;Get sequence no. of examined dir. + LDYIM ARGE + STAIY ARGPTR ;And return it + +70 JSR UNLOCK + + LDAIM 0 ;OK EXIT +75 JMP DREXIT + + + +;******** DRINFO ******** + +;DRINFO: RETRIEVE DETAILS OF A GIVEN OBJECT IN +;FORMATTED FORM. + +;ENTRY: +;ARGB-C PTR TO USER INFO +;ARGD-E PTR TO FILE TITLE +;ARGF-G ADDRESS OF RESULT AREA +;ARGH Wild Card Flag + +;EXIT: +;ARGB-C ADDRESS OF BYTE AFTER RESULT AREA + +;BYTE AFTER RESULT AREA IS USED TO +;SET UP BUFFER POINTERS IN TXCB AFTER +;DETAILS CALL. + + +DRINFO ROUT + JSR DRRET2 ;**4/4/88** Retrieve info to output area + BNE #40 + + JSR SETINF ;Set pointer to result area + LDA INFPTR ;Set up to copy details + STA MOVFRM ;(as we will overwrite output area) + LDA INFPTR+1 + STA MOVFRM+1 + SEC + LDAIM :LSB:DETNAM + STA MOVTO + SBCIM :LSB:DRTITL + STA CRNTEN ;Save for use in EXAM routines + LDAIM :MSB:DETNAM + STA MOVTO+1 + SBCIM :MSB:DRTITL + STA CRNTEN+1 + LDXIM INFNXT ;Move all details + JSR MOVE + + JSR MOVEFT ;Copy info as text, name first + JSR OUTSP + JSR OUTLEX + STZ FILLFL + LDA DETSZ+2 + JSR OUTBYT + LDA DETSZ+1 + JSR OUTBYT + LDA DETSZ + JSR OUTBYT + LDXIM 3 + JSR OUTSPS + JSR OUTEN2 ;Rest of entry common with EXAM + +;END OF ENTRY. PUT CR AT END TO FORCE +;A NEW LINE IF OSASCII'ING AT THE +;CLIENT END, AND EXTERM CHAR. TO +;INDICATE END OF DATA. + + LDAIM CR + JSR OUTCH + LDAIM EXTERM + JSR OUTCH + + LDYIM ARGB ;PUT INFPTR ON STACK AS RESULT + LDA INFPTR + STAIY ARGPTR + INY + LDA INFPTR+1 + STAIY ARGPTR + + LDAIM 0 + +40 JMP DREXIT + +;Copy DIRSIN to OBJSIN + +DIROBJ ROUT + LDA DIRSIN + STA OBJSIN ;SET SIN FOR SIZE ROUTINE + LDA DIRSIN+1 + STA OBJSIN+1 + LDA DIRSIN+2 + STA OBJSIN+2 + RTS + + + +;************ DRMAKE ************ + + +;DRMAKE: MAKE THE ROOT DIRECTORY-BUT DON'T RETAIN IT. +;USED IN DISC INITIALISATION. + +;ENTRY: ARGB-ARGD = APPROX SIZE OF DIR(IN BYTES) +;N.B. DRDISC MUST = DISC NUMBER + +;EXIT : ARGA = RC +;ARGF-ARGS SAME AS DIRMAN.PRESERVE'S ENTRY ARGS + +DRMAKE ROUT + [ 1=0 + STZ DIRWC ;get wild card flag + LDYIM ARGB + LDAIY ARGPTR + STA DIRTMP + INY + LDAIY ARGPTR + STA DIRTMP+1 + INY + LDAIY ARGPTR + STA DIRTMP+2 + STZ EXRTN ;**23/1/87** no parent directory + STZ EXRTN+1 + STZ EXRTN+2 + JSR MAKDIR + +;MOVE "$" INTO THE HEADER + + BNE #40 + LDXIM NAMLNT + LDYIM DRNAME + LDAIM ROOT +10 STAIY DPTRLD + LDAIM SPACE + INY + DEX + BNE #10 + +;NOW ENSURE THE DIR UPTO DATE ON DISC AND ENSURE +;THE DISC MAP + + JSR ENSRIT ;ENSURE & UNLOCK IT + BEQ #30 + +20 JSR DELOBJ ;DELETE IT + BRA #40 + +30 JSR ENSOMP ;OBJSIN MUST = SIN OF DIR + BNE #20 +40 JMP DREXIT + | + LDAIM &FF + JMP DREXIT ;**3/10/84** + ] + +;************* DRFTDN **************** + +;GIVEN FILE TITLE, ANALYSE TO GET DISC NUMBER +;AND RETURN. USED BY SAVE IN C.PROC TO +;RESOLVE ON WHAT DISC TO SAVE A FILE + +;ENTRY: +;ARGB-C PTR TO USER INFO +;ARGD-E PTR TO FILE TITLE + +;EXIT: +;ARGB-C DISC NUMBER + +DRFTDN ROUT + LDYIM ARGF + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV + BNE #10 + LDYIM ARGB + LDA DRDISC + STAIY ARGPTR + INY + LDA DRDISC+1 + STAIY ARGPTR + LDAIM 0 ;=> success +10 JMP DREXIT + + LNK UADE0D diff --git a/FileStore/SRC/FileStore/Uade0D.6502 b/FileStore/SRC/FS/FileStore/Uade0D similarity index 98% rename from FileStore/SRC/FileStore/Uade0D.6502 rename to FileStore/SRC/FS/FileStore/Uade0D index 88a6a88..124dfad 100644 --- a/FileStore/SRC/FileStore/Uade0D.6502 +++ b/FileStore/SRC/FS/FileStore/Uade0D @@ -148,11 +148,6 @@ CHKTEX ROUT BEQ #40 CMPIM "." BEQ #40 - -;v1.23 - CMPIM ":" - BEQ #40 - CMPIM "#" BEQ #40 ;Nope => error CMPIM "$" @@ -575,18 +570,11 @@ INITDV ROUT 84 RTS 85 JSR #77 ;**20/5/87** initialise to current directory - -;v1.23 - LDYIM &19 - LDAIY DRUSIN - -;v1.31 -; LDYIM HTDISC ;**1/6/88** "^" for parent directory -; LDAIY HNDPTR ;**1/6/88** get current disc + LDYIM HTDISC ;**1/6/88** "^" for parent directory + LDAIY HNDPTR ;**1/6/88** get current disc STA DRDISC INY -; LDAIY HNDPTR - LDAIY DRUSIN + LDAIY HNDPTR STA DRDISC+1 JSR RETPAR ;**20/5/87** retrieve parent BNE #84 diff --git a/FileStore/SRC/FileStore/Uade0DA.6502 b/FileStore/SRC/FS/FileStore/Uade0DA similarity index 85% rename from FileStore/SRC/FileStore/Uade0DA.6502 rename to FileStore/SRC/FS/FileStore/Uade0DA index 7cc75e4..1318e81 100644 --- a/FileStore/SRC/FileStore/Uade0DA.6502 +++ b/FileStore/SRC/FS/FileStore/Uade0DA @@ -141,35 +141,9 @@ Tsparn ROUT ;**1/6/87** ; Retrieve parent directory **23/1/87** -RETPAR -;v1.23 - LDYIM UTPRIV - LDAIY DRUSIN ;A:=HANDLE FOR SELECTED DIR - ANDIM &40 - BNE #20 - LDA UMHUFD - JSR FNDHND ;FIND HANDLE IN HANDTB - BNE #60 ; D0 51 - LDAIM :LSB:DRDISC ; A9 BA - STA MOVFRM ; 85 22 - LDAIM :MSB:DRDISC ; A9 8A - STA MOVFRM+1 ; 85 23 - CLC ; 18 - LDA HNDPTR - ADCIM 5 - STA MOVTO - LDA HNDPTR+1 - ADCIM 0 - STA MOVTO+1 - LDXIM 5 - JSR COMPAR - BNE #20 - LDAIM " " - STA DIRACC -20 JSR LOADDR ;**23/1/87** load current directory - BNE #10 - - +RETPAR ROUT + JSR LOADDR ;**23/1/87** load current directory + BNE #50 LDYIM DRSTAR+DRLINK ;**23/1/87** special unchained entry? LDAIM &FF CMPIY DPTRLD @@ -188,59 +162,33 @@ RETPAR STA DIRSIN+2 JSR UNLOCK ;release current directory - JSR LOADDR ;load parent directory - BNE #10 - LDAIM 0 - RTS + LDYIM UTPRIV ;now select access + LDAIY DRUSIN + ANDIM SYSTPV ;same as now if system user + BNE #30 + LDAIM 4 ;MAPMAN.SINOFROOT + JSR SETDSA + JSR MAPMAN ;**1/6/88** revised tests + BNE #70 ;fail if can't locate root + LDYIM ARGB ;check if parent is root directory + LDAIY NEWARG + CMP DIRSIN + BNE #30 ; no, will use same access as child + INY + LDAIY NEWARG + CMP DIRSIN+1 + BNE #30 + INY + LDAIY NEWARG + CMP DIRSIN+2 + BNE #30 + LDAIM TYPDIR+ANYBDY ;root, access reverts now to public + STA DIRACC -;v1.31 -; JSR LOADDR ;**23/1/87** load current directory -; BNE #50 -; LDYIM DRSTAR+DRLINK ;**23/1/87** special unchained entry? -; LDAIM &FF -; CMPIY DPTRLD -; BNE #60 -; INY -; CMPIY DPTRLD -; BNE #60 -; LDYIM DRSTAR+DRSIN ;**23/1/87** extract parent SIN only -; LDAIY DPTRLD -; STA DIRSIN -; INY -; LDAIY DPTRLD -; STA DIRSIN+1 -; INY -; LDAIY DPTRLD -; STA DIRSIN+2 -; JSR UNLOCK ;release current directory -; -; LDYIM UTPRIV ;now select access -; LDAIY DRUSIN -; ANDIM SYSTPV ;same as now if system user -; BNE #30 -; LDAIM 4 ;MAPMAN.SINOFROOT -; JSR SETDSA -; JSR MAPMAN ;**1/6/88** revised tests -; BNE #70 ;fail if can't locate root -; LDYIM ARGB ;check if parent is root directory -; LDAIY NEWARG -; CMP DIRSIN -; BNE #30 ; no, will use same access as child -; INY -; LDAIY NEWARG -; CMP DIRSIN+1 -; BNE #30 -; INY -; LDAIY NEWARG -; CMP DIRSIN+2 -; BNE #30 -; LDAIM TYPDIR+ANYBDY ;root, access reverts now to public -; STA DIRACC -; -;30 JSR LOADDR ;load parent directory -; BNE #50 -; LDAIM 0 -;50 RTS +30 JSR LOADDR ;load parent directory + BNE #50 + LDAIM 0 +50 RTS 60 LDAIM DRERRC ;parent not found 70 JMP UNLOCK ;unlock and exit diff --git a/FileStore/SRC/FileStore/Uade0E.6502 b/FileStore/SRC/FS/FileStore/Uade0E similarity index 91% rename from FileStore/SRC/FileStore/Uade0E.6502 rename to FileStore/SRC/FS/FileStore/Uade0E index ceba9d8..38e60b3 100644 --- a/FileStore/SRC/FileStore/Uade0E.6502 +++ b/FileStore/SRC/FS/FileStore/Uade0E @@ -373,14 +373,6 @@ MOVEFT ROUT BCC #10 RTS -;v1.23 -OUTZRO LDXIM 8 - LDAIM "0" ;Used to put out root load/exec addresses -OUTZLP JSR OUTCH - DEX - BNE OUTZLP - RTS - OUTSPS JSR OUTSP DEX @@ -465,24 +457,18 @@ OUTDAT ROUT LDYIM DRDATE LDAIY CRNTEN -;v1.23 - STA TDATE - INY - LDAIY CRNTEN - STA TDATE + 1 - -OUTRTD - -;ENTRY POINT FOR PRINTING ROOT DATE, SET IN -;TDATE DURING INITDV - - LDA TDATE + PHA ;**24/2/88** + ANDIM &1F ;**24/2/88** Isolate day of month JSR OUTDEC LDAIM ":" JSR OUTCH - LDA TDATE + 1 + PLA ;**24/2/88** + ANDIM &E0 ;**24/2/88** Year high order + STA Fillfl ;**24/2/88** + LDYIM DRDATE+1 + LDAIY CRNTEN PHA ANDIM &F JSR OUTDEC ;MONTH @@ -493,52 +479,18 @@ OUTRTD LSRA LSRA LSRA + ORA Fillfl ;**24/2/88** LSRA CLC ;ADD TO GET BASEYR ADCIM BASEYR - JSR OUTDEC + CMPIM 100 ;**24/2/88** Year 20xx? + BCC #10 + SBCIM 100 +10 JSR OUTDEC JMP OUTSP - - -;v1.31 -; -; PHA ;**24/2/88** -; ANDIM &1F ;**24/2/88** Isolate day of month -; JSR OUTDEC -; -; LDAIM ":" -; JSR OUTCH -; -; PLA ;**24/2/88** -; ANDIM &E0 ;**24/2/88** Year high order -; STA Fillfl ;**24/2/88** -; LDYIM DRDATE+1 -; LDAIY CRNTEN -; PHA -; ANDIM &F -; JSR OUTDEC ;MONTH -; LDAIM ":" -; JSR OUTCH -; -; PLA -; LSRA -; LSRA -; LSRA -; ORA Fillfl ;**24/2/88** -; LSRA -; CLC -; -;;ADD TO GET BASEYR -; -; ADCIM BASEYR -; CMPIM 100 ;**24/2/88** Year 20xx? -; BCC #10 -; SBCIM 100 -;10 JSR OUTDEC -; JMP OUTSP @@ -557,14 +509,7 @@ OUTDEC ROUT TXA ;OUTPUT TOP DIGIT JSR #20 PLA -20 -;v1.23 - CLC - ADCIM "0" - -;v1.31 -;ORAIM "0" ;CONVERT TO CHAR. - +20 ORAIM "0" ;CONVERT TO CHAR. JMP OUTCH @@ -578,10 +523,6 @@ OUTACC ROUT LDYIM DRACCS ;OFFSET IN DIR. ENTRY LDAIY CRNTEN ASLA ;ONE LEFT SO ACCESS BITS ROTATED INTO B.7 - -;v1.23 -OUTACA - LDXIM 0 LDYIM 0 @@ -632,10 +573,6 @@ OACCCH ASLA OUTSZE ROUT JSR CRNSIN ;SET CURRENT SIN TO A VARIABLE - -;v1.23 -OUTSZA - JSR SETDSN ;SET DISC NO. + SIN ON STACK JSR SINSZE ;GET SIZE FROM MAP BNE #20 ;ERROR ... EXIT diff --git a/FileStore/SRC/FileStore/Uade0EA.6502 b/FileStore/SRC/FS/FileStore/Uade0EA similarity index 93% rename from FileStore/SRC/FileStore/Uade0EA.6502 rename to FileStore/SRC/FS/FileStore/Uade0EA index 771f8fe..95a06b8 100644 --- a/FileStore/SRC/FileStore/Uade0EA.6502 +++ b/FileStore/SRC/FS/FileStore/Uade0EA @@ -79,17 +79,7 @@ RETA12 STA TEMPA ;skip DELCHK entry point LDAIM DRERRK ;TYPES DON'T MATCH BRA #15 -;v1.23 -30 JSR RATDIR - BNE #15 - JSR ENSMAP - BNE #20 - - -;v1.31 -;30 JSR #45 ;**1/6/88** check entry code and update header - - +30 JSR #45 ;**1/6/88** check entry code and update header JSR CRNSIN ;OBJSIN:=SIN OF OBJECT TO BE DELETED JSR COPYDT ;COPY OBJECT DETAILS INTO DIR JSR COPYNM ;Copy name TXTNAM -> dir. entry @@ -113,30 +103,23 @@ RETA12 STA TEMPA ;skip DELCHK entry point BEQ #10 ;TRY AGAIN RTS ;Failed, exit (directory unlocked) **25/12/86** -;v1.23 -50 JSR RATDIR ;IF DIR THEN UPDATE NAME IN HEADER - BNE #15 - JSR ENSMAP - BNE #15 - -;v1.31 -;45 LDYIM ARGA ;**1/6/88** check if preserve-check only -; LDAIY ARGPTR -; EORIM 13 ;set zero if so -; BEQ #47 ;and go unlock and return -; JSR RATDIR ;IF DIR THEN UPDATE NAME IN HEADER -; BNE #47 -; JSR ENSMAP ;ENSURE MAP OF OBJECT TO BE RETAINED -; BNE #47 -; RTS -; -;47 TAY -; PLA -; PLA -; TYA -; BRA #15 -; -;50 JSR #45 ;**1/6/88** check entry code and update header +45 LDYIM ARGA ;**1/6/88** check if preserve-check only + LDAIY ARGPTR + EORIM 13 ;set zero if so + BEQ #47 ;and go unlock and return + JSR RATDIR ;IF DIR THEN UPDATE NAME IN HEADER + BNE #47 + JSR ENSMAP ;ENSURE MAP OF OBJECT TO BE RETAINED + BNE #47 + RTS + +47 TAY + PLA + PLA + TYA + BRA #15 + +50 JSR #45 ;**1/6/88** check entry code and update header ;REMOVE ENTRY FROM FREE CHAIN AND INSERT ;IT IN APPROPRIATE POSITION, ON THE IN USE CHAIN. diff --git a/FileStore/SRC/FileStore/Uade0F.6502 b/FileStore/SRC/FS/FileStore/Uade0F similarity index 89% rename from FileStore/SRC/FileStore/Uade0F.6502 rename to FileStore/SRC/FS/FileStore/Uade0F index a5d6cef..6ba7457 100644 --- a/FileStore/SRC/FileStore/Uade0F.6502 +++ b/FileStore/SRC/FS/FileStore/Uade0F @@ -79,33 +79,9 @@ ATNWUS ROUT ;Find free slot in p/w file -;v1.23 05 STZ ATWORK ;Find free slot STZ ATDRIV ;**23/1/87** First drive to scan in default - - JSR CHKPRV ;**23/1/87** To get GENPTR:=Userinfo - LDYIM UTDISC - LDAIY GENPTR - TAX - INY - LDAIY GENPTR - LDYIM ARGC - STAIY NEWARG ;Selected disc number to stack - TXA - DEY - STAIY NEWARG - LDAIM 15 - JSR SETRTN - JSR MAPMAN ;MAPMAN.MPDRNB - BNE #07 ;use default if error - LDYIM ARGB - LDAIY NEWARG ;Else get selected drive number - STA ATDRIV -07 JSR FDUSID - -;v1.31 -; JSR ATOPWF ;**22/5/88** Scan drives to open pw file - + JSR ATOPWF ;**22/5/88** Scan drives to open pw file BEQ #10 CMPIM ATERRB ;Not found? BEQ ATNWUE ;Go enlarge file @@ -202,33 +178,32 @@ ATNWUS ROUT 65 JSR APENFL ;**25/12/86** flush from cache JMP ATEXIT -;v1.31 -;; ATOPWF finds a suitable password file, on disc with -;; user's CSD if available, else on lowest numbered drive -;; Exit A=0 if OK else error code -; -;ATOPWF ROUT -; JSR CHKPRV ;**23/1/87** To get GENPTR:=Userinfo -; BNE #10 -; LDYIM UTDISC -; LDAIY GENPTR -; TAX -; INY -; LDAIY GENPTR -; LDYIM ARGC -; STAIY NEWARG ;Selected disc number to stack -; TXA -; DEY -; STAIY NEWARG -; LDAIM 15 -; JSR SETRTN -; JSR MAPMAN ;MAPMAN.MPDRNB -; BNE #07 ;use default if error -; LDYIM ARGB -; LDAIY NEWARG ;Else get selected drive number -; STA ATDRIV -;07 JSR FDUSID -;10 RTS +; ATOPWF finds a suitable password file, on disc with +; user's CSD if available, else on lowest numbered drive +; Exit A=0 if OK else error code + +ATOPWF ROUT + JSR CHKPRV ;**23/1/87** To get GENPTR:=Userinfo + BNE #10 + LDYIM UTDISC + LDAIY GENPTR + TAX + INY + LDAIY GENPTR + LDYIM ARGC + STAIY NEWARG ;Selected disc number to stack + TXA + DEY + STAIY NEWARG + LDAIM 15 + JSR SETRTN + JSR MAPMAN ;MAPMAN.MPDRNB + BNE #07 ;use default if error + LDYIM ARGB + LDAIY NEWARG ;Else get selected drive number + STA ATDRIV +07 JSR FDUSID +10 RTS ;***** ATCKPW ***** @@ -356,17 +331,8 @@ ATSTPW ROUT ;EXIT: ARGA = RC ATDLUS ROUT - -;v1.23 - JSR CHKPRV - BNE #30 - JSR SETAUT - JSR FDUSID - BNE #30 - -;v1.31 -; JSR ATOPWF ;**22/3/88** open suitable password file -; BNE #30 ;**22/3/88** br if error (including unprivileged) + JSR ATOPWF ;**22/3/88** open suitable password file + BNE #30 ;**22/3/88** br if error (including unprivileged) ;NOW CLEAR PASSWORD FILE ENTRY @@ -397,17 +363,8 @@ ATDLUS ROUT ATSPRT = 0, SYSTPV, LOPRIV, 0 ; table for priv bits *** 25/5/86 *** ATSPRV - -;v1.23 - JSR CHKPRV - BNE #30 - JSR SETAUT - JSR FDUSID - BNE #30 - -;v1.31 -; JSR ATOPWF ;**22/3/88** open suitable password file -; BNE #30 ;**22/3/88** br if error (including unprivileged) + JSR ATOPWF ;**22/3/88** open suitable password file + BNE #30 ;**22/3/88** br if error (including unprivileged) LDYIM ARGF LDAIY ARGPTR ;Load priv. flag diff --git a/FileStore/SRC/FS/FileStore/Uade0FA b/FileStore/SRC/FS/FileStore/Uade0FA new file mode 100644 index 0000000..0d948a0 --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Uade0FA @@ -0,0 +1,589 @@ + + OPT UADE0F ;> Uade0FA + TTL File server file UADE0FA + +;***** ATWRIT ***** + +;ENTRY as for ATFREE+ ARGF-I value to write + +ATWRIT ROUT + JSR CHKPRV + BNE #30 ;check for priv + + LDYIM ARGD + LDAIY ARGPTR + TAX + INY + LDAIY ARGPTR + LDYIM ARGC + STAIY NEWARG + DEY + TXA + STAIY NEWARG ;pointer to name + + LDAIM ARGF + STA OFF1 + LDXIM ARGPTR + LDAIM ARGD + STA OFF2 + LDYIM NEWARG + LDAIM 4 + JSR MOVBLK + + LDAIM 9 + JSR SETRTN ;call update user free space + JSR USRMAN + BNE #30 + + JSR SETAUT + JSR FDUSID + BNE #30 ;not found + + LDAIM PWFREE ;area to copy to + STA OFF2 + LDYIM PWFPTR + + LDAIM ARGF + STA OFF1 + LDXIM ARGPTR + + LDAIM 4 + JSR MOVBLK + + JSR MARKDT ;indicate that PW file is dirty + LDAIM 0 + JSR APENFL ;flush the PW file block + +30 JMP ATEXIT + +ATFPTR LDYIM ARGF ;setup Zpage pointer from ARGE + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 + RTS + +ATFIND ROUT + LDXIM 4 ;EXIT Z=1 => ok user: C=1 => not logged on + LDYIM ARGB +10 LDAIY ARGPTR + STAIY NEWARG + INY + DEX + BNE #10 ;copy stack for USRMAN + + LDAIM 6 ;find user + JSR SETRTN + JSR USRMAN + CLC + BEQ #20 ;user found in table + + CMPIM URERRE ;'not logged on' +20 RTS + +SETAUT LDYIM ARGD + LDAIY ARGPTR + STA AUTPTR + INY + LDAIY ARGPTR + STA AUTPTR+1 ;AUTPTR:=ADDRESS OF USERID + RTS + +CHKPRV ROUT + LDYIM ARGB + LDAIY ARGPTR + STA GENPTR + INY + LDAIY ARGPTR + STA GENPTR+1 + LDYIM UTPRIV + LDAIY GENPTR + ANDIM SYSTPV + BNE #10 + LDAIM ATERRD ;INSUFFICIENT PRIV + RTS + +10 LDAIM 0 + RTS + +;RETPWF: RETRIEVE PW FILE FROM DISC (ARGB-C HOLDS DISCNO) + +;FIRST SETUP ARGS FOR DIRMAN.RETRIEVE + +RETPTB = 2 ;DIRMAN.RETRIEVE + & ATUSRI ;userinfo + & PWTITL ;PW file title + & ATINF ;result area + = 0 + +RETPWF ROUT + LDYIM ARGB ;**25/12/86** Copy disc no to UTDISC + LDAIY NEWARG + LDYIM UTDISC + STAIY ATUSPT + LDYIM ARGC + LDAIY NEWARG + LDYIM UTDISC+1 + STAIY ATUSPT + + LDYIM ARGA +10 LDAAY RETPTB-ARGA + STAIY NEWARG + INY + CPYIM ARGI + BNE #10 + + JSR DIRMAN + BNE #30 + LDYIM ARGB + LDAIY NEWARG + ANDIM TYPDIR + CMPIM TYPFIL + BEQ #20 + LDAIM ATERRI ;$.PASSWORDS WRONG TYPE + JSR INTERR +20 LDAIM 0 ;RC:=0 +30 PHP + CMPIM MPERRA ;DISC NOT FOUND + BNE #40 + LDAIM ATERRA +40 PLP + RTS + +; DSCSIA: Put arg, INFDIS & INFSIN on NEWARG stack +; DSCSIN: Put just INFDIS & INFSIN on NEWARG stack +; Exit: Y=ARGF + +DSCSIA ROUT + JSR SETRTN ;**25/12/86** +DSCSIN LDYIM ARGB ;PLACE DISC NO & SIN ONTO NEWARG STACK + LDA ATINF+INFDIS ;disc number (lo) + STAIY NEWARG + INY + LDA ATINF+INFDIS+1 ;disc number (hi) + STAIY NEWARG + INY + LDA ATINF+INFSIN + STAIY NEWARG ;SIN (ls) + INY + LDA ATINF+INFSIN+1 + STAIY NEWARG ;SIN (cs) + INY + LDA ATINF+INFSIN+2 + STAIY NEWARG ;SIN (ms) + RTS + +MARKDT LDA ATSTRA + STA GENPTR + LDA ATSTRA+1 + STA GENPTR+1 + JMP MRKDRT + +;FDUSID: SEARCH THE PW FILE FOR GIVEN USERID + +;ENTRY: AUTPTR = POINTER TO USERID +; ATDRIV = first drive to scan (usually zero) +; ATWORK = +- to search for userid, 0 to find free entry +; if 0, then ATDRIV has a hint for a first drive + +;EXIT: A = RC +;PWFPTR = PTR TO RELEVANT ENTRY IN PW FILE + + +FDUSID ROUT + LDA ATDRIV ;**23/1/87** first drive to scan + LDY ATWORK ;**23/1/87** free entry with hint? + BNE #00 + DEY + STY ATDRIV ;**23/1/87** so drive 0 up next after hint +00 JSR DRVINF + BEQ #04 ;**25/12/86** Br if disc on this drive +02 INC ATDRIV ;**25/12/86** Next drive + LDA ATDRIV + CMP DRIVES + BCC #00 ;**25/12/86** More drives, scan on + LDAIM ATERRB ;**25/12/86** Cannot find user id + RTS + +04 JSR APINIT ;get first block of entries + BEQ #05 + CMPIM DRERRC ;**25/12/86** onto next disc if no pw file + BEQ #02 + RTS + +05 STZ DOTFLG ;initialise the flag for every lookup + + LDYIM PWFLAG + LDAIY PWFPTR + ANDIM INUSE ;IS THE ENTRY IN USE? + BEQ #45 + + LDA ATWORK + BEQ #60 + LDYIM PWUSID + STY TEMPA ;use registers to hold pointers + STY TEMPB ;pointer into PW file +10 LDY TEMPA + LDAIY AUTPTR + JSR ISCHAR ;C=1 -> not alpha + LDY TEMPB + EORIY PWFPTR ;Compare with PW file + BCS #15 + ANDIM &DF ;Compare with case forcing +15 BNE #60 + + LDAIY PWFPTR ;Here are equal, so check if are terminators + CMPIM TERMIN + BEQ #40 ;Both terminators => found + + CPYIM PWPASS-1 ; *** LH 24/10/85 + BNE #20 ;Not last pair so continue + LDY TEMPA ;Check USERID terminated + INY + LDAIY AUTPTR + CMPIM TERMIN + BEQ #40 ;End and terminated + BRA #60 ;Not terminated so step on + +20 INC TEMPA + INC TEMPB + LDY TEMPA + LDAIY AUTPTR + CMPIM DOT + BNE #30 + INC DOTFLG + + CPYIM MAXID ;only skip if the dot could have been omitted + BNE #30 ;from the PW file + + LDY TEMPB ;just look for "." + EORIY PWFPTR + BNE #25 ;dont adjust if it is there + INC TEMPB +25 INC TEMPA ;step past in AUTPTR, not PWFPTR + +30 LDY TEMPA + CPYIM MAXID+1 ;check that we have had a dot in first 11 chars + BNE #10 ;** LH 24/10/85 check next match ** + + LDA DOTFLG + BEQ #60 ;should have found one by now + BRA #10 ;Dot found so continue + +40 LDAIM 0 ;FOUND IT +42 RTS + +45 LDA ATWORK ;**25/12/86** looking for free slot? + BEQ #42 ;**25/12/86** exit with free slot in PWFPTR + +;NOW MAKE PWFPTR POINT TO THE NEXT ENTRY + +60 JSR APTEST ;check for end-of-window + BNE #05 + JSR APEND ;check end-of-file + BEQ #90 + JSR APNEXT ;get next window + BEQ #05 + RTS + +90 LDAIM 0 ;**25/12/86** flush final block + JSR APENFL + BNE #42 + LDA ATWORK ;**25/12/86** stop after first file + BEQ #95 ;**25/12/86** if looking for free slot + JMP #02 ;**25/12/86** userid not found - next drive + +95 LDAIM ATERRB ;**25/12/86** no free slot + RTS + +;CHEKPW: CHECK PASSWORD SUPPLIED BY THE USER WITH +;THAT IN THE PASSWORD FILE. + +;ENTRY: AUTPTR = PTR TO USERID (TERMINATED CR) FOLLOWED BY PW. +;PWFPTR = PTR TO PW FILE ENTRY. + +;EXIT: A = RC + +CHEKPW ROUT + JSR STEPUR ;Step Y past userid. to password +CHEKP1 ;Entry from SETPASSWORD (Y already set) + LDAIM PWPASS ;Set up offsets for PW comparison + STA OFF2 + +10 LDAIY AUTPTR + STY OFF1 + LDY OFF2 ;Offset into PW file + CPYIM PWPASS+MAXPW ;Check if reached end of pw in file + BEQ #20 ;If so, check that pw from AUTPTR is terminated + + EORIY PWFPTR + INC OFF2 ;Increment PW ptr. for next time + LDY OFF1 ;Get offset from AUTPTR + INY ;Increment for next time + ANDIM &DF ;Complete comparison + BNE #30 ;Not the same -> exit with error + + DEY ;Point to char. off AUTPTR + LDAIY AUTPTR ;The same -> check if end of string + INY ;Restore Y in case going back to CHEKWB + SEC + SBCIM TERMIN + BNE #10 + RTS + +20 SEC + SBCIM TERMIN + BEQ #40 ;Both are terminators => exit with zero + +30 LDAIM ATERRC ;=> not found +40 RTS + +STEPUR LDYIM 0 +50 LDAIY AUTPTR + INY + CMPIM TERMIN ;Move Y to point to posn. after userid + BNE #50 ;Not there yet + RTS + +SETAP1 ;Set pointer to callers user id + CLC + LDYIM ARGB + LDAIY ARGPTR + ADCIM UTUSID + STA AUTPTR + INY + LDAIY ARGPTR + ADCIM 0 + STA AUTPTR+1 ;AUTPTR:=PTR TO CALLER'S USERID + RTS + +;**** Start of PW paging routines **** + +;start pointer := 0 +;end pointer := 0 +;current pointer := 0 ;initialisation of variables + +;REPEAT +; load window ( end pointer DIV 256, window size) +; End pointer+:= amount loaded +; Current pointer := Current pointer REM 256 +; REPEAT +; perform operation (current pointer) +; start pointer+:= entry size +; current pointer+:= entry size +; UNTIL end pointer - start pointer < entry size OR ... +; IF end pointer <> start pointer THEN end pointer -:= 256 +;UNTIL end pointer >= file size OR ... + +;**** Initialisation of variables **** + +APINIT ROUT + STZ STRPTR + STZ STRPTR+1 ;start := 0 + STZ PTREND + STZ PTREND+1 ;end := 0 + STZ PWFPTR + STZ PWFPTR+1 ;current := 0 + JSR RETPWF ;read the password file info + BEQ #20 ;first call has no window to release + CMPIM DRERRC ;**25/12/86** file not found? + BNE #20 ;continue if not + TAX + RTS ;**25/12/86** Error exit + +;**** Grab next chunk of PW file **** + +APNEXT LDAIM 0 ;flush previous block + JSR APENFL + BNE #60 ;detect error here +20 LDAIM 1 ;Disc address -> store address + JSR DSCSIA ;put disc number & SIN onto NEWARG stack + INY + LDA STRPTR+1 + STAIY NEWARG ;logical block (lo) + INY + LDAIM 0 + STAIY NEWARG ;logical block (hi) + + INY + SEC + LDA ATINF+INFSZE+1 + SBC STRPTR+1 ;get number of blocks remaining + LDX ATINF+INFSZE ;**1/6/88** round up if part sector + BEQ #30 + INCA + BEQ #35 ;**1/6/88** in case now 256 +30 CMPIM APWIND + BCC #40 ;<= window size left +35 LDAIM APWIND +40 STAIY NEWARG ;no of blocks (lo) + + INY + LDAIM 0 ;no of blocks (hi) + STAIY NEWARG + + JSR STRMAN ;do the call + + PHA ;save RC + CLC + LDYIM ARGB + LDAIY NEWARG ;get store address + STA ATSTRA + ADC STRPTR + STA PWFPTR + INY + LDAIY NEWARG + STA ATSTRA+1 ;two bytes + ADCIM 0 + STA PWFPTR+1 + + INY + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 ;get number of blocks loaded + + LDYIM CEBLKS ;from cache descriptor + LDAIY GENPTR + CLC + ADC STRPTR+1 ;**1/6/88** + STA PTREND+1 ;update PTREND by this value + + PLA + BCC #60 ;**1/6/88** br if password file not too big + JSR APENFL ;**1/6/88** flush unwanted segment + LDAIM ATERRB ;**1/6/88** else say entry not found +60 RTS ;return code from STRMAN + +;**** Update counters, test end condition **** +;**** Z-> end condition met **** + +APTEST ROUT + CLC + LDAIM PWENSZ + ADC STRPTR + STA STRPTR ;strptr+:= entry size + BCC #10 + INC STRPTR+1 + +10 CLC + LDAIM PWENSZ + ADC PWFPTR + STA PWFPTR ;curptr+:= entry size + BCC #20 + INC PWFPTR+1 + +20 LDA STRPTR+1 ;**1/6/88** test for endfile + CMP ATINF+INFSZE+1 + BCC #30 + LDA STRPTR + CMP ATINF+INFSZE + BCS #40 + +30 SEC + LDA PTREND + SBC STRPTR + TAX ;save result + LDA PTREND+1 + SBC STRPTR+1 + BNE #50 ;not zero condition + TXA + BEQ #50 ;start=end + CMPIM PWENSZ + LDXIM &FF ;unset Z if necessary + BCS #50 +40 LDAIM 0 +50 RTS + +;**** test for end of PW file **** + +APEND ROUT + LDXIM &FF + LDA PTREND+1 + CMP ATINF+INFSZE+1 + BCC #10 + BNE #00 + LDA PTREND + CMP ATINF+INFSZE + BCC #10 +00 INX +10 TXA ;set code + RTS ;Z shows condition + + +;**** release old window **** + +APENLV ROUT + PHA + LDAIM 3 ;STRMAN.unlock window + BRA #10 ;but leave it in cache + +APENFL PHA + LDAIM 4 ;STRMAN.flush old window +10 JSR SETRTN + INY + LDA ATSTRA ;store address + STAIY NEWARG + INY + LDA ATSTRA+1 + STAIY NEWARG + INY + LDAIM &FF + STAIY NEWARG ;decrement reference count (2) +20 JSR STRMAN ;make call + TAX ;return the first error code + PLA + BNE #30 + TXA +30 RTS ;return error + +APENRG ROUT ;enlarge the password file + LDA ATINF+INFSZE+2 + BNE #00 + LDA ATINF+INFSZE+1 ;**1/6/88** see if maximal size already + CMPIM &FE ;**1/6/88** won't work if bigger than this + BCC #05 ;**1/6/88** because two byte offsets only used +00 LDAIM ATERRH ;**1/6/88** password file too big + RTS + +05 LDAIM 14 ;MAPMAN.changesize without space check + JSR DSCSIA ;put disc number & SIN onto NEWARG stack + INY + LDAIM 0 + STAIY NEWARG ;new size (lo) + CLC + INY + LDA ATINF+INFSZE+1 + ADCIM 1 + STAIY NEWARG ;new size (mid) + INY + LDA ATINF+INFSZE+2 + ADCIM 0 + STAIY NEWARG ;new size (hi) + + JSR MAPMAN + BNE #10 ;skip if some error + + LDAIM 13 ;Zero area of disc + JSR DSCSIA + INY + LDA ATINF+INFSZE + STAIY NEWARG + INY + LDA ATINF+INFSZE+1 + STAIY NEWARG + INY + LDA ATINF+INFSZE+2 + STAIY NEWARG + + JSR MAPMAN + BNE #10 + + LDAIM 6 ;MAPMAN.ensure + JSR DSCSIA ;discno & sin onto NEWARG stack + JSR MAPMAN +10 RTS ;leave with RC set + + LNK UADE10 diff --git a/FileStore/SRC/FileStore/Uade10.6502 b/FileStore/SRC/FS/FileStore/Uade10 similarity index 98% rename from FileStore/SRC/FileStore/Uade10.6502 rename to FileStore/SRC/FS/FileStore/Uade10 index 6bf4c7d..666746d 100644 --- a/FileStore/SRC/FileStore/Uade10.6502 +++ b/FileStore/SRC/FS/FileStore/Uade10 @@ -98,12 +98,9 @@ MPCRSP LDYIM ARGG JSR FNDMAP ;GET POINTER TO MAPTB BEQ #25 20 JMP #90 - -25 -;v1.31 -; LDA Mpdrve ;**24/2/88** check drive for write protect -; JSR Testdv -; BNE #20 +25 LDA Mpdrve ;**24/2/88** check drive for write protect + JSR Testdv + BNE #20 LDYIM ARGD ;NUMBER OF BYTES REQUIRED LDAIY ARGPTR STA DIVPAR @@ -116,7 +113,6 @@ MPCRSP LDYIM ARGG JSR DVDE ;TO FIND MOST LIKELY NUMBER OF BLOCKS BCC #30 JMP #85 - 30 LDYIM MPCYMP ;READY TO CHECK IF ENOUGH ROOM LDAIY MAPPTR STA MPCYPT diff --git a/FileStore/SRC/FS/FileStore/Uade10A b/FileStore/SRC/FS/FileStore/Uade10A new file mode 100644 index 0000000..f7a18a5 --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Uade10A @@ -0,0 +1,723 @@ + OPT UADE10 ;> Uade10A + TTL File server file UADE10A + +;MPCHSZ: CHANGE THE SIZE OF A CHAIN ON DISC + +;ENTRY: +;ARGB-C DISC NO +;ARGD-F SIN +;ARGG-I NEW SIZE IN BYTES +;ARGJ-K Ptr to user info + +;EXIT: ARGA = RC + +;FUNCTION: MAPTB IS SCANNED TO FIND THE RELEVANT ENTRY. IF NECESSARY +;THE SECTOR MAP IS READ INTO STORE. THE CURRENT SIZE IS DISCOVERED AND IT +;IS DECIDED WHETHER IT IS AN INCREASE OR A DECREASE IN SIZE. +;THE RELEVANT NUMBER OF BLOCKS ARE THEN ALLOCATED/DEALLOCATED. + + +MPCHSZ ROUT + JSR FNDMAP ;find map entry, set MPDRVE ** 16/1/86 ** + BNE #10 + LDYIM ARGJ + JSR MPFRAD ;get size of chain + BNE #10 ;catch errors + + LDXIM :LSB:-3 + LDYIM ARGG + SEC +05 LDAAX MPNWFR-:LSB:-3 + SBCIY ARGPTR + STAAX MPNWFR-:LSB:-3 + INY + INX + BNE #05 ;calculate new size required + + LDA MPNWFR+3 + SBCIM 0 + STA MPNWFR+3 + + LDAIM MPERRN + BCC #10 ;exit 'cos there's no room + BRA #08 + +MPCHSJ JSR FNDMAP + BNE #10 +08 STZ ERRTYP ;NO ERRORS + STZ DNDLTE + STZ MPTMPB + STZ MPTMPB+1 + STZ MPTMPB+2 + STZ SAVSC ;FIRST BLOCK FLAGGED + JSR MPsetd ;**8/5/87** MPTMPA->ARGD + LDAIY ARGPTR ;GET LENGTH IN BYTES + STA DIVPAR + INY + LDAIY ARGPTR + STA DIVPAR+1 + INY + LDAIY ARGPTR + STA DIVPAR+2 + CLC + JSR RDMPBK ;READ IN RELEVANT MAP BLOCK + LDA ERRTYP + BEQ #13 + LDAIM MPERRC +10 JMP MPCHEN ;REPORT DISC ERROR + +13 JSR DVDE ;DIVIDE BYTES TO GET BLOCKS + BCC #16 + LDAIM MPERRB + BRA #10 + +16 LDA DIVTMP ;DECREMENT SINCE NO MAP BLOCK REQUIRED + BNE #18 + LDA DIVTMP+1 + BNE #17 + DEC DIVTMP+2 +17 DEC DIVTMP+1 +18 DEC DIVTMP + + STZ MPTMPB + STZ MPTMPB+1 + STZ MPTMPB+2 + +19 LDA MAPTMP ;ADDRESS OF MAP BLOCK + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + CLC + LDA MPMBPT ;GET TO POINT AT ENTRIES + ADCIM :LSB:MBENTS + STA MPMBPT + LDA MPMBPT+1 + ADCIM :MSB:MBENTS + STA MPMBPT+1 +20 LDYIM 0 + LDAIY MPMBPT ;CHECK IF NEXT POINTER IS ZERO + INY + ORAIY MPMBPT + INY + ORAIY MPMBPT + BEQ #30 + CLC + LDA MAPTMP + ADCIM :LSB:LSTENT + TAX + LDA MAPTMP+1 + ADCIM :MSB:LSTENT + CPX MPMBPT + BNE #26 + CMP MPMBPT+1 + BNE #26 + LDYIM 0 ;YES, SO THIS POINTER IS SIN OF MAP BLOCK + LDAIY MPMBPT + STA MPTMPA ;PREPARE TO READ NEW MAP BLOCK + INY + LDAIY MPMBPT + STA MPTMPA+1 + INY + LDAIY MPMBPT + STA MPTMPA+2 + CLC + JSR RDMPBK ;READ IN NEW MAP BLOCK + BRA #19 ;**8/5/87** + +26 CLC ; KEEP ADDING UP NUMBER OF BLOCKS + LDYIM 3 + LDAIY MPMBPT + ADC MPTMPB + STA MPTMPB + INY + LDAIY MPMBPT + ADC MPTMPB+1 + STA MPTMPB+1 + BCC #28 + INC MPTMPB+2 +28 LDA MPTMPB + CMP DIVTMP ;CHECK IF ENOUGH BLOCKS FOUND + LDA MPTMPB+1 + SBC DIVTMP+1 + LDA MPTMPB+2 + SBC DIVTMP+2 + BCS #30 ;BRANCH IF ENOUGH FOUND + CLC ;HERE IF JUST LOOK AT NEXT ENTRY + LDA MPMBPT + ADCIM :LSB:ENSZ + STA MPMBPT ; LOOK AT NEXT ENTRY + LDA MPMBPT+1 + ADCIM :MSB:ENSZ + STA MPMBPT+1 + BRA #20 + +30 LDA MPTMPB ;NOW SEE ABOUT THE SIZE + CMP DIVTMP + LDA MPTMPB+1 + SBC DIVTMP+1 + LDA MPTMPB+2 + SBC DIVTMP+2 + BCS #33 ;BRANCH IF MORE SPACE REQUIRED + JMP NEEDMR +33 LDA MPTMPB + CMP DIVTMP + BNE #36 ;IF THESE ARE NOT THE SAME, ODD BLOCKS MUST BE DISCARDED + LDA MPTMPB+1 + CMP DIVTMP+1 + BNE #36 + LDA MPTMPB+2 + CMP DIVPAR+2 + BNE #36 ;THEY ARE EQUAL SO NO PART GROUPS TO DEALLOCATE + JMP #80 +36 SEC ;FIND ODD NUMBER FOR DEALLOCATION + LDA MPTMPB + SBC DIVTMP + STA MPTMPB + LDA MPTMPB+1 + SBC DIVTMP+1 + STA MPTMPB+1 + LDA MPTMPB+2 + SBC DIVTMP+2 + STA MPTMPB+2 + LDYIM 3 + SEC ;GET NUMBER OF THIS GROUP TO DEALLOCATE + LDAIY MPMBPT + SBC MPTMPB + STA MPTMPD + STAIY MPMBPT + INY + LDAIY MPMBPT + SBC MPTMPB+1 + STA MPTMPD+1 + STAIY MPMBPT + LDAIM 0 + SEC + SBC MPTMPB+2 + STA MPTMPD+2 + LDA MAPTMP + STA CBSTA + LDA MAPTMP+1 + STA CBSTA+1 + JSR MMBWT + LDYIM 0 + CLC ; FIND DISC ADDRESS FOR DEALLOCATION + LDAIY MPMBPT + ADC MPTMPD + STA MPTMPE + INY + LDAIY MPMBPT + ADC MPTMPD+1 + STA MPTMPE+1 + INY + LDAIY MPMBPT + ADC MPTMPD+2 + STA MPTMPE+2 + INY + LDAIY MPMBPT + INY + ORAIY MPMBPT + BNE #40 + LDYIM 0 + TYA + STAIY MPMBPT + INY + STAIY MPMBPT + INY + STAIY MPMBPT +40 ;FIND CYLINDER NUMBER + STZ MPTMPC ;ZERO CYLINDER COUNT + STZ MPTMPC+1 +43 SEC + LDYIM MPSPCY + LDA MPTMPE + SBCIY MAPPTR + STA MPTMPE + INY + LDA MPTMPE+1 + SBCIY MAPPTR + STA MPTMPE+1 + LDA MPTMPE+2 + SBCIM 0 + STA MPTMPE+2 + BCC #46 ; FOUND IF GONE NEGATIVE + INC MPTMPC + BNE #43 + INC MPTMPC+1 + BRA #43 + +46 JSR RDBTMP ;READ THE RELEVANT BIT MAP + BEQ #47 + JMP MPCHEN ;**23/2/87** failed, attempt recovery + +47 JSR MBMLKD + LDYIM MPSPCY + CLC + LDA MPTMPE + ADCIY MAPPTR + STA MPTMPD + INY + LDA MPTMPE+1 + ADCIY MAPPTR + STA MPTMPD+1 + LDYIM 0 +50 LDA MPTMPD+1 + BNE #53 ; CANNOT OF GOT TO THE RIGHT PLACE IF THIS NON-ZERO + LDA MPTMPD + CMPIM 8 ;CHECK FOR LESS THAN EIGHT + BCC #56 ;IF LESS GO AND FIND ACTUAL BIT +53 INY + SEC + LDA MPTMPD ; KEEP DECREMENTING + SBCIM 8 + STA MPTMPD + BCS #50 + DEC MPTMPD+1 + BRA #50 + +56 LDA MPTMPB + PHA ; SAVE THIS COUNT + LDA MPTMPB+1 + PHA + LDXIM 9 ; X TRACKS POSITION IN CURRENT BYTE + LDAIY MPSCPT ; GET THE BYTE +60 RORA ; KEEP ROTATING FOR POSITION + DEX + DEC MPTMPD + BPL #60 +63 SEC ;MARK BLOCK FREE + RORA + PHP ; SAVE THESE VALUES + PHA + DEX + BEQ #70 ; CHECK FOR END OF THIS BYTE +66 LDA MPTMPB ;CHECK IF ALL BLOCKS HAVE BEEN FREED + BNE #67 + DEC MPTMPB+1 +67 DECA + STA MPTMPB + ORA MPTMPB+1 + BEQ #73 ; ZERO WHEN ALL DEALLOCATED + PLA + PLP ;GET VALUES BACK + BRA #63 ;JUMP BACK TO FREE NEXT + +70 STAIY MPSCPT ;SAVE THIS VALUE + LDXIM 8 ;SET UP FOR WHOLE BYTE + INY ;POINT TO NEXT ENTRY IN BIT MAP + PLA + PLP ;JUST TO GET RID OF THEM + LDAIY MPSCPT ; GET NEW BYTE + RORA ;SET UP FOR FREEING BLOCKS + PHP + PHA + BRA #66 + +73 PLA + PLP ;CLEAR VALUES ON STACK +76 RORA + DEX + BNE #76 + STAIY MPSCPT ; AND SAVE HIS VALUE + PLA ; RETRIEVE BLOCK COUNT + STA MPTMPB+1 + PLA + STA MPTMPB + JSR ADDFR ; ADD FREED BLOCKS TO BLOCK COUNT + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JSR MBMWT +80 LDYIM ENSZ ; NOW REST OF ENTRIES CAN BE DEALLOCATED + LDAIY MPMBPT ;CHECK FOR LAST ENTRY + INY + ORAIY MPMBPT + INY + ORAIY MPMBPT + BEQ #90 ;IF NONE LEFT WE'VE FINSHED + SEC + LDA MPMBPT ; RETRIEVE ADDRESS OF MAP BLOCK + SBC MAPTMP ; AND GET OFFSET + STA MPSCPT + LDA MPMBPT+1 + SBC MAPTMP+1 + STA MPSCPT+1 + CLC ;NOW POINT AT NEXT ENTRY + LDA MPSCPT + ADCIM :LSB:ENSZ + STA MPSCPT + LDA MPSCPT+1 + ADCIM :MSB:ENSZ + STA MPSCPT+1 + STZ MPTMPE ;don't delete this map block + JSR CLRBLK +90 JSR ULBM + JSR ENSMB + JSR ENSBM + LDA ERRTYP + BEQ #95 + LDAIM MPERRC + JMP MPCHEN + +95 JMP CSEND ;FINISH REDUCTION +; +; SIZE TO BE INCREASED +; +NEEDMR ROUT + SEC ;GET THE POINTER + LDA MPMBPT + SBC MAPTMP + STA SAVPTA ;SAVE THE OFFSET IN THE MAP BLOCK IN CASE IT NEEDS TO BE RESTORED + LDA MPMBPT+1 + SBC MAPTMP+1 + STA SAVPTA+1 + LDA MPTMPA ;SAVE THE SIN OF THE MAP BLOCK + STA SAVPTB + LDA MPTMPA+1 + STA SAVPTB+1 + LDA MPTMPA+2 + STA SAVPTB+2 + SEC ;DISCOVER HOW MUCH NEEDS TO BE ALLOCATED + LDA DIVTMP + SBC MPTMPB + STA DIVTMP + LDA DIVTMP+1 + SBC MPTMPB+1 + STA DIVTMP+1 + LDA DIVTMP+2 + SBC MPTMPB+2 + STA DIVTMP+2 + LDYIM MPCYMP ;GET ADDRESS OF CYLINDER MAP + LDAIY MAPPTR + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 + SEC + LDYIM 0 ; CHECK IF THERE IS ENOUGH SPACE + LDAIY MAPGEN + SBC DIVTMP + STAIY MAPGEN + INY + LDAIY MAPGEN + SBC DIVTMP+1 + STAIY MAPGEN + INY + LDAIY MAPGEN + SBC DIVTMP+2 + STAIY MAPGEN + BCS #10 + JMP #50 ; BRANCH IF THERE IS NO ROOM +10 LDA SAVPTA + CMPIM MBENTS + BNE #20 + LDA SAVPTA+1 + BEQ #30 ; EMPTY MAP BLOCK SO ALLOCATE FROM SIN +20 SEC + LDA MPMBPT + PHA + SBCIM :LSB:ENSZ + STA MPMBPT + LDA MPMBPT+1 + PHA + SBCIM :MSB:ENSZ + STA MPMBPT+1 + LDYIM 0 ; GET A CURRENT DISC ADDRESS + LDAIY MPMBPT + STA MPTMPA + INY + LDAIY MPMBPT + STA MPTMPA+1 + INY + LDAIY MPMBPT + STA MPTMPA+2 + PLA + STA MPMBPT+1 ;**1/7/88** restore pointer + PLA + STA MPMBPT +30 JSR DIVSEC ; FIND CYLINDER FROM SIN + LDA MPTMPB ;GET CYLINDER TO SOMEWHERE USEFUL + STA MPTMPC + LDA MPTMPB+1 + STA MPTMPC+1 + JSR GTCYPS ; FIND A CLOSE CYLINDER WITH FREE BLOCKS + LDA MPTMPE + STA MPTMPC + LDA MPTMPE+1 + STA MPTMPC+1 + JSR RDBTMP + BNE #55 ;**23/2/87** Failed, attempt to report error + LDA MAPGEN + STA MPCYPT ; READY TO ALLOCATE BLOCKS + LDA MAPGEN+1 + STA MPCYPT+1 + JSR ABLKS ; ALLOCATE ONE LOT OF BLOCKS + BCS #40 ; BRANCH IF FAILED + LDA DIVTMP + ORA DIVTMP+1 + ORA DIVTMP+2 + BEQ CSEND ; CHECK IF FINISHED + JSR FLBLKS ; FILL IN THE REST OF THE BLOCKS + BCS #40 ; BRANCH IF ALL WENT WELL + JSR ENSBM + BRA CSEND + +40 LDA SAVPTB ; IT FAILED SO DEALLOCATE ANY BLOCKS STILL ALLOCATED + STA MPTMPA ; GET SIN BACK + LDA SAVPTB+1 + STA MPTMPA+1 + LDA SAVPTB+2 + STA MPTMPA+2 + LDA SAVPTA ; GET OFFSET BACK + STA MPSCPT + LDA SAVPTA+1 + STA MPSCPT+1 + STZ MPTMPE ; LEAVE CURRENT MAP BLOCK ALONE + JSR CLRBLK ; TIDY UP +50 CLC + LDYIM 0 + LDAIY MAPGEN + ADC DIVTMP + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC DIVTMP+1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC DIVTMP+2 + STAIY MAPGEN + LDA ERRTYP + BEQ #60 + LDAIM MPERRC +55 BRA MPCHEN + +60 LDAIM MPERRB ; FLAG NO ROOM + BRA MPCHEN + +CSEND JSR RDmpbd ;**8/5/87** Read block at ARGD + LDA MAPTMP + STA MPMBPT + STA CBSTA + LDA MAPTMP+1 + STA MPMBPT+1 + STA CBSTA+1 + LDYIM BILB ; POSITION OF ODD BYTES + LDA DIVPAR ; BYTES FROM DIVISION + STAIY MPMBPT + INY + LDA DIVPAR+1 + STAIY MPMBPT + JSR MMBWT + JSR ENSMB + JSR ENSBM + LDAIM 0 ; INDICATE SUCCESS + +MPCHEN BNE #80 + LDYIM ARGA + LDAIY ARGPTR + EORIM 14 ;detect special case + BEQ #80 + LDYIM ARGJ + LDAIM 0 + JSR MPSETF +80 JMP MPEXIT + +;MPREST: +;FUNCTION: LOADS THE MAP TABLE FROM DISC. +;CHECKS THAT ALL MAPS ARE O.K. ALSO +;SETS UP TABLE FOR FREE STORE MANAGEMENT + +MPREST ROUT + STZ ERRTYP + LDX DRIVES ;FOR LOOP + LDYIM MPTBSZ + JSR SETTAB ;SET MAP TABLE AND CLEAR STORE + STY MAPTB + STY MAPPTR + STX MAPTB+1 + STX MAPPTR+1 + + LDXIM NTSIZE + LDYIM NTENSZ + JSR SETTAB ;SET NAME TABLE + STY NAMETB + STX NAMETB+1 + + STY DNMPTR + STX DNMPTR+1 + LDXIM NTSIZE + LDAIM UNUSED + LDYIM NTUSED + +;MARK ALL NAME TABLE ENTRIES UNUSED + +10 STAIY DNMPTR + PHA + JSR INAMPT + PLA + DEX + BNE #10 + + LDXIM 1 + STX NXTDNO + STZ NXTDNO+1 ;SET DISC ALLOCATION NO. + JSR INBKMN + + STZ MPDRVE +20 LDA FREPTR + STA MPSCPT ;GENERAL PTR. TO SEC. ZERO DATA + LDA FREPTR+1 + STA MPSCPT+1 + LDA MPDRVE + STA DRIVNO + + JSR RDDATA ;GET INFO FROM DISC + BNE #50 ;Ignore if disc error ** 14/06/86 ** + JSR CHKDSC ;CHECK IS FS DISC + BNE #50 ;NOPE, ISN'T + +;NOW SET MAP TABLE ENTRY FOR THIS DRIVE + + JSR SMAPEN + + JSR CHDNAM ;PUT IN NAME TABLE + BEQ #30 +25 LDAIM 0 ;Couldn't (duplicate disc name??) + LDYIM Mpnocy + STAIY Mapptr ;... so mark map entry unused + INY + STAIY Mapptr ;by saying it has no cylinders + BRA #50 ; ** 14/10/86 ** + +30 JSR Defdsc ;Define disc parameters to MOS + BNE #25 ; back off map entry if failed + +;NOW CREATE CYCLINDER MAP FOR THIS DISC'S MAP + JSR MPRESZ ;**5/3/88** get number of cylinders + CLC ;NOW INCREASE SIZE TO HOLD FREE SPACE COUNT + LDA MPTMPB + ADCIM 3 + TAY + LDA MPTMPB+1 + ADCIM 0 + TAX + JSR GETVEC ;get space for cylinder map + TYA ; SAVE ADDRESS OF CY.MAP + LDYIM MPCYMP + STAIY MAPPTR + INY + TXA + STAIY MAPPTR + JSR MPSTCY +50 JSR MPADMP + INC MPDRVE ; ** 14/06/86 ** drives contiguously numbered + LDA MPDRVE + CMP DRIVES + BNE #20 + LDAIM 0 ;RC + JMP MPEXIT + +MPRESZ ROUT ;**5/3/88*** calculate number of cylinders + JSR MPMPSZ ;total number of sectors + STZ MPTMPB + STZ MPTMPB+1 + LDYIM MPDSCS + LDAIY MAPPTR + TAX +10 LDYIM MPNOCY + CLC + LDAIY MAPPTR + ADC MPTMPB + STA MPTMPB + INY + LDAIY MAPPTR + ADC MPTMPB+1 + STA MPTMPB+1 + DEX + BNE #10 + STAIY MAPPTR ;restore total count + DEY + LDA MPTMPB + STAIY MAPPTR + CLC + ROL MPTMPB ;multiply cyls by two + ROL MPTMPB+1 + RTS + +;MPSZIN: RETURNS THE LENGTH OF A CHAIN IN BYTES AND BLOCKS + +;ENTRY: +;ARGB-C DISC NO +;ARGD-F SIN + +;EXIT: +;ARGA = RC +;ARGB-D SIZE IN BYTES +;ARGE-F SIZE IN BLOCKS + +;FUNCTION: GETS THE RELEVANT ENTRY IN MAPTB. CHECKS THAT +;THE SIN POINTS TO THE START OF A CHAIN. RETURNS THE LENGTH OF THE CHAIN. + +MPSZIN ROUT + JSR FNDMAP ;GET MAP TO MAPPTR + BNE #20 + JSR RDmpbd ;**8/5/87** Read block at ARGD + BEQ #10 + LDAIM MPERRC ;ERROR RETURN OF NOT START + BRA #20 ;AND RETURN + +10 LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + JSR MPGTSZ ;GET SIZE OF MAP + LDYIM ARGB + LDA MPTMPA ;SIZE IS IN MPTMPA + STAIY ARGPTR + INY + LDA MPTMPA+1 + STAIY ARGPTR + INY + LDA MPTMPA+2 + STAIY ARGPTR + LDYIM ARGE + LDA MPTMPD + STAIY ARGPTR ;SAVE NUMBER OF BLOCKS + INY + LDA MPTMPD+1 + STAIY ARGPTR + LDAIM 0 ;RC +20 JMP MPEXIT + +;MPSNRT: RETURNS THE SIN OF THE ROOT DIRECTORY +;ENTRY: +;ARGB-C DISC NO + +;EXIT: +;ARGA = RC +;ARGB-D SIN OF ROOT DIRECTORY +;ARGE-F DATE ROOT CREATED + + +MPSNRT ROUT + JSR FNDMAP + BNE #30 + LDYIM MPRTSN +10 LDAIY MAPPTR + PHA + INY + CPYIM MPRTSN+5 + BNE #10 + + LDYIM ARGF +20 PLA + STAIY ARGPTR + DEY + CPYIM ARGA + BNE #20 + + LDAIM 0 +30 JMP MPEXIT + + LNK UADE11 diff --git a/FileStore/SRC/FS/FileStore/Uade11 b/FileStore/SRC/FS/FileStore/Uade11 new file mode 100644 index 0000000..7dc1d14 --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Uade11 @@ -0,0 +1,629 @@ + OPT UADE11 ;> Uade11 + TTL File server file UADE11 + +;************************ +;* Restart one drive * +;* Disc number -> name * +;* Disc name -> number * +;* * +;* U T I L I T I E S * +;************************ + + +;MPFRSP: FREE SPACE + +;ENTRY: +;ARGB-C DISC NUMBER +;ARGD-F SIN +;ARGG-H Ptr to user info + +;EXIT: ARGA = RC + +;FUNCTION: MAPTB IS SEARCHED TO FIND THE RELEVANT ENTRY. IF THE SECTOR +;MAP IS NOT IN STORE IT IS READ IN. THE SIN IS CHECKED TO ENSURE THAT IT +;POINTS TO THE FIRST BLOCK OF THE CHAIN. ALL THE SECTORS ON THE CHAIN ARE +;THEN ADDED TO THE FREE CHAIN. THE FREE SECTOR COUNT IS THEN ADJUSTED. THE +;DIRTY FLAG FOR THE SECTOR MAP IS SET. + +MPFRSP ROUT + JSR FNDMAP ;GET CURRENT MAP TABLE POSITION + BNE #10 + + STZ ERRTYP + STZ DNDLTE + + LDYIM ARGG + JSR MPFRAD + BNE #10 + + JSR MPDLTE + BNE #10 + JSR ENSMB + JSR ENSBM + LDAIM 0 ; REPLY ZERO +10 LDYIM ARGG + JSR MPSETF + JMP MPEXIT + + +;MPREDR: *** RESTART ONE DRIVE ** + +;ENTRY: ARGB = DRIVE NO. + +;EXIT: ARGA = RC + +MPREDR ROUT + STZ ERRTYP + LDA BBUF + STA DSCCB+TRADD ;SET UP AREA TO READ IN SECTOR TWO + STA MPSCPT + LDA BBUF+1 + STA DSCCB+TRADD+1 + STA MPSCPT+1 + + LDYIM ARGB + LDAIY ARGPTR + STA CURDRV ;SET CURRENT DRIVE + STA MPDRVE + + JSR SMPPTR ;**6/7/88** MAPPTR to map table + LDYIM MPNOCY ;**6/7/88** see if drive was used + LDAIY MAPPTR + INY + ORAIY MAPPTR + BEQ #20 ;**6/7/88** no, pretend mount ok now + + LDA MPDRVE + JSR RDSTWO ;GET SECTOR ZERO TO BIG BUFFER + BNE #30 ;**6/7/88** + + JSR CHKDSC ;CHECK DISC IS FS DISC + BNE #30 + +; Store old MAPTB entry for use after new entry has been copied. + + LDYIM MPDCNO +10 LDAIY MAPPTR + STAAY MAPTBF-MPDCNO + INY + CPYIM MPTBSZ + BNE #10 + + JSR SMAPEN ;Move sector zero info. from BBUF + + JSR MPRESZ ;**5/3/88** get size of disc + JSR CHMPSZ ;CHECK MAP WILL FIT IN AVAILABLE SPACE + BNE #30 + + JSR MPSTCY ;SET CORRECT MAP (MOST RECENT) + + JSR AGENTB ;AGE NAME TABLE + + LDA BBUF + STA MPSCPT + LDA BBUF+1 + STA MPSCPT+1 ;CHMAPS destroys MPSCPT + + LDA MAPTBF + STA CURDSC ;Set disc no. for FNDDNO + LDA MAPTBF+1 + STA CURDSC+1 + JSR FNDDNO ;Find name table entry of old disc + LDAIM UNUSED + LDYIM NTUSED + STAIY DNMPTR ;Mark old disc unused + + JSR CHDNAM ;CHECK DISC NAME AND PUT IN NAME TABLE + BNE #30 ;POSSIBLY NOT UNIQUE DISC + JSR Defdsc ;Define disc parameters to MOS + BNE #30 + + LDAIM 0 ;=> Success +20 JMP MPEXIT ;*** EXIT ** + +30 PHA ;Error exit !! + LDYIM MPNOCY ;**6/7/88** mark entry unavailable + LDAIM 0 + STAIY MAPPTR + INY + STAIY MAPPTR + PLA + BRA #20 + +;MPDRNB: + +;ENTRY: ARGB-C DISC NUMBER + +;EXIT: ARGA = RC +;ARGB DRIVE NUMBER + +;FUNCTION: finds the relevant entry +;in MAPTB and returns the drive number currently +;containing that disc (if any) + +MPDRNB ROUT + JSR FNDMAP ;to find disc number + PHA + LDYIM ARGB ;save possible answer + LDA MPDRVE + STAIY ARGPTR + PLA + JMP MPEXIT + +;MPDSNB: + +;ENTRY: ARGB = DRIVE NUMBER + +;EXIT: ARGA = RC +;ARGB-C DISC NUMBER + +;FUNCTION: FINDS THE RELEVANT ENTRY +;IN MAPTB AND RETURNS THE DISC NUMBER CURRENTLY +;ON THAT DRIVE. + +MPDSNB ROUT + LDYIM ARGB ;TO FIND DRIVE NUMBER + LDAIY ARGPTR + CMP DRIVES + BCS #10 ;BRANCH IF LEG PULL + STA CURDRV + JSR SMPPTR + LDYIM MPNOCY ; ** 14/06/86 ** Unless disc has cyls ... + LDAIY MAPPTR + INY + ORAIY MAPPTR + BEQ #10 ; ** 14/06/86 ** It is a gap between drives + +;ENTRY FOUND SO LOOK AT IT + LDYIM MPDCNO ;FOR DISC NUMBER + LDAIY MAPPTR + LDYIM ARGB ;TO SAVE IT FOR RETURN + STAIY ARGPTR + LDYIM MPDCNO+1 + LDAIY MAPPTR + LDYIM ARGC + STAIY ARGPTR + LDAIM 0 ;RC + BRA #20 + +10 LDAIM MPERRF +20 JMP MPEXIT + +;MPDNNA + +;ENTRY: ARGB-C PTR TO DISC NAME + +;EXIT : ARGB-C DISC NO. + +MPDNNA ROUT + LDYIM ARGB + LDAIY ARGPTR + STA GENPTR + INY + LDAIY ARGPTR + STA GENPTR+1 + LDYIM 0 + + LDAIY GENPTR + CMPIM CR + BNE #10 + LDAIM MPERRK + BRA #50 ;null disc name + +10 LDAIY GENPTR + CMPIM CR + BEQ #20 ;ARG. IS TERMINATED CR, SO NEEDS PADDING + STAAY DNMBUF + INY + BRA #10 + +20 LDAIM SPACE +30 CPYIM DNAMLN ;CONTINUE PADDING ? + BCS #40 ;NOPE, Y>=DNAMLN + STAAY DNMBUF ;YEP, CONTINUE + INY + BRA #30 + +40 JSR FNDNAM ;LOOK UP NAME IN NAME TABLE + BNE #50 ;NOT FOUND ... + + LDYIM NTDNO + LDAIY DNMPTR + PHA + INY + LDAIY DNMPTR + LDYIM ARGC + + STAIY ARGPTR + PLA + DEY + STAIY ARGPTR + LDAIM 0 + +50 JMP MPEXIT + + +;MPNADN + +;** DISC NO. -> DISC NAME ** + +;ENTRY: ARGB-C DISC NO. + +;EXIT: ARGB-C PTR. TO NAME + +MPNADN ROUT + LDYIM ARGB + LDAIY ARGPTR + STA CURDSC + INY + LDAIY ARGPTR + STA CURDSC+1 + + JSR FNDDNO + BEQ #10 + + LDAIM MPERRA ;DISC NO. NOT FOUND + BRA #20 + +10 LDYIM ARGB + CLC + LDA DNMPTR + ADCIM NTNAME + STAIY ARGPTR + INY + LDA DNMPTR+1 + ADCIM 0 + STAIY ARGPTR + LDAIM 0 ;OK EXIT ... + +20 JMP MPEXIT + +;MPFREE +; RETURN SIZE OF FREE CHAIN +; +; Entry: +; ARGB-C DISC NO +; +; Exit: +; ARGB-D SIZE +; ARGE-G TOTAL SPACE + +MPFREE ROUT + JSR FNDMAP ;GET MAP TO STORE + BNE #10 + LDYIM MPCYMP + LDAIY MAPPTR + STA MPCYPT + INY + LDAIY MAPPTR + STA MPCYPT+1 + LDYIM 0 + LDAIY MPCYPT ;GET FREE SPACE + STA MPTMPA + INY + LDAIY MPCYPT + STA MPTMPA+1 + INY + LDAIY MPCYPT + STA MPTMPA+2 + LDYIM ARGB + LDA MPTMPA + STAIY ARGPTR + INY + LDA MPTMPA+1 + STAIY ARGPTR + INY + LDA MPTMPA+2 + STAIY ARGPTR + LDYIM MPSCTT + LDAIY MAPPTR + STA MPTMPA + INY + LDAIY MAPPTR + STA MPTMPA+1 + INY + LDAIY MAPPTR + LDYIM ARGG + STAIY ARGPTR + DEY + LDA MPTMPA+1 + STAIY ARGPTR + DEY + LDA MPTMPA + STAIY ARGPTR + LDAIM 0 +10 JMP MPEXIT + +;MPZDSK: ZERO AREA OF DISC +; +;ENTRY: +;ARGB-C DISC NUMBER +;ARGD-F SIN +;ARGG-I OLD SIZE +; +;EXIT: ARGA = RC + +MPZDSK ROUT + JSR MPsetd ;**8/5/87** MPTMPA = ARGD + LDAIY ARGPTR + STA OLDSZE + INY + LDAIY ARGPTR + STA OLDSZE+1 + INY + LDAIY ARGPTR + STA OLDSZE+2 + STZ OLDSZE+3 + JSR ZERDSK + JMP MPEXIT + +;********************************** +;* M A P M A N * +;* U T I L I T I E S * +;********************************** + + + +; READS THE SPECIFIED BIT MAP INTO STORE +; +; ON ENTRY +; MAPPTR points to map table entry +; MPTMPC IS CYLINDER NUMBER OF BIT MAP +; +; ON EXIT +; MPSCPT points to first byte of bit map +; MPSCOR points to first byte of bit map sector + +RDBTMP ROUT ;READ BIT MAP + STZ CBSIN ;ZERO OUT SIN + STZ CBSIN+1 + STZ CBSIN+2 + STZ MPSCPT + STZ MPSCPT+1 + LDYIM MP1BIT + LDAIY MAPPTR ;**23/1/87** See if packed bitmap + BNE #60 + LDA MPTMPC ;GET CYLINDER NUMBER + STA CBTPPT ;SAVE FOR DECREMENTING + LDA MPTMPC+1 + STA CBTPPT+1 + JSR #90 ;**23/1/87** Calculate SIN of bit map +20 JSR SETBM ;**23/1/87** FOUND SO SET SIZE OF BIT MAP CHAIN + JSR GTBTS ;READ IN BLOCK IF NECESSARY + BNE #50 ;NON-ZERO IF FAILED + CLC + LDA CBSTA ;GET STORE ADDRESS + STA MPSCOR ;**23/1/87** AND SAVE FOR RETURN + ADC MPSCPT + STA MPSCPT ;**23/1/87** calculate offset start + LDA CBSTA+1 + STA MPSCOR+1 + ADC MPSCPT+1 + STA MPSCPT+1 + LDA ERRTYP + BEQ #40 + LDA RSTFLG + BNE #30 + LDAIM IERRAJ + JSR INTERR +30 LDA CBSTA + STA CLRPTR + LDA CBSTA+1 + STA CLRPTR+1 + LDYIM 0 + LDXIM 1 + JSR CLRSTR +40 LDAIM 0 +50 RTS + +60 LDYIM MPSCYL ;**23/1/87** packed bit map code + LDAIY MAPPTR ;calculate SIN of packed map + STA CBTPPT + INY + LDAIY MAPPTR + STA CBTPPT+1 + JSR #90 + LDA MPTMPC ;get cylinder number + STA CBTPPT + LDA MPTMPC+1 + STA CBTPPT+1 +70 LDA CBTPPT ;see if sector/offset found + ORA CBTPPT+1 + BEQ #20 ;yes, go read bit map sector + LDA CBTPPT + BNE #75 + DEC CBTPPT+1 +75 DEC CBTPPT ;count through cylinders + LDYIM MP1BIT + CLC + LDA MPSCPT ;calculate offset + ADCIY MAPPTR + BEQ #80 + STA MPSCPT + ADCIY MAPPTR ;entry must not cross sector bdry + BCC #70 + BEQ #70 ;exact fit allowed ok +80 STZ MPSCPT ;flows or new sector + INC CBSIN + BNE #70 + INC CBSIN+1 + BNE #70 + INC CBSIN+2 + BRA #70 + +90 LDA CBTPPT ;CHECK IF CYLINDER FOUND + ORA CBTPPT+1 + BEQ #50 ; FOUND SO GO AND READ IN + LDYIM MPSPCY + CLC + LDA CBSIN + ADCIY MAPPTR + STA CBSIN + INY + LDA CBSIN+1 ;GET TO NEXT BIT MAP + ADCIY MAPPTR + STA CBSIN+1 + BCC #95 + INC CBSIN+2 +95 LDA CBTPPT ; DECREMENT CYLINDER COUNTER + BNE #96 + DEC CBTPPT+1 +96 DEC CBTPPT + BRA #90 + +; +; READ THE BLOCK SPECIFIED AT ARGD INTO STORE +; +RDmpbd ROUT + JSR MPsetd ;**8/5/87** MPTMPA = ARGD + CLC ;**8/5/87** fall into RDMPBK + +; +; READ THE SPECIFIED MAP BLOCK INTO STORE +; +; ON ENTRY +; MPTMPA HOLDS SIN +; CARRY SET IF BLOCK NOT TO BE READ IN +; +; ON EXIT +; MAPTMP HOLDS POINTER +; +RDMPBK ROUT ;READ IN MAP BLOCK + PHP ;SAVE STATE OF CARRY FLAG + LDA MPTMPA ;GET SIN TO RIGHT PLACE + STA CBSIN + LDA MPTMPA+1 + STA CBSIN+1 + LDA MPTMPA+2 + STA CBSIN+2 + JSR SETMB ;**1/7/88** + PLP ;GET CARRY FLAG BACK + BCS #30 ;BRANCH IF NOT TO BE READ IN + JSR GTBTS ; GET THE MAP BLOCK TO STORE + BNE #20 ; NON-ZERO IF FAILED + LDA CBSTA ;SAVE ADDRESS IN CORRECT PLACE + STA MAPTMP + STA GNCBPT + LDA CBSTA+1 + STA MAPTMP+1 + STA GNCBPT+1 + LDYIM MBSQNO ;POINT TO FIRST SEQUNCE NUMBER + LDAIY GNCBPT + TAX + CLC + LDA GNCBPT + ADCIM :LSB:LSTSQ + STA GNCBPT + LDA GNCBPT+1 + ADCIM :MSB:LSTSQ + STA GNCBPT+1 + LDYIM 0 + TXA + CMPIY GNCBPT ;COMPARE WITH LAST NUMBER + BEQ #10 + LDAIM MPERRC + RTS + +10 LDAIM 0 +20 RTS + +30 JSR FNDMB + BCC #40 + LDYIM CBSA + BRA #50 + +40 JSR GETFR ;JUST FIND A FREE SPACE + BNE #20 + LDYIM CBDR + LDA MPDRVE + STAIY GNCBPT + LDYIM CAFLG + LDAIY GNCBPT + ORAIM 1 ;FLAG ALLOCATED + STAIY GNCBPT + INY + LDA MPTMPA + STAIY GNCBPT + INY + LDA MPTMPA+1 + STAIY GNCBPT + INY + LDA MPTMPA+2 + STAIY GNCBPT + INY +50 LDAIY GNCBPT ;GET ADDRESS OF FREE STORE + STA MAPTMP + STA CLRPTR + INY + LDAIY GNCBPT + STA MAPTMP+1 + STA CLRPTR+1 + LDYIM :LSB:BTINBK + LDXIM :MSB:BTINBK + JSR CLRSTR ;CLEAR MAP BLOCK TO ZEROES SINCE NOT READ IN + BRA #10 + +; CALCULATE THE NUMBER OF SECTORS REQUIRED FROM +; THE NUMBER OF BYTES REQUIRED. +; +; ON ENTRY +; DIVPAR HOLDS THE NUMBER OF BYTES +; +; ON EXIT +; DIVPAR HOLDS ODD BYTES +; DIVTMP HOLDS THE NUMBER OF BLOCKS +; Carry Set if Overflow +; +DVDE ROUT + STZ DIVTMP + STZ DIVTMP+1 + STZ DIVTMP+2 + LDA DIVPAR + ORA DIVPAR+1 + ORA DIVPAR+2 + BEQ #40 +10 SEC ;NOW LOOP DO DIVIDE BY BLOCK SIZE + LDA DIVPAR + SBCIM :LSB:BTINBK + STA DIVPAR + LDA DIVPAR+1 + SBCIM :MSB:BTINBK + STA DIVPAR+1 + LDA DIVPAR+2 + SBCIM 0 + STA DIVPAR+2 + BCC #20 ;CARRY CLEAR AT END OF DIVISION + LDA DIVPAR + ORA DIVPAR+1 + ORA DIVPAR+2 + BEQ #30 + INC DIVTMP + BNE #10 + INC DIVTMP+1 + BRA #10 + +20 LDA DIVPAR ;REPLACE LOWER BYTE + ADCIM :LSB:BTINBK + STA DIVPAR + LDA DIVPAR+1 + ADCIM :MSB:BTINBK + STA DIVPAR+1 + BCC #30 + INC DIVPAR+2 +30 CLC + LDA DIVTMP + ADCIM 2 ;AT LEAST TWO BLOCKS LONG + STA DIVTMP + BCC #45 + INC DIVTMP+1 + BNE #45 + INC DIVTMP+2 + BNE #45 + SEC + RTS + +40 INC DIVTMP +45 CLC + RTS + + LNK UADE11A diff --git a/FileStore/SRC/FS/FileStore/Uade11A b/FileStore/SRC/FS/FileStore/Uade11A new file mode 100644 index 0000000..c36046d --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Uade11A @@ -0,0 +1,542 @@ + OPT UADE11 ;> Uade11A + TTL File server file UADE11A + +;GETPOS +; FINDS NEXT FREE POSITION IN MAP BLOCK +; SETS CARRY FLAG IF MAP BLOCK FULL +; +; ON ENTRY +; MAPGEN POINTS TO START OF MAP BLOCK +; +; ON EXIT +; MAPGEN POINTS TO NEXT FREE POSITION +; +; USES +; MPTMPE +; +GETPOS ROUT + CLC + LDA MAPGEN + ADCIM :LSB:MBENTS ;GET MAPGEN TO START OF ENTRIES + STA MAPGEN + LDA MAPGEN+1 + ADCIM :MSB:MBENTS + STA MAPGEN+1 + STZ MPTMPE + STZ MPTMPE+1 ;CLEAR VARIABLES +10 LDA MPTMPE + CMPIM :LSB:(MXENTS-1) ;CHECK FOR END OF LIST + LDA MPTMPE+1 + SBCIM :MSB:(MXENTS-1) + BCS #50 ;RETURNS WITH CARRY SET IF END OF LIST + LDYIM 0 ;Y POINTS AT SIN + LDAIY MAPGEN + BNE #30 ;ZERO IS END OF LIST + INY + LDAIY MAPGEN + BNE #30 + INY + LDAIY MAPGEN + BEQ #40 +30 CLC ;LOOK AT NEXT ENTRY + LDA MAPGEN + ADCIM ENSZ + STA MAPGEN + BCC #35 + INC MAPGEN+1 +35 INC MPTMPE ;MPTMPE HOLDS NUMBER OF ENTRIES WE'VE LOOKED AT + BNE #10 + INC MPTMPE+1 + BRA #10 + +40 CLC +50 RTS ;RETURNS HERE WITH CARRY CLEAR, ALL OK, SET IF NOT. + +; GET CYLINDER MAP POSITION +; +; STARTS A SEARCH FROM MPTMPC FOR THE NEXT +; CYLINDER WITH A FREE SECTOR +; +; ON ENTRY +; MPTMPC HOLDS THE CURRENT CYLINDER +; MAPGEN POINTS TO START OF CYLINDER MAP +; MAPPTR POINTS TO MABTB ENTRY +; +; ON EXIT +; MAPGEN POINTS TO CYLINDER WITH FREE ENTRY +; +; USES MPTMPE + +GTCYPS ROUT + LDA MPTMPC + ASLA + STA MPTMPE ;**1/7/88** current position*2 + LDA MPTMPC+1 + ROLA + STA MPTMPE+1 + CLC + LDA MAPGEN ;POINT TO START OF MAP + ADCIM 3 + STA MAPGEN + BCC #10 + INC MAPGEN+1 +10 CLC + LDA MAPGEN ;**1/7/88** add offset to cylinder + ADC MPTMPE + STA MAPGEN + LDA MAPGEN+1 + ADC MPTMPE+1 + STA MAPGEN+1 + LSR MPTMPE+1 + ROR MPTMPE + +30 LDYIM 0 ;NOW LOOK FOR POSITION WITH FREE BLOCK + LDAIY MAPGEN + INY + ORAIY MAPGEN + BNE #50 ;FOUND IF NON ZERO + INC MPTMPE + BNE #32 + INC MPTMPE+1 +32 LDA MPTMPE + LDYIM MPNOCY ;CHECK FOR END OF CYCLINDER MAP + CMPIY MAPPTR + INY + LDA MPTMPE+1 + SBCIY MAPPTR + BCS #40 + LDAIM 2 ;NOT END SO LOOK AT NEXT ENTRY +35 CLC + ADC MAPGEN + STA MAPGEN + BCC #30 + INC MAPGEN+1 + BRA #30 + +40 STZ MPTMPE ;END SO BACK TO BEGINNING + STZ MPTMPE+1 + LDYIM MPCYMP + LDAIY MAPPTR ;GET START OF CYLINDER MAP + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 + LDAIM 3 ;GET POINTER TO START OF ENTRIES + BRA #35 + +50 RTS + +; FIND CYLINDER +; +; FINDS THE CYCLINDER WITH THE LARGEST AMOUNT +; OF FREE SPACE +; +; ON ENTRY +; MPCYPT POINTS TO START OF CYLINDER MAP +; +; ON EXIT +; MPCYPT POINTS TO CYLINDER FOUND +; +; USES MAPTMP MPTMPA MPTMPB + +FNDCY ROUT + STZ MAPTMP ;ZERO VALUES + STZ MAPTMP+1 + STZ MPTMPA + STZ MPTMPA+1 + STZ MPTMPC + STZ MPTMPC+1 + CLC + LDA MPCYPT ;GET TO START OF ENTRIES + ADCIM 3 + STA MPCYPT + STA MPTMPB + LDA MPCYPT+1 + ADCIM 0 + STA MPCYPT+1 + STA MPTMPB+1 +10 LDYIM 0 ;NOW SCAN ENTRIES FOR LARGEST + LDA MAPTMP + CMPIY MPCYPT + INY + LDA MAPTMP+1 + SBCIY MPCYPT ; MAPTMP HOLDS LARGEST SO FAR + BCS #20 ;BRANCH IF NOT LARGER + LDAIY MPCYPT + STA MAPTMP+1 + DEY + LDAIY MPCYPT + STA MAPTMP + LDA MPCYPT ;SAVE POSITION + STA MPTMPB + LDA MPCYPT+1 + STA MPTMPB+1 + LDA MPTMPA + STA MPTMPC ;SAVE CYLINDER NUMBER + LDA MPTMPA+1 + STA MPTMPC+1 +20 CLC + LDA MPCYPT ;MOVE TO NEXT ENTRY + ADCIM 2 + STA MPCYPT + BCC #25 + INC MPCYPT+1 +25 INC MPTMPA + BNE #30 + INC MPTMPA+1 +30 LDYIM MPNOCY ;CHECK FOR END OF MAP + LDAIY MAPPTR + CMP MPTMPA + BNE #10 + INY + LDAIY MAPPTR + CMP MPTMPA+1 + BNE #10 + LDA MPTMPB ;END SO RETURN POINTER + STA MPCYPT + LDA MPTMPB+1 + STA MPCYPT+1 + RTS + +; RETURNS THE SIZE OF A BLOCK OF STORE +; +; ON ENTRY +; MPSCPT POINTS TO BIT MAP +; +; ON EXIT +; MPTMPD HOLDS THE SIZE +; +; USES MPTMPE +; +SIZE ROUT + LDYIM MPSPCY + LDAIY MAPPTR + STA TMPSPC + INY + LDAIY MAPPTR + STA TMPSPC+1 + STZ MPTMPD ;CLEAR VARIABLES + STZ MPTMPD+1 + STZ MPTMPE + STZ MPTMPE+1 + LDYIM 0 +10 LDAIY MPSCPT + BEQ #80 ;NO FREE BITS IN THIS PART + LDXIM 8 ;LOOK AT ALL EIGHT BITS +20 RORA ;GET BIT INTO CARRY + PHA + BCC #70 ;CLEAR SO CHECK FOR END + INC MPTMPD + BNE #30 ;KEEP A COUNT OF SECTORS + INC MPTMPD+1 +30 INC MPTMPE + BNE #40 + INC MPTMPE+1 ;AND CHECK HOW MANY BITS WE'VE LOOKED AT +40 JSR TESTME ;**23/1/87** check for end of map + BCC #60 + LDA MPTMPD + ORA MPTMPD+1 + BNE #50 +48 LDAIM &F6 + JSR INTERR +50 PLA ;GET BIT MAP VALUE BACK +55 RTS + +60 PLA + DEX + BNE #20 +65 INY + BRA #10 + +70 LDA MPTMPD + ORA MPTMPD+1 + BNE #50 ;END IF ALREADY SOME COUNT + BRA #30 + +80 LDA MPTMPD + ORA MPTMPD+1 + BNE #55 + CLC + LDA MPTMPE + ADCIM 8 ;LOOK AT NEXT BYTE OF MAP + STA MPTMPE + BCC #85 + INC MPTMPE+1 +85 JSR TESTME ;**23/1/87** test for end of map + BCC #65 + BRA #48 + +; FILL BLOCKS +; ALLOCATES REST OF BLOCKS THAT ARE REQUIRED +; +; ON ENTRY +; DIVTMP HOLDS SIZE +; MPSCPT POINTS TO CURRENT BIT MAP +; MPTMPC HOLDS CYLINDER NUMBER +; MAPTMP POINTS TO MAP BLOCK +; MAPPTR POINTS TO MAP TABLE +; MPCYPT POINTS TO POSITION IN CYLINDER MAP +; +; ON EXIT +; C SET IF FAILED +; + +FLBLKS ROUT + LDA DIVTMP ;CHECK IF ALL BLOCKS ALLOCATED + ORA DIVTMP+1 + ORA DIVTMP+2 + BEQ #40 + JSR GETBIT ;FIND FIRST FREE BLOCK + BCS #10 ;NONE LEFT SO GET NEXT TRACK + JSR ABLKS ;ALLOCATE THESE BLOCKS + BCC FLBLKS ;KEEP ALLOCATING BLOCKS UNTIL NONE LEFT + LDA ERRTYP + BEQ #10 +00 SEC + RTS + +10 INC MPTMPC + BNE #20 + INC MPTMPC+1 +20 LDA MPTMPC ;GET NEXT BIT MAP + LDYIM MPNOCY ; CHECK FOR END + CMPIY MAPPTR + INY + LDA MPTMPC+1 + SBCIY MAPPTR + BCS #30 + CLC + LDA MPCYPT ;KEEP CYLINDER MAP POINTER UP TO DATE + ADCIM 2 + STA MPCYPT + BCC #25 + INC MPCYPT+1 +25 LDYIM 0 + LDAIY MPCYPT + INY + ORAIY MPCYPT + BEQ #10 + JSR RDBTMP ; GET THE BIT MAP + BNE #00 ;**23/2/87** Failed + BRA FLBLKS ; KEEP TRYING TO ALLOCATE + +30 STZ MPTMPC ;GO BACK TO THE BEGINNING + STZ MPTMPC+1 + LDYIM MPCYMP ;RETURN CYLINDER MAP TO BEGINNING + CLC + LDAIY MAPPTR + ADCIM 1 + STA MPCYPT + INY + LDAIY MAPPTR + ADCIM 0 + STA MPCYPT+1 + BRA #20 + +40 CLC ;INDICATE OK + RTS + +; +; GET BIT +; FINDS THE FIRST FREE BIT IN THE BIT MAP +; +; ON ENTRY +; MPSCPT POINTS TO BIT MAP +; +; ON EXIT +; MPTMPE HOLDS BIT NUMBER +; C SET IF NOT BITS FOUND +; +GETBIT ROUT + LDYIM MPSPCY + LDAIY MAPPTR + STA TMPSPC + INY + LDAIY MAPPTR + STA TMPSPC+1 + LDYIM 0 + STY MPTMPE + STY MPTMPE+1 +10 LDAIY MPSCPT ; GET BYTE OF BIT MAP + BEQ #40 ; IF NONE FREE GET NEXT BYTE +20 RORA ; ROTATE UNTIL BIT FOUND + BCS #50 ; BRANCH WHEN FOUND + INC MPTMPE ;KEEP TRACK OF WHERE WE ARE + BNE #30 + INC MPTMPE+1 +30 PHA + JSR TESTME ;CHECK FOR END OF ENTRY + PLA + BCC #20 +40 CLC + LDA MPTMPE ;ADD 8 FOR THIS BYTE + ADCIM 8 + STA MPTMPE + BCC #45 + INC MPTMPE+1 +45 INY + JSR TESTME ; CHECK FOR END OF BIT MAP + BCC #10 + SEC ;WHEN NONE FOUND + RTS + +50 CLC + RTS + +; +; CHECK FOR END OF BIT MAP +; +TESTME LDA MPTMPE + CMP TMPSPC + LDA MPTMPE+1 + SBC TMPSPC+1 + RTS +; +; CORRECT THE CURRENT FREE BLOCK COUNT +; +; ON ENTRY +; MPTMPB HOLDS NUMBER OF BLOCKS +; MPTMPC HOLDS CYLINDER NUMBER +; MAPPTR POINTS TO MAP TABLE ENTRY +; +; USES MAPGEN +; +ADDFR ROUT + LDYIM MPCYMP + LDAIY MAPPTR + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 ;GET POINTER TO CYLINDER MAP + LDYIM 0 + CLC + LDAIY MAPGEN ;ADD TO FREE COUNT AT START + ADC MPTMPB + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC MPTMPB+1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC MPTMPB+2 + STAIY MAPGEN + CLC ; NOW FOUND CYLINDER POSITION + LDA MAPGEN + ADCIM 3 ;START OF ENTRIES + STA MAPGEN + BCC #05 + INC MAPGEN+1 +05 LDA MPTMPC + ORA MPTMPC+1 + BEQ #40 + LDX MPTMPC + LDY MPTMPC+1 + BRA #20 + +10 CLC + LDA MAPGEN + ADCIM 2 + STA MAPGEN + BCC #20 + INC MAPGEN+1 +20 CPXIM 0 + BEQ #30 + DEX + BRA #10 + +30 CPYIM 0 + BEQ #40 + DEX + DEY + BRA #10 + +40 LDYIM 0 + CLC ;NOW ADD THE NEW VALUES + LDAIY MAPGEN + ADC MPTMPB + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC MPTMPB+1 + STAIY MAPGEN + RTS + +MPMKFR ROUT + LDAIY ARGPTR ;form zero page pointer from supplied info + STA GENPTR + INY + LDAIY ARGPTR + STA GENPTR+1 +10 RTS + +MPSETF TAX + BNE #10 ;non-zero => dont update the free store + JSR MPMKFR + CLC + TAX + LDA GENPTR + ADCIM UTUSID + LDYIM ARGB + STAIY NEWARG + INY + BCC #20 + INX +20 TXA + STAIY NEWARG + + LDXIM :LSB:-4 +30 INY + LDAAX MPNWFR-:LSB:-4 ;write calculated new free space + STAIY NEWARG + INX + BNE #30 + LDAIM 9 + JSR SETRTN + JMP USRMAN + +MPsetd ROUT ;**8/5/87** Copy ARGD into MPTMPA + LDYIM ARGD + LDAIY ARGPTR + STA MPTMPA + INY + LDAIY ARGPTR + STA MPTMPA+1 + INY + LDAIY ARGPTR + STA MPTMPA+2 + INY ;exit with Y=ARGG + RTS + +MPFRAD ROUT + JSR MPMKFR ;setup pointer + JSR RDmpbd ;**8/5/87** Read block at ARGD + BNE #30 ;exit + + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + JSR MPGTSZ + + LDXIM :LSB:-3 + LDYIM UTFREE + CLC + +20 LDAIY GENPTR + ADCAX MPTMPA-:LSB:-3 + STAAX MPNWFR-:LSB:-3 ;save it away + INY + INX + BNE #20 + +;deal with extra length byte + + LDAIY GENPTR + ADCIM 0 ;'cos size only three bytes + STAAX MPNWFR+3 + + TXA ;return ok +30 RTS + + LNK UADE12 diff --git a/FileStore/SRC/FileStore/Uade12.6502 b/FileStore/SRC/FS/FileStore/Uade12 similarity index 93% rename from FileStore/SRC/FileStore/Uade12.6502 rename to FileStore/SRC/FS/FileStore/Uade12 index b58b7f6..e612793 100644 --- a/FileStore/SRC/FileStore/Uade12.6502 +++ b/FileStore/SRC/FS/FileStore/Uade12 @@ -48,50 +48,30 @@ RDDATA ROUT STZ DSCCB+TRADD+2 STZ DSCCB+TRADD+3 -RDSTWO -;v1.31 -; STZ RBDA ;Sector zero -; RDSTWX - - STA Drivno ;Enter here with sector (<256) preset +RDSTWO STZ RBDA ;Sector zero +RDSTWX STA Drivno ;Enter here with sector (<256) preset JSR Defdef ;Define default drive parameters LDXIM Length+3-Cmd 00 STZAX Dsccb+Cmd ;Zero part of disc CB ** 27/9/86 ** DEX BPL #00 - -;v1.31 -; LDAIM &08 -; STA DSCCB+CMD - + LDAIM &08 + STA DSCCB+CMD LDA Drivno LSRA RORA RORA RORA STA DSCCB+CMD+1 - -;v1.23 - LDAIM &08 - STA DSCCB+CMD - LDA DSCCB+TRADD STA MPCYPT LDA DSCCB+TRADD+1 STA MPCYPT+1 - -;v1.23 - STZ RBDA ;Sector zero INC DSCCB+LENGTH+1 ;All was zero -10 JSR DSCCMD - -;v1.31 -; INC DSCCB+LENGTH+1 ;All was zero -;10 LDA RBDA ;**18/2/88** Set sector -; STA DSCCB+CMD+3 -; STZ DSCCB+CMD+2 -; JSR DSCCMD - +10 LDA RBDA ;**18/2/88** Set sector + STA DSCCB+CMD+3 + STZ DSCCB+CMD+2 + JSR DSCCMD BNE #20 LDYIM SZOFF LDAIY MPCYPT @@ -115,10 +95,6 @@ RDSTWO LDY RBDA BNE #30 INC RBDA - -;v1.23 - INC DSCCB+CMD+3 - BRA #10 30 TAX ;Set CC @@ -286,10 +262,7 @@ MKEN ROUT INY BCC #35 INC MPTMPE+1 - -;v1.31 -; CLC - + CLC BRA #35 50 PHA @@ -608,17 +581,19 @@ ABLKS ROUT STA MAPGEN+1 JSR SIZE ;GET SIZE OF THIS BLOCK LDA MPTMPD ;MPTMPD HAS SIZE + TAX ;**1/7/88** CMP DIVTMP ;SEE IF WE NEED THEM ALL LDA MPTMPD+1 + TAY SBC DIVTMP+1 - BCC ABSALL + BCC #10 LDA DIVTMP+2 - BNE ABSALL ;ABSALL ALLOCATES ALL BLOCKS - LDA DIVTMP - STA MKENVA ;MAKE ENTRY IN MAP BLOCK - LDA DIVTMP+1 - STA MKENVA+1 -10 JSR MKEN + BNE #10 ;ABSALL ALLOCATES ALL BLOCKS + LDX DIVTMP + LDY DIVTMP+1 +10 STX MKENVA ;MAKE ENTRY IN MAP BLOCK + STY MKENVA+1 + JSR MKEN BCS #30 ;ALL DONE SO FINISH LDA ERRTYP BNE #30 @@ -659,11 +634,4 @@ ABLKS ROUT SEC ;TO INDICATE FAILURE RTS -;v1.23 -ABSALL LDA MPTMPD - STA MKENVA ;PREPARE TO MAKE ENTRY IN MAP BLOCK - LDA MPTMPD+ 1 - STA MKENVA+ 1 - BRA #10 - LNK UADE12A diff --git a/FileStore/SRC/FileStore/Uade12A.6502 b/FileStore/SRC/FS/FileStore/Uade12A similarity index 100% rename from FileStore/SRC/FileStore/Uade12A.6502 rename to FileStore/SRC/FS/FileStore/Uade12A diff --git a/FileStore/SRC/FileStore/Uade13.6502 b/FileStore/SRC/FS/FileStore/Uade13 similarity index 92% rename from FileStore/SRC/FileStore/Uade13.6502 rename to FileStore/SRC/FS/FileStore/Uade13 index c22b47e..09835d3 100644 --- a/FileStore/SRC/FileStore/Uade13.6502 +++ b/FileStore/SRC/FS/FileStore/Uade13 @@ -15,10 +15,6 @@ FNDMAP ROUT STA MAPPTR ;LOOK AT FIRST ENTRY LDA MAPTB+1 STA MAPPTR+1 - -;v1.23 - LDXIM 0 ;X HOLDS DRIVE NUMBER - 10 LDYIM MPDCNO ;OFFSET TO DISC NUMBER LDAIY MAPPTR LDYIM ARGB @@ -790,12 +786,9 @@ CHKDSC ROUT LDA MPdrve ;**23/1/87** Check if Winnie CMPIM 4 BCS #00 ;br if floppy - -;v1.31 -; LDXIM CAcopy -; JSR OSrdad ;**23/3/88** find if check to be done -; BNE #00 - + LDXIM CAcopy + JSR OSrdad ;**23/3/88** find if check to be done + BNE #00 LDAIM &25 ;check user page A LDXIM :LSB:CAcorn LDYIM :MSB:CAcorn @@ -826,17 +819,23 @@ CHKDSC ROUT 60 STZAX Dsccb DEX BPL #60 - -;v1.23 STA Dsccb+Cmd+2 ;Set page number + LDA Mpdrve ;**1/8/88** + ASLA + ASLA + ASLA + ASLA + ASLA + STA Dsccb+Cmd+1 LDAIM &1A ;Mode sense command STA Dsccb+Cmd CLC - LDA BIGBUF ;Where to read user pages + LDA Mpscpt ;Where to read user pages STA Dsccb+Tradd ADCIM 3 - STA Movfrm - LDA BIGBUF+1 + STA Movfrm ; location of block descriptor length + LDA Mpscpt+1 + INCA ;**6/7/88** don't overlay sector zero on restart STA Dsccb+Tradd+1 ADCIM 0 STA Movfrm+1 @@ -844,56 +843,18 @@ CHKDSC ROUT STA Dsccb+Cmd+4 JSR Dsccmd BNE #20 ;exit on any error, Z clear - - CLC - LDAI Movfrm - ADCIM 6 - ADC BIGBUF + CLC ;**8/8/87** allow SCSI 4A spec + LDAI Movfrm ; load block descriptor length + ADCIM 6 ; skip block header plus page descriptor + ADC Mpscpt STA Movfrm - LDA BIGBUF+1 - ADCIM 0 - STA Movfrm+1 + LDA Mpscpt+1 + ADCIM 1 + STA Movfrm+1 ; point to user data LDXIM 4 JMP Compar ;go compare text and return -;v1.31 -; STA Dsccb+Cmd+2 ;Set page number -; LDA Mpdrve ;**1/8/88** -; ASLA -; ASLA -; ASLA -; ASLA -; ASLA -; STA Dsccb+Cmd+1 -; LDAIM &1A ;Mode sense command -; STA Dsccb+Cmd -; CLC -; LDA Mpscpt ;Where to read user pages -; STA Dsccb+Tradd -; ADCIM 3 -; STA Movfrm ; location of block descriptor length -; LDA Mpscpt+1 -; INCA ;**6/7/88** don't overlay sector zero on restart -; STA Dsccb+Tradd+1 -; ADCIM 0 -; STA Movfrm+1 -; LDAIM 20 ;Max length of data area -; STA Dsccb+Cmd+4 -; JSR Dsccmd -; BNE #20 ;exit on any error, Z clear -; CLC ;**8/8/87** allow SCSI 4A spec -; LDAI Movfrm ; load block descriptor length -; ADCIM 6 ; skip block header plus page descriptor -; ADC Mpscpt -; STA Movfrm -; LDA Mpscpt+1 -; ADCIM 1 -; STA Movfrm+1 ; point to user data -; LDXIM 4 -; JMP Compar ;go compare text and return - - ;SMAPEN ;MOVE SECTOR ZERO INFO. POINTED TO @@ -948,8 +909,7 @@ ZERDSK ROUT JSR DVDE BCC #15 LDAIM &F9 -;v1.23 - JSR USRERR + JSR INTERR 15 LDAIM 2 LDY OLDSZE BNE #20 @@ -1014,7 +974,9 @@ ZERDSK ROUT INC MPTMPA+2 ;Next bit writes 0's to MPTMPD entries until ;none left. -60 JSR SETBM ;Use bit maps +60 + [ 1=0 +JSR SETBM ;Use bit maps JSR GETFR LDYIM CBSA LDAIY GNCBPT @@ -1031,10 +993,9 @@ ZERDSK ROUT STA DCSTAD LDA MPCYPT+1 STA DCSTAD+1 - -;v1.31 -; STZ DCSTAD ;**29/4/88** zero store address -; STZ DCSTAD+1 ;**29/4/88** MOS treats as write zeroes + ] + STZ DCSTAD ;**29/4/88** zero store address + STZ DCSTAD+1 ;**29/4/88** MOS treats as write zeroes LDA MPDRVE STA DRIVNO 75 LDA MPTMPD @@ -1048,7 +1009,8 @@ ZERDSK ROUT STA RBDA+2 LDAIM &A STA SAVCOM - JSR XFER + JSR XFERIN ;**29/4/88** + [ 1=0 LDA MPTMPD BNE #77 DEC MPTMPD+1 @@ -1059,6 +1021,7 @@ ZERDSK ROUT BNE #75 INC MPTMPA+2 BRA #75 + ] 80 JSR NXTEN BNE #90 diff --git a/FileStore/SRC/FileStore/Uade14.6502 b/FileStore/SRC/FS/FileStore/Uade14 similarity index 94% rename from FileStore/SRC/FileStore/Uade14.6502 rename to FileStore/SRC/FS/FileStore/Uade14 index fa2c2d7..bc55166 100644 --- a/FileStore/SRC/FileStore/Uade14.6502 +++ b/FileStore/SRC/FS/FileStore/Uade14 @@ -50,17 +50,13 @@ DCEXIT JMP PREXIT DCIORD ROUT DCREAD LDAIM 8 ;Select MOS read command -10 STA SAVCOM ;SAVCOM := DOS DISC READ COMMAND - JSR DCINIT ;INITIALISE FOR DSCMAN VARIABLES - -;v1.31 -;00 PHA ;**29/2/88** save function code -; JSR DCINIT ;INITIALISE FOR DSCMAN VARIABLES -; TAX -; PLA -; STA SAVCOM ;**29/2/88** restore function code -; TXA +00 PHA ;**29/2/88** save function code + JSR DCINIT ;INITIALISE FOR DSCMAN VARIABLES + TAX + PLA + STA SAVCOM ;**29/2/88** restore function code + TXA BNE #30 20 LDA MAPTMP ;DCSECT := MAPTMP (I.E SECTOR NUMBER) @@ -104,7 +100,7 @@ DCREAD LDAIM 8 ;Select MOS read command DCIOWR DCWRIT LDAIM &0A ;Select MOS write command - BRA #10 + BRA #00 ;DCINIT: INITIALISE DSCMAN VARIABLES FOR TRANSFER @@ -458,13 +454,11 @@ DSCCMD ROUT CMPIM &FF ;Disc protected? LDAIM DCERRE ;Code if so BCS #10 - -;v1.31 -; LDXIM 2 ;**12/7/88** copy disc addr for reports -;00 LDAAX DSCCB+CMD+1 -; STAAX IEsin -; DEX -; BPL #00 + LDXIM 2 ;**12/7/88** copy disc addr for reports +00 LDAAX DSCCB+CMD+1 + STAAX IEsin + DEX + BPL #00 LDAIM DCERRF ;Other hard disc fault 10 RTS @@ -515,17 +509,16 @@ DEFDSC LDYIM MPnocy ; used mainly to determine if write protected ; A on entry is the required drive number -;v1.31 -;Testdv ROUT ;**24/2/88** -; LDXIM Length+3 -;10 STZAX Dsccb -; DEX -; BPL #10 -; LSRA -; RORA -; RORA -; RORA -; STA Dsccb+Cmd+1 -; BRA Dsccmd +Testdv ROUT ;**24/2/88** + LDXIM Length+3 +10 STZAX Dsccb + DEX + BPL #10 + LSRA + RORA + RORA + RORA + STA Dsccb+Cmd+1 + BRA Dsccmd LNK UADE15 diff --git a/FileStore/SRC/FileStore/Uade15.6502 b/FileStore/SRC/FS/FileStore/Uade15 similarity index 95% rename from FileStore/SRC/FileStore/Uade15.6502 rename to FileStore/SRC/FS/FileStore/Uade15 index 7660517..d7483b5 100644 --- a/FileStore/SRC/FileStore/Uade15.6502 +++ b/FileStore/SRC/FS/FileStore/Uade15 @@ -85,19 +85,13 @@ COMRTS ;come here for new command LDAIM 9 JSR Setrtn JSR Mapman ;*** Restart one drive *** - -;v1.23 + BEQ #22 + CMPIM DCerrf ;**6/7/88** ignore if disc now unavailable BNE #25 - LDA Curdrv +22 LDA Curdrv BRA #20 -;1.31 -; BEQ #22 -; CMPIM DCerrf ;**6/7/88** ignore if disc now unavailable -; BNE #25 -;22 LDA Curdrv -; BRA #20 -25 JSR USRERR ;drive restart failed. What better now? +25 JSR Interr ;drive restart failed. What better now? 30 LDAIM 6 ;Restart AUTMAN JSR Setrtn ;Ignore any error (no PW file) because @@ -202,7 +196,7 @@ FNTAB ROUT ;Addresses of functions & CLINE ;Decode command line - & SAVONA ;1 + & SAVE ;1 & LOAD ;2 & EXAMIN ;3 & CATHDR ;4 @@ -230,7 +224,7 @@ FNTAB ROUT & CPSPAC ;26 - returns disc free space & CDIRFN ;27 - cdir from function code, specify size & CPSETD ;28 - Set date and time from program - & SAVONA ; 29 - Do a 'create', like 'save' but no data + & SAVE ; 29 - Do a 'create', like 'save' but no data & RDFREE ;30 - read callers free space & WRFREE ;31 - write users free space & CPWHO ;32 - return client user name @@ -247,16 +241,10 @@ FCMAX * (.-FNTAB)/2 COMTAB [ Lang = English - = "CAT",&A0 - & CAT = "DELETE",&A0 & DELETE = "INFO",&A0 & INFO - = "LOAD",&A0 - & DOLOAD - = "SAVE",&A0 - & SAVE = "DIR",&A0 & SELDIR = "SDISC",&A0 @@ -281,21 +269,21 @@ COMTAB & REMUSE = "RENAME",&A0 & RENAME - = "REPORT",&E0 + = "FSREPORT",&E0 & REPORT = "PRNAME",&A0 & PRNAME - = "FORMAT",&C0 + = "PRPAGE",&E0 ;**8/2/88** + & PRPAGE + = "FSFORMAT",&C0 & FMFORM - = "VERIFY",&C0 + = "FSVERIFY",&C0 & VERIFY - = "CERTIFY",&C0 - & CERTIFY - = "MAXDRIVE",&C0 + = "FSMAXDRIVE",&C0 & RDMAXD - = "MAXUSER",&C0 + = "FSMAXUSER",&C0 & RDMAXU - = "FSSTN",&C0 + = "FSSTATION",&C0 & SETSTN = "FSMODE",&F0 ;unique code for FSMODE & FSMODE @@ -303,6 +291,8 @@ COMTAB & FSPROT = "FSUSER",&C0 & FSUSER + = "FSNAMEDISC",&C0 ;**18/2/88** + & NMDISC = 0 ;Indicates table end ] diff --git a/FileStore/SRC/FS/FileStore/Uade15A b/FileStore/SRC/FS/FileStore/Uade15A new file mode 100644 index 0000000..086afff --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Uade15A @@ -0,0 +1,478 @@ + OPT UADE15 ; > Uade15A + TTL File server file UADE15A + +; FSREPORT command tells authorised user only of last internal error. + +Repmes ROUT + [ Lang = English + = "Last error was " + ] + [ Lang = Italian + = "Ultimo errore era " + ] +10 = "XX" + = " X=" +20 = "XX" + = " Y=" +30 = "XX" + [ Lang = English + = " at " + ] + [ Lang = Italian + = " a " + ] +40 = "XX" +50 = "XX" + = " SIN=" +60 = "XX" +70 = "XX" +80 = "XX" + = CR,&80 +Repend + +Reptab + = #10-Repmes + = #20-Repmes + = #30-Repmes + = #50-Repmes + = #40-Repmes + = #60-Repmes + = #70-Repmes + = #80-Repmes + +Report ROUT + JSR Spaces ;**1/6/88** look for arguments + ANDIM &DF + CMPIM "R" + BNE #20 + BIT Cmndsw ;**1/6/88** must be maint mode 1 for reset + BMI #00 ;**7/7/88** or user mode + JSR Getusr ;**1/6/88** and privileged user + BNE #20 + LDYIM Utpriv + LDAIY Ustptr + ANDIM Systpv + BEQ #20 +00 LDXIM IEaddr +10 LDAIM 0 + PHX + JSR OSwrad ;**1/6/88** Reset reports to zero + PLX + INX + CPXIM IEaddr+8 + BCC #10 + +20 LDXIM 0 +30 LDAAX Repmes ;copy base message + STAAX Midtx + INX + CMPIM &80 ;Terminator? + BNE #30 + + LDXIM IEaddr +40 JSR OSrdad ;read next byte of error logout + PHX + TAY + LDAAX Reptab-IEaddr ;msg offset + TAX + TYA + JSR Wrterr ;place hex in msg + PLX + INX + CPXIM IEaddr+8 + BCC #40 ;continue till all done + + LDAIM Repend-Repmes ;get msg length + +Datour + CLC + ADCIM Txhdr + LDXIM CCinf ;fudge up zero rc reply with msg + STX Ccode + JSR Replyc ;and go send reply to user + JMP Comrts + +; FSMAXDRIVE <n> command sets max number of drives +; FSMAXUSER <n> command sets max number of users +; FSSTN <n> command sets ECOnet station id +; All commands allowed only in maintenance mode + +RDMAXD ROUT + LDXIM MDaddr ;eventual store address + LDAIM 6+1 ;highest drive+1 (Winnies 0-3 + floppies 4,5) + BRA #10 + +RDMAXU + LDXIM MUaddr ;eventual store address + LDAIM Maxuse+1 ;max user number+1 + BRA #10 + +SETSTN + LDXIM 0 ;marker + LDAIM &FF ;first invalid value +10 STX Cozero ;save parm offset + STA Cozero+1 ;and max + JSR Spaces + LDXIM 0 ;running total +20 CMPIM "0" + BCC #50 + CMPIM "9"+1 + BCS #50 + ANDIM &F ;digit value + STA Cozero+2 + TXA ;get sum to date + CMPIM 26 ;lowest value that will overflow + BCS #60 + ASLA + STA Cozero+3 + ASLA + ASLA + ADC Cozero+3 ;*10 (C was zero) + ADC Cozero+2 ;+new digit + BCS #60 ;overflowed + TAX + INY + LDAAY Midrx ;next char + BRA #20 + +50 JSR Comend + BNE #70 + LDA Cozero ;check type + CMPIM MDaddr ;FSMAXDRIVE? ** 29/09/86 ** + BNE #52 + INX ;add one if so +52 TXA + BEQ #60 + CMP Cozero+1 ;check against max value + BCS #60 + LDX Cozero ;ok, write to non-volatile memory + BEQ #80 + JSR OSwrad +55 LDAIM 0 ;send null reply for success + JMP Datous + +60 LDAIM Numerr + JMP Error + +70 JMP Comrts ;message already sent + +80 STA OSwork+1 + LDAIM 1 ; write fileserver number + STA OSwork + LDXIM :LSB:OSwork + LDYIM :MSB:OSwork + LDAIM &13 ; Station information + JSR OSword ; write fileserver station + BRA #55 + +; FSMODE <mode> changes mode between maintenance and user modes. +; A system-privileged user can issue FSMODE M to terminate +; user-mode running and enter maintenance mode from his station. +; A user in maintenance mode can issue FSMODE U to terminate +; maintenance mode running and re-enter user mode. +; The form FSMODE alone is allowed from any mode, and reports +; the current running mode in text to the user. + +FSMODE ROUT + JSR Spaces ;Find arg + ANDIM &DF ;Uppercase if alpha + CMPIM "M" + BEQ #10 + CMPIM "U" + BEQ #20 + CMPIM CR + BEQ #40 + LDAIM Woterr ;Error if neither +05 JMP Error + +10 BIT Cmndsw ;To Maintenance mode 1, must be in user mode + BMI #32 + JSR Getuse ;Get client station info and set MCNUMB + BNE #30 + LDYIM Utpriv + LDAIY Ustptr + ANDIM Systpv ;Check system privileged + BEQ #15 ;Error if not + LDA MCnumb ;Preserve MCNUMB + PHA + LDA MCnumb+1 + PHA + JSR #80 ;Take down world + PLA ;Restore MCNUMB + STA MCnumb+1 + PLA + STA MCnumb + LDAIM &C0 ;Set maintenance mode 1 + STA Cmndsw + JMP Strtf2 ;Partial restart, MCNUMB preset + +15 LDAIM Aterrd ;Insufficient privilege + BRA #05 + +20 BIT Cmndsw ;To user mode, must be in maintenance mode + BPL #32 + BVC #22 + JSR FSmody ;If maintenance mode 1 check locked station + BNE #32 +22 LDAIM 128 ;...and with drive door shut + LDXIM 0 + JSR OSbyte ;read door switch + ANDIM 2 + BNE #25 ;Door open, bounce + JSR #80 ;Take down world + STZ Cmndsw ;Set user mode (for neatness) + LDAIM 0 ;Record door open and ... + JMP Strtf1 ;Full FileStore restart + +25 LDAIM Doorer ;Say "Door open" + BRA #05 + +30 JMP Comrts + +32 JMP Badmod ;Say bad in this mode + +40 LDXIM 0 ;build mode message alone + JSR #70 + LDAIM &80 ;add CCinf terminator + STAAX Midtx + INX + TXA + JMP Datour ;send msg as info message + + [ Lang = English +65 = "User mode",CR +66 = "Maintenance mode 0",CR +67 = "Maintenance mode 1",CR + ] + [ Lang = Italian +65 = "Modo Utente",CR +66 = "Modo Mantenzione 0",CR +67 = "Modo Mantenzione 1",CR + ] + +Setmod +70 LDYIM 0 ;describe mode (always) + BIT Cmndsw + BPL #75 + LDYIM #66-#65 + BVC #75 + LDYIM #67-#65 +75 LDAAY #65 + STAAX Midtx ;copy mode message + INY + INX + CMPIM CR + BNE #75 + RTS + +80 LDAIM 0 ;space saver + JSR Rcode ;reply ok now, world vanishing + LDAIM 137 + LDXIM 1 + JSR OSbyte ;turn on led + + LDAIM &34 ;cancel RECEIVE control block + LDX RXtab + JSR OSbyte + + BIT Cmndsw ;no more shutdown if maintenance mode + BMI #90 + LDAIM 10 ;but if user mode... + JSR SETRTN + JSR USRMAN ;*** LOGOFF ALL USERS ** + PHA + JSR Flusys ;ensure discs + PLA + BEQ #90 ;br if ok + JSR Interr ;else report problem +90 RTS + +FSmody + LDY Qptr ;Check this is locked station + LDAAY CBstid + CMP MCnumb + BNE #85 + LDAAY CBstid+1 + CMP MCnumb+1 +85 RTS ;Exit Z set appropriately + +; FSPROT <ON|OFF> sets ECOnet protection on or off. May be +; issued from maintenance mode 1 only. + +FSPROT ROUT + JSR Spaces ;skip spaces + ANDIM &DF + CMPIM "O" + BNE #50 ;Error + INY + LDAAY Midrx ;next char + ANDIM &DF + CMPIM "N" + BEQ #10 + CMPIM "F" + BNE #50 ;Error unless N or F + INY + LDAAY Midrx ;next char + ANDIM &DF + CMPIM "F" + BNE #50 + LDXIM 0 ;protection-off mask +00 INY + JSR Comend + BNE #60 + TXA ;mask to A + JSR DoProt ;set mask + LDAIM 0 ;success + JMP Datous + +10 LDXIM Mask ;protection-on mask + BRA #00 + +50 LDAIM Woterr + JMP Error + +60 JMP Comrts ;message already send + +; FSUSER <userid> sets into CMOS RAM the userid to replace +; the fallback id as that to be used to log on from +; maintenance mode 0 into maintenance mode 1. + +FSUSER ROUT + JSR Spaces ;Find argument string + JSR Buftxt ;Read into TXTBUF + BNE #40 + JSR Comend + BNE #40 + + LDXIM 0 ;check string and find length +00 LDAAX Txtbuf + CMPIM CR + BEQ #05 + JSR ISDCHA ;Check syntax + BCS #50 + INX + BNE #00 ;stop when found +05 TXA ;check some chars present + BEQ #50 + CPXIM FSusie-FSusid-1 ;Check max length + BCS #50 ;(less checksum byte) + + STZ Tempa ;clear checksum + LDXIM FSusid +10 LDAAX Txtbuf-FSusid ;next char + PHA + JSR OSwrad ;write to CMOS RAM + PLA + PHA + CLC + ADC Tempa ;accumulate checksum + BCC #20 ;with end-round carry + INCA +20 STA Tempa + INX + PLA + CMPIM CR ;propagate CR to end + BNE #30 + STAAX Txtbuf-FSusid +30 CPXIM FSusie-1 + BCC #10 + LDA Tempa ;then add checksum + JSR OSwrad + +35 LDAIM 0 + JMP Datous ;end with zero return code + +40 JMP Comrts + +50 LDAIM Aterrg +60 JMP Error + +; FSNAMEDISC <n> <title> renames a disc. Maintenance mode 1 only. +; Reads both descriptor sectors for the disc and replaces the name +; with that specified. + +NMDISC JSR NMdisr ;**22/3/88** Read arguments + JSR Rddata ;Read first descriptor sector +70 BNE #50 + LDYIM MPsznm +80 LDAAY Txtbuf-MPsznm ;Copy in new disc name + STAIY Mpcypt + INY + CPYIM MPsznm+Dnamln + BCC #80 + LDAIM &0A ;Write code + STA Dsccb+Cmd + JSR Dsccmd ;Write back sector + BNE #60 + LDA RBda ;First or second done? + BNE #35 ;Second done + INC RBda ;Set second now + LDA MPdrve + JSR RDstwx + BRA #70 + +; Subroutine, read disc number followed by disc name. +; Exit: A=Disc number, TXTBUF=disc name. +; Syntax errors pop link and take error actions. + +NMDISR ROUT + JSR Spaces ;**18/2/88** Find disc number + CMPIM "0" + BCC #85 + CMPIM "6" + BCS #85 + ANDIM 7 + STA Mpdrve ;Set variables for RDDATA routine in MAPMAN + INY ;(Maybe should make this a MAPMAN function) + JSR Rdtitl ;Read disc name + BNE #80 + LDXIM &FF +60 INX + LDAAX Txtbuf ;Check and find end of name + CMPIM "A" + BCC #61 + CMPIM "Z"+1 + BCC #60 +61 CMPIM "a" + BCC #62 + CMPIM "z"+1 + BCC #60 +62 CPXIM 0 ;first char? + BEQ #63 + CMPIM "-" + BEQ #60 + CMPIM "_" + BEQ #60 + CMPIM "0" + BCC #63 + CMPIM "9"+1 + BCC #60 +63 CMPIM CR + BNE #90 + CPXIM 0 + BEQ #90 + CPXIM Dnamln+1 + BCS #90 + LDAIM Space +65 STAAX Txtbuf + INX + CPXIM Dnamln + BCC #65 + LDA Mpdrve + RTS + +80 PLA ;**22/3/88** unstack link + PLA + JMP Comrts + +85 PLA ;**4/4/88** unstack link + PLA + LDAIM Numerr + JMP Error + +90 PLA ;**22/3/88** unstack link + PLA + LDAIM Synerr + JMP Error + + LNK UADE16 diff --git a/FileStore/SRC/FS/FileStore/Uade16 b/FileStore/SRC/FS/FileStore/Uade16 new file mode 100644 index 0000000..4c12753 --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Uade16 @@ -0,0 +1,365 @@ + OPT UADE16 ; > Uade16 + TTL File server file UADE16 + +;SAVE/LOAD/ ETC. + +;************* +;* S A V E * +;************* + +;1) Do FINDMC, get disc number from +;DIRMAN file title -> disc number + +;2) Call CREATESPACE in MAPMAN using above args +;and size given in operation request +;for create goto 7 +;3) Send first reply +;4) Receive blocks one at a time into big buffer +;5) Write to disc (DSCMAN) +;6) If disc error, continue to receive, +;but set error flag +;7) All received OK => call PRESERVE in DIRMAN +;8) Send final return code +;9) Possibly DELETE previous file from map, +;flush from store and ensure map. + +;**8/2/88** Command level code deleted + +SAVE ROUT ; Also entered here for a CREATE 11/6/84 BC + JSR STKUSE ;Set m/c no. and call FINDMC + BNE #22 ;Fail, return + + LDAIM 13 ;DIRMAN.CHECKPRES + JSR #95 ;**23/3/88** see if preserve will work + BNE #23 + + LDAIM &A ;File title -> disc number + JSR SETRTN + JSR STKUSA + LDAIM SAVFTO + JSR SETFTP + INY + LDAIM &80 ;no wild cards in last name + STAIY NEWARG + + JSR DIRMAN ;Disc number on stack + BNE #23 ;**9/6/87** + + LDX BPTR + LDYIM ARGD + +;Move size from message buffer to +;arg. stack for create space call + +10 LDAAX MIDRX+8 + STAIY NEWARG + INX + INY + CPYIM ARGD+3 + BNE #10 + + DEY ;pass info @ ARGG,H + JSR SETUSE ;put userinfo on stack + + LDAIM 1 + JSR SETRTN + + JSR MAPMAN ;** CREATE SPACE ** + BNE #23 + + LDXIM 4 + LDYIM ARGF +20 LDAIY NEWARG + STAAX DANDS ;Save disc. no. and SIN + DEY + DEX + BPL #20 + + ; New stuff for create 11/6/84 BC + LDX BPTR + LDAAX FCODE + EORIM FCCRET ; The function code for create + BNE #25 + STZ CCODE ; Blat the command return code + JMP #70 + +22 JMP COMRTS ;Finish + +23 JMP ERROR + +25 LDAIM PSAVD + STA MIDTX ;Save data port + + LDAIM :LSB:BUFSZ ;** 6/2/84 ** + STA MIDTX+1 ;Size of save buffer + LDAIM :MSB:BUFSZ ;** 6/2/84 ** + STA MIDTX+2 ;Size of save buffer hi + + STZ RTCODE + LDAIM 3 ;offset in buffer of name + STA CCODE + + JSR SAVNAM ;get filename + TYA ;Y=length of filename + CLC + ADCIM TXHDR+7 + + JSR REPLY ;Send message with 0 RC and C.code + BNE #42 ;No contact => abort + +;If we get here, ready to receive +;data, so set up for receive loop. + + STZ DATAIN + STZ DATAIN+1 + STZ DATAIN+2 ;DATAIN -> no. of bytes received + STZ DSCERR ;Error flag + LDX BPTR + LDAAX MIDRX+8 ;Check if zero length file + ORAAX MIDRX+9 + ORAAX MIDRX+&A + BNE #35 ;Nope -> carry on + JMP #65 ;Yep -> send final reply + +35 LDAIM 0 + LDYIM ARGG + STAIY NEWARG ;Current disc block start + INY + STAIY NEWARG ;Current disc block start (hi) + +;Set buffer pointers in control block + +40 LDY QPTR + LDA BBUF + STAAY CBBUF + LDA BBUF+1 ;Buffer (hi) + STAAY CBBUF+1 + + LDA BBEND + STAAY CBBUFE ;Buffer end (lo) + LDA BBEND+1 + STAAY CBBUFE+1 ;Buffer end (hi) + + LDAIM &00 + STAAY CBBUF+2 + STAAY CBBUF+3 + STAAY CBBUFE+2 + STAAY CBBUFE+3 ;high order addresses + + LDAIM PSAVD ;Set data port + STAAY CBPORT + + JSR WAIT ;Station set + BEQ #45 ;Ok, continue +42 JMP #90 ;No contact => abort + +;Now subtract buffer received limits to +;get how much data was received. + +45 LDY QPTR ;** Y corrupted in WAIT ** + SEC + LDAAY CBBUFE + SBCAY CBBUF + STA DIVPAR + + LDAAY CBBUFE+1 + SBCAY CBBUF+1 + STA DIVPAR+1 + STZ DIVPAR+2 ;Top byte always 0 + +;Add no. received to total no. of +;bytes received. + + CLC + LDA DIVPAR + ADC DATAIN + STA DATAIN + LDA DIVPAR+1 + ADC DATAIN+1 + STA DATAIN+1 + LDA DIVPAR+2 ;For superstitions sake + ADC DATAIN+2 + STA DATAIN+2 + + LDA DSCERR + +;If error code set, ignore received +;data and jump past disc write. + + BNE #50 + + JSR DIVIDE ;Get no. of disc blocks to write (in BREGA) + + LDYIM ARGI + LDA DIVPAR + STAIY NEWARG + INY + LDA DIVPAR+1 + STAIY NEWARG ;No. of blocks to write + INY + LDA BBUF + STAIY NEWARG ;Address of data to write + INY + LDA BBUF+1 + STAIY NEWARG ;As above (hi) + + LDYIM ARGB + JSR SINDSC ;Set SIN and disc number + + LDAIM 4 ;write from IO side + JSR SETRTN + JSR DSCMAN + BEQ #50 + STA DSCERR + + +;Now compare amount received (in DATAIN) +;with file size (in receive message buffer). + +50 LDY BPTR + SEC + LDAAY MIDRX+8 + SBC DATAIN + STA BREGA + LDAAY MIDRX+9 + SBC DATAIN+1 + STA BREGA+1 + LDAAY MIDRX+&A + SBC DATAIN+2 + + ORA BREGA + ORA BREGA+1 + BEQ #65 ;If equal, SAVE finished... + BCS #55 ;If rx'd < size, carry on + +;Otherwise, client has sent too +;much data, so send error code and +;abort. + + LDAIM SAVERA ;Error code + JMP #85 + +;Add no. of blocks saved to block +;start to get block start for next +;reception of data. + +55 LDYIM ARGI + LDAIY NEWARG + DEY + DEY + CLC + ADCIY NEWARG + STAIY NEWARG + INY + LDAIY NEWARG + INY + INY + ADCIY NEWARG + DEY + DEY + STAIY NEWARG + +;Now send ack. on ack. port sent from client + + LDY BPTR + LDXAY CPUFD ;Ack. port + LDAIM 1 ;Message length + JSR REPLYB + BNE #90 ;Not ok, abort + JMP #40 ;Go off round loop again. + +;At this point, have received the +;correct amount of data, so check +;error flag to see if all data was +;written, and if not, send the +;error off as a return code. + +65 LDA DSCERR + BNE #85 + +;Now prepare to do PRESERVE to +;keep the data on disc. + +70 LDAIM DRPRS + JSR #95 + BNE #85 + + LDYIM ARGG ;** 4/8/83 ** + LDAIY NEWARG ;access status + STA MIDTX + LDAIM TXHDR+3 ;Otherwise reply with access + date + JSR REPLYC + + JSR OBJCLR ;Delete object if neccessary (see PRESERVE) + BNE #85 ;**** 17/3/83 **** + +80 JMP COMRTS ;Finished ... exit + +85 JSR EXTERR ;Send error to client + +;Abort exit ... clear entry from +;map of created space using FREESTORE, +;and exit. + +90 LDYIM ARGB + JSR SINDSC ;Get disc/sin to stack + LDAIM 2 + JSR SETRTN + + LDYIM ARGF ;pass pointer to user info (ARGG,H) + JSR SETUSE ;** 3/10/84 ** + + JSR MAPMAN ;** Free space ** + BEQ #80 + JSR INTERR + +;Routine to DIRMAN.DRPRS or DIRMAN.CHECKPRES +;DIRMAN code in A on entry + +95 JSR SETRTN + + LDYIM ARGO ;SIN GOES IN ARGQ->ARGS (!) + JSR SINDSC ;Get SIN/DISC to stack + LDAIM &80 + STAIY NEWARG ;ARGT = wild card flag + + JSR STKUSA + + LDAIM SAVFTO + JSR SETFTP + + [ Pseudods = Yes + LDYIM UTHUFD ;**1/7/87** fix up user root handle + LDAIY USTPTR + STA UMHUFD + ] + +;Move load/exec addresses from +;receive message buffer to stack + + LDX BPTR + LDYIM ARGF +97 LDAAX MIDRX + STAIY NEWARG + INX + INY + CPYIM ARGF+8 + BNE #97 + + LDAIM ACCDEF ;Access default + STA MIDTX ;Store for final reply + STAIY NEWARG + + JSR GETDTE ;Read date & time + LDYIM ARGO + LDA DATE + STA MIDTX+1 ;Store for final reply + STAIY NEWARG + INY + LDA DATE+1 + STA MIDTX+2 ;Store for final reply + STAIY NEWARG + + JMP DIRMAN ;*** DO PRESERVE ** + + LNK UADE16A diff --git a/FileStore/SRC/FS/FileStore/Uade16A b/FileStore/SRC/FS/FileStore/Uade16A new file mode 100644 index 0000000..fb6e9dd --- /dev/null +++ b/FileStore/SRC/FS/FileStore/Uade16A @@ -0,0 +1,515 @@ + OPT UADE16 ; > Uade16A + TTL File server file UADE16A + +;************* +;* L O A D * +;************* + +;1) RETRIEVE object info. (DIR. MAN) +;check access and type. + +;2) Get handle of file, and open for +;reading, just in case. + +;3) REPLY +;4) Loop round DSCMAN doing getdata from disc +;into Big Buffer, and sending to client. +;If disc error, set error flag but continue +;to pad out data until loop end. +;5) Return code reply. + +;**8/2/88* Command level code deleted + +LOAD ROUT + JSR GETUSE ;Get user info. using FINDMC + BNE #17 ;Fail, exit + + [ Pseudods = Yes + LDYIM UTHUFD ;**1/7/87** fix up user root handle + LDAIY USTPTR + STA UMHUFD + ] + + JSR LDRETR ;Do retrieve + BEQ #20 ;OK, continue + + LDX BPTR + LDYAX FCODE + CPYIM FCCMND ;Do a command ?? + BNE #15 ;Nope, send not found error. + + LDAAX CPLIB ;Get lib. handle + LDYIM UTHSLD + STAIY USTPTR ;Note, assumes USTPTR still OK from STKUSE. + + JSR LDRETR ;Do another retrieve. + BEQ #20 ;OK, continue + CMPIM DRERRC + BEQ #10 ;Is, "not found". + CMPIM DRERRA ;Is bad file title ? + BNE #15 ;Nope, carry on +10 LDAIM WOTERR +15 JMP ERROR + +17 JMP COMRTS ;Finish !!! + +20 LDYIM ARGB + LDAIM TYPDIR ;Directory type + ANDIY NEWARG ;0 => is file + BEQ #25 ;OK, carry on + LDAIM LODERA ;Not ok, external error + BRA #15 + +25 LDAIM READAC + ANDIY NEWARG + BNE #30 ;Read access => OK + LDAIM LODERB ;Not ok, external error + BRA #15 + +30 LDA DETDIS + STA DANDS ;Store Disc. no. + LDA DETDIS+1 + STA DANDS+1 + + LDXIM 2 +35 LDAAX DETSIN ;Store SIN + STAAX DANDS+2 + DEX + BPL #35 + + LDAIM 2 ;arg to RNDMAN.INFO + JSR SETRTN + INY + JSR SINDSC ;put disc number & SIN on stack + JSR RNDMAN + BNE #40 ;opject not open at all + LDYIM ARGB ;test mode of access to object + LDAIY NEWARG + ANDIM &02 ;test bit 1 (write bit) + BEQ #40 + LDAIM DRERRI ;object in use + BRA #15 + +;Move load/exec info. from COWORK to transmit buffer +;Note CPYLXS copies date and access as well + +40 LDXIM 0 ;Offset from MIDTX + JSR CPYLXS ;Note corrupts COTEMP + + LDXIM 10 +45 LDAAX COWORK + STAAX MIDTX+14 + DEX + BPL #45 + + LDAIM &20 + STA MIDTX+24 + STA MIDTX+25 + STX MIDTX+26 ;negative byte here + + LDXIM 2 +50 LDAAX DETSZ ;Move file size to TOSEND variable + STAAX TOSEND + DEX + BPL #50 + + STZ RTCODE + LDAIM 14 ;offset of name string in buffer + STA CCODE + + LDAIM TXHDR+28 ;Message length (load/exec/size/acc/date) + JSR REPLY ;Send reply + BEQ #55 + JMP #95 ;Reply failed + +55 STZ DSCERR ;Set disc error flag + STZ FINFLG ;Set finish flag + STZ CURBLK + STZ CURBLK+1 + +;Loop round sending data to client +;in blocks of size BBSIZE. TOSEND +;is the amount left to send, decremented +;by BBSIZE each loop. +;If a disc error occurs, the disc +;error number is put in DSCERR and +;the loop continues, padding out the +;data until the right amount has +;been sent. The disc error number +;is then sent as a return code. + +;First, subtract BBSIZE from TOSEND + +60 SEC + LDA TOSEND + SBC BBSIZE + STA COWORK + LDA TOSEND+1 + SBC BBSIZE+1 + STA COWORK+1 + LDA TOSEND+2 + +;Note BBSIZE is TWO bytes !! + + SBCIM 0 + STA COWORK+2 + + ORA COWORK + ORA COWORK+1 + +;If result +ve TOSEND > BBSIZE, so send +;a block of size BBSIZE. + + BEQ #65 + BCS #70 + +;If BBSIZE >= TOSEND, send remaining +;data (in TOSEND) and set flag. + +65 LDA TOSEND + STA OUTBSZ + LDA TOSEND+1 + STA OUTBSZ+1 + DEC FINFLG ;Set loop finish flag=#FF + ORA TOSEND + BEQ #90 ;Zero length file => send final reply only + BRA #75 + +70 LDA BBSIZE + STA OUTBSZ + LDA BBSIZE+1 + STA OUTBSZ+1 + +;The size of the block to send (in +;bytes) is now in OUTBSZ. So divide +;by disc block size to get number +;of disc blocks to transfer. + +75 LDA OUTBSZ + STA DIVPAR + LDA OUTBSZ+1 + STA DIVPAR+1 + STZ DIVPAR+2 ;3 byte arg. + JSR DIVIDE + LDYIM ARGB + JSR SINDSC ;Set disc/SIN on stack + JSR IBLOCK ;Set disc block parms on stack + LDAIM 3 ;Read disc function + JSR SETRTN + JSR DSCMAN ;*** DO DISC XFER TO BIG BUFFER ** + BEQ #80 ;OK => continue + STA DSCERR ;Otherwise set disc error + +80 LDY BPTR + LDAAY CPUFD ;Get data port sent from client + + JSR SENDBC ;Send big block + BNE #95 ;Otherwise, contact lost with client, so give up. + +;At end of loop, test finish flag, +;and set CURBLK to be start disc +;block for next iteration. +;Also set TOSEND from COWORK as decremented counter + +85 BIT FINFLG + BMI #90 ;#FF => exit + + CLC + LDA CURBLK + ADC DIVPAR ;Add no. of blocks xfered + STA CURBLK + LDA CURBLK+1 + ADC DIVPAR+1 + STA CURBLK+1 + + LDA COWORK + STA TOSEND + LDA COWORK+1 + STA TOSEND+1 + LDA COWORK+2 + STA TOSEND+2 + + JMP #60 ;*** LOOP RETURN ** + +90 LDA DSCERR + JSR RCODE ;Send return code + +;No cleaning up to do, so exit + +95 JMP COMRTS + + + +;*************** +;* D E L E T E * +;*************** + + +;1) CALL DELETE IN DIRMAN, WHICH SUPPLIES +;SIN AND DISC NO. OF OBJECT TO BE DELETED +;AFTER REMOVING IT FROM THE APPROPRIATE +;DIRECTORY. + +;2) CALL UTILITY OBJCLR TO REMOVE OBJECT FROM +;STORE, FROM THE MAP, AND ENSURE THE MAP. + + +DELETE ROUT + STY COTEMP ;Store command line pointer + JSR STKUSE + BNE #10 + + LDY COTEMP + JSR RDTITL + BNE #10 + + LDYIM ARGC + JSR SBUFPT + LDAIM 3 + JSR SETRTN + + LDYIM ARGG + LDAIM &80 + STAIY NEWARG ;specify full last name + + JSR DIRMAN ;*** DIRECTORY DELETE ** + BNE #05 ;**23/1/87** if error, reply now + JSR OBJCLR ;OTHERWISE CLEAR OLD OBJECT +05 JSR RCODE ;**** 17/3/83 **** + +10 JMP COMRTS + + + +;********************** +;* C A T H E A D E R * +;********************** + +;1) DIRMAN CALL RETRIEVE TO GET DIR. NAME +;AND DISC. NO. +;2) MAPMAN CALL TO GET DISC NAME FOR GIVEN NO. +;3) FORMAT ABOVE WITH INDICATION OF WHETHER +;OWNER OR PUBLIC ACCESS TO DIR. (ALSO +;GOT FROM EXAMINE CALL) + +CATHDR ROUT + JSR GETUSE + BNE #30 + + LDAIM 0 ;Offset from MIDTX to put dir. title + JSR DIRIND ;Get dir. title/access/disc no. + BNE #40 + + LDAIM SPACE + STA MIDTX+NAMLNT + LDYIM ARGD + LDAIY NEWARG + ANDIM OWNER + BEQ #10 + LDAIM "O" + BRA #20 + +10 LDAIM "P" ;PUBLIC OR OWNER ACCESS +20 STA MIDTX+&B + LDAIM SPACE + STA MIDTX+&C + STA MIDTX+&D + STA MIDTX+&E + + LDAIM &F ;Offset from MIDTX to put disc name + JSR CPDNAM ;Read disc name of current disc + BNE #40 + + LDAIM CR + STAAX MIDTX ;Note assumes X is offset remaining from CPDNAM + LDAIM EXTERM ;BLOCK DELIM. + STAAX MIDTX+1 + + TXA + CLC + ADCIM TXHDR+2 ;GET MESSAGE LENGTH + JSR REPLYC +30 JMP COMRTS + +40 JMP ERROR + + + +;***************** +;* E X A M I N E * +;***************** + +;Mainly concerned with getting args +;from RXBUF to NEWARG, calling DIRMAN, +;and getting args back again. + +EXAMIN + JSR STKUSE ;CALL FINDMC AND SET USTPTR ON STACK + BNE #30 + + LDAIM EXAFTO + JSR SETFTP ;SET FILE TITLE POINTER ON STACK + + INY + CLC + LDA BBUF + ADCIM TXHDR+2 + STAIY NEWARG ;SET POINTER TO RESULT AREA + +;RESULT OF CALL OF DIRMAN IS PLACED IN THE BIG +;BUFFER, OFFSET BY TWO BYTES FOR THE MESSGE HEADER +;TO BE INSERTED + + INY + LDA BBUF+1 + ADCIM 0 + STAIY NEWARG + +;NOW COPY 3 ARGS FROM RXBUF TO STACK + + LDX BPTR ;OFFSET IN RXBUF FOR THIS RX BUFFER + INY + LDAAX MIDRX + STAIY NEWARG ;ARG + INY + LDAAX MIDRX+1 + STAIY NEWARG ;entry point + INY + LDAAX MIDRX+2 + STAIY NEWARG ; number of entries + + LDAIM 7 ;FUNCTION NUMBER IN DIRMAN + JSR SETRTN + + LDYIM ARGK + LDAIM &C1 ;specify directory here + STAIY NEWARG ;pass parameter + + JSR DIRMAN ;*** DIRECTORY MANAGER CALL ** + BNE #40 + LDA BBUF + STA GENPTR + LDA BBUF+1 + STA GENPTR+1 + LDYIM 0 + TYA + STAIY GENPTR ;STORE 0 RETURN CODE IN MESSAGE + INY + STAIY GENPTR ;STORE 0 COMMAND CODE + + LDYIM ARGD + LDAIY NEWARG ;GET NUMBER OF ENTRIES RETURNED + PHA ;Store for later + INY + LDAIY NEWARG + LDYIM TXHDR+1 ;Store cycle no. of directory + STAIY GENPTR + PLA ;Restore no. of entries returned + DEY + STAIY GENPTR ;Set in message to client + + +;NOW SET UP CONTROL BLOCK + + LDA RPLYPT ;REPLY PORT + LDX QPTR ;C.B POINTER + STAAX CBPORT + + LDA BBUF ;POINTER TO MESSAGE START + STAAX CBBUF + LDA BBUF+1 + STAAX CBBUF+1 + + LDYIM ARGB + LDAIY NEWARG ;POINTER TO END OF MESSAGE, + ;RETURNED BY DIR. MAN. + + STAAX CBBUFE + INY + LDAIY NEWARG + STAAX CBBUFE+1 + + LDY QPTR ;SET ARG FOR SEND + JSR SEND ;*** SEND INFO ** + + JMP COMRTS + + + +;*********** +;* I N F O * +;*********** + + +;GET INFO ON A FILE IN A CHAR STRING +;FROM DIRMAN INTO BIG BUFFER AND SEND + +INFO ROUT + JSR RDTITL + BNE #20 + JSR STKUSE + BNE #20 + + JSR SBUFPT + INY + CLC + LDA BBUF + ADCIM TXHDR + STAIY NEWARG + +;RESULT POINTER PASSED TO DIRMAN IS BBUF +A BIT +;TO ALLOW ROOM FOR THE MESSAGE HEADER +;IN THE FINAL MESSAGE BACK TO THE CLIENT. + + INY + LDA BBUF+1 + ADCIM 0 ;RESULT AREA TOP BYTE + STAIY NEWARG + + LDAIM 8 + JSR SETRTN + + LDYIM ARGH + LDAIM &C0 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;*** GET THE INFO ** + BEQ #10 ;OK, CONTINUE + JMP ERROR + +10 LDA BBUF + STA GENPTR + LDA BBUF+1 + STA GENPTR+1 + + LDYIM 0 + LDAIM CCINF + STAIY GENPTR ;Command code + INY + LDAIM 0 ;Zero r.code + STAIY GENPTR + +;FROM HERE, SET UP TRANSMIT CONTROL BLOCK + + LDX QPTR + LDA RPLYPT + STAAX CBPORT + + LDA BBUF + STAAX CBBUF ;MESSAGE BUFFER + LDA BBUF+1 + STAAX CBBUF+1 + + LDYIM ARGB ;GET MESSAGE BUFFER END FROM STACK + LDAIY NEWARG + STAAX CBBUFE + INY + LDAIY NEWARG + STAAX CBBUFE+1 + + LDY QPTR + JSR SEND ;OFF WE GO .... + +20 JMP COMRTS + + LNK UADE17 diff --git a/FileStore/SRC/FileStore/Uade17.6502 b/FileStore/SRC/FS/FileStore/Uade17 similarity index 100% rename from FileStore/SRC/FileStore/Uade17.6502 rename to FileStore/SRC/FS/FileStore/Uade17 diff --git a/FileStore/SRC/FileStore/Uade17A.6502 b/FileStore/SRC/FS/FileStore/Uade17A similarity index 100% rename from FileStore/SRC/FileStore/Uade17A.6502 rename to FileStore/SRC/FS/FileStore/Uade17A diff --git a/FileStore/SRC/FileStore/Uade18.6502 b/FileStore/SRC/FS/FileStore/Uade18 similarity index 100% rename from FileStore/SRC/FileStore/Uade18.6502 rename to FileStore/SRC/FS/FileStore/Uade18 diff --git a/FileStore/SRC/FileStore/Uade19.6502 b/FileStore/SRC/FS/FileStore/Uade19 similarity index 91% rename from FileStore/SRC/FileStore/Uade19.6502 rename to FileStore/SRC/FS/FileStore/Uade19 index abce461..0bfa710 100644 --- a/FileStore/SRC/FileStore/Uade19.6502 +++ b/FileStore/SRC/FS/FileStore/Uade19 @@ -16,16 +16,7 @@ GETBYT ROUT JSR STKUSE ;Put user info ptr on stack BNE #10 - LDX BPTR - LDAAX RXBUF+2 ;Get file handle - LDYIM ARGD - STAIY NEWARG - - LDX QPTR ;Get seq no. from control block - LDAAX RXCBV - ANDIM 1 ;Mask out reception flag - INY - STAIY NEWARG + JSR #30 LDAIM 7 ;RNDMAN.RDCH JSR SETRTN @@ -49,6 +40,19 @@ GETBYT ROUT 20 JMP ERROR +30 LDX BPTR + LDAAX RXBUF+2 ;Get file handle + LDYIM ARGD + STAIY NEWARG + + LDX QPTR ;Get seq no. from control block + LDAAX RXCBV + ANDIM 1 ;Mask out reception flag + INY + STAIY NEWARG + RTS + + ;********** ;* PUTBYT * ;********** @@ -59,20 +63,12 @@ GETBYT ROUT ;Entry: BPTR is offset of buffer in RXBUF ;QPTR is offset of control block in RXCBV -PUTBYT ROUT +PUTBYT JSR STKUSE ;Put user info ptr on stack BNE #10 - LDX BPTR - LDAAX RXBUF+2 ;Get file handle - LDYIM ARGD - STAIY NEWARG + JSR #30 - LDX QPTR ;Get seq no. from control block - LDAAX RXCBV - ANDIM 1 ;Mask out reception flag - INY - STAIY NEWARG LDX BPTR LDAAX RXBUF+3 ;Get byte to be written INY @@ -85,8 +81,7 @@ PUTBYT ROUT ;Note that sequence no. is still in control block JSR RCODE ;Send return code -10 - JMP Comrts ;Exit + BRA #10 ;Exit ;* CPRDAR * @@ -403,9 +398,9 @@ PBYTES ROUT LDXAY CPUFD ;Ack port LDAIM 1 ;Message length JSR REPLYB ;Send byte (random contents) - BNE #90 ;Contact lost => abort + BNE #80 ;Contact lost => abort - JMP #20 ;Round loop again +60 JMP #20 ;Round loop again ;Have received all the data. ;Final RC is in DSCERR. @@ -467,37 +462,34 @@ GBYTES ROUT JSR RMSUBO ;Set up RNDMAN for GETBYTES calls BEQ #15 -;05 - - JSR EXTERR ;Not OK, send RC +05 JSR EXTERR ;Not OK, send RC 10 JMP COMRTS ;Exit -15 -; LDYIM ARGB ;**23/3/88** check mode of access for file -; LDAIY NEWARG -; ANDIM READAC -; BNE #16 -; LDAIM RDERRO -; BRA #05 - -;16 -; [ 1=0 -; LDX BPTR ;**23/3/88** check if GETBYTES or GETPUTBYTES -; LDAAX RXBUF+1 -; EORIM 35 -; BNE #17 -; JSR #99 ;**23/3/88** zero sequence number -; LDAIM &E ;**23/3/88** GETPUTBYTES, prepare put also -; JSR SETUSA -; LDAAX MIDRX+1 -; JSR RMSUBP -; BNE #05 -; JSR #99 ;**23/3/88** zero sequence number -; BRA #20 - -;17 -; ] -; LDAIM 0 +15 LDYIM ARGB ;**23/3/88** check mode of access for file + LDAIY NEWARG + ANDIM READAC + BNE #16 + LDAIM RDERRO + BRA #05 + +16 + [ 1=0 + LDX BPTR ;**23/3/88** check if GETBYTES or GETPUTBYTES + LDAAX RXBUF+1 + EORIM 35 + BNE #17 + JSR #99 ;**23/3/88** zero sequence number + LDAIM &E ;**23/3/88** GETPUTBYTES, prepare put also + JSR SETUSA + LDAAX MIDRX+1 + JSR RMSUBP + BNE #05 + JSR #99 ;**23/3/88** zero sequence number + BRA #20 + +17 + ] + LDAIM 0 JSR RCODE ;Send "OK" rc BNE #10 ;lost contect so ABORT @@ -595,37 +587,14 @@ GBYTES ROUT 40 LDX BPTR LDAAX MIDRX ;Get file handle - - LDYIM ARGD - STAIY NEWARG ;Put handle on stack - - LDA BBUF ;Put buffer address on stack - INY - STAIY NEWARG - LDA BBUF+1 - INY - STAIY NEWARG - - LDA OUTBSZ ;Put no. of bytes on stack - INY - STAIY NEWARG - LDA OUTBSZ+1 - INY - STAIY NEWARG - - LDAIM 9 ; RNDMAN.GETBYTES - JSR SETUSA - - JSR RNDMAN ;*** Call RNDMAN ** - BEQ #50 ;OK, continue - STA DSCERR ;Otherwise set error code - + LDXIM 9 ;**23/3/88** RNDMAN.GETBYTES + JSR RMSUBR ;Add number of bytes actually read to ;GBBXFD, and OR end-of-file flag ;into GBEFLG. -50 CLC + CLC LDYIM ARGB LDAIY NEWARG ;Bytes xferred (LS) ADC GBBXFD @@ -696,6 +665,14 @@ GBYTES ROUT 90 JMP COMRTS ;Exit from command + [ 1=0 +99 LDYIM RTINUS ;**23/3/88** fudge to keep sequence number + LDAIY RTEPTR ;**23/3/88** safely at zero as it cannot be + ANDIM &FE ;**23/3/88** used by GETPUTBYTES + STAIY RTEPTR + RTS + ] + ;*** Call RNDMAN to set up bytes operation RMSUBO ROUT @@ -728,32 +705,31 @@ RMSUBP INY ;Routine to call RNDMAN.GETBYTES or .PUTBYTES. ;Entry: A=Handle; X=RNDMAN code -;v1.31 -;RMSUBR ROUT -; LDYIM ARGD -; STAIY NEWARG ;Put handle on stack -; -; LDA BBUF ;Put buffer address on stack -; INY -; STAIY NEWARG -; LDA BBUF+1 -; INY -; STAIY NEWARG -; -; LDA OUTBSZ ;Put no. of bytes on stack -; INY -; STAIY NEWARG -; LDA OUTBSZ+1 -; INY -; STAIY NEWARG -; -; TXA ;RNDMAN function code -; JSR SETUSA -; -; JSR RNDMAN ;*** Call RNDMAN ** -; BEQ #50 ;OK, continue -; STA DSCERR ;Otherwise set error code -;50 RTS +RMSUBR ROUT + LDYIM ARGD + STAIY NEWARG ;Put handle on stack + + LDA BBUF ;Put buffer address on stack + INY + STAIY NEWARG + LDA BBUF+1 + INY + STAIY NEWARG + + LDA OUTBSZ ;Put no. of bytes on stack + INY + STAIY NEWARG + LDA OUTBSZ+1 + INY + STAIY NEWARG + + TXA ;RNDMAN function code + JSR SETUSA + + JSR RNDMAN ;*** Call RNDMAN ** + BEQ #50 ;OK, continue + STA DSCERR ;Otherwise set error code +50 RTS ;Yet another interface - this one allows an application diff --git a/FileStore/SRC/FileStore/Uade20.6502 b/FileStore/SRC/FS/FileStore/Uade20 similarity index 100% rename from FileStore/SRC/FileStore/Uade20.6502 rename to FileStore/SRC/FS/FileStore/Uade20 diff --git a/FileStore/SRC/FileStore/Uade20A.6502 b/FileStore/SRC/FS/FileStore/Uade20A similarity index 95% rename from FileStore/SRC/FileStore/Uade20A.6502 rename to FileStore/SRC/FS/FileStore/Uade20A index d8eb608..a2e3a84 100644 --- a/FileStore/SRC/FileStore/Uade20A.6502 +++ b/FileStore/SRC/FS/FileStore/Uade20A @@ -148,11 +148,10 @@ SETTXP INY 10 INY ADCIM 0 STAIY NEWARG + PHX LDX BPTR -;v1.23 - STZAX RXBUFT ;RX buffer terminater -;v1.31 -; STZAX (RXBUF+RXBUFL) ;**22/3/88** + STZAX RXBUF+RXBUFL ;**22/3/88** + PLX RTS ;Sets file title pointer to stack @@ -166,20 +165,12 @@ SETTXP INY ;get carried away. SETFTP INY - CLC - ADC BPTR ;Add file title offset to buffer offset - ADCIM RXBUF - STAIY NEWARG - LDAIM 0 - ADCIM /(RXBUF ) - INY - STAIY NEWARG - PHX ;Store X just in case - LDX BPTR - STZAX RXBUFT ;RX buffer terminater - PLX - RTS - + CLC + ADC BPTR ;Add file title offset to buffer offset + ADCIM :LSB:RXBUF + STAIY NEWARG + LDAIM :MSB:RXBUF + BRA #10 ;Returns the last component of the pathname handed to save ;in MIDTX [3:13] @@ -554,7 +545,7 @@ BUFERR LDAIM NAMERR PLP 70 RTS ;Give Z unset exit - + [ 1=0 ;Read hex number (up to 4 bytes) ;into 4-byte p.0 area at X. NOTE ;uses 1 extra byte at X. @@ -595,7 +586,7 @@ RDNUM ROUT 40 LDAZX 4 RTS - + ] SPACER DEY 50 INY @@ -615,9 +606,9 @@ RDTITL ROUT COMEND JSR SPACES CMPIM CR BEQ #10 - LDAIM WOTERR + LDAIM SYNERR JSR EXTERR - LDAIM WOTERR ;Give non-zero exit + LDAIM SYNERR ;Give non-zero exit 10 RTS ;** E R R O R T A B L E ** @@ -627,9 +618,9 @@ ERRTAB [ Lang = English = URERRA,"Who are you?",CR = WOTERR,"Bad Command",CR -; = SYNERR,"Syntax",CR + = SYNERR,"Syntax",CR = NAMERR,"Bad string",CR -; = NUMERR,"Bad number",CR + = NUMERR,"Bad number",CR = DRERRA,"Bad file name",CR = DRERRB,"Broken dir",CR = DRERRC,"Not found",CR @@ -675,7 +666,7 @@ ERRTAB = WOTERR,"Comando Errato",CR = SYNERR,"Syntax",CR ; ************************************ = NAMERR,"Sequenza errata",CR -; = NUMERR,"Numero errata",CR ; ************************************ + = NUMERR,"Numero errata",CR ; ************************************ = DRERRA,"Nome file errato",CR = DRERRB,"Dir rotto",CR = DRERRC,"Non trovato",CR diff --git a/FileStore/SRC/FS/GO b/FileStore/SRC/FS/GO new file mode 100644 index 0000000..fe8f457 --- /dev/null +++ b/FileStore/SRC/FS/GO @@ -0,0 +1,6 @@ +*ADFS +*LIB ADFS::0.$.LIBRARY +*65ARTHURT +*DIR ADFS::0.$ +*EXEC FSASM + diff --git a/FileStore/SRC/FS/GO.inf b/FileStore/SRC/FS/GO.inf new file mode 100644 index 0000000..0272292 --- /dev/null +++ b/FileStore/SRC/FS/GO.inf @@ -0,0 +1 @@ +GO FFFFD65A 606A5A84 00000044 19 CRC32=E8C7503D \ No newline at end of file diff --git a/FileStore/SRC/FS/LIBRARY/65ARTHURT b/FileStore/SRC/FS/LIBRARY/65ARTHURT new file mode 100644 index 0000000..767b5f5 Binary files /dev/null and b/FileStore/SRC/FS/LIBRARY/65ARTHURT differ diff --git a/FileStore/SRC/LIBRARY/65ARTHURT.INF b/FileStore/SRC/FS/LIBRARY/65ARTHURT.INF similarity index 100% rename from FileStore/SRC/LIBRARY/65ARTHURT.INF rename to FileStore/SRC/FS/LIBRARY/65ARTHURT.INF diff --git a/FileStore/SRC/FS/LIBRARY/CB b/FileStore/SRC/FS/LIBRARY/CB new file mode 100644 index 0000000..41cee62 Binary files /dev/null and b/FileStore/SRC/FS/LIBRARY/CB differ diff --git a/FileStore/SRC/LIBRARY/CB.INF b/FileStore/SRC/FS/LIBRARY/CB.INF similarity index 100% rename from FileStore/SRC/LIBRARY/CB.INF rename to FileStore/SRC/FS/LIBRARY/CB.INF diff --git a/FileStore/SRC/FS/LIBRARY/TURMASM b/FileStore/SRC/FS/LIBRARY/TURMASM new file mode 100644 index 0000000..ebe1435 Binary files /dev/null and b/FileStore/SRC/FS/LIBRARY/TURMASM differ diff --git a/FileStore/SRC/LIBRARY/TURMASM.INF b/FileStore/SRC/FS/LIBRARY/TURMASM.INF similarity index 100% rename from FileStore/SRC/LIBRARY/TURMASM.INF rename to FileStore/SRC/FS/LIBRARY/TURMASM.INF diff --git a/FileStore/SRC/FS/README b/FileStore/SRC/FS/README new file mode 100644 index 0000000..f224279 --- /dev/null +++ b/FileStore/SRC/FS/README @@ -0,0 +1,379 @@ +FileStore FS ROM v1.31 +====================== + +This disc contains the original source code for the Acorn FileStore E01/E01S +file server ROM. + +Assembling the File Store Source Code +====================================== + +The source code will assemble on either a BBC with an Acorn Turbo (256K) +6502 Co-Processor and ADFS or on Arthur/RISC OS using the 6502 Turbo +Co-Processor emulator which is included here. +To assemble on a BBC, use SHIFT-BREAK or *EXEC !BOOT. On RISC OS, double +clicking the file GO will start the process. The assembled file "FSROM" will be +placed in the root directory. The assembly process is significantly faster +when a hard drive is used instead of a floppy. + +Files +===== + +\ $ + !BOOT - BBC Routine to set library, load co-pro BASIC and call FSASM + FSASM - Loads TurboMasm and starts the FileStore binary assembly + GO - RISC OS Routine to set library, load emulator and call FSASM + README - This file + +\ LIBRARY + 65ARTHURT - The Turbo Co-processor emulator for RISC OS + CB - BASIC for the Turbo Co-processor + TURMASM - Turbo version of MASM assembler + +\ FILESTORE + The source code files + FSmake - BASIC program to put together the assembed parts and create + the Filestore ROM binary "FSROM" + +\ FILESTORE\X + Location for the assembled parts. Do not delete or the assembler will fail. + + +Version 1.31 +============ + +Date - estimated 20/7/88. This was the latest date of a comment in the code. +The E01S first appeared in Technomatic adverts in Acorn User Jan 1989. + +Comments +======== +The file server ROM is the original and unchanged source code. Since just +before v1.20 the FileStore had become an Acorn product which used the same +code base as the L3 fileserver. + +The original file server FSmake that puts together the assembled parts has been +altered to insert 512 bytes at the start of the ROM so the image is ready +for use directly (if less than 32K). This maps to 512 bytes of zero page +workspace as the ROM code executes from address 0x200. + +An ammendement has been made at the end of the code to add some bytes to the +file server ROM. When the file server code was originally assembled, it +appears that when creating a ROM, some noise was picked up from code already +on the disk. These few bytes have been replicated at the end, so a binary +compare to an original ROM is correct. + +v1.31 was the first release for the revised Acorn FileStore E01S model. +The E01S uses 1 x 64K ROM instead of 2 x 32K ROMs. There is no difference in +the code between the two systems. + +From the Acorn parts list there was a release between v1.23 and v1.31. A binary of this has not been found. There wasn't a corresponding MOS ROM and it is +assumed only the file server ROM had the revision at this point. + + DATE 21.5.90 + +========================================================================== + DRAWING / | TITLE | ISS | SHT | LAST + NUMBER / | | | | AMR/ECO +=============|=======================================|=====|=====|======== +0254,206-01 FILESTORE FILESERVER ROM V 1.2A + +v1.31 is not listed in Acorn parts list. + +Depending on the options used, the FS ROM can overflow the 32K ROM as was the +case in later versions. There is space at the start of the MOS ROM for the +overflow but care must be taken with the start of workspace areas. +The file MAKEROMS will take any overflow bytes and add them to the start of the +MOS ROM, create a 32K FSROM, 32K MOSROM (for E01 Filestores) and a single 64K +E01SROM (for E01S Filestores). Copy both the FSROM and MOSROM into the same +directory, and run the program under Turbo Hi-BASIC. +*CB +CHAIN "MAKEROMS" +The program can be found with the MOS ROM disk. + +Warning: There appear to be changes made to the file system handling over +previous versions. It has been found that hard drives from previous versions +are not fully compatible with v1.31 - both L3 and FileStore. + +Changes (from v1.23) (FileServer) +================================= + +The Filestore software has a big buffer cache option introduced for replies +which is enabled in this version. + +Support for Pseudo directory symbols is no longer present, but kept as an +optional assembler directive. The same for the MOS ROM debug code. +Command line changes: +Old Version New command and syntax +*FORMAT *FSFORMAT <4|5> <NAME> +*FSMODE *FSMODE <U|M> +*VERIFY *FSVERIFY d +*FSSTN *FSSTATION sss +*MAXDRIVE *FSMAXDRIVE d +*FSUSER *FSUSER <name> +*FSPROT *FSPROT <ON|OFF> +*REPORT *FSREPORT + +New Commands are +*PRPAGE <Y|N> +*FSNAMEDISC <name> + +Commands removed are +*CAT +*LOAD +*SAVE +*CERTIFY + +Form Feed suppression option (*PRPAGE). Bypass flag in CMOS for the Acorn copyright hard drive check. SIN added to disc error report strings. +Year 20xx compatable, bugfix enlarging the password file. Support for multiple +hard drives and E40S, E60S. Reset CMOS to default values if they are corrupt. +A revised version of the AFS0 disk format is used to optimise use of the larger +hard drives. Disks and floppies with the older AFS0 format will have issues. + +HEADER FILE 1 +20/07/88 Uade01 Line 0059 VERLB, version changed from 23 to 31 +18/02/88 Uade01 Line 0065 Pseudo directory (%, &, @) switch added - default off + Uade01 Line 0267 Size of IEaddr changed to 8 bytes for better error reporting +08/02/88 Uade01 Line 0273 Flag added for the supression of print Form Feed +23/03/88 Uade01 Line 0274 Flag added to bypass hard drive ACORN copyright check +05/03/88 Uade01 Line 0275 variable CMinen added for CMOS table length + +HEADER FILE 2 + Uade02 Line 0117 Pseudo directory (%, &, @) switch + to 0119 ] +08/02/88 Uade02 Line 0239 Receive buffer length extended from 80 to 127 bytes +01/05/86 Uade02 Line 0261 Mask for task number in control byte changed from &1E to &78 +08/02/88 Uade02 Line 0399 size of MIDRX changed to calculated length +08/02/88 Uade02 Line 0418 File title buffer made always the same size as RXBUFL + Uade02 Line 0450 variable added for SIN of last disc error +08/02/88 Uade02 Line 0465 Flag for printing no trailer FormFeed + +ERROR HANDLING +29/04/88 Uade03 Line 0051 reporting added for the SIN of last disc error +29/04/88 Uade03 Line 0092 cancel any pending receive control blocks after error + +FILE SERVER INITIALISATION + Uade04 Line 0036 INTERR changed to USRERR +05/03/88 Uade04 Line 0046 Table of default values for initialsing CMOS RAM added +05/03/88 Uaed04 Line 0066 Initialise CMOS RAM if not initialised +24/02/88 Uade04 Line 0204 Code optimisation for date sanity check + to 0205 " + Uade04 Line 0216 " + Uade04 Line 0228 " + Uade04 Line 0233 " + to 0236 " + +USRMAN + Uade06A Line 0307 Pseudo directory (%, &, @) switch + to 0310 ] +01/06/88 Uade06A Line 0372 Routine LOGOFF + to 0379 +07/07/88 Uade06A Line 0454 Routine GETUFD, add SETUID + to 0458 and code optimzation reusing RTROOT +07/07/88 Uade06A Line 0494 Routine GETLBH, to retrieve file "LIBRARY" + to 0539 + +RNDMAN +29/04/88 Rman02 Line 0160 Change file size. code moved to a subroutine + to 0163 RDEXSZ in Rman04 to extend the file +29/04/88 Uade19 Line 0188 use RXEXSZ + to 0189 +01/06/88 Rman02 Line 0382 bugfix: High water mark not increased when setting + the sequential file pointer, if it exceeded + the high existing high water mark +23/03/88 Rman03 Line 0247 bugfix for the access mode for Putbytes/Getbytes + to 0250 operations +29/04/88 Rman04 Line 0182 Set new file size and call the new subroutine + to 0187 RDEXSZ to extend the file +29/04/88 Rman04 Line 0219 Subroutine RDEXSZ added + Rman04 Line 0252 + +DIRMAN +23/03/88 Uade0C Line 0021 New function 13 added. Check if object will preserve + to 0022 Increase the number of functions + Uade0C Line 0041 add routine to table +04/04/88 Uade0C Line 0122 call as a subroutine + to 0126 and use the DIRMAN exit function +04/04/88 Uade0C Line 0150 Routine DRRET2 set up the name, root character and 9 + to 0154 spaces +04/04/88 Uade0C Line 0167 add check for directory type and the locked bit + to 0178 + Uade0C Line 0206 + to 0209 + Uade0C Line 0212 Pseudo directory (%, &, @) switch + to 0227 | + to 0229 ] + Uade0C Line 0223 + to 0226 + Uade0C Line 0533 Pseudo directory (%, &, @) switch + to 0540 ] +04/04/88 Uade0C Line 0260 Change to RTS as a subroutine exit + Uade0CA Line 0032 INTERR changed to USRERR +04/04/88 Uade0CA Line 0303 DRINFO most of the routine changed + to 0335 + Uade0D Line 0152 check for : character removed as it was there twice + Uade0D Line 0152 check for : character removed as it was there twice + Uade0D Line 0415 Pseudo directory (%, &, @) switch + to 0420 ] + Uade0D Line 0517 Pseudo directory (%, &, @) switch + to 0523 ] + Uade0D Line 0535 Pseudo directory (%, &, @) switch + to 0540 ] +01/06/88 Uade0D Line 0573 compatibility for "^" ? +01/06/88 Uade0D Line 0577 code optimisation, no longer required + + Uade0DA Line 0145 Code for RETPAR changed around in order of + Uade0DA to 0191 execution. + Uade0DA Line 0535 Pseudo directory (%, &, @) switch + to 0540 ] + Uade0DA Line 0865 + to 0912 + + Uade0E Line 0377 OUTZRO routine removed +24/02/88 Uade0E Line 0460 ensure only the day of the month is output + Uade0E Line 0461 + Uade0E Line 0467 + Uade0E Line 0468 set the value for the year + to 0471 + Uade0E Line 0482 +24/02/88 Uade0E Line 0489 ensure year 20xx compatable + to 0492 + Uade0E Line 0512 code optimised for character conversion + Uade0E Line 0526 Jump label OUTACA removed + Uade0E Line 0576 Jump label OUTSZA removed + +01/06/88 Uade0EA Line 0082 check entry code and update header +01/06/88 Uade0EA Line 0106 Check if preserve only, update header + to 0122 routine + +AUTMAN +22/03/88 Uade0F Line 0084 code moved to subroutine ATOPWF +22/03/88 Uade0F Line 0181 new subroutine ATOPWF + to 0206 +22/03/88 Uade0F Line 0334 use subroutine ATOPWF to check PW file +22/03/88 Uade0F Line 0534 use subroutine ATOPWF to check PW file + + Uade0FA Line 0213 RTS added + Uade0FA Line 0282 check removed for alternative RC + to 0288 +01/06/88 Uade0FA Line 0413 + to 0417 +01/06/88 Uade0FA Line 0448 code to look for runnimg over page boundary removed +01/06/88 Uade0FA Line 0455 check if the password file will be too big before + to 0457 trying to enlarge it +01/06/88 Uade0FA Line 0478 add test for end of file + to 0483 + Uade0FA Line 0504 code optimised to check for end of PW file + to 0509 +01/06/88 Uade0FA Line 0543 check if the password file will be too big before + to 0549 trying to enlarge it + Line 0572 + +MAPMAN +24/02/88 Uade10 Line 0101 check added for write protect + to 0102 + +01/07/88 Uade10A Line 0418 code optimisation. keep a copy of the map block + Line 0422 pointer on the stack +01/07/88 Uade10A Line 0434 and use it instead of making the calculation again + to 0437 + Uade10A Line 0533 Code optimised with temp variables no longer being zero'ed + + Uade10A Line 0568 Code optimised to save having to get the drive + Uade10A Line 0573 number twice +05/03/88 Uade10A Line 0597 code moved to a new subroutine MPRESZ +05/03/88 Uade10A Line 0621 new subroutine MPRESZ from previous code + to 0646 + +MAPMAN UTILITIES +06/07/88 Uade11 Line 0069 check if disc needs to be mounted + to 0076 +05/03/88 Uade11 Line 0094 code optimised to use the new routine MPRESZ +06/07/88 Uade11 Line 0125 + to 0129 +06/07/88 Uade11 Line 0408 JSR USRERR replaced by JSR INTERR +01/07/88 Uade11 Line 0499 code replaced by subroutine SETMB +01/07/88 Uade11A Line 0072 Get Cylinder Map position routine chnaged + to 0081 + +MAPMAN UTILITIES II + Uade12 Line 0051 + Uade12 Line 0058 code optimised. Setting command 8 moved up to here + to 0059 + Uade12 Line 0070 + to 0072 + Uade12 Line 0098 + Uade12 Line 0265 bugfix: ensure carry is cleared +01/07/88 Uade12 Line 0584 optimise ABLKS + to 0595 + Uade12 Line 0636 routine ABSALL removed as is now in routine ABLKS + + Uade13 Line 0018 optimise code. No need to clear drive number in X +23/03/88 Uade13 Line 0789 Bypass (C)Acorn hard drive check + to 0791 +01/08/88 Uade13 Line 0829 Set drive number + Line 0833 Use different memory area + Line 0837 Use different memory area +06/07/88 Uade13 Line 0838 bugfix: don't overlay sector zero on restart + Uade13 Line 0849 Use different memory area + to 0853 + Uade13 Line 0912 Use INTERR instead of USRERR +29/04/88 Uade13 Line 0978 Remove code and zero DCSTAD + to 0998 +29/04/88 Uade13 Line 1013 Remove code + to 1024 + +DSCMAN +29/02/88 Uade14 Line 0053 optimise code. use stack + to 0058 +12/07/88 Uade14 Line 0457 copy disc address for error reporting + to 0461 +24/02/88 Uade14 Line 0508 routine Testdv, mainly to check for write protect + to 0522 + +COMMAND PROCESSOR +06/07/88 Uade15 Line 0088 Ignore error if removable disc is unavailable + to 0094 Use INTERR instead of USRERR +08/02/88 Uade15 Line 0332 comment added PRPAGE NOT TRANSLATED TO ITALIAN +08/02/88 Uade15 Line 0352 comment added NOMEDISC NOT TRANSLATED TO ITALIAN? + Uade15A Line 0026 add error reporting string SIN= + to 0029 +01/06/88 Uade15A Line 0044 add support to reset the error report +07/07/88 to 0049 & in user mode +01/06/88 to 0064 in maintenance mode for privileged user + Uade15A Line 0085 support change in message length +22/03/88 Uade15A Line 0390 add support to rename a disc in maintenance mode + to 0476 + +08/02/88 Uade16 Line 0028 SAVE Routine changes + to 0088 + Uade16 Line 0331 Pseudo directory (%, &, @) switch + to 0335 ] + Uade16A Line 0027 Pseudo directory (%, &, @) switch + to 0031 ] + Uade19 Line 0591 code optimisation and moved to RMSUBR + to 0592 + Uade19 Line 0705 new subroutine RMSUBR + to 0732 + +22/03/88 Uade20A Line 0153 bugfix. + +PRINT +08/02/88 PRINT0 Line 0040 check for trailer banner suppress state + to 0043 +20/05/87 PRINT0 Line 0269 + to 0271 +08/02/88 PRINT0 Line 0495 add option for a single Form Feed as a trailer banner + to 0522 + +FORMAT + FORM00 Line 0029 multiple lines of code removed + FORM00 Line 0048 JMP COMRTS removed + FORM00 Line 0245 image format changes + FORM00 Line 0257 + FORM00 Line 0260 + FORM00 Line 0265 + FORM00 Line 0269 + to 0280 + FORM00 Line 0283 + FORM00 Line 0303 + FORM00 Line 0402 + to 0406 diff --git a/FileStore/SRC/FS/README.inf b/FileStore/SRC/FS/README.inf new file mode 100644 index 0000000..fce6806 --- /dev/null +++ b/FileStore/SRC/FS/README.inf @@ -0,0 +1 @@ +$.README FFFFFF59 18948126 00003CB6 19 A544 2B2010 A242 210F0E diff --git a/FileStore/SRC/FileStore/FSASM b/FileStore/SRC/FileStore/FSASM deleted file mode 100644 index f484ab9..0000000 --- a/FileStore/SRC/FileStore/FSASM +++ /dev/null @@ -1 +0,0 @@ -*|Assembly sequence for Filestore FS > FsAsm *|By Jes 3/9/84, Updated by Glenn 8/5/85 *OPT 1 1 *TurMasm STOP ON ASM UADE01 *CB CH."FSmake" \ No newline at end of file diff --git a/FileStore/SRC/FileStore/FSASM.inf b/FileStore/SRC/FileStore/FSASM.inf deleted file mode 100644 index c79b862..0000000 --- a/FileStore/SRC/FileStore/FSASM.inf +++ /dev/null @@ -1 +0,0 @@ -$.FSASM 00000000 00000000 0000008D 33 diff --git a/FileStore/SRC/FileStore/FSmake b/FileStore/SRC/FileStore/FSmake deleted file mode 100644 index fe6416b..0000000 Binary files a/FileStore/SRC/FileStore/FSmake and /dev/null differ diff --git a/FileStore/SRC/FileStore/FSmake.inf b/FileStore/SRC/FileStore/FSmake.inf deleted file mode 100644 index 4f339d7..0000000 --- a/FileStore/SRC/FileStore/FSmake.inf +++ /dev/null @@ -1 +0,0 @@ -FSmake 00000800 0000B823 000005B9 WR diff --git a/FileStore/SRC/FileStore/Form00.6502.inf b/FileStore/SRC/FileStore/Form00.6502.inf deleted file mode 100644 index 78ad567..0000000 --- a/FileStore/SRC/FileStore/Form00.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Form00 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Mbbmcm.6502.inf b/FileStore/SRC/FileStore/Mbbmcm.6502.inf deleted file mode 100644 index 8aa013d..0000000 --- a/FileStore/SRC/FileStore/Mbbmcm.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Mbbmcm 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Print0.6502.inf b/FileStore/SRC/FileStore/Print0.6502.inf deleted file mode 100644 index df21ddd..0000000 --- a/FileStore/SRC/FileStore/Print0.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Print0 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Rman01.6502.inf b/FileStore/SRC/FileStore/Rman01.6502.inf deleted file mode 100644 index f25df3d..0000000 --- a/FileStore/SRC/FileStore/Rman01.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Rman01 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Rman02.6502.inf b/FileStore/SRC/FileStore/Rman02.6502.inf deleted file mode 100644 index 6e9d725..0000000 --- a/FileStore/SRC/FileStore/Rman02.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Rman02 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Rman02A.6502.inf b/FileStore/SRC/FileStore/Rman02A.6502.inf deleted file mode 100644 index 4cc461f..0000000 --- a/FileStore/SRC/FileStore/Rman02A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Rman02A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Rman03.6502.inf b/FileStore/SRC/FileStore/Rman03.6502.inf deleted file mode 100644 index e18c6d8..0000000 --- a/FileStore/SRC/FileStore/Rman03.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Rman03 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Rman04.6502.inf b/FileStore/SRC/FileStore/Rman04.6502.inf deleted file mode 100644 index 3db6d0a..0000000 --- a/FileStore/SRC/FileStore/Rman04.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Rman04 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Rman05.6502.inf b/FileStore/SRC/FileStore/Rman05.6502.inf deleted file mode 100644 index 31a59a3..0000000 --- a/FileStore/SRC/FileStore/Rman05.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Rman05 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade01.6502.inf b/FileStore/SRC/FileStore/Uade01.6502.inf deleted file mode 100644 index ce5f25a..0000000 --- a/FileStore/SRC/FileStore/Uade01.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade01 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade02.6502.inf b/FileStore/SRC/FileStore/Uade02.6502.inf deleted file mode 100644 index 66b02bb..0000000 --- a/FileStore/SRC/FileStore/Uade02.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade02 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade03.6502.inf b/FileStore/SRC/FileStore/Uade03.6502.inf deleted file mode 100644 index f73604a..0000000 --- a/FileStore/SRC/FileStore/Uade03.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade03 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade04.6502.inf b/FileStore/SRC/FileStore/Uade04.6502.inf deleted file mode 100644 index 08c7a23..0000000 --- a/FileStore/SRC/FileStore/Uade04.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade04 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade05.6502.inf b/FileStore/SRC/FileStore/Uade05.6502.inf deleted file mode 100644 index 1e66296..0000000 --- a/FileStore/SRC/FileStore/Uade05.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade05 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade06.6502.inf b/FileStore/SRC/FileStore/Uade06.6502.inf deleted file mode 100644 index dc5e1a9..0000000 --- a/FileStore/SRC/FileStore/Uade06.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade06 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade06A.6502.inf b/FileStore/SRC/FileStore/Uade06A.6502.inf deleted file mode 100644 index 6b03420..0000000 --- a/FileStore/SRC/FileStore/Uade06A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade06A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0A.6502.inf b/FileStore/SRC/FileStore/Uade0A.6502.inf deleted file mode 100644 index 7823147..0000000 --- a/FileStore/SRC/FileStore/Uade0A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0B.6502.inf b/FileStore/SRC/FileStore/Uade0B.6502.inf deleted file mode 100644 index c2676fb..0000000 --- a/FileStore/SRC/FileStore/Uade0B.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0B 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0C.6502.inf b/FileStore/SRC/FileStore/Uade0C.6502.inf deleted file mode 100644 index ba8eec1..0000000 --- a/FileStore/SRC/FileStore/Uade0C.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0C 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0CA.6502.inf b/FileStore/SRC/FileStore/Uade0CA.6502.inf deleted file mode 100644 index ba6c6dd..0000000 --- a/FileStore/SRC/FileStore/Uade0CA.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0CA 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0D.6502.inf b/FileStore/SRC/FileStore/Uade0D.6502.inf deleted file mode 100644 index d26d787..0000000 --- a/FileStore/SRC/FileStore/Uade0D.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0D 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0DA.6502.inf b/FileStore/SRC/FileStore/Uade0DA.6502.inf deleted file mode 100644 index 545f05b..0000000 --- a/FileStore/SRC/FileStore/Uade0DA.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0DA 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0E.6502.inf b/FileStore/SRC/FileStore/Uade0E.6502.inf deleted file mode 100644 index a42587c..0000000 --- a/FileStore/SRC/FileStore/Uade0E.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0E 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0EA.6502.inf b/FileStore/SRC/FileStore/Uade0EA.6502.inf deleted file mode 100644 index cc0a486..0000000 --- a/FileStore/SRC/FileStore/Uade0EA.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0EA 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0F.6502.inf b/FileStore/SRC/FileStore/Uade0F.6502.inf deleted file mode 100644 index 9bd5370..0000000 --- a/FileStore/SRC/FileStore/Uade0F.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0F 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade0FA.6502.inf b/FileStore/SRC/FileStore/Uade0FA.6502.inf deleted file mode 100644 index caad411..0000000 --- a/FileStore/SRC/FileStore/Uade0FA.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade0FA 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade10.6502.inf b/FileStore/SRC/FileStore/Uade10.6502.inf deleted file mode 100644 index 0ea5ba8..0000000 --- a/FileStore/SRC/FileStore/Uade10.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade10 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade10A.6502.inf b/FileStore/SRC/FileStore/Uade10A.6502.inf deleted file mode 100644 index 092e19b..0000000 --- a/FileStore/SRC/FileStore/Uade10A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade10A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade11.6502.inf b/FileStore/SRC/FileStore/Uade11.6502.inf deleted file mode 100644 index dd55fc0..0000000 --- a/FileStore/SRC/FileStore/Uade11.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade11 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade11A.6502.inf b/FileStore/SRC/FileStore/Uade11A.6502.inf deleted file mode 100644 index 3a744e1..0000000 --- a/FileStore/SRC/FileStore/Uade11A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade11A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade12.6502.inf b/FileStore/SRC/FileStore/Uade12.6502.inf deleted file mode 100644 index 598e651..0000000 --- a/FileStore/SRC/FileStore/Uade12.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade12 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade12A.6502.inf b/FileStore/SRC/FileStore/Uade12A.6502.inf deleted file mode 100644 index d680ddb..0000000 --- a/FileStore/SRC/FileStore/Uade12A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade12A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade13.6502.inf b/FileStore/SRC/FileStore/Uade13.6502.inf deleted file mode 100644 index 9a0b542..0000000 --- a/FileStore/SRC/FileStore/Uade13.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade13 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade14.6502.inf b/FileStore/SRC/FileStore/Uade14.6502.inf deleted file mode 100644 index 43239b1..0000000 --- a/FileStore/SRC/FileStore/Uade14.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade14 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade15.6502.inf b/FileStore/SRC/FileStore/Uade15.6502.inf deleted file mode 100644 index 51b345d..0000000 --- a/FileStore/SRC/FileStore/Uade15.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade15 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade15A.6502.inf b/FileStore/SRC/FileStore/Uade15A.6502.inf deleted file mode 100644 index 77231f2..0000000 --- a/FileStore/SRC/FileStore/Uade15A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade15A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade16.6502.inf b/FileStore/SRC/FileStore/Uade16.6502.inf deleted file mode 100644 index 0908037..0000000 --- a/FileStore/SRC/FileStore/Uade16.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade16 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade16A.6502.inf b/FileStore/SRC/FileStore/Uade16A.6502.inf deleted file mode 100644 index 1579ce5..0000000 --- a/FileStore/SRC/FileStore/Uade16A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade16A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade17.6502.inf b/FileStore/SRC/FileStore/Uade17.6502.inf deleted file mode 100644 index 280c70b..0000000 --- a/FileStore/SRC/FileStore/Uade17.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade17 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade17A.6502.inf b/FileStore/SRC/FileStore/Uade17A.6502.inf deleted file mode 100644 index d53398c..0000000 --- a/FileStore/SRC/FileStore/Uade17A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade17A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade18.6502.inf b/FileStore/SRC/FileStore/Uade18.6502.inf deleted file mode 100644 index 549839e..0000000 --- a/FileStore/SRC/FileStore/Uade18.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade18 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade19.6502.inf b/FileStore/SRC/FileStore/Uade19.6502.inf deleted file mode 100644 index 2a2a6e6..0000000 --- a/FileStore/SRC/FileStore/Uade19.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade19 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade20.6502.inf b/FileStore/SRC/FileStore/Uade20.6502.inf deleted file mode 100644 index e698990..0000000 --- a/FileStore/SRC/FileStore/Uade20.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade20 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/FileStore/Uade20A.6502.inf b/FileStore/SRC/FileStore/Uade20A.6502.inf deleted file mode 100644 index 6977fc3..0000000 --- a/FileStore/SRC/FileStore/Uade20A.6502.inf +++ /dev/null @@ -1 +0,0 @@ -Uade20A 00000000 00000000 \ No newline at end of file diff --git a/FileStore/SRC/GO b/FileStore/SRC/GO deleted file mode 100644 index ccadc1e..0000000 Binary files a/FileStore/SRC/GO and /dev/null differ diff --git a/FileStore/SRC/GO.INF b/FileStore/SRC/GO.INF deleted file mode 100644 index 74b54b2..0000000 --- a/FileStore/SRC/GO.INF +++ /dev/null @@ -1 +0,0 @@ -GO FFFFD65A 606A5A84 00000057 WR diff --git a/FileStore/SRC/MOS/!BOOT b/FileStore/SRC/MOS/!BOOT new file mode 100644 index 0000000..cbc5a0b --- /dev/null +++ b/FileStore/SRC/MOS/!BOOT @@ -0,0 +1 @@ +MODE0 *DIR $ *LIB LIBRARY *E.MOSASM \ No newline at end of file diff --git a/FileStore/SRC/MOS/!BOOT.inf b/FileStore/SRC/MOS/!BOOT.inf new file mode 100644 index 0000000..e184663 --- /dev/null +++ b/FileStore/SRC/MOS/!BOOT.inf @@ -0,0 +1 @@ +$.!BOOT 00000000 00000000 00000024 19 A341 122311 A24F 350114 diff --git a/FileStore/SRC/MOS/GO b/FileStore/SRC/MOS/GO new file mode 100644 index 0000000..97beda0 --- /dev/null +++ b/FileStore/SRC/MOS/GO @@ -0,0 +1,5 @@ +*ADFS +*LIB ADFS::0.$.LIBRARY +*65ARTHURT +*DIR ADFS::0.$ +*EXEC MOSASM diff --git a/FileStore/SRC/MOS/GO.INF b/FileStore/SRC/MOS/GO.INF new file mode 100644 index 0000000..db765a2 --- /dev/null +++ b/FileStore/SRC/MOS/GO.INF @@ -0,0 +1 @@ +GO FFFFD65A 606A5A84 00000044 19 CRC32=D764CA69 \ No newline at end of file diff --git a/FileStore/SRC/MOS/GOROMS b/FileStore/SRC/MOS/GOROMS new file mode 100644 index 0000000..da69568 --- /dev/null +++ b/FileStore/SRC/MOS/GOROMS @@ -0,0 +1,6 @@ +*ADFS +*LIB ADFS::0.$.LIBRARY +*65ARTHURT +*DIR ADFS::0.$ +*CB +CHAIN"MAKEROMS" diff --git a/FileStore/SRC/MOS/GOROMS.INF b/FileStore/SRC/MOS/GOROMS.INF new file mode 100644 index 0000000..505c151 --- /dev/null +++ b/FileStore/SRC/MOS/GOROMS.INF @@ -0,0 +1 @@ +GOROMS FFFFD65A 606A5A84 00000044 19 CRC32=D764CA69 \ No newline at end of file diff --git a/FileStore/SRC/MOS/LIBRARY/65ARTHURT b/FileStore/SRC/MOS/LIBRARY/65ARTHURT new file mode 100644 index 0000000..767b5f5 Binary files /dev/null and b/FileStore/SRC/MOS/LIBRARY/65ARTHURT differ diff --git a/FileStore/SRC/MOS/LIBRARY/65ARTHURT.INF b/FileStore/SRC/MOS/LIBRARY/65ARTHURT.INF new file mode 100644 index 0000000..9fddd51 --- /dev/null +++ b/FileStore/SRC/MOS/LIBRARY/65ARTHURT.INF @@ -0,0 +1 @@ +65ARTHURT FFFFFA40 9444A542 0000A0C4 WR diff --git a/FileStore/SRC/MOS/LIBRARY/CB b/FileStore/SRC/MOS/LIBRARY/CB new file mode 100644 index 0000000..41cee62 Binary files /dev/null and b/FileStore/SRC/MOS/LIBRARY/CB differ diff --git a/FileStore/SRC/MOS/LIBRARY/CB.INF b/FileStore/SRC/MOS/LIBRARY/CB.INF new file mode 100644 index 0000000..7c2b7eb --- /dev/null +++ b/FileStore/SRC/MOS/LIBRARY/CB.INF @@ -0,0 +1 @@ +CB 0000B800 0000B800 00004000 WR diff --git a/FileStore/SRC/MOS/LIBRARY/TURMASM b/FileStore/SRC/MOS/LIBRARY/TURMASM new file mode 100644 index 0000000..ebe1435 Binary files /dev/null and b/FileStore/SRC/MOS/LIBRARY/TURMASM differ diff --git a/FileStore/SRC/MOS/LIBRARY/TURMASM.INF b/FileStore/SRC/MOS/LIBRARY/TURMASM.INF new file mode 100644 index 0000000..61de852 --- /dev/null +++ b/FileStore/SRC/MOS/LIBRARY/TURMASM.INF @@ -0,0 +1 @@ +TURMASM B000 B000 diff --git a/FileStore/SRC/MOS/MAKEROMS b/FileStore/SRC/MOS/MAKEROMS new file mode 100644 index 0000000..44ec4e6 Binary files /dev/null and b/FileStore/SRC/MOS/MAKEROMS differ diff --git a/FileStore/SRC/MOS/MAKEROMS.inf b/FileStore/SRC/MOS/MAKEROMS.inf new file mode 100644 index 0000000..9281c72 --- /dev/null +++ b/FileStore/SRC/MOS/MAKEROMS.inf @@ -0,0 +1 @@ +$.MAKEROMS 00000800 0000B823 00000610 99 A544 0D1010 A544 250010 diff --git a/FileStore/SRC/MOS/MOS/DOS01 b/FileStore/SRC/MOS/MOS/DOS01 new file mode 100644 index 0000000..606cc72 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/DOS01 @@ -0,0 +1,620 @@ + OPT 1 ; > <FileStoreMOSSource>.DOS01 + TTL File server file DOS01 + +; OSWORD &72 - Double Density Disk Access +; +; Transfer up to &FF00 bytes at a time +; XY=>control block: +; XY+ 0 Flag on entry, Returned result on exit +; XY+ 1 Addr0 +; XY+ 2 Addr1 +; XY+ 3 Addr2 +; XY+ 4 Addr3 +; XY+ 5 Command +; (=&8 to read / &A to write / &D set drive param / &E Verify / &F Format) +; XY+ 6 b0 +; : top 5 bits of sector number b16-b20 +; b4 +; b5 +; : drive number to be ORed with currently selected drive +; b7 +; XY+ 7 Sector b8-b15 +; XY+ 8 Sector b0-b7 +; XY+ 9 Sector Count +; XY+10 unused +; XY+11 Length0 +; XY+12 Length1 +; XY+13 Length2 +; XY+14 Length3 +; XY+15 +; +; On exit: A=result. 0=OK, <>0=error, with ADFS error block filled in + +DRERRA * &4 ; NOT READY +DRERRB * &40 ; WRITE PROTECTED +DRERRC * &48 ; CRC ERROR +DRERRD * &50 ; SECTOR NOT FOUND +DRERRE * &60 ; BAD COMMAND +DRERRF * &61 ; BAD SECTOR ADDRESS +DRERRG * &63 ; VOLUME ERROR +DRERRH * &65 ; BAD DRIVE +DRERRI * &6F ; ABORT + +MAXDRV * 6 ; Maximum number of drives + +; OSWORD &72 Operations +DSREAD * &8 +DSWRIT * &A +DSSETP * &D +DSVERF * &E +DSFORM * &F + + +OSWDRW ROUT + STX DISCCB ; XY is address of the control block (CB) + STY DISCCB+1 + LDYIM 0 ; Offset 0 is a flag byte + LDAIY DISCCB ; read the flag byte + BEQ #20 ; if zero, then it's OK to proceed, else error + +BADDRV + LDAIM DRERRH ; Bad Drive +OW72XX ; shared exit routine + STAI DISCCB +10 ; return with XY pointing to the CB + LDXIM :LSB:DISCCB + LDYIM :MSB:DISCCB + RTS + +20 + LDYIM 6 ; Drive / Sector + LDAIY DISCCB + LSRA ; get the drive number from bits 7..5 + LSRA + LSRA + LSRA + LSRA + CMPIM MAXDRV ; drive number >= 6 + BCS BADDRV + SBCIM 3 ; subtracting 4 (3+1) changes floppy drives 4/5 into 0/1 + STA DRIVE ; and hard drives 0/1/2/3 into FC/FD/FC/FF + TAX ; store modified drive number in X + LDYIM 5 ; Offset 5 is the command byte + LDAIY DISCCB ; read the command byte from the control block + BEQ RWDISK + + CMPIM DSREAD ; Disk read command + BEQ RWDISK ; branch to common disk read/write code + + CMPIM DSWRIT ; Disc write command + BEQ RWDISK ; branch to common disk read/write code + + CMPIM DSSETP ; command <&0D (Disc Set Parameters) + BCC DSCMDX ; return with bad command code + CMPIM &10 ; command >=&10 + BCS DSCMDX ; return with bad command code + + ; only command &D (Set Paramaters), &E (Verify) and &F (Format) remain + CPXIM 2 ; drive >=2? + BCS #10 ; return without doing anything at all + + ; save the drive geometry for future OSWORD calls + + LDYIM 6 ; Y = 6 + LDAIY DISCCB ; geometry: number of sides + ANDIM &1F ; just consider bits 4..0 + BEQ DSCMDX ; if zero, return with bad command code + STAAX SECTHI ; if non-zero, store in CB+13 (drive 0) or CB+14 (drive 1) + + CMPIM 3 ; only supported values are 1 (single sided) or 2 (double sided) + BCS DSCMDX ; if number of sides > 2, return with bad command code + INY ; Y = 7 + LDAIY DISCCB ; geometry: physical sectors per track + STAAX SECTMI ; store to SECTMI (drive 0) or SECTMI+1 (drive 1) TODO: better as DISCCB+x? + INY ; Y = 8 + LDAIY DISCCB ; geometry: physical cylinders (tracks) + STAAX SECTLO ; store to SECTLO (drive 0) or SECTLO+1 (drive 1) + + LDYIM 5 ; Offset 5 is the command byte + LDAIY DISCCB ; read command + CMPIM DSVERF ; command <&E + BCC #10 ; command D (Set Parameters) - return without doing anything + BEQ #40 ; command E (verify) - skip forward + JMP FDFRMT ; command F (Format) - in DOS03 + +DSCMDX ; Disc command not known + TXA ; X = modified drive number + BMI PASSHD ; negative if hard drive, otherwise + LDAIM DRERRE ; BAD COMMAND code + BRA OW72XX ; return from OSWORD &72 with return code in A + +40 + JMP FDVRFY ; Command E (verify) in DOS03 + +PASSHD + JMP HDOSW72 ; pass on to hard disc driver (in DOS02) + +; ------------------------------------------------------------------------------- + +; Read/Write floppy disk +; On Entry : +; X = modified drive number (= original drive nummber - 4) +; hard drive: FC/FD/FC/FF +; floppy drive: 00/01 + +RWDSK1 + LDX DRIVE + LDAAX DBDRIV ; get last FDC status value (???) + JSR OWSTAT ; Convert FDC status (in A) to an OSWORD &72 return value (in A) + BRA OW72XX ; return from OSWORD &72 + +RWDISK ROUT + LDYIM 10 ; byte 10 in the command block is reserved + LDAIY DISCCB ; it is expected to be set to zero by the caller + BNE DSCMDX ; if non-zero, return with bad command code + LDYIM 9 ; sector count + LDAIY DISCCB + STA SECCNT ; save sector count + BNE #30 ; if sector count non-zero, skip the code to process the length field + +; calculate sector count from length.. + + LDYIM &E ; Y = 14 + LDAIY DISCCB ; Length3 + BNE DSCMDX ; if non-zero, return with bad command code + DEY ; Y = 13 + LDAIY DISCCB ; Length2 + BNE DSCMDX ; if non-zero, return with bad command code + DEY ; Y = 12 + LDAIY DISCCB ; Length + STA SECCNT ; save sector count + DEY ; Y = 11 + LDAIY DISCCB ; Length0 + BEQ #20 ; length is an exact number of sectors + INC SECCNT ; round up sector count + BEQ DSCMDX ; if > 255 sectors, return with bad command code + + PHX ; stack the modified disk number + TAX ; length0 + CLC + LDYIM 1 ; Addr0 + LDAIY DISCCB + STA #10+1 ; low byte of STZAX address = Addr0 + INY ; Y = 2 + LDAIY DISCCB ; Addr1 + LDYIM &C ; Y = 12 + ADCIY DISCCB ; + Length1 + STA #10+2 ; high byte of STZAX address = Addr1 + Length + +10 ; loop from X=Length0 to X=FF + STZAX &FFFF ; zero the unused/end of the buffer + INX ; so it's now a whole number of sectors + BNE #10 + PLX ; restore the modified drive number +20 + LDYIM 9 ; sector count offset in the control block + LDA SECCNT ; sector count + STAIY DISCCB ; save this back to the control block +30 + TXA ; X = modified drive number + BMI PASSHD ; negative if hard drive + +; Floppy Disk Sector Read/Write Code + +; Map logical sector to physical track / sector + +; The algorithm is roughly: +; Y (track) = 0 +; sector_counter = logical start sector (b21..0) +; stride = 256b sectors per track +; do { +; Y ++ +; sector_count -= stride +; } while sector_count >= 0 +; Y -- +; sector_count += stride +; +; we now have +; Y = physical track +; sector_count = physical_sector + + LDYIM 5 + LDAIY DISCCB + BEQ RWDSK1 + +; Initialize sector_counter (BUFLEN+1/BUFLEN/PHYSEC) with logical start sector + + INY ; Y = 6 + LDAIY DISCCB ; Drive / Sector + ANDIM &1F ; mask off drive bits + STA BUFLEN+1 ; store sector counter b16-b20 + INY ; Y = 7 + LDAIY DISCCB ; Sector b8-b15 + STA BUFLEN ; store to sector counter b8-b15 + INY ; Y = 8 + LDAIY DISCCB ; Sector b0-7 + STA PHYSEC ; store to sector counter b8-b15 + + LDYIM 0 ; Y = track = 0 + + ; Calculate stride (sectors per track) + + LDX DRIVE ; modified drive number (0 or 1) + LDAAX SECTHI ; geometry: number of sides (1 or 2) + RORA ; C=1 if single sided, C=0 if double sided + LDAAX SECTMI ; geometry: sectors per track for drive X + BCS #40 + ASLA ; double sectors per track if disk double sided +40 + STA DxSIDE ; stride = 256b sectors per track + +; Loop doing repeated 24-bit subtraction + +50 + INY ; increment track + ; TODO: there should be a test for overflow here + LDA PHYSEC ; Sector count b0-b7 + SEC + SBC DxSIDE ; subtract stride (256b sectors per track) + STA PHYSEC ; Sector count b0-b7 + LDA BUFLEN ; Sector count b8-b15 + SBCIM 0 + STA BUFLEN ; Sector count b8-b15 + LDA BUFLEN+1 ; Sector count b16-b20 + SBCIM 0 + STA BUFLEN+1 ; Sector count b16-b20 + BCS #50 ; C=1 if sector count >= 0 + + DEY ; decrement track + + LDA PHYSEC ; Sector count b0-b7 + ADC DxSIDE ; stride + STA PHYSEC ; Sector count b0-b7 + + TYA ; track count + CMPAX SECTLO ; compare sectors per track + BCC #60 ; branch if less + LDAIM DRERRF ; BAD SECTOR ADDRESS + JMP OW72XX ; return from OSWORD &72 with return code in A + +60 + JSR FDSWTR ; Y unchanged + STYZX DxTRCK ; store track (Y) in DxTRCK (drive 0) or DxTRCK+1 (drive 1) + LDYIM 1 ; Y = 1 + LDAIY DISCCB ; Addr0 in control block + STA BUFLEN ; current Addr0 + INY ; Y = 2 + LDAIY DISCCB ; Addr1 in control block + STA BUFLEN+1 ; current Addr1 + +65 + LDAIM :LSB:REC ; compare the low byte of the network NMI handler against + CMP NMINET ; the default REC handler + BNE #65 ; different, so wait + LDAIM :MSB:REC ; compare the low byte of the network NMI handler against + CMP NMINET+1 ; the default REC handler + BNE #65 ; different, so wait + +FDSEEK + LDAIM &A ; 10 RETRYS (for recoveable errors) + STA RETRYS ; store in the retry counter +80 + LDAAX DxTRCK ; track number for drive X + STA FDCD ; write desired track number to FDC Data Register + PHP ; Z=1 if track zero + LDAIM &1C ; FDC command &1C - Seek (and load head and verify track num) + LDXIM :LSB:#90 + LDYIM :MSB:#90 + PLP ; Z=1 if track zero + BEQ #95 ; track 0? +85 + JMP FDCMDA ; issue floppy disk command +90 + BCC FDNEXT + BPL FDBAD + DEC RETRYS ; decrement the retry count + BEQ FDBAD +FDTRK0 + LDXIM :LSB:#80 ; after FDC command, resume from label 80 + LDYIM :MSB:#80 +95 + LDAIM 8 ; FDC command &08 - Restore/Seek Track 0 (and load head) + BRA #85 ; issue command + +; ------------------------------------------------------------------------------- +; +; Read/Write the next FDC Sector + +FDNEXT ROUT + LDX DRIVE ; X = drive number (0 or 1) + LDAAX DxTRCK ; read track number for drive X + CMP FDCTRK ; compare with FDC track register + BNE FDSEEK ; if different, do a seek + + LDAIM &A ; 10 retries (for recoverable errors) + STA RETRYS ; store in the retry counter + + LDAIM &BD ; LDA abx + STA FDLDAX + LDA BUFLEN+1 ; read Addr1 (the MSB of the buffer address) + BNE #10 + + LDAIM &A9 ; LDA imm &EA00 + STA FDLDAX + LDAIM 0 + STA FDLDAX+1 + LDAIM &EA + STA FDLDAX+2 + BRA #20 + +10 ; A = Addr1 (the MSB of the buffer address) + STA FDLDAX+2 ; update MSB of the LDA abx instruction in the FDNMWR NMI handler + STA FDSTAX+2 ; update MSB of the STA abx instruction in the FDNMRD NMI handler + LDA BUFLEN ; A = Addr0 (the LSB of the buffer address) + STA FDLDAX+1 ; update LSB of the LDA abx instruction in the FDNMWR NMI handler + STA FDSTAX+1 ; update LSB of the STA abx instruction in the FDNMRD NMI handler +20 + LDA PHYSEC ; physical sector + LDX DRIVE ; X = drive number (0 or 1) + CMPAX SECTMI ; compare with geometry: sectors per track for drive X + BCC #30 + SBCAX SECTMI ; if greater, subtract sectors per track +30 + STA FDCSEC ; store sector to the FDC Sector register + CMP FDCSEC ; check it's stored + BNE #30 ; if not, keep trying + + LDYIM 5 ; Command offset + LDAIY DISCCB ; read command from control block + CMPIM DSWRIT ; write? + BNE #50 ; no + + LDAIM &A2 ; FDC Command &A2 = Write Sector + LDXIM :LSB:FDNMWR + LDYIM :MSB:FDNMWR ; Use the FDC NMI Write Handler (FDNMWR) + BRA #60 + +40 + LDAIM &D0 ; FDC Command &D0 = Force Interrupt + STA FDCC + JSR FDDEFI ; set NMI vector back to "INT" +FDBAD + JMP BADDRV + +45 BRA FDTRK0 ; seek track zero + +50 LDAIM &82 ; FDC Command &82 = Read Sector + LDXIM :LSB:FDNMRD + LDYIM :MSB:FDNMRD ; Use the FDC NMI Read Handler (FDNMRD) +60 + PHA ; save the command + JSR FDNEWI ; set the NMI vector from X/Y + STZ DxSIDE + LDX DRIVE ; X = drive number (0 or 1) + LDA PHYSEC ; physical sector + CMPAX SECTMI ; compare with geometry: sectors per track for drive X + BCC #65 ; if less, then skip + INC DxSIDE + PLA + ORAIM &8 ; set bit 3 in the command (side 0/1) + PHA +65 + JSR FDSDSL ; Floppy side select + LDXIM 0 + LDYIM 3 + STY DISCCB+&C ; initialize the transfer done flag (set by the NMI) + PLA + STA FDCC ; write the FDC command register (at last!) + LDAIM 3 ; set timeout counter &030000 * 28 cycles @ 2MHz = 2.75s + STZ CNTLSB + STZ CNTCSB + STA CNTMSB + +70 + JSR #96 ; decrement timeout counter (20 cycles) + BEQ #40 ; if zero, it's been too long, so force FDC to interrupt (2 cycles) + CPY DISCCB+&C ; check transfer done flag (3 cycles) + BEQ #70 ; if zero, then transfer still in progress (3 cycles) + + JSR FDDEFI ; set NMI vector back to "INT" + +72 + JSR #96 ; decrement timeout counter + BEQ #40 ; if zero, it's been too long, so force FDC to interrupt (2 cycles) + LDA FDCS ; read the FDC status register + RORA ; shift bit 0 (BUSY) into carry + BCS #72 ; loop back if BUSY (i.e. wait for the idle state) + ASLA ; undo the ROR A + + BITIM 4 ; test bit 2 (LOST DATA - meaning the CPU didn't respond to DRQ in one byte time) + BNE #20 ; loop-back and retry the sector (indefitely I think) + + BITIM &40 ; test bit 6 (WRITE PROTECT) + BNE #75 ; if set, then bail without retries + + BITIM &18 ; test bits 3 (CRC ERROR) and 4 (RECORD NOT FOUND) + BEQ #80 ; branch if both OK + + DEC RETRYS ; decrement the retry counter + BPL #45 ; if >= 0 then seek track 0 and try again + +75 ; a fatal error has occurred + JSR OWSTAT ; Convert FDC status (in A) to an OSWORD &72 return value (in A) + JMP OW72XX ; return from OSWORD &72 with return code in A + +80 ; sector read/write was sucessful, so continue... + DEC SECCNT ; decrement the sector count + BEQ #97 ; if zero, we are done, so exit + + INC PHYSEC ; increment physical sector + + LDX DRIVE ; X = drive number (0 or 1) + LDAAX DISCCB+13 ; geometry: sector size (1=256b or 2=512b) for drive X + RORA ; C=1 if single sided, C=0 if double sided + LDAAX SECTMI ; geometry: sectors per track for drive X + BCS #85 + ASLA ; double sectors per track if disk double sided +85 + CMP PHYSEC ; compare physical sector to number 256b sectors per track + BNE #90 ; branch if still on the same track + + STZ PHYSEC ; next track, so set physical sector to zero + INCAX DxTRCK ; and increment the desired track for drive X + +90 + LDA BUFLEN+1 ; read Addr1 (the MSB of the buffer address) + BEQ #95 ; why is this a special case? + INC BUFLEN+1 ; increment Addr1 (the MSB of the buffer address) +95 + JMP FDNEXT ; and back for the next sector + +96 ; Decrement the 24-bit timeout counter + DEC CNTLSB ; 5 cycles + BNE #97 ; 3 cycles + DEC CNTCSB + BNE #97 + DEC CNTMSB +97 + RTS ; 6 cycles + +; ------------------------------------------------------------------------------- +; FDC Read NMI Handler +; - reads the FDC data register and writes the buffer + +FDNMRD ROUT + PHA + CPY FDCS ; check FDC status matches &03 = bit 0:BUSY; bit 1:DRQ (set by caller) + BNE #10 ; branch if it doesn't + LDA FDCD ; read FDC data register +FDSTAX + STAAX &FFFF ; write buffer - the address here is patched dynamically + INX ; increment buffer index + BNE #20 ; branch if less then 256 bytes read +10 + STZ DISCCB+&C ; clear the flag to indicate sector transfer complete + PLA + RTI + + +; ------------------------------------------------------------------------------- +; FDC Write NMI Handler +; - reads the buffer and writes the FDC data register + +FDNMWR + PHA + CPY FDCS ; check FDC status matches &03 = bit 0:BUSY; bit 1:DRQ (set by caller) + BNE #10 ; branch if it doesn't +FDLDAX + LDAAX &FFFF ; write buffer - the address here is patched dynamically + INX ; increment buffer index + STA FDCD ; write FDC data register + BEQ #10 ; branch if 256 bytes written +20 + LDA FDCS ; check FDC status matches &01 = bit 0:BUSY + CMPIM 1 + BNE #10 ; branch if it doesn't + PLA + RTI + + +; ------------------------------------------------------------------------------- +; Setup new NMI handler (for read/write transfers) +; +; ON Entry X=New handler routeine lo byte +; Y=New handler routeine hi byte + +FDNEWI ROUT + SEI + JSR INTCND ; disable network use of NMI during disk accesses + STX NMIV + STY NMIV+1 + RTS + + +; ------------------------------------------------------------------------------- +; Reset NMI to the default NMI handler (INT) + +FDDEFI ROUT + LDXIM :LSB:INT ; INT is the default NMI handler, in MOS03 + LDYIM :MSB:INT + STX NMIV + STY NMIV+1 + CLI + JMP INTCNU ; increase interrupt count + + +; ------------------------------------------------------------------------------- +; OSWORD Status +; - convert the common FDC status bits into an OSWORD &72 return code + +OWSTAT ROUT + BITIM &10 ; bit 4 = RECORD NOT FOUND + BEQ #10 + LDAIM DRERRD ; SECTOR NOT FOUND + RTS +10 + BITIM &40 ; bit 6 = WRITE PROTECT + BEQ #20 + LDAIM &FF ; WRITE PROTECTED (??) + RTS +20 + BITIM 8 ; bit 3 = CRC ERROR + BEQ #30 + LDAIM DRERRC ; CRC ERROR + RTS +30 + LDAIM 0 ; SUCCESS + RTS + +; ------------------------------------------------------------------------------- + +; Select Floppy Drive and Write Track register + +FDSWTR ROUT + LDX DRIVE ; X = drive number (0 or 1) + LDA MSTATE ; get current state from memory + +; clear selected drives and set side selected to 0 + ANDIM &E8 ; Clear any existing drive status + ; LED FDCTST FDCRST -FDCDEN NVRAM -FDSSEL -DRV2 -DRV1 + ORAAX TFDRIV ; Set status for this drive from x,Drive + STA MSTATE ; update status in memory + STA ROMSWW ; select drive + + LDA FDCS ; Read FDC status register + RORA ; C = bit 0 (BUSY) + BCC #30 ; not busy, so proceed +10 + LDAIM &D0 ; FDC Command &D0 = Force Interrupt + STA FDCC ; Write FDC command register +20 + INCA ; wait ~125us + BNE #20 +30 + LDAAX DxTRCK ; read desired track for drive X + STA FDCTRK ; Write FDC track register + CMP FDCTRK ; check write successful + BNE #10 ; if not, force interrupt and try again + RTS + + +; ------------------------------------------------------------------------------- + +; Floppy Drive Side Select +; +; On Entry: +; DxSIDE should have the side number (0 or 1) + +FDSDSL ROUT + LDX DxSIDE ; get side to select 0 or 1 + LDA MSTATE ; get current state from memory + ; ensure bit is cleared + ANDIM &FB ; LED FDCTST FDCRST FDCDEN NVRAM -FDSSEL DRV2 DRV1 + ORAAX TFSSEL ; set select bit for side 0 or 1 (OR 0 | OR 4) + STA MSTATE ; store a copy of the intended state + STA ROMSWW ; select floppy side + RTS + + + + LNK DOS02 diff --git a/FileStore/SRC/MOS/MOS/DOS02 b/FileStore/SRC/MOS/MOS/DOS02 new file mode 100644 index 0000000..db40e97 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/DOS02 @@ -0,0 +1,488 @@ + OPT 1 ; > <FileStoreMOSSource>.DOS02 + TTL File server file DOS02 + + +; Hard Drive + +; ------------------------------------------------------------------------------- +; Issue SCSI Command to Hard Drive, with 10 RETRYS +; +; On Entry: +; DISCCB/DISCCB+1 point to the control block containing the SCSI command +; +; This wrapper is responsible for the retry logic if there are errors +; +; The SCSI command is passed to HDCMD, and this is where most of the work happens + + +HDOSW72 ROUT + LDAIM &A ; 10 RETRYS (for recoveable errors) + STA RETRYS ; store in the retry counter + LDAIM &53 + STA HDDATA + STZ HDIRQ ; disable HD IRQ + CMP HDDATA + BNE #10 + + LDAIM &A5 + STA HDDATA + STZ HDIRQ ; disable HD IRQ + CMP HDDATA + BEQ #30 + +; Otherwise the SCSI interface is broken, return BAD DRIVE + +10 + LDAIM DRERRH ; BAD DRIVE +20 + JMP OW72XX ; return from OSWORD &72 with return code in A + +30 + JSR HDCMD ; Issue SCSI command (running through the different bus phases) + BEQ #20 ; Z=1 indicates success + CMPIM &25 ; &25 = ASC (additional sense code) &25 = LOGICAL UNIT NOT SUPPORTED + BEQ #10 ; return BAD DRIVE error code + CMPIM &65 ; &65 = set if drive could not be selected + BEQ #10 ; return BAD DRIVE error code + CMPIM 4 ; &04 = ASC (additional sense code) &04 = LOGICAL UNIT NOT READY + BNE #50 ; if not, then retry immediately + LDYIM &19 ; delay &190000 x 12 cycles @ 2MHz = 9.83s for the unit to be reads +40 + PHA ; 3 cycles + PLA ; 4 cycles + DECA ; 2 cycles + BNE #40 ; 3 cycles + DEX + BNE #40 + DEY + BNE #40 + LDAIM 4 +50 + DEC RETRYS ; decrement the retry counter + BPL #30 ; if >= 0 then retry command + BRA #20 ; exit OSWORD + +; ------------------------------------------------------------------------------- +; Issue SCSI Command to Hard Drive +; +; This routine runs through the phases of a SCSI transfer: +; - selection phase: selects the target device (based on the drive number) +; - command phase: sends the command from the control block to the target +; - data phase: transfers data blocks between the target and initiator +; - status phase: reads the status code from the target +; - message-in phase: checks for the COMMAND_COMPLETE message from the target +; +; In addition, if the status code is CHECK_CONDITION (02), then a REQUEST SENSE +; command is issued to retrieve additional SENSE DATA about the error. +; +; On Entry: +; DISCCB/DISCCB+1 point to the control block containing the SCSI command +; +; On Exit: +; A = the status code +; Z = 1 and A = 00 indicates success +; Z = 0 and A /= 00 indicates failure + +HDCMD ROUT + JSR HDSLCT ; select drive + INY ; Y=1 + LDAIY DISCCB ; read LSB of buffer address (Addr0) + STA BUFLEN ; store in ZP + INY ; Y = 2 + LDAIY DISCCB ; read MSB of buffer address (Addr1) + STA BUFLEN+1 + LDYIM 5 ; Y = 5 + LDAIY DISCCB ; read SCSI command byte from control block + JSR HDXFER ; transfer command byte + INY ; Y = 6 + LDAIY DISCCB ; Drive / Sector + ANDIM &1F + BRA #20 +10 + INY ; increment the control block index + LDAIY DISCCB ; and read the next command byte from the control block +20 + JSR HDXFER ; output A to the target (sending the multi-byte SCSI command) + JSR HDWAIT ; wait for the target to assert REQ* + BPL #30 ; N=0 indicates we are should move to the data phase + BVC #10 ; V=0 indicates more command bytes are expected + +30 ; we are now in the data phase + LDYIM 5 + LDAIY DISCCB ; re-read the command byte + ANDIM &FD ; 11111101 + EORIM &8 ; 00001000 + BEQ #70 ; branch if commands 08/0A (READ6/WRITE6) + +; transfer code for other commands (like format) +; each byte of the transfer is paced using REQ* which is slow + + JSR HDWAIT ; wait for the target to assert REQ* + CLC + BVC #40 ; copy V to C - i.e. remember the transfer direction + SEC +40 + LDYIM 0 ; set the buffer index to zero +50 + JSR HDWAIT ; wait for the target to assert REQ* + BMI HDSTPH ; N=1 indicates the data phase has ended + BCS #60 ; C=1 indicates reads + LDAIY BUFLEN ; + STA HDDATA ; transfer a byte from buffer -> target (i.e. a SCSI write) + BRA #65 +60 + LDA HDDATA + STAIY BUFLEN ; transfer a byte from target -> buffer (i.e. a SCSI read) +65 + INY ; increment the buffer index + BNE #50 ; loop back if fewer than 256 bytes have been transferred + INC BUFLEN+1 ; increment the high byte of the buffer pointer + BRA #50 ; loop back always (transfer ends when the target ends the data phase) + +; transfer code for commands 08/0A/28/2A (READ6/WRITE6/READ10/WRITE10) +; the transfer is done as fast as possible (one byte every 7us) without checking REQ* +70 + LDYIM 0 ; set the buffer index to zero + LDA BUFLEN+1 + BEQ #90 +80 + JSR HDRDST ; read the hard drive status register (into A and HDSR ) + ANDIM &20 + BEQ #80 + BIT HDSR + BMI HDSTPH ; N=1 indicates the data phase has ended + BVS #84 ; V=1 indicates reads +82 + LDAIY BUFLEN ; transfer a byte from buffer -> target (i.e. a SCSI write) + STA HDDATA + INY ; increment the buffer index + BNE #82 ; loop back if fewer than 256 bytes have been transferred + INC BUFLEN+1 ; increment the high byte of the buffer pointer + BRA #80 ; loop back always (transfer ends when the target ends the data phase) +84 + LDA HDDATA ; transfer a byte from target -> buffer (i.e. a SCSI read) + STAIY BUFLEN + INY ; increment the buffer index + BNE #84 ; loop back if fewer than 256 bytes have been transferred + INC BUFLEN+1 ; increment the high byte of the buffer pointer + BRA #80 ; loop back always (transfer ends when the target ends the data phase) +90 + JSR HDRDST + ANDIM &20 + BEQ #90 + BIT HDSR + BMI HDSTPH + BVS #84 + STZ HDDATA + BRA #90 + +; ------------------------------------------------------------------------------- +; Transfer one command byte to the target (i.e. in the SCSI command phase) +; +; The bus should in an output direction, and error recovery code will be involked +; if this is not the case. +; +; On Entry: +; A = byte to transfer + + +HDXFER ROUT + JSR HDWAIT ; wait for the target to assert REQ* + BVS #20 ; V=1 is an error case (the bus direction should be output) + STA HDDATA ; write the command (in A) to the bus + PHP + LDAIM &40 ; delay for 64 * 5 cycles @ 2MHz = 160us +10 + DECA ; 2 cycles + BNE #10 ; 3 cycles + PLP + LDAIM 0 ; A=0 + RTS ; return + +20 ; V = 1 indicates the bus direction is input, but it should be output + PLA ; i.e. the bus is in an unexpected state... + PLA ; unstack an address so next RTS will return to rtFA1E + ; then fall through to the SCSI status phase code + +; handle the SCSI status phase +; +; (it looks like this code expects the status byte to be followed +; by a COMMAND COMPLETE message) + +HDSTPH + JSR HDWAIT ; wait for the target to assert REQ* (or de-assert BSY*) + LDA HDDATA ; read the SCSI status code + NOP + NOP + JSR HDWAIT ; wait for the target to assert REQ* (or de-assert BSY*) + TAY ; save SCSI status code in Y + JSR HDRDST ; read the hard drive status register (into A and HDSR ) + ANDIM 2 + BEQ #45 + LDA HDSR + ANDIM 1 ; test bit 0 + BEQ HDSTPH ; if 0 check again + TYA ; get the SCSI status code back in A + LDX HDData ; read the first byte of the message + BNE #45 + TAX + ANDIM &F + CMPIM 2 + BEQ #50 + TXA +40 + ANDIM &7F ; status code in A + RTS ; return +45 + LDAIM &FF + BRA #40 +50 + LDXIM 0 +52 + DEX + BNE #52 + JSR HDSLCT + LDAIM 3 + JSR HDXFER + JSR HDXFER + JSR HDXFER + JSR HDXFER + LDAIM &D + JSR HDXFER + JSR HDXFER + TAX +55 + JSR HDWAIT + BMI #70 + LDA HDDATA + CPXIM 7 + BCC #60 + CPXIM &C + BNE #65 + LDXIM 0 + CMPIM 0 + BNE #60 + LDA DISCCB+4 +60 + STAAX DISCCB+2 +65 + INX + BRA #55 +70 + LDYIM 6 ; byte for drive number in the CB + LDAIY DISCCB + ANDIM &E0 ; mask drive number from sector + TSB DISCCB+3 + JSR HDWAIT + LDX DISCCB+2 + LDA HDDATA + JSR HDWAIT + LDY HDDATA + BNE #45 + ANDIM 2 + BNE #45 + TXA + BRA #40 +; ------------------------------------------------------------------------------- +; Select Drive +; +; On entry: +; drive number is read from the control block +; +; On exit: +; If the drive is successfully selected +; Y = 0 +; If the drive is not selected within ~6ms +; A = &65 +; control is returned to the caller's caller (always HDOSW72) + +HDSLCT ROUT + LDYIM 6 ; byte for drive / sector in CB + LDAIY DISCCB + LSRA ; set the top 3 bits with the drive number + LSRA + LSRA + LSRA + LSRA + TAY + LDAAY DRVTAB + PHA +10 + JSR HDRDST ; read the hard drive status register (into A and HDSR ) + ANDIM 2 ; test bit 1, the BSY* bit + BEQ #20 + BIT HDDATA + BRA #10 + +20 + PLA ; A=1 + STA HDDATA ; write it to the SCSI data register + STA HDSEL ; write it to the SCSI select register + LDYIM 0 +30 + JSR HDRDST ; read the hard drive status register (into A and HDSR ) (35 cycles) + ANDIM 2 ; test bit 1, the BSY* bit ( 2 cycles) + BEQ #40 ; BSY*=0 indicates the bus is still in the free phase ( 3 cycles) + ; BSY*=1 indicates the device has been selected + LDYIM 0 + RTS ; return with Y=0 + +40 + DEY + BNE #30 + PLA + PLA + LDAIM &65 + RTS + +DRVTAB + = &1, &2, &4, &8 + + +; ------------------------------------------------------------------------------- +; Read Hard Drive Status Register + +HDRDST ROUT + PHP ; save the flags +10 + LDA HDSTAT ; read the hard drive status register + STA HDSR ; store it in HDSR + LDA HDSTAT ; re-read the hard drive status register + CMP HDSR ; compare against previous value + BNE #10 ; loop back if changed + PLP ; restore the flags + RTS + +; ------------------------------------------------------------------------------- +; Wait for the SCSI target to assert REQ* or de-assert BSY* +; +; All information transfer (command, data or status) over the data bus +; between the initiator and target is controlled by the target. The +; target transfers one byte at a time using handshaking with the REQ* +; and ACK* lines. +; +; The target asserts REQ* to start a transfer and the initiator +; responds with ACK* to acknowledge the transfer. On transfers from +; the target to the initiator the target asserts the data before +; asserting REQ* and waits until ACK* is asserted before sending the +; next byte. On transfers from the initiator to the target the target +; asserts REQ* and waits until ACK* is asserted before reading the +; data from the bus. +; +; On exit: +; N is the control/data status bit +; N = 0 indicates the target expects data information to be transferred +; N = 1 indicates the target expects control information to be transferred +; +; V is the input/output status bit +; V = 0 indicates the target expects the initiator to do an output operation +; V = 1 indicates the target expects the initiator to do an input operation +; +; Note: an asserted SCSI signal is seen as a '1' in the status register +; because the signals are passed through inverting buffers. + +HDWAIT ROUT + PHA ; save A +10 + JSR HDRDST ; read the hard drive status register (into A and HDSR ) + ANDIM &20 ; test bit 5, the REQ* bit, which is driven by the target + BNE #20 ; if REQ* isn't asserted, then read again + LDA HDSR + ANDIM 2 + BNE #10 +20 + PLA ; restore A + BIT HDSR ; test the caches status register + RTS ; return with N=command/data status bit and V=input/output status bit + + [ DEBUG = TRUE + +; Read floppy disk track + +FDRDTK ROUT + CLI + LDAIM 0 ; select drive 0 + STA DRIVE + JSR FDSWTR ; Select Floppy Drive and Write Track register +10 + LDYIM 0 ; delay counter + LDA DBTRCK ; track number + STA FDCD ; write FDC data register + LDX DRIVE ; X = drive number (0 or 1) + STAAX DxTRCK ; store updated track number + LDAIM &1C ; FDC command &1C - Seek (and load head and verify track num) +20 + STA FDCC ; write FDC command register + +30 ; delay for 256 * 5 cycles & 2MHz = 640us + DEY ; 2 cycles + BNE #30 ; 3 cycles + +40 + LDA FDCS ; read the FDC status register + RORA ; shift bit 0 (BUSY) into carry + BCS #40 ; loop back if BUSY (i.e. wait for the idle state) + + ROLA ; undo the ROR A + STA HDSR + + BITIM &10 ; test bit 4 = RECORD NOT FOUND + BEQ #50 + LDAIM 8 ; replace with A = Restore FDC Command (==return to track 0) + BRA #20 + +50 + LDA DBTRCK ; track number + CMP FDCTRK ; compare with FDC track register, was successful? + BNE #10 ; if not, try again + + LDAIM &A0 ; memory location &A000 + STA #80+2 ; to store data + LDXIM :LSB:#75 ; read data routine + LDYIM :MSB:#75 + JSR FDNEWI ; set the NMI vector from X/Y + LDXIM 0 + LDYIM 3 + LDAIM &E0 ; FDC Command &E0 = Read Track + STA FDCC + +60 + TYA ; A=3 + BNE #60 + + LDA FDCC + STA HDSR + BIT FDCD ; read and discard the data register + LDAIM &D0 ; FDC Command &D0 = Force Interrupt + STA FDCC ; Write FDC command register +70 + INCA ; wait ~125us + BNE #70 + JMP FDDEFI ; Reset NMI to the default NMI handler (INT) + +; replacement interrupt routine for reading a track +; and place at &A000 +75 + LDA FDCD ; read FDC data register +80 + STAAX &A000 ; store data at &A0xx + INX ; all data read + BNE #90 + INC #80+2 ; increment the memory storage location +90 + LDA FDCS ; read FDC status register + RORA ; C = bit 0 (BUSY) + BCC #95 ; not busy, so proceed + RTI +95 + LDA FDCD ; read FDC data register + LDYIM 0 + RTI + ] + + +FILL + xFILL &FF,&FC00-FILL ; fill to end of page with &FF + + + LNK MOS06 diff --git a/FileStore/SRC/MOS/MOS/DOS03 b/FileStore/SRC/MOS/MOS/DOS03 new file mode 100644 index 0000000..df2f897 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/DOS03 @@ -0,0 +1,635 @@ + OPT 1 ; > <FileStoreMOSSource>.DOS03 + TTL File server file DOS03 + + ORG &FD00 + + +; Table for floppy drive select in the ROMSWW register (&FC08) +TFDRIV + = 1 ; Drive 0 + = 2 ; Drive 1 + +; Table for floppy side compare in the READ SECTOR command (&82) +TFSCMP + = 0 + = 8 + +; Table for floppy side select in the ROMSWW register (&FC08) +TFSSEL + = 0 ; Side 0 + = 4 ; Side 1 + + +; ------------------------------------------------------------------------------- +; +; OSWORD &72 Command F (Format) +; +; On Entry: +; X = drive number (0 or 1) +; +; FSECTR,X = number of sectors per track (16 or 17) [ set by preceeding Set Drive Params command ] + +FDFRMT ROUT + JSR FDSWTR ; Select Floppy Drive and Write Track register + LDAIM :LSB:FHEAD ; initialize the LSB of the compressed format data pointer + STA DISCCB+2 + LDAIM :MSB:FHEAD ; initialize the MSB of the compressed format data pointer + STA DISCCB+3 + LDYIM 1 ; Y = 1 + LDAIY DISCCB ; Addr0 in control block + STA DISCCB+4 ; store to ZP + INY ; Y = 2 + LDAIY DISCCB ; Addr1 in control block + STA DISCCB+5 ; store to ZP, this buffer is used for the uncompressed format data + + LDAAX FSECTR ; geometry: physical sectors per track for drive X + STA FTRCK ; patch the compressed format data with this value + LDAIM 3 ; set other value to 03 if 17 sector per track + STA FSECT ; patch the compressed format data with 03 (ends up in sector data) + LDAAX FSECTR ; geometry: physical sectors per track for drive X + CMPIM &11 ; is it 17 sectors per track? + BEQ #10 ; yes, then continue for format + STZ FSECT ; patch the compressed format data with 00 (ends up in sector data) + CMPIM &10 ; is it 16 sectors per track? + BEQ #10 ; yes, then continue with format + LDAIM DRERRE ; BAD COMMAND + JMP OW72XX ; return from OSWORD + +; Expand the compressed format data, which has the following +; two-level run-length encoded structure +; +; <COUNT1> +; <COUNT2> +; <VALUE> +; ... +; <COUNT2> +; <VALUE> +; <00> +; ... +; <COUNT1> +; <COUNT2> +; <VALUE> +; ... +; <COUNT2> +; <VALUE> +; <00> +; <00> + +05 + DEC DISCCB+8 ; decrement COUNT1 + BNE #15 ; branch if not zero +10 ; <<<< Main Entry Point >>>>> + JSR GETNXT ; read next byte of compressed format data + STA DISCCB+8 ; save the byte, which will be used as COUNT1 + TAX ; test if zero + BEQ #30 ; yes, we are done uncompressing the compressed format data + LDA DISCCB+2 ; copy the format buffer pointer to the temp pointer + STA DISCCB+6 + LDA DISCCB+3 + STA DISCCB+7 +15 + LDA DISCCB+6 ; copy the temp pointer back to the format buffer pointer + STA DISCCB+2 + LDA DISCCB+7 + STA DISCCB+3 +20 + JSR GETNXT ; COUNT2 = next byte of compressed format data + TAY ; test if zero + BEQ #05 ; if so, loop back + JSR GETNXT ; VALUE = next byte of compressed format data +22 + STAI DISCCB+4 ; store VALUE in the memory buffer + INC DISCCB+4 ; increment LSB of buffer pointer + BNE #25 + INC DISCCB+5 ; increment MSB of buffer pointer +25 + DEY ; decment COUNT2 + BNE #22 ; loop back, storing VALUE again until COUNT2 reaches zero + BRA #20 ; loop back, reading the next COUNT2 + +; prepare to patch the format buffer with the actual track/side/sector numbers +30 + JSR GETNXT ; offset to track number byte in format buffer (A = &30) + STA TRACK + JSR GETNXT ; offset to side number byte in format buffer (A = &31) + STA SIDE + JSR GETNXT ; offset to sector number byte in format buffer (A = &32) + STA SECCNT + JSR GETNXT ; low byte of raw sector length including all marks and gaps (A = &68) + STA BUFLEN + JSR GETNXT ; high byte of raw sector length including all marks and gaps (A = &01) + STA BUFLEN+1 + LDX DRIVE + STZAX DxTRCK ; zero track number + STZ DxSIDE ; zero side + +; format track loop, repeated for each track on each side +; patch the format buffer with the actual track/side/sector numbers for this track/side + +35 + LDA TRACK ; A = offset to track number byte in format buffer + JSR SETFBP ; Set the format buffer pointer to format buffer + A + LDYAX FSECTR ; Y = geometry: physical sectors per track for drive X +40 + LDAAX DxTRCK ; A = actual track number + STAI DISCCB+4 ; store in format buffer (this replaces the first fixed 0xAA byte) + JSR ADDLEN ; increment format buffer pointer by raw sector length + DEY ; decrement the sector count + BNE #40 ; loop back until zero + + LDA SIDE ; A = offset to side number byte in format buffer + JSR SETFBP ; Set the format buffer pointer to format buffer + A + LDYAX FSECTR ; Y = geometry: physical sectors per track for drive X +45 + LDA DxSIDE ; A = actual side number + STAI DISCCB+4 ; store in format buffer (this replaces the second fixed 0xAA byte) + JSR ADDLEN ; increment format buffer pointer by raw sector length + DEY ; decrement the sector count + BNE #45 ; loop back until zero + + LDA SECCNT ; A = offset to sector number byte in format buffer + JSR SETFBP ; Set the format buffer pointer to format buffer + A + LDYAX FSECTR ; Y = geometry: physical sectors per track for drive X + LDXIM 0 ; X = sector number, starting at zero + TYA + INCA + LSRA ; DISCCB + 0 = (sectors per track + 1) / 2 = sector skew of half a track + STA DISCCB+9 ; = 8 (16 sectors per track) or 9 (17 sectors per track) +50 + TXA ; X = sector number + STAI DISCCB+4 ; store in format buffer (this replaces the third fixed 0xAA byte) + CMP DISCCB+9 ; compare the current sector number to the skew + BCS #55 + ADC DISCCB+9 ; if less, then add the skew + BRA #60 +55 + SBC DISCCB+9 ; if greater, then subtract the skew-1 + INCA +60 + TAX ; X = next sector number + JSR ADDLEN ; increment format buffer pointer by raw sector length + DEY ; decrement the sector count + BNE #50 ; loop back until zero + +; for 16 sector per track this gives a sequence of +; 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 + +; for 17 sector per track this gives a sequence of +; 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8 + + LDAIM &A ; 10 RETRYS (for recoveable errors) + STA RETRYS ; store in the retry counter + JSR FDSDSL ; Floppy side select + + TXA ; X = DxSIDE (set by FDSDSL) + BNE #75 ; branch if side 1 + + LDAIM &58 ; A = Step-In FDC Command + LDX DRIVE ; X = drive number (0 or 1) + LDYAX DxTRCK ; test track number (for drive X) + BNE #65 ; branch if not track zer0 + LDAIM 8 ; replace with A = Restore FDC Command (==return to track 0) +65 + LDXIM :LSB:#70 + LDYIM :MSB:#70 + JMP FDCMDA ; issue the FDC command to move to the right track... + +70 ; ...and continue here + LDAIM DRERRH ; BAD DRIVE + BCS #85 ; branch to return from OSWORD code if there was a error + +75 + BIT TXCLR1 ; TX clear? + BPL #75 ; no, then wait for it to be clear to transmit + + LDXIM :LSB:FMTINT ; Set new NMI handler to supply the format data + LDYIM :MSB:FMTINT + JSR FDNEWI + + LDXIM 0 + LDYIM 1 ; Y = 1 + LDAIY DISCCB ; Addr0 in control block (the buffer used for the format data) + STA FMTINS+1 ; Patch the LSB of the load instruction in the FMTINT NMI handler + INY ; Y = 2 + LDAIY DISCCB ; Addr1 in control block (the buffer used for the format data) + STA FMTINS+2 ; Patch the LSB of the load instruction in the FMTINT NMI handler + + LDAIM 3 ; Initialize the FLAG used to signal when the FDC command is complete + STA DISCCB+&C + LDYIM &F4 ; Y = Write Track FDC Command + STY FDCC ; Write Y to the FDC command register + [ DEBUG = TRUE + STY FDCCMD + ] +80 + CMP DISCCB+&C ; wait for the FDC command to complete + BEQ #80 + + JSR FDDEFI ; set NMI vector back to "INT" + LDA FDCS ; read the FDC status register + [ DEBUG = TRUE + STA HDSR + ] + BITIM 4 ; test bit 2 (LOST DATA) + BNE #75 ; if set, then loop back and try again (this doesn't count as a retry) + + BITIM &C0 ; test bit 7 (NOT READY) and bit 6 (WRITE PROTECT) + BEQ #87 ; branch if both clear + + DEC RETRYS ; decrement the retry count + BPL #75 ; if >= 0, then loop back and try again + ; if < 0 then a exit with an error + + JSR OWSTAT ; Convert FDC status (in A) to an OSWORD &72 return value (in A) + +85 + JMP OW72XX ; return from OSWORD + +87 + LDA DxSIDE + INCA ; A = current side + 1 + LDX DRIVE ; X = drive number (0 or 1) + CMPAX DISCCB+13 ; compare A to the disk geometry: number of sides (1 or 2) + BCS #95 ; branch if A >= number of sides + STA DxSIDE ; store updated side number +90 + JMP #35 ; loopback to format the next side/track +95 + STZ DxSIDE ; zero side + LDAAX DxTRCK ; A = track nummber (for drive X) + INCA ; increment to the next track + CMPAX FCYLIN ; compare A to the disk geometry: number of tracks + BCS FDVRFY ; branch if we have done all the tracks + STAAX DxTRCK ; store updated track number + BRA #90 ; loopback to format the next side/track + + ; fall through to + + +; ------------------------------------------------------------------------------- +; OSWORD &72 Command E (Verify) +; +; On Entry: +; X = drive number (0 or 1) + +FDVRFY ROUT ; OSWORD &72 Command &0E + JSR FDSWTR ; Select Floppy Drive and Write Track register + STZAX DxTRCK ; zero track number + LDAIM 8 ; A = Restore FDC Command (==return to track 0) +10 + LDXIM :LSB:#20 + LDYIM :MSB:#20 + JMP FDCMDA ; issue the FDC command in A +20 ; ...and continue here + LDAIM DRERRH ; BAD DRIVE + BCS #90 ; branch to return from OSWORD code if there was a error + STZ DxSIDE ; zero the side number + LDX DRIVE + LDAAX DxTRCK ; A = desired track + STA FDCTRK ; write to the FDC track register +30 + JSR FDSDSL ; Floppy Side Select + STZ PHYSEC ; zero the desired sector + LDAIM 2 + STA RETRYS +40 + LDA PHYSEC ; A = desired sector + STA FDCSEC ; write to the FDC sector register + + LDXIM :LSB:VFYINT ; Set new NMI handler to supply the format data + LDYIM :MSB:VFYINT + JSR FDNEWI + + LDX DxSIDE ; X = side (0 or 1) + LDAAX TFSCMP ; map side to value 0 or 8 in A (i.e. to bit 3) + ORAIM &82 ; A = FDC read sector command (bit 3 indicates the side compare value) + TAY ; save command in Y + LDXIM 0 + LDAIM 3 ; Initialize the FLAG used to signal when the FDC command is complete + STA DISCCB+&C + STY FDCC ; issue the FDC command to read the sector + [ DEBUG = TRUE + STY FDCCMD + ] +50 + CMP DISCCB+&C ; wait for the FDC command to complete + BEQ #50 + + PHX ; save + JSR FDDEFI ; set NMI vector back to "INT" + PLA ; restore + BNE #70 ; branch if not zero + + LDA FDCS ; read the FDC status register + BITIM 4 ; test bit 2 (LOST DATA) + BNE #40 ; if set, then loop back and try again + + BITIM &D8 ; test using mask 11011000 (Not Ready/Undefined/Record Not Found/CRC Error) + BEQ #60 ; branch of if all of these clear + DEC RETRYS ; decrement the retry count + BPL #40 ; if >= 0, then loop back and try again + ; if < 0 then a exit with an error + JSR OWSTAT ; Convert FDC status (in A) to an OSWORD &72 return value (in A) + BRA #90 ; return from OSWORD +60 + INC PHYSEC ; increment the sector number + LDA PHYSEC ; compare the sector number + LDX DRIVE ; X = drive number (0 or 1) + CMPAX FSECTR ; agaist geometry: physical sectors per track for drive X + BCC #40 ; if less, then loop back + + INC DxSIDE ; increment the side number + LDA DxSIDE ; compare the side nummber + CMPAX FSIDES ; against the number of sides for drive X + BCC #30 ; if less, then loop back + + LDAAX DxTRCK ; increment the track number + INCA ; compare the track nummber + CMPAX FCYLIN ; against geometry: number of tracks + BCS #80 ; branch if greater or equal, to the successful exit point + STAAX DxTRCK ; store the update track number + LDAIM &58 ; A = Step-In FDC Command + BRA #10 ; loop back, to handle the next track +70 + LDAIM DRERRD ; return code SECTOR NOT FOUND + BRA #90 +80 + LDAIM 0 ; return code SUCCESS +90 + JMP OW72XX ; return from OSWORD + + +; ------------------------------------------------------------------------------- +; Interrupt handlers for format and verify + +FMTINT ROUT + CMP FDCS ; compare FDC status register to A (which contains 03) + BNE #30 ; branch if not BUSY + DRQ +FMTINS + LDYAX &FFFF ; Y = next byte from the format buffer (self modifying code) + INX ; increment buffer index + BNE #10 ; branch if not zero + INC FMTINS+2 ; increment MSB of address in the above LDYAX instruction +10 + STY FDCD ; store byte to the FDC data register +20 + LDY FDCS ; read the FDC status register + CPYIM 1 ; compare against 01 (BUSY + ~DRQ) + BNE #30 ; branch if different + RTI ; return from interrupt +30 + STZ DISCCB+&C ; signal command complete via the FLAG + RTI ; return from interrupt + +VFYINT + CMP FDCS ; compare FDC status register to A (which contains 03) + BNE #30 ; branch if not BUSY + DRQ + BIT FDCD ; read and discard the data register + INX ; increment buffer indexed (don't think this is needed) + BRA #20 ; branch always + + +; ------------------------------------------------------------------------------- +; Issue a single Floppy Disk Command +; +; This is used only for TYPE I ommands that don't require data, such as STEP, SEEK, RESTORE +; +; On Entry: +; A = command +; X = LSB of next address +; Y = MSB of next address +; +; On Exit: +; Intead of RTS, this code jumps to the address passed in X/Y + +FDCMDA ROUT + STX DISCCB+&A ; store the "next address" passed in, for use by indirect JMP at the very end + STY DISCCB+&B + STZ DISCCB+&C ; clear the FLAG use to signal command completion (or timeout) by the FDCINT NMI handler + LDX FDCS ; read the FDC status register on entry + STX HDSR ; and save the value just read + LDXIM :LSB:FDCINT ; Set X/Y to the FDCINT NMI interrupt handler just below + LDYIM :MSB:FDCINT + JSR INTCND ; disable network use of NMI during disk accesses + STX NMIFD ; patch in the FDCINT NMI handler into the main NMI handler (INT in MOS03) + STY NMIFD+1 + [ DEBUG = TRUE + STA FDCCMD + ] + STA FDCC ; write command to the FDC command register + +; the structure of the following code is a bit hard to follow. It's a timeout +; loop that is exited early if FLAG (DISCCB+&C) is set to a value other than &00/&80 + + LDAIM &1E ; timeout of &1E1E1E iteratons of 14 cycles @ 2MHz = 13.81 seconds + TAX + TAY +10 + DECA ; inner delay loop - 2 cycles + BNE #20 ; inner delay loop - 3 cycles + DEX + BNE #20 + DEY + BNE #20 ; this BNE only falls through if the FDC command does not complete + ; within the timeout period + + LDAIM &D0 ; A = FDC FORCE_INTERRUPT command + STA FDCC + LDAIM &BF ; A = 10111111 + STA DISCCB+&C ; this will force the below ASL/BEQ to fall through with C = 1 +20 + ASL DISCCB+&C ; inner delay loop - 6 cycles ; shift bit 7 into C + BEQ #10 ; inner delay loop - 3 cycles ; this BEQ will fall as soon as FDCINT writes to DISCCB+&C + PHP ; save C (C=0 indicates the command was successful) + JSR INTCNU ; increment the interrupt depth count (this must be for debugging purposes, as it's never read back) + PLP ; restore C + BCS #30 ; branch to exit code if C=1 (timeout or error case) + BIT HDSR ; test the original FDC status register (this was saved before the command was issues) + BPL #30 ; branch to exit code if bit 7 (NOT READY) indicates the drive was READY + JSR FDWAIT ; the drive was NOT READY, so wait a few seconds, or for index pulses to start +30 + JMI DISCCB+&A ; pass control to address passed to FDCMDA in X/Y + ; if these was a recoverable error, the higher level code will retry + + +; ------------------------------------------------------------------------------- +; This is the NMI handler for Type I FDC Commands +; +; It's used by FDCMDA for FDC commands that don't require data to be transferred + +FDCINT ROUT + PHA ; save A + LDA FDCS ; read the FDC status register + RORA ; test bit 0 (BUSY) + BCS #30 ; branch if BUSY set (indicating command still executing) + ROLA ; undo the ROR A + LDY DRIVE + STAAY DBDRIV + BITIM &18 ; test bits 4 (RECORD NOT FOUND) and 3 (CRC ERROR) + BEQ #10 ; branch if both clear + [ DEBUG = TRUE + STA HDSR + ] + DEC DISCCB+&C ; decrement FLAG from &00 to &FF, which signals command-failure to FDCMDA + BRA #20 +10 + INC DISCCB+&C ; increment FLAG from &00 to &01, which signals command-success to FDCMDA +20 + LDAIM :LSB:FDCNMD + STA NMIFD ; reset the NMI handler to FDCNMD, which handles + LDAIM :MSB:FDCNMD ; unexepected FDC NMI interrupts + STA NMIFD+1 +30 + PLA ; restore A + JMP FDCINC ; FDCINC is in MOS03, and increments the interrupt depth count + + +; ------------------------------------------------------------------------------- +; Set the format buffer pointer to (Addr0 + Addr1 << 8 + A) +; (i.e. set it to offset A in the buffer) + +SETFBP ROUT + CLC + LDYIM 1 ; Y = 1 + ADCIY DISCCB ; add the LSB of the buffer (from the control block) + STA DISCCB+4 ; store in the LSB of the format buffer pointer + INY ; Y = 2 + LDAIY DISCCB ; load the MSB of the buffer (from the control block) + ADCIM 0 ; add any carry from the first addition + STA DISCCB+5 ; store in the MSB of the format buffer pointer + RTS + + +; ------------------------------------------------------------------------------- +; Add the length to the format buffer pointer + +ADDLEN ROUT + LDA BUFLEN ; this is a standard 16-bit addition + CLC + ADC DISCCB+4 + STA DISCCB+4 + LDA BUFLEN+1 + ADC DISCCB+5 + STA DISCCB+5 + RTS + + +; ------------------------------------------------------------------------------- +; Get the next byte of compressed format data, and increment the data pointer + +GETNXT ROUT + LDAI DISCCB+2 ; read the next byte of compressed format data + INC DISCCB+2 ; increment the LSB of the compressed format data pointer + BNE #10 ; branch if not zero + INC DISCCB+3 ; increment the MSB of the compressed format data pointer +10 + RTS + + +; ------------------------------------------------------------------------------- +; Wait for three index pulses, or a 5-7 second timeout +; +; This is used if a FDC command failed, and the drive reported not +; READY before the command. + +FDWAIT + LDXIM 3 ; number of DRQ pulses to wait for + LDAIM 2 ; mask for testing bit 1 (DRQ) + SEC ; default to C=1 on exit (timed out) + LDY TIMER+1 ; TIMER is 100Hz; TIMER+ is every 2.56s + INY + INY + INY +10 + CPY TIMER+1 ; has ~5-8 seconds expired + BEQ #30 + BIT FDCS ; wait for INDEX to be one + BEQ #10 +20 + CPY TIMER+1 ; has ~5-8 seconds expired + BEQ #30 + BIT FDCS ; wait for INDEX to be zero + BNE #20 + DEX ; decrement counter + BNE #10 ; loop back if not zero + CLC ; set C=0 to indicate success +30 + RTS + +; ------------------------------------------------------------------------------- +; Compressed Format Data +; +; When uncompressed, this is the data that the FORMAT command needs to +; format a track of 16 (or 17) 256b sectors. +; +; This is compressed using quite a clever two-level run-length +; encoding, with zero counts as terminators +; +; The disk format used by the filestore is similar to the IBM SYSTEM 34 +; FORMAT 256 BYTES/SECTOR in WD2793 datasheet + +FHEAD + = &01 ; COUNT1 ; track + = &20 ; COUNT2 + = &4E ; VALUE ; Write 32 x 0x4E (Gap 1) + = &00 ; COUNT2 ; terminator +FTRCK + = &11 ; COUNT1 ; patched with the number of tracks + = &0C ; COUNT2 + = &00 ; VALUE ; Write 12 x 0x00 + = &03 ; COUNT2 + = &F5 ; VALUE ; Write 3 x 0xA1, Preset CRC + = &01 ; COUNT2 + = &FE ; VALUE ; Write 1 x 0xFE (ID Address Mark) + = &03 ; COUNT2 + = &AA ; VALUE ; Write 3 x 0xAA (Track/Side/Sector) + = &01 ; COUNT2 + = &01 ; VALUE ; Write 1 x 0x01 (Sector Length) + = &01 ; COUNT2 + = &F7 ; VALUE ; Generate/Write CRC *(2 CRC's written) + = &16 ; COUNT2 + = &4E ; VALUE ; Write 22 x 0x4E (Gap 2) + = &0C ; COUNT2 + = &00 ; VALUE ; Write 12 x 0x00 + = &03 ; COUNT2 + = &F5 ; VALUE ; Write 3 x Write A1, Preset CRC + = &01 ; COUNT2 + = &FB ; VALUE ; Write 1 x 0xFB (Data Address Mark) + = &01 ; COUNT2 + = &FE ; VALUE ; Write 1 x 0xFE (Sector Data) + = &03 ; COUNT2 + = &FF ; VALUE ; Write 3 x 0xFF (Sector Data) + = &01 ; COUNT2 +FSECT + = &03 ; VALUE ; Write 1x 0x00/0x03 (Sector Data 16/17 tracks) + = &FB ; COUNT2 + = &00 ; VALUE ; Write 251 x 0x00 (Sector Data. 256b total) + = &01 ; COUNT2 + = &F7 ; VALUE ; Generate/Write CRC *(2 CRC's written) + = &2C ; COUNT2 + = &4E ; VALUE ; Write 44 x 0x4E (Gap 3) + = &00 ; COUNT2 ; terminator + = &01 ; COUNT1 + = &FA ; COUNT2 + = &4E ; VALUE ; Write 250 x 0x4E (Gap 4) + = &FA ; COUNT2 + = &4E ; VALUE ; Write 250 x 0x4E (Gap 4) + = &FA ; COUNT2 + = &4E ; VALUE ; Write 250 x 0x4E (Gap 4) + = &96 ; COUNT2 + = &4E ; VALUE ; Write 150 x 0x4E (Gap 4) + = &00 ; COUNT2 ; terminator + = &00 ; COUNT1 ; terminator + + = &30 ; -> TRACK - offset to track number byte in format buffer + = &31 ; -> SIDE - offset to side number byte in format buffer + = &32 ; -> SECCNT - offset to sector number byte in format buffer + = &68 ; -> BUFLEN - low byte of raw sector length including all marks and gaps + = &01 ; -> BUFLEN + ONE - high byte of raw sector length including all marks and gaps + +FILL1 + xFILL &FF, &FFE3-FILL1 + + + LNK MOS07 + \ No newline at end of file diff --git a/FileStore/SRC/MOS/MOS/MOS01 b/FileStore/SRC/MOS/MOS/MOS01 new file mode 100644 index 0000000..8e48709 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/MOS01 @@ -0,0 +1,143 @@ + OPT 2 ; FILE > <FileStoreMOSSource>.MOS01 + TTL File server file MOS01 + + +;********************************* +;* H E A D E R F I L E 1 * +;********************************* + + ORG &E800 + CPU 1 + +VERLA * "3" ; Major +VERLB * "3" ; Minor +VERLC * &3F + +;HARDWARE DEPENDANT CONSTANTS +MCTYPE * &0B ; Filestore + +; ******************************************************************* +; NETWORK + + +;CONTROL BLOCK FORMAT - LOCATED ANYWHERE IN MEMORY +CBCNTL * &00 ;N.B. SEE CONTROL BYTE VALUES VALID CONTROL BLOCK +CBPORT * &01 +CBSRLO * &02 ;N.B. SEE STATION ID VALUES CONTROL BLOCK SOURCE LO +CBSRHI * &03 +CBSALO * &04 ;CONTROL BLOCK DATA START ADDRESS LO +CBSAHI * &05 +CBSAH1 * &06 +CBSAH2 * &07 +CBEALO * &08 ;CONTROL BLOCK DATA END ADDRESS LO +CBEAHI * &09 +CBEAH1 * &0A +CBEAH2 * &0B +XTRA1L * &0C +XTRA1H * &0D +XTRA2L * &0E +XTRA2H * &0F + +; SCOUT BUFFER FORMAT +SRLO * &00 +SRHI * &01 +CNTL * &02 ; ZERO FOR IMMEDIATE OPERATIONS +PORTn * &03 +ADTO1 * &04 +ADTO2 * &05 +ADTO3 * &06 +ADTO4 * &07 +ADFR1 * &08 +ADFR2 * &09 +ADFR3 * &0A +ADFR4 * &0B +SBSIZE * &0C ; SIZE OF SCOUT BUFFER + +;CONTROL BYTE VALUE IMMEDIATE CONSTANTS. +IPEEK * &81 ;REMOTE PEEK N.B. MUST BE LOWEST NUMBER +IPOKE * &82 ;REMOTE POKE +IRTN * &83 ;REMOTE ROUTINE CALL +IPROCE * &84 ;REMOTE EVENT PROCEDURE CALL +IPROCH * &85 ;REMOTE HIGH LEVEL PROCEDURE CALL +ISTOP * &86 ;REMOTE STOP +ISTRT * &87 ;REMOTE RESTART +IMACH * &88 ;MACHINE TYPE PEEK. + +;PORT BYTE VALUE CONSTANTS. +ANYPRT * &00 ;ANY PORT ACCEPTED + +;STATION ID RESERVED CONSTANTS +BDCAST * &FF ;BROADCAST ADDRESS +PRIVID * &F0 ;N.B STATIONS 240-254 NOT SUBJECT TO REMOTE IMMED OP CONTROL MASK +NETnum * &00 ;NETWORK ID CONSTANT + +;STATION STATE CONSTANTS EXIST UNTIL CHANGED +STOP * &04 ;FLAGS A STOPPED STATE + +;NET STATE FLAG BITS RESET EVERY MESSAGE +SHORT * &01 ;2 WAY HANDSHAKE +BCAST * &40 ;SIGNALS A BROADCAST MESSAGE HAS BEEN RECEIVED +DACK * &80 ;FLAGS A DATA ACK PACKET + +;STATIC PAGE OFFSET CONSTANTS +PROBUF * &82 ;PROCEDURE PARAMETER BUFFER + + +MSIZE * &04 ; MACHINE AREA FOUR BYTES TO PEEK + +RXCLR * &F ; delete flag byte +RXRDY * &7F +RXBLEN * &C ; 12 bytes length of RX Block +RXBCNT * 18 ; number of RX blocks + +FSDEF * 254 ; default file station number +CR * &D ; Carriage Return +LF * &A + +LEDOFF * &7F ; MODE LED Off +LEDON * &80 ; MODE LED On + +; Define non-volatile workspace in CMOS - 146818 clock chip +; Bytes 0-13 are date/time function, must not go beyond 63. + + ^ 14 ;Start after date/time space in CMOS +Stnids # 2 ;ECOnet station id offset (14+2) + + +BASEYR * 81 + +ZERO * 0 +ONE * 1 +TWO * 2 +THREE * 3 +FOUR * 4 +FIVE * 5 +SIX * 6 +SEVEN * 7 +EIGHT * 8 +NINE * 9 + +TRUE * 0 +FALSE * &FFFF +YES * TRUE +NO * FALSE + + +; Flags for fast code assembly + +FAST1 * TRUE +FAST2 * TRUE +FAST3 * TRUE +FAST4 * TRUE +FAST5 * TRUE +FAST6 * TRUE +FAST7 * TRUE +FAST8 * TRUE +FAST9 * TRUE +FAST10 * FALSE +FAST11 * TRUE +FAST12 * TRUE + +DEBUG * FALSE ; debug logging + + LNK MOS02 diff --git a/FileStore/SRC/MOS/MOS/MOS02 b/FileStore/SRC/MOS/MOS/MOS02 new file mode 100644 index 0000000..498d173 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/MOS02 @@ -0,0 +1,368 @@ + OPT 1 ; > <FileStoreMOSSource>.MOS02 + TTL File server file MOS02 + +;********************************* +;* H E A D E R F I L E 2 * +;********************************* + +; Memory Maps +START * &200 ; Execution address for FS code + +; MOS Workspace +HIMEM * &E600 ; FIRST FREE STORE LOCATION + + +;********************************* +; Page ZERO + +; Debug locations + ^ &0 +COPYA # 1 ; copy of the A Register +COPYX # 1 ; copy of the X Register +COPYY # 1 ; copy of the Y Register +COPYST # 1 ; copy of the Stack Pointer +CPYIFR # 1 ; copy of the VIA IFR Reg at interrupt +CPYRTC # 1 ; copy of the RTC Register C interrupt +CPYHDS # 1 ; copy of the HD Status Reg at interrupt +CPYIC # 1 ; copy of interrupt counter +CPYSR1 # 1 ; copy of 6854 Status Reg 1 +CPYSR2 # 1 ; copy of 6854 Status Reg 2 +DBDRIV # 1 ; drive number +DBTRCK # 1 ; track number to read +YEAR # 1 ; copy of year +SRSTCT # 1 ; Soft Reset Counter +INTOVR # 1 ; Interrupt depth overrun limiter +INTCNT # 1 ; Interrupt depth counter + + +;********************************* +; &10 - &8F reserved for fileserver + + +;********************************* +; &90 - &9F Econet workspace + +SCOUTB * &90 ; SCOUT RECEIVE BUFFER LOCATION +SBSRLO * SCOUTB +SRLO +SBSRHI * SCOUTB +SRHI +SBCNTL * SCOUTB +CNTL ;ZERO FOR IMMEDIATE OPERATIONS +SBPORT * SCOUTB +PORTn +SBADT1 * SCOUTB +ADTO1 +SBADT2 * SCOUTB +ADTO2 +SBADT3 * SCOUTB +ADTO3 +SBADT4 * SCOUTB +ADTO4 +SBADF1 * SCOUTB +ADFR1 +SBADF2 * SCOUTB +ADFR2 +SBADF3 * SCOUTB +ADFR3 +SBADF4 * SCOUTB +ADFR4 + +TXCLR1 * &9C ; FLAGS WHETHER CLEAR FOR USER TO TX +IMASK * &9D ; IMMEDIATE OPERATION MASK PERMIT IMMEDIATE OPERATIONS +MASKST * &9E ; STORES VALUE OF IM PROT MASK WHEN JSR +SSTATE * &9F ; STATION STATE CONTROL BLOCKS EXIST + + +;********************************* +; &A0 - &AF Econet workspace + + ^ &A0 +NMINET # 2 ; address of current network NMI handler +NMIFD # 2 ; address of current floppy drive NMI handler +MSTATE # 1 ; Copy of the current machine state + +CNTLSB # 1 ; 3 byte loop counter +CNTCSB # 1 +CNTMSB # 1 + +TXCBPT # 2 ; TX CNTRL BLOCK POINTER. ONE BLOCK ONLY +TXYOFF # 1 ; Y INDEX OF DATA TO TX +TXPAGE # 1 ; NUMBER OF PAGES TO TX +TXDAPT # 2 ; 16 BIT POINTER OF DATA TO TX + +RXYOFF * TXYOFF ; Y INDEX OF DATA TO RX +RXPAGE * TXPAGE ; NUMBER OF PAGES TO RX +RXDAPT * TXDAPT ; 16 BIT POINTER OF DATA TO RX +RXCBPT # 2 ; RX CNTRL BLOCK POINTER. POINTS TO ARRAY OF CNTRL BLOCKS + +;********************************* +; Page B reserved for fileserver + +;********************************* +; &C0 - &CF Econet workspace + ^ &C0 +TXCB # &E ; TX CONTROL BLOCK +WORKP1 # 2 ; pointer to workarea + + +;********************************* +; &D0 - &D1 OSWORD PTR +; &D2 - &DF Econet Workspace + + ^ &D0 +PARAMP # 2 ;PTR TO OSWORD PARAMTER CONTROL BLOCK +TXBUFl # 2 ; &D2 ;SCOUT TRANSMIT BUFFER +TXDELO * TXBUFl +&00 +TXDEHI * TXBUFl +&01 +TXSRLO * TXBUFl +&02 ; <-stn ID +TXSRHI * TXBUFl +&03 +TXCNTL * TXBUFl +&04 +TXPORT * TXBUFl +&05 +TXADRT * TXBUFl +&06 +TXADRF * TXBUFl +&0A +STNID * TXBUFl +&02 ; store copy of CMOS STN ID + +;********************************* +; Page &D-&E Floppy disk workspace + + ^ &E0 +DISCCB # &D ; Floppy Disc Control Block +SECTHI # 2 ; Drive X Sectors high byte +SECTLO # 2 ; Drive X Sectors low byte +SECTMI # 2 ; Drive X Sectors mid byte +SIDE # 1 ; Side +TRACK # 1 ; Track +SECCNT # 1 ; Sector Count +BUFLEN # 2 ; Length Hi/Lo +DRIVE # 1 +DxTRCK # 2 ; Drive X track number +DxSIDE # 1 ; Floppy side select +PHYSEC # 1 +RETRYS # 1 ; retry counter +HDSR # 1 ; copy of the HD Status Register + [ DEBUG = TRUE + FDCCMD # 1 + ] + +;OSWORD &72 commands &D (Set Paramaters), &E (Verify) and &F (Format), +;use the control block differently from the sector read/write commands +;and reuse the above SECTHI, SECTLO and SECTMI differently + +FSIDES * SECTHI ; Number of sides +FSECTR * SECTMI ; sectors per track +FCYLIN * SECTLO ; total tracks (cylinders) + +; ******************************************************************* +; Page &200 to 85xx used by Fileserver code 85A0 is the start of +; Fileserver dynamic workspace + +DYNVC1 * &89E4 ; DYNAMIC WORKSPACE + + + +; ******************************************************************* +; START of MOS Workspace area +; +; PAGE &E600 + + ^ HIMEM +NSTATE # 1 ; NETWORK STATUS BITS INDICATE STATE +ENTXCT # 1 ; END COUNT OF TX PACKET +TXCNT # 1 ; COUNT FOR TX SCOUT PACKET +TXLINK # 2 ; TRANSMIT SUBROUTINE LINKAGE +IRQSTR # 7 ; IRQ STORE FOR VARIABLES COS ITS SLOW 7 bytes + ; +0 Scout Control byte <ROL + ; +1 ADT1 from Scout Buffer + ; +2 + ; +3 Scout buffer parameter size + ; +4 Scout receive buffer location + ; +5 calling station number + + ^ HIMEM+&89 +RXCB # RxBLEN*RXBCNT ; RX buffer spans the page + +; ******************************************************************* +; PAGE &E700 + +RXEOB # 1 ; End of buffer byte. Set at 0 +DATE # 5 ; Date and time values - 5 bytes +HRS * DATE+2 ; +MINS * DATE+3 ; +SECS * DATE+4 ; +TIMER # 5 ; 5 byte counter in 1/100th second +VSTATE # 1 ; Last VIA interrupt setting +RTCFS # 1 ; Station ID +PBNEXT # 1 ; next char to print from buffer +PBPTR # 1 ; pointer to next slot in printer buffer +PBUFF # 1 ; printer buffer queue +PSIZE * HRESET-PBUFF ; rest of space to MOS code for printer buffer (90 bytes) + + + +; M A N I F E S T S + +; ******************************************************************* +; * FC00 - FCFF Memory mapped hardware * +; ******************************************************************* + + +; ******************************************************************* +; RTC 146818 +; +; Memory : &FC00 - &FC04 +; ******************************************************************* + +RTCadd * &FC00 ; RTC address register +RTCdat * &FC04 ; RTC data register + + +; ******************************************************************* +; EPROM/RAM Switch & MACHINE STATE +; +; Memory : &FC08 +; +; READ +; A read at this location causes the hardware to switch all future +; reads to RAM locations instead of the EPROM +; WRITE Miscellaneous functions latch +; bit 0 Floppy 1 (left) select +; bit 1 Floppy 2 (right) select +; bit 2 Floppy side (0|1) select +; bit 3 Access to NVRAM possible if set +; bit 4 FDC Disc Density (active low) +; bit 5 FDC MasterReset (active low) +; bit 6 FDC Test (active low) +; bit 7 Mode (red) LED +; ******************************************************************* + +ROMSWW * &FC08 ;ROM SWITCH WRITE LOCATION + +DRV1 * &01 ; Floppy 1 (left) select +DRV2 * &02 ; Floppy 2 (right) select +FDSSEL * &04 ; Floppy side (0|1) select +NVRAM * &08 ; Access to NVRAM possible if set +FDCDEN * &10 ; FDC Disc Density (active low) +FDCRST * &20 ; FDC MasterReset (active low) +FDCTST * &40 ; FDC Test (active low) +LED * &80 ; Mode (red) LED + + +; ******************************************************************* +; Floppy Disc Controller 2793 +; +; Memory : &FC0C - &FC0F +; set to support 250Kbps data transfer and MFM encoding. +; ******************************************************************* + +FDCS * &FC0C ; Read Status Reg +FDCC * &FC0C ; Write Command Reg +FDCTRK * &FC0D ; Track Reg +FDCSEC * &FC0E ; Sector Reg +FDCD * &FC0F ; Data Reg + + +; ******************************************************************* +; VIA - 6522 +; +; Memory : &FC10 - &FC1F +; +; E01 PA0-PA7 Printer +; CA1 Printer pin1 STROBE CA1 & CA2 are incorrectly transposed +; CA2 Printer pin19 GND on the circuit diagram +; PB0-PB7 User Port only the data lines are connected to +; a header space on the PCB +; CB2 Network Clock +; +; E01S +; As E01 without PB0-PB7 +; ******************************************************************* + +VIA * &FC10 +OUTA * 1 ; VIA Data out Register A +DDRA * 3 ; VIA DDRA Data Direction Register A +T1CL * 4 ; VIA T1 Low-Order Latches | T1 Low-Order Counter +T1HI * 5 ; VIA Timer1 High-Order Counter +AUX * &B ; VIA Auxiliary Control Register +PCR * &C ; VIA Program Control Register +IFR * &D ; VIA Interrupt Flag Register +IER * &E ; VIA Interrupt Enable Register + + +; ******************************************************************* +; Econet Interface 6854 ADLC +; +; Memory : &FC20 - &FC23 +; &FC24 - Interrupt Off +; &FC28 - Interrupt On +; ******************************************************************* + +ADLC * &FC20 ;6854 SERIAL CONTROL CHIP LOCATION + +CReg1 * ADLC +&00 ; CONTROL REGISTER 1 C1B0=X +CReg2 * ADLC +&01 ; CONTROL REGISTER 2 C1B0=0 +CReg3 * ADLC +&01 ; CONTROL REGISTER 3 C1B0=1 +CReg4 * ADLC +&03 ; CONTROL REGISTER 4 C1B0=1 +SReg1 * ADLC +&00 ; STATUS REGISTER 1 C1B0=X +SReg2 * ADLC +&01 ; STATUS REGISTER 2 C1B0=X +RXBYTE * ADLC +&02 ; RECEIVE BYTE C1B0=X +TXBYTE * ADLC +&02 ; TRANSMIT NEXT BYTE C1B0=X +TXLAST * ADLC +&03 ; TRANSMIT LAST BYTE C1B0=0 + +;STATUS REGISTER A EVENT CONSTANTS +S2RQ * &02 ; STATUS REGISTER 2 REQUEST +FD * &08 ; FLAG DETECT +CTS * &10 ; CLEAR TO SEND +TDRA * &40 ; TRANSMIT DATA REGISTER AVAILABLE + +;STATUS REGISTER B EVENT CONSTANTS +AP * &01 ; ADDRESS PRESENT +FV * &02 ; FRAME VALID +RXIDLE * &04 ; INACTIVE IDLE RECEIVED +CRC * &10 ; FRAME CHECKSUM ERROR +DCD * &20 ; DATA CARRIER DETECT +RDA * &80 ; RECEIVE DATA AVAILABLE + + +; Network Interrupt +INTOFF * &FC24 ;INTERUPT DISABLE ADDRESS +INTON * &FC28 ;INTERUPT ENABLE ADDRESS + + +; ******************************************************************* +; Front panel switch +; +; Memory : &FC2C[- &FC2F] +; Door status, present on bit 6 +; E01 has a SW3 on bit 7 for command mode not present on E01S +; ******************************************************************* + +FPSWTCH * &FC2C ; Front Panel Switch + + +; ******************************************************************* +; SCSI hardware +; +; Memory : &FC30-&FC33 FileStore expansion bus interface. +; +; Strapped to emulate bus address &40. +; The bottom two bits of the &FC3x address indicate bus &4x. + +; Address Read Write + +; &FC30 data data (buffered) +; &FC31 status - +; bit 0 Message +; bit 1 Busy +; bit 2 - (low) +; bit 3 - (low) +; bit 4 !IRQ +; bit 5 Request +; bit 6 Input/Output +; bit 7 Command/Data + +; &FC32 - select +; &FC33 - enable IRQ +; 0 - Disable +; 1 - Enable +; ******************************************************************* + +HDData * &FC30 +HDStat * &FC31 ; Read HD Status +HDSel * &FC32 ; HD Select +HDIRQ * &FC33 ; HD IRQ + ; 0 Disable + ; 1 Enable + + + + + LNK MOS03 diff --git a/FileStore/SRC/MOS/MOS/MOS03 b/FileStore/SRC/MOS/MOS/MOS03 new file mode 100644 index 0000000..1da9a4f --- /dev/null +++ b/FileStore/SRC/MOS/MOS/MOS03 @@ -0,0 +1,466 @@ + OPT 1 ; > <FileStoreMOSSource>.MOS03 + TTL File server file MOS03 + + +;MACRO + + MACRO +$label CPYROM $start,$end +$label LCLA $addr + +$addr SETA $start + WHILE $addr < $end + LDAAX $addr + STAAX $addr +$addr SETA $addr + &100 + WEND + MEND + +; used to fill blank bytes with &FF + MACRO +$label xFILL $value,$end +$label LCLA $addr + +$addr SETA 0 + WHILE $addr < $end + = $value +$addr SETA $addr + 1 + WEND + MEND + + +; Machine hardware reset + +HRESET ROUT + [ DEBUG = TRUE + PHP ; Push CPU status to stack + STAZ COPYA ; store a copy of A + STXZ COPYX ; store a copy of X + STYZ COPYY ; store a copy of Y + TSX ; Stack pointer to X + STX COPYST ; store a copy of the stack pointer + ] + + BIT INTOFF ; Disable the network interrupt + LDAIM LEDON ; +LED +FDCTST +FDCRST +FDCDEN -NVRAM -FDSSEL -DRV2 -DRV1 + STA ROMSWW ; write to hardware + +; copy the firmware from EPROM to RAM + + LDXIM 0 ; copy 256 bytes + +CPYMOS + CPYROM &200, &7FFF + CPYROM &E800, &FBFF +; miss memory mapped hardware at page &FC00 and +; avoid &FC08 which would change the RAM selector switch prematurely + CPYROM &FD00, &FEFF + LDAAX &FF00 + STAAX &FF00 + + DEX + BEQ #20 ; finished copying ROM to RAM? + JMP CPYMOS + +20 BIT ROMSWW ; Read the selector switch at &FC08 + ; this changes reads from EPROM to RAM + ; effectively disabling the EPROM + + +; change future resets to a soft reset + LDAIM :LSB:SRESET ; put the soft reset routine + STA RSTV ; into the reset vector + LDAIM :MSB:SRESET + STA RSTV+1 + +; Drop through to soft reset handler +; soft reset without copying firmware + +SRESET + BIT INTOFF ; Disable the network interrupt + SEI ; set interrupt flag - prevent maskable interupts + CLD ; ensure decimal flag is clear + LDXIM &FF ; initialise the stack pointer + TXS + + LDAIM &88 ; +LED +FDCTST +FDCRST +FDCDEN +NVRAM -FDSSEL -DRV2 -DRV1 + STA ROMSWW ; enable NVRAM access + + LDAIM &A + STA RTCaddr ; write RTC register A + LDAIM &26 ; -UIP +DV2 -DV1 -DV0 -RS3 +RS2 +RS1 -RS0 + STA RTCdata ; + + LDAIM &B ; write RTC register B + STA RTCaddr + LDAIM &1E ; -SET -PIE -AIE +UIE +SQWE +DM +24/12 -DSE + ; square mode enable, data mode binary, 24 hour DATE + ; no daylight savings time + STA RTCdata + +; Initialise Server station ID from NVRAM + LDAIM STNIDS ; offset of station number in NVRAM + STA RTCaddr + LDA RTCdata ; read from NVRAM + STA STNID ; save in memory + + LDAIM STNIDS+1 ; station number control byte + STA RTCaddr + LDA RTCdata ; read from NVRAM + +; turn off NVRAM access + LDXIM &80 ; +LED +FDCTST +FDCRST +FDCDEN -NVRAM -FDSSEL -DRV2 -DRV1 + STX ROMSWW ; disable NVRAM access + + SEC ; check the station number control byte + ADC STNID + BEQ #45 ; Does it match? continue + LDAIM FSDEF ; otherwise it is corrupt so set to default + STA STNID +45 STZ STNID+1 ; clear the control byte + +; Initialise the VIA + STZ VIA + AUX ; clear the AUX control register + STZ VIA + PCR ; clear the Program control register + + LDAIM &7F ; bit 7=0 disable all interrupts + STA VIA + IER ; -SET/CLR +TIMER1 +TIMER2 +CB1 +CB2 +SHIFT +CA1 +CA2 + STA VIA + IFR ; -SET/CLR +TIMER1 +TIMER2 +CB1 +CB2 +SHIFT +CA1 +CA2 + JSR PCRINIT + +; Initialise the network + JSR CPINIT + +; clear the 2 pages of MOS work space +; and zero page work space to &00 + + LDXIM 0 +50 + STZAX HIMEM ; MOS Workspace &E600-&E6FF + STZAX HIMEM +&100 ; MOS Workspace &E700-&E7FF + DEX + BNE #50 + +; Initialise Econet workspace + LDAIM &3E ; mask is usually &3F for protected systems + STA IMASK + + LDAIM &80 ; set top bit of TX clear + STA TXCLR1 ; user clear to transmit + + LDA STNID ; station ID as read from CMOS + STA RTCFS ; store a copy as file server ID + + LDXIM RxBLEN*RXBCNT ; clear the RX Blocks + LDAIM RXCLR ; with deleted flag +55 + STAAX RXCB-1 + DEX + BNE #55 + + LDAIM :LSB:REC ; load address of the default Network NMI handler + STA NMINET ; update the Network NMI handler to the default + LDAIM :MSB:REC + STA NMINET+1 + + LDAIM &28 ; TO DO <why is this set to &28 + STA INTOVR + LDAIM &FC ; TO DO <why is this set to &FC + STA INTCNT + + LDAIM :LSB:FDCNMD ; update the FDC NMI handler to the default + STA NMIFD + LDAIM :MSB:FDCNMD + STA NMIFD+1 + +; initialise the FDC + + LDAIM &E0 ; +LED -FDCTST -FDCRST -FDCDEN -NVRAM -FDSSEL -DRV2 -DRV1 + STA ROMSWW ; Set MODE LED on, clear FDC Test and FDC Reset clear + + LDAIM &C0 ; +LED -FDCTST +FDCRST -FDCDEN -NVRAM -FDSSEL -DRV2 -DRV1 + STA ROMSWW ; Set MODE LED on, clear FDC Test, FDC reset active + +; allow a delay for the FDC to reset + LDAIM 25 ; delay for 25 * 5 cycles @ 2MHz = 62.5us +60 DECA ; 2 cycles + BNE #60 ; 3 cycles + + LDAIM &E0 ; +LED -FDCTST -FDCRST -FDCDEN -NVRAM -FDSSEL -DRV2 -DRV1 + STA MSTATE ; store a copy of the intended state + STA ROMSWW ; Set MODE LED on, clear FDC Test and FDC Reset clear + + BIT FDCS ; Read the FDC Status Register + +; set the floppy geometry + LDAIM &50 + STA DxTRCK ; Drive 0 Track number + STA DxTRCK + ONE ; Drive 1 Track number + STA SECTLO ; Drive 0 Sectors LSB + STA SECTLO + ONE ; Drive 1 Sectors LSB + + LDAIM 2 + STA SECTHI ; Drive 0 Sectors MSB + STA SECTHI + ONE ; Drive 1 Sectors HSB + + LDAIM &10 + STA SECTMI ; Drive 0 Sectors CSB + STA SECTMI + ONE ; Drive 1 Sectors CSB + + BIT INTON ; enable Network IRQ + CLI ; set interrupt flag - enable maskable interupts + +; output test string to printer + + LDXIM 0 +65 LDAAX PRNTST ; get the string + BEQ #70 ; end of string signalled by 0x00? + JSR OSWRCH ; otherwise write character to output stream + INX + BNE #65 ; fetch next char + +70 STZ SRSTCT ; clear the soft reset counter + + LDA #90 ; store JMP OPCODE at FFF7, before the + STA SRSTV-1 ; Soft Reset vector + + LDXIM :LSB:SRSETC ; routine to increase the Soft Reset Counter by 1 + STX SRSTV ; put in the Soft Reset Vector + LDXIM :MSB:SRSETC + STX SRSTV+1 + +; simple test for code has downloaded from the FS ROM + CMP START ; is JMP code at start of executable code + BEQ #85 ; yes, start up + + STZ IMASK ; no immediate operations +; Flash LED every second +75 + LDA Secs ; Seconds + RORA ; set carry on/off depending on second + LDA MSTATE ; get current state from memory + ANDIM LEDOFF ; -LED FDCTST FDCRST FDCDEN NVRAM FDSSEL DRV2 DRV1 + BCC #80 ; if seconds has changed, change LED status + ORAIM LEDON ; +LED FDCTST FDCRST FDCDEN NVRAM FDSSEL DRV2 DRV1 +80 + STA MSTATE ; store a copy of the intended state + STA ROMSWW ; set MODE LED to ON or OFF + + LDA SRSTCT ; is soft reset still clear? + BEQ #75 ; if 0, loop again + + JSR #95 + STZ SRSTCT ; clear the soft reset counter + + LDA MASKST ; load the IM Protection mask value + STA IMASK ; set the immediate operations allowed mask + BRA #75 ; flash LED + +; delay +85 + LDA TIMER+1 ; 5 byte timer in 1/100th second, + CMPIM 4 ; starts at 0, + BCC #85 + +90 + JMP START ; start the File server code + +95 + JMI IRQSTR + SIX ; offset initialised at 00 + +; increase the Soft Reset counter by 1 +SRSETC ROUT + INC SRSTCT + RTS + +; +; ****** NEVER fall through here ************ +; + + +;INITS ADLC CHIP +CPINIT + LDAIM &C1 ;+TXRS +RXRS -FRDIS -TDSR -RDSR -TIE -RIE SELCR3 + STA CReg1 + LDAIM &1E ;NRZ -ABTEX -ABT 8TX 8RX 8RX F + STA CReg4 + STZ CReg2 ;-DTR *** NFS CODE was CReg3 +CPRST + LDAIM &82 ;+TXRS -RXRS -FRDISC -TDSR -RDSR -TIE +RIE SELCR2 + ; Enable Rx Interrupt and Tx Reset + STA CReg1 + LDAIM &67 ;-RTS +CTXST +CRXST -TXLAST TDRA FLAG 2BYTE +PSE + ; Prioritized Status Enabled, 2 byte transfer + STA CReg2 ; Set Idle Flag, Clear Rx Tx status + RTS + + +; Initialise the Peripheral control register +PCRINIT ROUT + LDAIM &E0 ; Initialise Peripheral control register + ; CB2 Control = High Output + ; CB1 Latch Ouput = Negative Active Edge + ; CA2 Control = Input Negative Active Edge + ; CA1 Latch Output = Negative Active Edge + TSB VIA +PCR ; VIA PCR + LDAIM 50 ; delay for 50 * 5 cycles @ 2MHz = 125us +10 DECA ; 2 cycles + BNE #10 ; 3 cycles + +NETPOLL + LDA Sreg2 + BITIM DCD ; check for insertion of the DCD signal on the Econet module + BEQ #20 + +; otherwise enable the automatic terminator/clock circuit via CB2 on the VIA + LDA VIA +PCR ; VIA PCR + ANDIM &1F ; 0001 1111 + ; keep current CA1 States + ; keep current CB2 Latch/IRQ control + ORAIM &C0 ; 1100 0000 + ; Set CB2 Control as low output + STA VIA +PCR ; VIA PCR + +20 RTS + + + +; NMI Vector entry point +; as defined at NMI vector &FFEA + +; + +; Upon an NMI, the network interrupt is disabled. The server looks to see if the ADLC +; caused the interrupt. If it did, it is handled... If this is the first ADLC +; interrupt, we look to see if it is a scout packet. If it is and it is ours, we +; rewrite our NMI handler vector to point to a handler for ADLC data (as further data +; will be a continuation, not a scout (actually this all happens in three stages, +; but the description is generally correct)). If not for us, we flag to discard the +; frame. +; The FDC is then checked (the ADLC code will 'fall through' to check the FDC). + +; I am still working on untangling the FDC interrupt code. It looks as if the +; default handler will read the FDC status in order to clear the interrupt, then +; ignore it. It is possible that this is what happens until such time as a disc +; operation actually takes place? + +; Likewise, I am still working on how/where exactly the SCSI host adaptor fits into +; the equation. Upon a cursory examination (of the v1.31 firmware), it appears as if +; the SCSI system does not use IRQs. The IRQs appear to be disabled twice when +; checking for the hardware, and never re-enabled. In addition, it seems as if the +; server 'polls' the harddisc awaiting a result. Given the overheads of reading data +; from a harddisc under interrupt, and the fact that the harddisc, once data located, +; ought to be more or less able to keep up with the server, it would make more sense +; to simply poll for the reply. + + +; Main interupt handler + +INT ; NMI ints enter here program routed via rx/tx jump vector + = &CE, :LSB:INTCNT, :MSB:INTCNT ; DEC INTCNT + BIT INTOFF ; Disable NMI interupt + BIT SReg1 ; is there a network interrupt? + + BPL FDCNMI ; no, handle a FDC interrupt + PHA ; Save acumulator + PHY ; Save Y register + JMI NMINET ; Jump to receive or transmit wait address + +; Main routine that waits for tx interupt +; Returns from one int waits for another tx interupt + +WRXINT ; Saves rx jump address +WTXINT ; Saves tx jump address + STYZ NMINET+1 +WRXNTF ; The fast version only stores the LOW byte +WTXNTF + STAZ NMINET +WRXIN2 ; Use same jump address as last time +WTXIN2 ; Use same jump address as last time + PLY ; Restore Y register + PLA ; Restore accumulator + +FDCNMI + JMI NMIFD ; Jump to receive or transmit wait address +FDCNMD ; but is changed dynamically + BIT FDCS +FDCINC ; increment the interrupt depth counter + = &EE, :LSB:INTCNT, :MSB:INTCNT ;INC INTCNT + CMPI INTOVR + RTI ; Return to user process + +; Decrease Interrupt Count +INTCND + = &CE, :LSB:INTCNT, :MSB:INTCNT ;DEC INTCNT + BIT INTOFF ; DISABLE NMI INTERUPT + RTS + +; Increase Interrupt Count ;ENABLE NMI INTERUPT +INTCNU + = &EE, :LSB:INTCNT, :MSB:INTCNT ;INC INTCNT + CMPI INTOVR ; + RTS + +IRQ ROUT + PHA + + [ DEBUG = TRUE + LDA VIA +IFR ; store a copy of the Interrupt Flag Register + STA CPYIFR + LDA HDStat ; store a copy of the HD Status + STA CPYHDS + ] + + LDAIM &40 ; SET/CLR +TIMER1 TIMER2 CB1 CB2 SHIFT CA1 CA2 + BIT VIA +IFR ; is TIMER1 flag set in VIA + BEQ #30 ; yes, update running counter + PHX + PHY + STA VIA +IFR ; SET/CLR +TIMER1 TIMER2 CB1 CB2 SHIFT CA1 CA2 + STA VIA +IER ; SET/CLR +TIMER1 TIMER2 CB1 CB2 SHIFT CA1 CA2 + LDA IMASK ; Get the permit immediate operation mask + STA MASKST ; keep a copy + + LDX IRQSTR ; adjusted Scout Control byte + CPXIM &C ; >=&C + BCS #10 + + ORAIM &1C ; set bits 4,3,2 + STA IMASK ; save bits 2,3,4 +10 + JSR #40 ; immediate ops + LDA SRSTCT ; A= Soft Reset Counter + BNE #20 + LDA MASKST ; load the copy + STA IMASK ; restore the original value +20 + PLY ; restore Y & X + PLX + +30 + JSR RDTIME ; get time and update the 5 byte counter + JSR PRNCHR ; check for chars to print + PLA + RTI + +40 + JMIX (EXITIM) ; X=3 PROTECTED FROM IM OPERATION + ; X=6 RXRTN2 + ; X=8 RXPRE2 + ; X=A RXPRE2 + ; X=C RXSTP2 + ; X=E RXSTR2 + +PRNTST = &0D ; printer test string +MCPEEK = MCTYPE ; this gives the M/C info. + = &00 ; always 0 + +; convert characters to hex values for NFS version + + = (VERLB-&30)*&10+(VERLC-&30) + ; NFS version low .xx + + = VERLA-&30 ; NFS version high x. + + + LNK MOS04 diff --git a/FileStore/SRC/MOS/MOS/MOS04 b/FileStore/SRC/MOS/MOS/MOS04 new file mode 100644 index 0000000..63b37cd --- /dev/null +++ b/FileStore/SRC/MOS/MOS/MOS04 @@ -0,0 +1,687 @@ + OPT 1 ; > <FileStoreMOSSource>.MOS04 + TTL File server file MOS04 + +;********************************* +;* OSWRCH & OSWORD * +;********************************* + +; OSWRCH Write character to currently selected output stream + +; OSWORD FUNCTIONS - checks for function are chained +; A = &10 Econet Transmit (Max 1 Tx block) +; &14 Send string to remote station +; &11 Econet Receive (Max 18 Rx blocks) +; &13 Read Write Station Information +; 1 write file server number +; 5 write protection mask +; &72 Read/Write blocks +; 8 Read block(s) +; A Write block(s) +; D set drive parameters +; F Format drive +; 2 Write date/time to RTC chip +; 1 Read date/time from RTC chip +; 3 Read timer interval +; 4 Write timer interval +; 5 Read CMOS memory +; 6 Write CMOS memory + + +; ******************************************************************* +; +; OSWRCH +; +; Write the character given in the accumulator to the printer +; +; On Entry +; A= ASCII value of character to ouput +; +; On Exit : A Undefined +; X Preserved +; Y Preserved + + +WRCVEC ROUT + PHX ; preserve X + LDX PBPTR ; pointer to next slot in printer buffer +10 + CPX PBNEXT ; current pos + BNE #20 + PHA ; save character to print + LDA VIA +IER ; Interrupt Enable Register + RORA ; bit 0 CA2 -> CARRY + RORA ; bit 1 CA1 -> CARRY + PLA ; retrieve print char + BCS #10 ; wait until CA1 is clear +20 + STAAX PBUFF ; insert character into buffer + JSR SETBUF ; construct buffer pointer + STX PBPTR + LDA VIA +IER ; Interrupt Enable Register + RORA + RORA ; CA1 -> CARRY + BCS #40 ; if set, exit. Can't print now + + CPX PBNEXT + BEQ #40 + + LDAIM &FF ; +PA7 +PA6 +PA5 +PA4 +PA3 +PA2 +PA1 +PA0 + STA VIA +DDRA ; select VIA pins PA7-PA0 as outputs + + LDA VIA +PCR + ANDIM &F0 + ORAIM &A + STA VIA +PCR + LDAIM 2 ; -SET/CLR -TIMER1 -TIMER2 -CB1 -CB2 -SHIFT +CA1 -CA2 + STA VIA +IFR ; clear CA1 in the interrupt flag register + LDAIM &82 ; +SET/CLR -TIMER1 -TIMER2 -CB1 -CB2 -SHIFT +CA1 -CA2 + STA VIA +IER ; enable CA1 + + LDX PBNEXT + +30 + LDAAX PBUFF + STA VIA +OUTA +40 + PLX ; reinstate X + RTS + +SETBUF + INX + CPXIM &90 + BCC #60 + LDXIM 0 +60 + RTS + +PRNCHR + PHX + LDAIM 2 ; pulse output on CA1 to the printer + BIT VIA +IER + BEQ #40 + BIT VIA +IFR + BEQ #40 + STA VSTATE + LDX PBNEXT + JSR SETBUF + STX PBNEXT + CPX PBPTR + BNE #30 + STA VIA +IER + STA VIA +&D + BRA #40 + + +; ******************************************************************* +; +; OSWORD Routines +; +; ******************************************************************* + + +; ******************************************************************* +; OSWORD &10 Econet Transmit (Max 1 Tx block) +; +; entry: A &10 +; X,Y pointer to Transmit Control Block +; +; exit : A Undefined +; X Undefined +; Y Undefined +; +; control block +; +; 0 control; on entry set top bit +; byte will be zero if transmission fails to start +; 1 destination port +; 2 destination station +; 3 destination nework +; 4 address of data buffer start +; 8 address of data buffer end +; 12 remote address for immediate operations +; +; Transmission must be polled with OSBYTE &32 (50). If the +; destination station is &FFFF, a broadcast will be sent, the eight +; bytes of data are in the control block at XY+4 to XY+11. If the +; port number is zero, an immediate operation is transmitted. + + +WORVEC ROUT + STX PARAMP ; store pointer to control block + STY PARAMP+1 + CMPIM &10 ; OSWORD &10? + BNE OPENRX ; no, go to OSWORD &11 OPEN RX + +TXPOLL ROUT + BIT TXCLR1 ; TX clear? + BMI #10 + LDAIM 0 ; TX failed to start + STAI PARAMP + RTS + +;claim work area + +10 + LDXIM :LSB:TXCB ; get pointer + LDYIM :MSB:TXCB + STX TXCBPT ; copy direct into the pointer + STY TXCBPT+1 + + LDYIM &B ; length of OSWORD CB +20 + LDAIY PARAMP ; copy parameters from the OSWORD CB + STAIY TXCBPT ; to the transmit CB + DEY + BPL #20 + + LDAIM &80 ; ensure bit 7 in the control byte is set + TSB TXCB + JMP TRANSM ; transmit + + +; ******************************************************************* +; OSWORD &14 Econet Various network functions +; +; entry: A &14 +; X,Y pointer to Control Block +; +; exit : A last character sent +; X Number of retries of last character +; Y length of string sent +; +; control block +; 0 command +; 1 remote station +; 1 remote network +; 3 string to send, terminated by CR or &00. + +; OSWORD &14 - various network functions + +; routine to send a string to a remote m/c +; and put it into the command buffer, to allow poking +; of BASIC programs etc. + +SENDST ROUT + LDAI PARAMP ; get control block pointer + CMPIM 1 ; only command 1, send string is implemented + BNE #60 + + LDAIM :LSB:TXCB ; get pointer to Tx Control block + LDYIM :MSB:TXCB + STA TXCBPT ; copy direct into the pointer + STY TXCBPT+1 + + CLC + ADCIM &E ; buffer for char in TXCB + STA TXCB+4 ; data buffer start lo = Rx block PTR + STY TXCB+5 ; data buffer start hi = Rx block PTR + INCA ; char sent one at a time, buffer end =+1 + + STA TXCB+8 ; data buffer end +1 + STY TXCB+9 ; data buffer end +1 + STZ TXCB+&C ; remote address = 0 + STZ TXCB+&D ; clear temp workspace + + STZ WORKP1+1 + STZ TXCB+1 ; destination port 0 + + LDYIM 1 + LDAIY PARAMP + STA TXCB+2 ; destination station + INY ; 2nd byte of control block + LDAIY PARAMP + STA TXCB+3 ; destination network + +; get string to send, char by char + +10 INY + LDAIY PARAMP ; get char to send + BEQ #60 ; 00? exit + CMPIM CR ; 0D? exit + BEQ #60 + +20 BIT TXCLR1 ; TX clear? + BPL #20 + STA WORKP1 ; char in buffer + LDXIM 0 + +30 LDAIM IPROCH ; REMOTE HIGH LEVEL PROCEDURE CALL + STA TXCB + PHX + PHY ; save index of string + JSR TRANSM ; transmit + PLY ; retrieve string index + PLX + +40 LDA TXCB ; check Tx status + BMI #40 ; wait? + BEQ #10 ; send next byte + +50 PHA ; slight delay loop + PLA ; before a retry + INCA + BNE #50 + INX ; no of retries + BNE #30 + +60 RTS + + +; ******************************************************************* +; OSWORD &11 Econet Receive Open/Read Rx Control block +; +; +; entry: A &11 +; X,Y pointer to Receive Control Block +; +; exit : A = 00 if unable to allocate because space limit reached +; X Undefined +; Y Undefined +; +; control block +; OPEN +; 0 00; is set to control block number on exit. +; Will be set to 0 if unable to open block because space +; limit reached +; 1 flag: must be set to &7F on entry; when transmission is +; received, control byte from remote station's Transmit +; control block is copied here +; 2 port +; 3 station +; 4 network +; 5 address of data buffer start +; 9 address of data buffer end +; +; READ receive block +; 0 Receive control block number to read +; x 1 flag: from Tx station +; x 2 port: from Tx station +; x 3 station: from Tx station +; x 4 network: from Tx station +; 5 address of data buffer start +; 9 address of data buffer end + + +OPENRX ROUT + + CMPIM &14 ; OSWORD &14? + BEQ SENDST + CMPIM &11 ; OSWORD &11 Open RX? + BNE RWSTN ; no, go to OSWORD &13 Read/Write Station + +;call to OPEN or READ an Rxcb +;If the call is for READ then the first +;byte of the CB contains the number of the +;block to be read. Otherwise the byte is zero. + +;If the CB is already deleted then ZERO +;is returned in this byte. + +;If the call is to OPEN then the CB number +;is returned here; if no CB's are free then +;ZERO is returned. + + LDAI PARAMP ; get Rx Block number from control block + TAX ; put in X + BNE #60 ; not 0, read and delete + +; find a free Rx block + LDAIM :LSB:RXCB ; get pointer to Rx buffer + LDYIM :MSB:RXCB + STA WORKP1 ; store ptr in temp workspace + STY WORKP1 + 1 + +10 INX ; increment RxCB index count + LDAI WORKP1 ; get first byte in RxCB + BEQ #40 ; =0, then end of buffer. exit + + CMPIM RXCLR ; is the block already used? + BNE #50 ; Yes. get next one + +; allocate the block + TXA ; rx block index->A + STAI PARAMP ; put index in OSWORD control block + INC PARAMP ; + BNE #20 + INC PARAMP+1 + +20 LDYIM RXBLEN-1 ; length of control block-1 + +30 LDAIY PARAMP ; copy the contents from the OSWORD CB + STAIY WORKP1 ; to the RxBlock + DEY + BPL #30 + +40 RTS + +50 JSR RXNEXT ; Next RX block + BRA #10 + +; RX block number was given so read and +; delete RxBlock +60 JSR FNDRXB ; allocate control block + BEQ RXEXIT ; returned 0? + +; copy the Rx block to the parameter block + LDYIM 0 +70 LDAIY WORKP1 + INY + STAIY PARAMP + CPYIM RXBLEN ; Finised copying Rx block? + BCC #70 + +; delete Rx block + LDAIM RXCLR ; flag the block as deleted + STAI WORKP1 + +RXEXIT + RTS + + +; ******************************************************************* +; OSWORD 0x13 Read/Write station infomation +; On entry: +; XY+0=function +; XY+1..=read or written data +; On exit: +; XY+1=this net or &00. +; If XY+3=0, returns XY?3=file server net number. +; If XY+3=this net, returns XY+3=0. +; If XY+3<>this net, returns XY+3 unchanged. +; only function 5 set mask and function 1 set station id are implemented + +RWSTN ROUT + CMPIM &13 ; Is the call for OSWORD 13? + BNE OSWD72 ; go to OSWORD &72 + LDYIM 0 ; start of control block + LDAIY PARAMP + INY + CMPIM 5 ; write protection mask? + BNE #10 ; no, check for write FS number + LDAIY PARAMP + STA IMASK + RTS + +10 + CMPIM 1 ; write FS number + BNE RXEXIT ; no other commands implemented + LDAIY PARAMP + STA RTCFS ; station ID for CMOS + LDXIM Stnids ; offset in CMOS + JSR CMOSWR ; write to CMOS + EORIM &FF ; station ID checkbyte + INX + JSR CMOSWR ; write to CMOS + RTS + +; CMOS Function +; Read a byte from CMOS with offset given in +; XY+0 + +OSWD5 ROUT + CMPIM 5 + BNE OSWD6 + LDAI PARAMP + TAX ; put offset in X + SEI + JSR CMOSRD ; read CMOS + + CLI + LDYIM 4 ; return value in XY+4 + STAIY PARAMP ; store value read + RTS + +; CMOS Function +; sends the byte at control block +4 to RTC +; to offset XY+0 + +OSWD6 ROUT + CMPIM 6 + BNE RXEXIT + LDAI PARAMP + TAX + LDYIM 4 + LDAIY PARAMP ; get the byte to transfer + SEI + JSR CMOSWR ; write to CMOS + CLI + RTS + +OSWD72 ROUT + CMPIM &72 + BNE OSWD2 + JMP OSWDRW + +; Read timer interval + +OSWD3 ROUT + CMPIM 3 + BNE OSWD4 + LDYIM 0 +10 LDAAY TIMER + STAIY PARAMP + INY + CPYIM 5 + BCC #10 + RTS + +; write timer interval + +OSWD4 ROUT + CMPIM 4 + BNE OSWD5 + LDYIM 0 +10 LDAIY PARAMP + STAAY TIMER + INY + CPYIM 5 + BCC #10 + RTS + +; The date and time are in the file server format, which is: +; byte 0: date in month +; byte 1: years since 1981 / month (4 bits each) +; byte 2: hours (24 hour clock) +; byte 3: minutes +; byte 4: seconds + +OSWD2 ROUT + CMPIM 1 ; OSWORD 1? + BEQ OSWD1 + CMPIM 2 ; Is this OSWORD 2 + BNE OSWD3 + + SEI + LDXIM &B ; RTC Register B + JSR CMOSRD + ORAIM &80 ; SET CMOS to enable update of time + JSR CMOSWR + + LDYIM 0 + LDAIY PARAMP + ANDIM &E0 ; mask top 3 bits of year + STA Year + LDAIY PARAMP + ANDIM &1F + LDXIM 7 ; Day of month + JSR CMOSWR + + INY + LDAIY PARAMP + LSRA + LSRA + LSRA + ORA Year + LSRA + SEC + SBCIM &13 + BCS #10 + ADCIM 100 + +10 LDXIM 9 ; Year + JSR CMOSWR + LDAIY PARAMP + ANDIM &F + DEX + JSR CMOSWR + + INY + LDAIY PARAMP + LDXIM 4 ; Hours + JSR CMOSWR + + INY + LDAIY PARAMP + LDXIM 2 ; Minutes + JSR CMOSWR + + INY + LDAIY PARAMP + LDXIM 0 ; Seconds + JSR CMOSWR + + LDXIM &B ; RTC Register B + JSR CMOSRD + ANDIM &7F ; disable CMOS time update + ORAIM &10 ; enable update ended flag + JSR CMOSWR + + CLI + RTS + +; return date/time which is stored in memory + +OSWD1 + LDX DATE+4 + LDYIM 4 +10 + LDAAY DATE ; read the time + STAIY PARAMP ; write to the OSWORD Control Block + DEY + BPL #10 + CPX DATE+4 ; are the seconds still the same? + BNE OSWD1 ; if not, redo + RTS + + +; Get the time from the RTC + +RDTIME ROUT + PHX + LDXIM &C ; RTC Register C + JSR CMOSRD + [ DEBUG = TRUE + STA CPYRTC + ] + BPL #20 + + LDAIM :LSB:REC ; Check the NMI handler routine + CMP NMINET + BNE #20 + LDAIM :MSB:REC + CMP NMINET+1 + BNE #20 + + LDXIM 7 ; Day + JSR CMOSRD + STA DATE ; YYY DDDD + + LDXIM 9 ; Year + JSR CMOSRD + SEC + SBCIM BASEYR + BCS #10 + ADCIM 100 + +10 + ASLA + STA YEAR + ASLA + ASLA + ASLA + STA DATE+1 ; YYYY MMM + + LDA YEAR + ANDIM &E0 + TSB DATE + DEX + JSR CMOSRD + TSB DATE+1 + + LDXIM 4 ; Hours + JSR CMOSRD + STA DATE+2 + + LDXIM 2 ; Minutes + JSR CMOSRD + STA DATE+3 + + LDXIM 0 ; Seconds + JSR CMOSRD + STA DATE+4 + + CLC + LDA TIMER + ADCIM 100 ; running count in 1/100th second + STA TIMER + BCC #20 + INC TIMER+1 + BNE #20 + INC TIMER+2 + BNE #20 + INC TIMER+3 + BNE #20 + INC TIMER+4 +20 + PLX + RTS + + +; On entry : +; A = data to write +; X = address to write + +CMOSRD ROUT + JSR CMseta ; set CMOS access + STX RTCadd ; address to write to + LDA RTCdat ; data + BRA CMclra ; clear CMOS access + +; On entry: +; X = Location to read +; On exit +; A = Value read + +CMOSWR + JSR CMseta ; set CMOS access + STX RTCadd ; address to read from + STA RTCdat ; data + +; drop through to clear CMOS access +CMclra + PHA ; preserve A + LDA MSTATE ; get current state from memory + ANDIM &F7 ; LED FDCTST FDCRST FDCDEN -NVRAM FDSSEL DRV2 DRV1 + STA ROMSWW ; disable NVRAM access in hardware + STA MSTATE ; update status in memory + JSR INTCNU + PLA ; restore A + RTS + +; CMOS Set Access + +CMseta ROUT + PHA + JSR INTCND + + LDA MSTATE ; get current state from memory + ORAIM 8 ; LED FDCTST FDCRST FDCDEN +NVRAM FDSSEL DRV2 DRV1 + + STA ROMSWW ; enable NVRAM access in hardware + STA MSTATE ; update status in memory + + PLA + RTS + + + LNK MOS05 diff --git a/FileStore/SRC/MOS/MOS/MOS05 b/FileStore/SRC/MOS/MOS/MOS05 new file mode 100644 index 0000000..42eca60 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/MOS05 @@ -0,0 +1,232 @@ + OPT 1 ; > <FileStoreMOSSource>.MOS05 + TTL File server file MOS05 + +;********************************* +;* OSBYTE * +;********************************* + + +; OSBYTE FUNCTIONS +; Checks are chained +; A = &32/50 Poll Txcb +; &33/51 Poll Rxcb +; &34/52 Delete Rxcb +; &80 X=0 Door switch open or closed +; X=&FC Read free bytes in printer output buffer +; &84 Read top of workspace address +; &89 MODE LED ON/OFF + + + +; ******************************************************************* +; +; OSByte Routines +; +; ******************************************************************* + +; ******************************************************************* +; OSBYTE &32 Polling Transmission +; +; entry: A &32 +; X,Y undefined +; +; exit : A Undefined +; X status of transmission: +; 0 if transmission successfully completed, otherwise +; bit state meaning +; 7 0 completed +; 1 in progress +; 6 0 successful +; 1 failed +; 5 0 +; 0-4 error code if failed, otherwise 0 +; +; Y Undefined +; +; error codes +; &40 line jammed +; &41 some part of four-way handshake lost or damaged +; &42 no scount acknowledgment in four-way handshake +; &43 no clock +; &44 bad TRANSMIT control block + +BYTVEC ROUT + CMPIM &32 + BNE OSBY33 + JSR NETPOLL + LDYIM 0 + LDAIY TXCBPT + TAX + RTS + +; ******************************************************************* +; OSBYTE &33 Polling Reception +; +; entry: A &33 +; X Receive control block number +; Y undefined +; +; exit : A Undefined +; X flag: if the top bit is set, a message has been received +; Y Undefined +; + +OSBY33 + CMPIM &33 + BNE DELCB + JSR NETPOLL + + +FNDRXB ROUT + LDAIM :LSB:RXCB ; get pointer to Rx buffer + LDYIM :MSB:RXCB + STA WORKP1 ; store ptr in temp workspace + STY WORKP1+1 +10 ; retry loop + LDAI WORKP1 ; get first byte in Rx buffer + BEQ #20 ; =0, end of buffer + + DEX ; + BNE #30 ; try the next one + +20 + TAX + RTS + +30 JSR RXNEXT ; try the next one + BRA #10 ; retry + + +; ******************************************************************* +; OSBYTE &34 Delete Receive control block +; +; entry: A &34 +; X Receive control block number +; Y undefined +; +; exit : A Undefined +; X control block number +; Y Undefined + + +DELCB ROUT + CMPIM &34 + BNE OSBY80 + + JSR FNDRXB ; find RX control block + BEQ #10 + + LDAIM RXCLR ; delete flag byte + STAI WORKP1 +10 RTS + +; ********************************************************* +; OSBYTE &80 + +; Filestore: Readstate + +; X=0: Read COMMAND/USER and Floppy drive door switch states, +; returns in A: 2 if drive door open, 1 if in COMMAND mode; 3 both + +; switch status, present on bit 6 +; E01 has a SW3 on bit 7, not present on E01S + + +; X=252: Read free bytes in printer output buffer. +; returns in X the number of spaces remaining + +OSBY80 + CMPIM &80 ; this OSBYTE CALL &80? + BNE #60 ; no, check the next one + TXA ; command into A + BNE #40 + +; Command 0 +; read door switch state + + BIT FPSWTCH ; Front panel switch, b7->N, b6->V + BMI #20 ; b7 set? yes, no command mode on E01 Filestore model + INCA ; otherwise set command mode +20 + BVC #30 ; b6 set? yes, door closed + ORAIM 2 ; add 2 +30 RTS + +; Command 252 + +40 + CPXIM &FC + BNE #10 ; no, then exit + +; read free bytes in the printer buffer + + LDA VSTATE ; get ; last VIA state + BEQ #55 + + LDA PBNEXT ; next byte free + SEC ; set carry + SBC PBPTR ; subtract the pointer from the current pos + BNE #50 ; something is in buffer, then branch + + LDA VIA +IER ; check for interrupt from the printer + RORA + RORA ; CA1 -> CARRY + LDAIM 0 ; set to 0 + BCS #55 ; exit if interrupt, otherwise return buffer size + +50 CLC + ADCIM PSIZE ; add the size of the buffer +55 TAX ; return number of free bytes in X + RTS + +; ******************************************************************* +; OSBYTE &84 +; +; A=132 Read address of top of workspace area to X/Y. The value +; returned is the current base of the MOS + +60 CMPIM &84 ; OSBYTE &84? + BNE #70 ; no, check next OSBYTE function &89 + + LDXIM :LSB:HIMEM + LDYIM :MSB:HIMEM + RTS + + +; ******************************************************************* +; OSBYTE 137 +; +; Filestore: Perform LED status On/off +; X=0 will turn off the programmable led, +; X=1 will turn it on + +70 CMPIM &89 + BNE #90 + TXA + RORA + LDA MSTATE ; get current state from memory + ANDIM LEDOFF ; -LED FDCTST FDCRST FDCDEN NVRAM FDSSEL DRV2 DRV1 + BCC #80 ; if MODE LED was on, turn off otherwise + ORAIM LEDON ; +LED FDCTST FDCRST FDCDEN NVRAM FDSSEL DRV2 DRV1 +80 + STA ROMSWW ; set MODE LED to ON or OFF + STA MSTATE ; update status in memory +90 + RTS + +; Get next RX block +; add the length of the rx block + +RXNEXT ROUT + CLC + LDAIM RXBLEN ; Length of RX Block + ADC WORKP1 + STA WORKP1 + BCC #10 + INC WORKP1+1 +10 + RTS + + + + LNK NET01 diff --git a/FileStore/SRC/MOS/MOS/MOS06 b/FileStore/SRC/MOS/MOS/MOS06 new file mode 100644 index 0000000..1eaafee --- /dev/null +++ b/FileStore/SRC/MOS/MOS/MOS06 @@ -0,0 +1,13 @@ + OPT 1 ; > <FileStoreMOSSource>.MOS06 + TTL File server file MOS06 + + + ORG &FC00 + + xFILL &FF,&FD00-&FC00 ; fill page with 256 bytes of &FF + +; This page is taken up by the memory mapped hardware + + + + LNK DOS03 diff --git a/FileStore/SRC/MOS/MOS/MOS07 b/FileStore/SRC/MOS/MOS/MOS07 new file mode 100644 index 0000000..774c90d --- /dev/null +++ b/FileStore/SRC/MOS/MOS/MOS07 @@ -0,0 +1,38 @@ + OPT 1 ; > <FileStoreMOSSource>.MOS07 + TTL File server file MOS07 + + + ORG &FFE3 + +OSASCI ; *** Osasci *** &FFE3 + CMPIM CR + BNE OSWRCH + +OSCRLF ; *** Oscrlf *** &FFE7 + LDAIM LF + JSR OSWRCH + LDAIM CR + +OSWRCH JMP WRCVEC ; *** OSwrch *** &FFEE +OSWORD JMP WORVEC ; *** OSword *** &FFF1 +OSBYTE JMP BYTVEC ; *** OSbyte *** &FFF4 + +BYFFF7 = &00 +SRSTV = &00, &00 +NMIV = :LSB:INT, :MSB:INT ; &FFFA +RSTV = :LSB:HRESET, :MSB:HRESET ; &FFFC +IRQV = :LSB:IRQ, :MSB:IRQ ; &FFFE + + + +FNSH +LEFT * HIMEM-. ; get free store + [ LEFT > 0 ; must not overflow workspace + | + ! 0,"HIMEM incorrect" + ] + +;** T H E E N D *** + END + + diff --git a/FileStore/SRC/MOS/MOS/MOSMAKE b/FileStore/SRC/MOS/MOS/MOSMAKE new file mode 100644 index 0000000..9eb3e18 Binary files /dev/null and b/FileStore/SRC/MOS/MOS/MOSMAKE differ diff --git a/FileStore/SRC/MOS/MOS/MOSMAKE.inf b/FileStore/SRC/MOS/MOS/MOSMAKE.inf new file mode 100644 index 0000000..036a6a9 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/MOSMAKE.inf @@ -0,0 +1 @@ +$.MOSmake 00000800 00008023 0000049E 33 A544 2D1013 A24F 350116 diff --git a/FileStore/SRC/MOS/MOS/NET01 b/FileStore/SRC/MOS/MOS/NET01 new file mode 100644 index 0000000..5d8fc48 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/NET01 @@ -0,0 +1,662 @@ + OPT 1 ; > <FileStoreMOSSource>.NET01 + TTL Receive routines. NET01 + +;RECEIVE ROUTINES +;THIS IS THE CODE NEEDED TO RECEIVE AN ECONET MESSAGE +;A SCOUT MESSAGE IS RECEIVED +;IF THIS IS CORRECT AN ACKNOWLEDGE IS TRANSMITED +;A DATA PACKET IS AWAITED +;THE DATA PACKET IS LOADED INTO MEMORY +;THE DATA PACKET IS ACKNOWLEDGED. +; +; ****** NEVER fall through here ************ +; + + +REC + STZ TXCLR1 + LDAIM AP + BIT SReg2 ;CHECK FOR ADDRESS PRESENT + BEQ RXSERR ;AP EXPECTED + LDA RXBYTE + CMP STNID ;TEST DESTLO FOR STATION MATCH + BEQ TESTHI + CMPIM BDCAST ;TEST DESTLO FOR BRCAST MATCH + BNE FRDISC + LDAIM BCAST + STA NSTATE ;FLAG BROADCAST MESSAGE + +TESTHI + LDAIM :LSB: RXDEHI + [ FAST1 <> TRUE + LDYIM :MSB: RXDEHI + JMP WRXINT + | + JMP WRXNTF ; New fast code ! + ] + +RXDEHI + BIT SReg2 + BPL RXSERR ;RXDA EXPECTED N.B IN 2BYTE MODE + LDA RXBYTE + BEQ FORUSB ;NET NUMBER MUST BE ZERO + EORIM BDCAST ;TEST DESTHI FOR NETWORK BROADCAST + BEQ FORUS + +FRDISC ;FRAME DISCONTINUE + LDAIM &A2 ;+TXRS -RXRS +FRDSC -TDSR -RDSR -TIE +RIE CR2 + STA CReg1 + JMP NOUPD3 ;WAIT FOR ANOTHER RXINT + +FORUSB ;BROADCAST FOR US + STA NSTATE ;FLAG BROADCAST MESSAGE + +FORUS ;NOT BROADCAST FOR US + STA RXYOFF + LDAIM :LSB: RXBRAN + + [ FAST2 <> TRUE + LDYIM :MSB: RXBRAN + JMP WRXINT + | + JMP WRXNTF ; New fast code ! + ] + +RXBRAN + BRA RXHEAD + +;RESET RECEIVER FOR MORE PACKETS +RXSERR + LDA SReg2 + ANDIM &81 + BEQ NORST + JSR PCRINIT + JSR CPINIT ;REINIT THE CHIP + JMP NOUPD3 +NORST + JMP NOUPD2 ;RESET CHIP AND WAIT FOR ANOTHER RXINIT + +;THIS LOOP BUFFERS THE SCOUT PACKET IN THE SCOUT BUFFER +RXHEAD ;RECEIVE PACKET: CNTRL,PORT,2DEST + LDY RXYOFF ;LOAD COUNT + LDA SReg2 +RXHED2 + BPL RXSERR ;RXDA EXPECTED N.B. IN 2 BYTE MODE.SCOUT IS EVEN + LDA RXBYTE + STAAY SCOUTB + INY + LDA SReg2 + BMI PASS3 ;2BYTES STILL AVAILABLE + BNE SBUFEN ;END OF SCOUT PACKET E.G. FV CONDITION +PASS3 + LDA RXBYTE + STAAY SCOUTB + INY ;INCREMENT COUNT + CPYIM SBSIZE ;TEST COUNT + BEQ SBUFEN + STY RXYOFF ;STORE COUNT + LDA SReg2 + BNE RXHED2 + JMP WRXIN2 ;WE HAVE ALREADY STORED JUMP VECTOR + + +;CLAIM LINE WITH FLAGS +SBUFEN + STZ CReg1 ;-TXRST -RXRST -RXDISC -TDSR -RDSR -TIE -RIE SCR2 + LDAIM &84 ;+RTS -CTXST -CRXST -TXLAST TDRA FLAG 1-BYT -PSE +SBUFN1 + STA CReg2 ;SWITCH TO 1-BYTE MODE PAD WITH FLAGS + +;CHECK FOR OK CRC + LDAIM FV + BIT SReg2 + BEQ RXSERR ;BAD CRC + +;CHECK FOR UNREAD DATA BYTE + BPL RXSERR ;NOT ONE MORE EXTRA BYTE + LDA RXBYTE + STAAY SCOUTB ;STORE LAST BYTE OF SCOUT BUFFER + LDAIM &44 ;-TXRST +RXRST -RXDISC -TDSR -RDSR +TIE -RIE SCR2 + STA CReg1 + +;CHECK FOR IMMEDIATE OPERATION + LDA SBPORT + BNE NOIMED + JMP RXIMED ;PROCESS IMMEDIATE OPERATION + +NOIMED +;SWITCH OFF TX IF BROADCAST + BIT NSTATE + BVC NOBRD + LDAIM SEVEN ; -RTS -CTXST -CRXST -TXLAST TDRA FLAG 2-BYT +PSE + STA CReg2 ;TURN OFF TX +NOBRD +;FIND A MATCHING RXCBLOCK + LDAIM :LSB: RXCB + LDYIM :MSB: RXCB + STA RXCBPT + STY RXCBPT + ONE ;LOAD UP TO POINT TO NFS CONTROL BLOCKS + +FINDLP + LDYIM ZERO + LDAIY RXCBPT + BEQ RXSCER ;TERMINATOR FOUND IN USER CBLOCKS + CMPIM RXRDY ;VALID RECEIVE CONTROL BYTE + BNE NOMACH + INY ;INCREMENT TO PORT + LDAIY RXCBPT + BEQ PMATCH ;WILDCARD ZERO PORT ID + CMP SBPORT + BNE NOMACH ;NO PORT MATCH +PMATCH + INY ;INCR TO STATION LO + LDAIY RXCBPT + BEQ MATCHl ; ****** Bruce 27/2/86 ******* SLOMAT ;WILDCARD ZERO STATION ID + CMP SBSRLO + BNE NOMACH ;NO STATION LO MATCH +SLOMAT + INY + LDAIY RXCBPT + BEQ MATCHl + CMP SBSRHI + BEQ MATCHl ;NO STATION HI MATCH +NOMACH ; Get past pointer locations + LDA RXCBPT + CLC + ADCIM &0C ;POINT TO NEXT RXCB + STA RXCBPT + BCC FINDLP ;RXCB SPACE EXHAUSTED AND NO MATCH + INC RXCBPT+1 + BRA FINDLP + +RXSCER ;ERROR IN SCOUT PACKET + BRA RXDERR + +MATCHl + JSR ADCALC + BIT NSTATE ; Check for broadcast RX + BVC ACKSCO ; If not then as normal + JMP BRDRX ; Recieve a broadcast + +;ACKNOWLEDGE SCOUT PACKET N.B. DONT HAVE TO CLAIM +ACKSCO + LDAIM :LSB: NOACK + LDYIM :MSB: NOACK + JMP TXACK + +NOACK + LDAIM &82 ;+TXRST -RXRST -RXDISC -TDSR -RDSR -RDSR -TIE +RIE SCR2 + STA CReg1 + + LDAIM :LSB: RXDAST + [ FAST3 <> TRUE + LDYIM :MSB: RXDAST + JMP WRXINT + | + JMP WRXNTF ; New fast code ! + ] + +;RECEIVE DATA PACKET +RXDAST + LDAIM AP + BIT SReg2 ;CHECK FOR ADDRESS PRESENT + BEQ RXDERR ;ADDR PRESENT EXPECTED + LDA RXBYTE + CMP STNID ;TEST DESTLO FOR STATION MATCH + BNE RXDERR ;DATA PACKET NOT FOR US. DISC PACKET +;TSTHI + LDAIM :LSB: WSOUR + [ FAST4 <> TRUE + LDYIM :MSB: WSOUR + JMP WRXINT ;WAIT FOR 2BYTES OF DATA + | + JMP WRXNTF ; New fast code ! + ] + +WSOUR + BIT SReg2 + BPL RXDERR ;RXDA EXPECTED N.B IN 2BYTE MODE + LDA RXBYTE ;NET NUMBER MUST BE ZERO + BNE RXDERR ;DATA PACKET NOT FOR US + BIT SReg1 ;QUICK IRQ POLL + BMI WDEST + + LDAIM :LSB: WDEST + [ FAST4 <> TRUE + LDYIM :MSB: WDEST + JMP WRXINT ;WAIT SCOUTACK PACKET + | + JMP WRXNTF ; New fast code ! + ] + +WDEST + BIT SReg2 + BPL RXDERR ;RXDA EXPECTED + LDA RXBYTE ;READ 2 DEST BYTES + LDA RXBYTE ;CHECK AGAINST SCOUT BUFF IF SECURITY NEEDED + BRA RXINF + +;RECEIVE DATA PACKET ERROR +RXDERR +;RESET RECEIVER FOR MORE PACKETS + LDA NSTATE + BPL NLACK ;BRANCH IF NO LONG ACK + JMP TXBER1 ;REPORT TRANSMIT ERROR +NLACK + JSR CPINIT ;FLUSH OUT ANY REMAINING BYTES + JMP NOUPD2 + + +RXINF + BIT SReg1 ;QUICK IRQ POLL + BMI AGAIN + LDAIM :LSB: AGAIN + LDYIM :MSB: AGAIN + JMP WRXINT + +AGAIN + LDY RXYOFF ;LOAD COUNT + LDA SReg2 + +AGAIN4 + BPL RXEND ;RDA EXPECTED N.B IN 2-BYTE MODE + LDA RXBYTE + STAIY RXDAPT + INY + BNE PASS + INC RXDAPT + ONE + DEC RXPAGE + BEQ RXDERR ;ERROR BUFFER FULL BUT ONE MORE BYTE +PASS + LDA SReg2 + BMI PASS8 + BNE RXEND +PASS8 + LDA RXBYTE + STAIY RXDAPT + INY + STY RXYOFF + BNE OUTK + +UPCONT + INC RXDAPT + ONE + DEC RXPAGE + BEQ RXEND ;IS THIS AN ERROR? +OUTK + LDA SReg2 ;QUICK IRQ POLL + BNE AGAIN4 +OUTL + JMP WRXIN2 + +;CHECK UNREAD DATA BYTE,CRC ETC. +RXEND + STZ CReg1 ;-TXRS -RXRS -FDISC -TDSR -RDSR -TIE -RIE SCR2 + LDAIM &84 ;+RTS -CTXST -CRXST -TLAST TDRA FLAG 1BYTE -PSE + STA CReg2 ;SWITCH TO 1-BYTE FOR LATER 1 BYTE TEST + STY RXYOFF + LDAIM FV ;CHECK CRC + BIT SReg2 + BEQ RXDERR ;PACKET CRC BAD + + BPL NOBYT ;CHECK UNREAD BYTE + LDA RXPAGE + BEQ RXDERR ;FRAME TOO LONG, NOW BEING BRANCHED THROUGH + LDA RXBYTE ;READ EXTRA BYTE + LDY RXYOFF + STAIY RXDAPT + INC RXYOFF ;UPDATE POINTERS + BNE NOBYT + INC RXDAPT + ONE +NOBYT + LDA NSTATE ;CHECK FOR LONG ACK PACKET + BPL TXAK + JMP UPTXCB ;UPDATE TXCBLOCK + +TXAK +;ACKNOWLEDGE DATA PACKET + LDAIM :LSB: UPDATE + LDYIM :MSB: UPDATE + +;TRANSMIT AN ACKNOWLEDGEMENT PACKET +TXACK + STA TXLINK + STY TXLINK + ONE ;SAVE SUBROUTINE LINKAGE + + LDAIM &44 ;-TXRST +RXRST -RXDISC -TDSR -RDSR -RDSR +TIE -RIE SCR2 + STA CReg1 + LDAIM &A7 ;+RTS -CTXST +CRXST -TLAST TDRA MARK 2-BYT +PSE + STA CReg2 + +;TX 2BYTES DESTINATION + LDA SBSRLO + BIT SReg1 + BVC RXAERR ;TDRA EXPECTED N.B. IN 2 BYTE MODE + STA TXBYTE ;TRANSMIT SOURCE LO + LDA SBSRHI + STA TXBYTE ;TRANSMIT SOURCE HI + LDA STNID + BIT SReg1 + BMI TXACK1 + + LDAIM :LSB: TXACKS + LDYIM :MSB: TXACKS + JMP WTXINT ;WAIT FOR TX INTERUPT + +TXACKS ;TX 2BYTES SOURCE + LDA STNID + BIT SReg1 +TXACK1 + BVC RXAERR ;TDRA EXPECTED N.B. IN 2-BYTE MODE + STA TXBYTE + LDAIM NETnum + BIT NSTATE + BMI NOEND +;END PACKET TRANSMISSION + LDYIM &2F ;-RTS -CTXST +CRXST -TXLST FC FLAG 2-BYT +PSE + STY CReg2 + STA CReg4 + LDA TXLINK + LDY TXLINK + ONE + JMP WTXINT ;WAIT FOR TX INTERUPT FC EVENT AND RETURN TO CALLER +NOEND + STA RXBYTE + JMP TXINF ;FOR LONG ACK + +;ERROR IN TRANSMITTING AN ACK PACKET +RXAERR +;RESET RECEIVER FOR MORE PACKETS + JMP RXDERR + + +;UPDATE RECEIVE CONTROL BLOCK +UPDATE + LDA SBPORT + BNE NOTTUB ;DONT UPDATE RXCB IF IMMED OPERATION + LDY SBCNTL + CPYIM IPOKE + BEQ NOTTUB + JMP ENDIM + +NOTTUB + LDA RXYOFF + CLC ;CALC BUFFER END + ADC RXDAPT + BCC NOPGE + INC RXDAPT + ONE + +NOPGE + LDYIM CBEALO + STAIY RXCBPT ;UPDATE BUFFER END LO + INY + LDA RXDAPT + ONE ;UPDATE BUFFER END HI + STAIY RXCBPT + +CBUUPD + LDA SBPORT + BEQ NOUPD2 ;IM PEEK OPERATION CHECK + LDA SBSRHI ;UPDATE SOURCE HI + LDYIM CBSRHI + STAIY RXCBPT + DEY + + LDA SBSRLO ;UPDATE SOURCE LO + STAIY RXCBPT + DEY + + LDA SBPORT ;UPDATE PORT + STAIY RXCBPT + DEY + + LDA SBCNTL ;UPDATE CONTROL BYTE + ORAIM &80 ;SET TOP BIT + STAIY RXCBPT + +NOUPD2 + JSR CPRST +NOUPD3 + LDA RTCFS + STA STNID + LDAIM &80 ; set top bit of TX clear + STA TXCLR1 ; user clear to transmit + LDAIM :LSB:REC + LDYIM :MSB:REC + JMP WRXINT + +BRDRX ; The new broadcast reception + PHX + LDXIM CBSALO + LDY RXYOFF + +IOBRC1 + LDAAX SCOUTB + STAIY RXDAPT + INY + BNE IOBRC2 + INC RXDAPT + ONE + DEC RXPAGE + BEQ BRCER1 ; Remember to pull X first +IOBRC2 + INX + STY RXYOFF + CPXIM CBSALO + EIGHT + BNE IOBRC1 +BRDCT1 + PLX + BRA NOTTUB +BRCER1 + INC RXYOFF + CPXIM &B + BEQ BRDCT1 + PLX +IMERR + JMP RXDERR + +;PROCESS IMMEDIATE OPERATION +RXIMED + LDY SBCNTL + CPYIM IPEEK + BCC IMERR + CPYIM IMACH + ONE + BCS IMERR ;RANGE CHECK + CPYIM ISTRT + BCS PRIVST ;NO PROTECTION FOR LAST TWO IM OPS + + TYA + SEC + SBCIM IPEEK + TAY + LDA IMASK +FINDIM + RORA + DEY + BPL FINDIM + BCS NOUPD2 ;PROTECTED FROM IM OPERATION + +PRIVST + PHX + LDA SBCNTL + CLC + ROLA + TAX + JMIX (JMPIML-2) + +JMPIML ;IMMED OP JUMP TABLE + & RXPEEK + & RXPOKE + & RXRTN + & RXPROE + & RXPROH + & RXSTOP + & RXSTRT + & RXMACH + +RXRTN +RXPROE +RXPROH + LDAIM PROBUF + STA RXYOFF + LDAIM ONE + STA RXPAGE + LDAIM :MSB: DYNVC1 ;POINT TO DYNAMIC WORKSPACE + STA RXDAPT + LDAIM :LSB: DYNVC1 + 1 + STA RXDAPT + 1 + LDYIM 1 ;LOAD COUNTER +MORSTR + LDAAY SBADT1 + STAAY IRQSTR + ONE + DEY + BPL MORSTR ;SAVE SCOUT BUFF VARIABLES COS IRQ IS VERY VERY SLOW + PLX + JMP ACKSCO + +RXPOKE + LDAIM :LSB: SCOUTB + STA RXCBPT + LDAIM :MSB: SCOUTB ;MAKE RXCBPT POINT TO SCOUT BUFFER + STA RXCBPT + ONE + PLX + JMP MATCHl +RXMACH + LDAIM ONE ;ONE PAGE + STA RXPAGE + LDAIM &100 - MSIZE ;POINT TO MACHINE PEEK AREA (&FC) + STA RXYOFF + LDAIM :LSB: (MCPEEK + MSIZE - &100) + STA RXDAPT + LDAIM :MSB: (MCPEEK + MSIZE - &100) + STA RXDAPT + ONE + BRA SENDIT + + +RXPEEK +;CALCULATE RXDAPT RXYOFF RXPAGE + LDAIM :LSB: SCOUTB ;MAKE RXCBPT POINT TO SCOUT BUFFER + STA RXCBPT + LDAIM :MSB: SCOUTB + STA RXCBPT + ONE + JSR ADCALC + +SENDIT + LDAIM &80 + TSB NSTATE ;SET LONG ACK FLAG + +RXSTOP +RXSTRT + PLX + LDAIM &44 ;-TXRST +RXRST -FDISC -TDSR -RDSR +TIE -RIE SCR2 + STA CReg1 + LDAIM &A7 ;+RTS -CTXST +CRXST -TXLD TDRA FLAG 2BYT +PSE + STA CReg2 ;ENABLE TRANSMIT + LDAIM :LSB: CIRQ + LDYIM :MSB: CIRQ + JMP TXACK + +ENDIM +;RESTORE RXDAPT TO POINT TO PROCEDURE BUFFER + + LDA RXYOFF ;CALC PARAMETER SIZE + CLC + ADCIM &100 -PROBUF +&02 ;TWO ALLOWS FOR STATION NUMBER + + STA IRQSTR + THREE + LDA SCOUTB + STA IRQSTR + FOUR + LDA SBSRHI + STA IRQSTR + FIVE ; STORE CALLING STATION NUMBER + +;CAUSE IRQ +CIRQ + LDA SBCNTL ; ZERO FOR IMMEDIATE OPERATIONS + CLC + ROLA + STA IRQSTR ;SAVE SCOUT BUF VARIABLES COS IRQ SLOW + LDAIM &C0 + STA VIA +&E ;ENABLE SHIFT INT,IER REG + TRB VIA +&B ;SHIFT CONTROL BY SYSTEM CLOCK,ACR REG + LDAIM &14 + STA VIA +&4 ; T1CL REG +EXITIM + STZ VIA +&5 ; T1HI REG + JMP NOUPD2 ;GOBACK TO NORMAL RECEIVE MODE + +JMPI2L ;IMMED OP LO BYTE JUMP TABLE + & RXRTN2 + & RXPRE2 + & RXPRH2 + & RXSTP2 + & RXSTR2 + +RXRTN2 + JMI IRQSTR + ONE ;NON TUBE TYPE ROUTINE CALL + +RXPRE2 +RXPRH2 + RTS + +RXSTP2 ROUT + LDAIM STOP + TSB SSTATE ;FLAG PROCESSOR IS STOPPED + BNE #20 + CLI ;ENABLE INTERUPT +10 + BIT SSTATE + BNE #10 ;LOOP UNTIL BIT RESET +20 + RTS + +RXSTR2 + LDAIM STOP + TRB SSTATE ;CLEAR STOPPED STATE + RTS + + + LNK NET02 + +; ******** + + [ :MSB: RXDEHI <> :MSB: REC + [ FAST1 = TRUE + PAGE ERROR :MSB: RXDEHI <> :MSB: REC ; FAST1 => FALSE + ] + | + [ FAST1 <> TRUE + PAGE OK :MSB: RXDEHI = :MSB: REC ; FAST1 => TRUE + ] + ] + +; ******** + + [ :MSB: RXHEAD <> :MSB: RXDEHI + [ FAST2 = TRUE + PAGE ERROR :MSB: RXHEAD <> :MSB: RXDEHI ; FAST2 => FALSE + ] + | + [ FAST2 <> TRUE + PAGE OK :MSB: RXHEAD = :MSB: RXDEHI ; FAST2 => TRUE + ] + ] + +; ******** + + [ :MSB: RXDAST <> :MSB: NOACK + [ FAST3 = TRUE + PAGE ERROR :MSB: RXDAST <> :MSB: NOACK ; FAST3 => FALSE + ] + | + [ FAST3 <> TRUE + PAGE OK :MSB: RXDAST = :MSB: NOACK ; FAST3 => TRUE + ] + ] + +; ******** + + [ :MSB: WSOUR <> :MSB: RXDAST + [ FAST4 = TRUE + PAGE ERROR :MSB: WSOUR <> :MSB: RXDAST ; FAST4 => FALSE + ] + | + [ FAST4 <> TRUE + PAGE OK :MSB: WSOUR = :MSB: RXDAST ; FAST4 => TRUE + ] + ] diff --git a/FileStore/SRC/MOS/MOS/NET02 b/FileStore/SRC/MOS/MOS/NET02 new file mode 100644 index 0000000..3414236 --- /dev/null +++ b/FileStore/SRC/MOS/MOS/NET02 @@ -0,0 +1,673 @@ + OPT 1 ; > <FileStoreMOSSource>.NET02 + TTL Transmit routines. NET02 + + +;TRANSMIT ROUTINES +;A MESSAGE IS TRANSMITTED WITH A FOUR WAY PACKET HANDSHAKE: +;A SCOUT PACKET IS TRANSMITTED +;AN ACKNOWLEGE PACKET IS AWAITED +;UPON ACKNOWLEDGE A DATA PACKET IS TRANSMITTED +;AN ACKNOWEGE PACKET IS AWAITED + + +;TRANSMIT NMI SHOULD BE CLAIMED ALREADY +TRANSM + STZ TXCLR1 + PHX ;SAVE X REG + +;COPY TXCBLOCK TO TX SCOUT AREA + LDYIM CBSRLO + LDAIY TXCBPT + STA TXDELO ;DEST LO + INY + LDAIY TXCBPT + STA TXDEHI ;DEST HI + LDYIM CBCNTL + LDAIY TXCBPT + BMI CBLOK ;CHECK VALID CONTROL BYTE TOP BIT SET + JMP TXCER4 ;CHECK VALID CONTROL BYTE TOP BIT SET +CBLOK + STA TXCNTL ;CONTROL BYTE + TAX + INY + LDAIY TXCBPT + STA TXPORT ;PORT BYTE + BNE NOTIM + + CPXIM IRTN ;CHECK IF PEEK OR POKE + BCS NOCALC +;CALCULATE IMMEDIATE VARIABLES N.B. CHECK GOOD CONTROL BYTE + SEC ;CALC PART OF ADDRESS FOR PEEK AND POKE + PHP + LDYIM CBEALO ;SUBTRACTION +LOOPP + LDAIY TXCBPT + DEY + DEY ;DOWN FOUR POINT TO START ADDRESS + DEY + DEY + PLP + SBCIY TXCBPT + STAAY TXADRF -CBSALO ;CALC EXTRA REMOTE ADDRESS + INY + INY + INY ;UP FIVE TO END ADDRESS + INY + INY + PHP + CPYIM XTRA1L + BCC LOOPP + PLP + +NOCALC + CPXIM IPEEK ;CHECK FOR LESS THAN PEEK + BCC TXCER4 + CPXIM IMACH + ONE ;COMPARE CONTROL BYTE + BCS TXCER4 ;NOT VALID IM OP CONTROL BYTE + LDYIM XTRA1L ;POINT TO CB REMOTE FROM +LP + LDAIY TXCBPT + STAAY TXADRT -XTRA1L ;STORE IN TX SCOUT AREA + INY + CPYIM XTRA2H + ONE ;COPY REMOTE FROM + BCC LP + +;CALCULATE DATA BUFFER VARIABLES +NOTIM + LDAIM DCD ;CHECK FOR CLOCK + BIT SReg2 + BNE TXCER3 ;NO ECONET CLOCK + +;INIT CLAIM VARIABLES + LDAIM &FE + STA CNTLSB + LDAIM TXADRT -TXDELO + STA ENTXCT ;STORE END COUNTER + STZ TXCNT ;STORE SCOUT BUFFER COUNTER + STZ CNTCSB ;STORE DELAY 3 BYTE LOOP COUNTER + STZ CNTMSB + LDYIM &E7 ;+RTS +CTXS +CRXS -TXLA TDRA FLAG 2BYT +PSE + +;POLL THE ECONET BUS FOR LINE FREE +POLBUS ;N.B. COULD BE RECEIVING A PACKET,TX MUST DETECT THIS + LDAIM RXIDLE + PHP ;SAVE INT STATE ON STACK + SEI ;DISABLE IRQ INTERUPT + JSR INTCND + BIT SReg2 + BEQ SKIP ;BUS IS NOT IDLE + LDA SReg1 ;READ STATUS FIRST + LDAIM &67 ;-RTS +CTXS +CRXS -TXL TDRA FLAG 2BYT +PSE + STA CReg2 ;CLEAR TX AND RX STATUS + LDAIM CTS + BIT SReg1 + BNE CLAIM ;BUS UNDRIVEN I.E.FREE + +SKIP + [ DEBUG = TRUE + STA CPYIC + LDA SReg1 + STA CPYSR1 + LDA SReg2 + STA CPYSR2 + ] + JSR INTCNU + PLP ;ENABLE IRQ INTERUPT + INC CNTMSB + BNE POLBUS ;APPROX 10 SEC TIMEOUT LOOP + INC CNTCSB + BNE POLBUS + INC CNTLSB + BNE POLBUS + BRA TXCER0 ;LINE JAMMED OR HW FAULT + +TXCER4 + LDAIM &44 ;NOT VALID CONTROL BYTE + BRA TXCERR +;ERROR IN CLAIMING THE ECONET +TXCER0 ;LINE JAMMED + LDAIM SEVEN ;-RTS -CTXS -CRXS -TXLA TDRA FLAG 2BYT +PSE + STA CReg2 ;TURN OFF TX IN CASE ITS ME JAMMING + + LDAIM &40 + BRA TXCERR +TXCER3 + JSR NETPOLL + LDAIM &43 ;NO CLOCK +TXCERR + LDYIM CBCNTL + STAIY TXCBPT + LDAIM &80 ;SIGNAL CLEAR FOR USER TX + STA TXCLR1 + PLX ;RESTORE X + RTS + +;CLAIM THE ECONET +CLAIM + STY CReg2 ;+RTS +CTXS +CRXS -TXLA TDRA FLAG 2BYT +PSE + LDXIM &44 ;-TXRS +RXRS -FRDI -TDRA -RDSR +TIE -RIE SCR2 + STX CReg1 ;-TXRS +RXRS -FRDI -TDRA -RDSR +TIE -RIE SCR2 + + LDXIM :LSB: WCLM + LDYIM :MSB: WCLM + STX NMINET + STY NMINET+1 ;SAVE TX JUMP ADDRESS + JSR INTCNU + + LDA TXPORT ;POINT TO PORT + BNE NTIMM ;NOT IMMED OPERATION + + LDA TXCNTL + ASLA + TAX + + LDAAX ENCT2-1 + STA NSTATE ;STORE NSTATE + LDAAX ENCT2-2 + STA ENTXCT ;STORE END COUNT + + JMIX (TXIML-2) + +TXIML + & PEEKIT + & POKEIT + & RTNIT + & PROEIT + & PROHIT + & STOPIT + & STRTIT + & MACHIT + +PEEKIT +POKEIT + CLC + PHP + LDYIM XTRA1L +MRCOPY + LDAAY TXADRF -XTRA1L ;ADDITION + PLP + ADCIY TXCBPT + STAAY TXADRF -XTRA1L ;CALCULATE EXTRA REMOTE ADDRESS LO + INY + PHP + CPYIM XTRA1L + FOUR + BCC MRCOPY ; Exit condition is Y = XTRA1L + FOUR ( Y <> 0) + PLP + BRA CALCAD ;CALCULATE ADDRESSES, Hence a BNE here not JMP + +NTIMM + LDA TXDELO ;LOAD SOURCE ADDRESS + AND TXDEHI + CMPIM &FF + BNE NOBR + LDAIM &0E ;LENGTH OF BROADCAST SCOUT PACKET + STA ENTXCT + LDAIM BCAST ;FLAG BROADCAST + STA NSTATE + LDYIM CBSALO ;POINT TO CB REMOTE FROM +LPP + LDAIY TXCBPT ;COPY BROADCAST PARAMETERS + STAAY TXBUFl + TWO ;STORE IN TX SCOUT AREA + INY + CPYIM XTRA1L + BCC LPP + BRA STOPIT + +NOBR + STZ NSTATE ;STORE STATE TO END SCOUT PACKET + +RTNIT +PROEIT +PROHIT +CALCAD +MACHIT + LDA TXCBPT + STA RXCBPT + LDA TXCBPT + ONE + STA RXCBPT + ONE + JSR ADCALC ;AND RETURN + +STOPIT +STRTIT + PLP ;ENABLE IRQ INTERUPT + PLX ;RESTORE X + RTS ;RETURN TO CALLER OF TX ROUTINE. CALLER NOW POLLS. +;TX OCCURS UNDER NMI INTERUPTS + +;SEND SCOUT +WCLM + LDY TXCNT ;LOAD COUNTER + BIT SReg1 +WCLM2 + BVC TXSER1 ;TDRA EXPECTED N.B. IN 2 BYTE MODE + LDAAY TXDELO + STA TXBYTE + INY + LDAAY TXDELO + INY + STY TXCNT + STA TXBYTE + CPY ENTXCT + BCS ENDSCT + BIT SReg1 ;QUICK IRQ POLL + BMI WCLM2 + JMP WTXIN2 ;WAIT FOR TX INTERUPT + + +;ERROR IN TXSCOUT PACKET +TXSER2 + LDAIM &42 ;AP EXPECTED ERROR IN SCOUT ACK PACKET + BRA SKIPIT +TXSER1 + LDAIM &67 ;-RTS +CTXST +CRXST -TXLST TDRA FLAG 2-BYT +PSE + STA CReg2 + LDAIM &41 ;TDRA EXPECTED DUE TO COLLISION OR LINE NOISE +SKIPIT + LDY STNID +COLARB ;THE NOTORIOUS COLLISION ARBITRATION + PHA + PLA ;DELAY A BIT + INY + BNE COLARB + JMP TXERRE ;JUMP TO ERROR REPORT + +ENDSCT + LDAIM &3F ;-RTS -CTXST +CRXST +TXLST FC FLAG 2-BYT +PSE + STA CReg2 + LDAIM :LSB: ENPAK + [ FAST5 <> TRUE + LDYIM :MSB: ENPAK + JMP WTXINT ;WAIT FOR PACKET TO COMPLETE + | + JMP WTXNTF ; New fast code ! + ] + +;SCOUT TRANSMITTED +ENPAK + LDAIM &82 ;+TXRST -RXRST -RXDISC -TDSR -RDSR -TIE +RIE SCR2 + STA CReg1 + BIT NSTATE + BVC NOOBRD + JMP UPTXCB +NOOBRD + LDAIM SHORT + BIT NSTATE + BEQ SCTAKK + JMP DATAK ;WAIT FOR DATA PACKET OR WAIT FOR LAST ACK PACKET + +;ERROR IN RECEIVED ACK PACKET +TXAER1 ;RXDA EXPECTED.NO MATCH ON SOUR/DEST ACK ADDR. BAD CRC + JMP TXBER1 ;JUMP TO ERROR REPORT + +SCTAKK + LDAIM :LSB: WSCACK + [ FAST6 <> TRUE + LDYIM :MSB: WSCACK + JMP WRXINT ;WAIT SCOUTACK PACKET + | + JMP WRXNTF ; New fast code ! + ] + + +;RECEIVE SCOUTACK PACKET +WSCACK + LDAIM AP + BIT SReg2 + BEQ TXSER2 ;AP EXPECTED I.E IF NOT LISTENING + LDA RXBYTE + CMP STNID + BNE TXAER1 ;NO SOURCE ADDRESS MATCH + LDAIM :LSB: WSCAKS + [ FAST7 <> TRUE + LDYIM :MSB: WSCAKS + JMP WRXINT ;WAIT FOR 1 BYTE OF SOURCE + | + JMP WRXNTF ; New fast code ! + ] + +WSCAKS ;WAIT FOR SCOUT ACK SOURCE ADDRESS + BIT SReg2 + BPL TXAER1 ;RXDA EXPECTED + LDA RXBYTE ;NET NUMBER MUST BE ZERO + BNE TXAER1 ;NO SOURCE ADDRESS MATCH + + +WSCAKD ;WAIT FOR SCOUT ACK DESTINATION + BIT SReg1 ;QUICK IRQ POLL TO SAVE TIME + + BMI WSCAKE + + LDAIM :LSB: WSCAKE + [ FAST8 <> TRUE + LDYIM :MSB: WSCAKE + JMP WTXINT ;WAIT FOR 2 BYTES OF DEST + | + JMP WRXNTF ; New fast code ! + ] + +WSCAKE + BIT SReg2 + BPL TXAER1 ;RXDA EXPECTED + LDA RXBYTE + CMP TXDELO + BNE TXAER1 ;NOT FROM STATION SCOUT WAS SENT TO + LDA RXBYTE + CMP TXDEHI + BNE TXAER1 ;NOT FROM NET SCOUT WAS SENT TO + + LDAIM FV ;SCOUT ACK END + BIT SReg2 + BEQ TXAER1 ;NOT FRAME VALID PACKET + + +;SEND DATA + LDAIM &A7 ;+RTS -CTXST +CRXST -TXLD TDRA FLAG 2BYT +PSE + STA CReg2 ;ENABLE TRANSMIT + LDAIM &44 ;-TXRST +RXRST -RXDISC -TDSR -RDSR +TIE -RIE SCR2 + STA CReg1 + LDAIM :LSB: DATAK + LDYIM :MSB: DATAK +;TX 2BYTES DESTINATION +TXDATA + STA TXLINK + STY TXLINK + ONE + LDA TXDELO + BIT SReg1 ;MAY NEED DELAY HERE IF S/W TOO FAST + BVC BCXXX2 ; TXDER1 ;TDRA EXPECTED N.B. IN 2 BYTE MODE + STA TXBYTE ;TRANSMIT SOURCE LO + LDA TXDEHI + STA TXBYTE ;TRANSMIT SOURCE HI + LDAIM :LSB: TXSR + LDYIM :MSB: TXSR + JMP WTXINT ;WAIT FOR TX INTERUPT + +TXSR ;TX 2BYTES SOURCE + LDA STNID + BIT SReg1 + BVC BCXXX2 ; TXDER1 ;TDRA EXPECTED N.B. IN 2-BYTE MODE + STA TXBYTE ;TX STATION ID + LDAIM NETnum + STA TXBYTE ;TX NET ID +TXINF + LDAIM :LSB: TXINFO + LDYIM :MSB: TXINFO + JMP WTXINT ;WAIT FOR TX INTERUPT + +;TRANSMIT DATA BYTES +TXINFO + LDY TXYOFF + BNE TXINF3 + LDA TXPAGE + BEQ TXEND2 +TXINF3 + BIT SReg1 +BCXXX2 BVC TXDER1 ;TDRA EXPECTED N.B. IN 2-BYTE MODE, BRANCH THROUGH + LDAIY TXDAPT + STA TXBYTE + INY + BNE PASSX + DEC TXPAGE + BEQ TXEND2 + INC TXDAPT + ONE +PASSX + LDAIY TXDAPT + STA TXBYTE + INY + STY TXYOFF + BNE OUTX +;UPCNT + DEC TXPAGE + BEQ TXEND2 + INC TXDAPT + ONE +OUTX + BIT SReg1 + BMI BCXXX2 + JMP WTXIN2 + +TXEND2 + LDAIM &3F ;-RTS -CTXST +CRXST +TXLST FC FLAG 2-BYT +PSE + STA CReg2 + LDA NSTATE + BPL NOIM + LDAIM :LSB: NOUPDA + [ FAST9 <> TRUE + LDYIM :MSB: NOUPDA + JMP WTXINT ;WAIT FOR IMMEDIATE DATA TO COMPLETE + | + JMP WTXNTF ; New fast code ! + ] + +NOUPDA + JMP NOUPD2 + +NOIM + LDA TXLINK + LDY TXLINK + ONE + JMP WTXINT ;WAIT FOR PACKET TO COMPLETE + +;ERROR IN TXDATA PACKET +TXDER1 + LDA NSTATE + BPL TXBER1 ; NOIMM ;NO LONG ACK PACKET + JMP NOUPD2 +;NOIMM ;ERROR IN TXDATA PACKET +; JMP TXBER1 ;JUMP TO ERROR REPORT + +;TXEN2 +DATAK + LDAIM &82 ;+TXRST -RXRST -RXDISC -TDSR -RDSR -TIE +RIE SCR2 + STA CReg1 + LDAIM :LSB: DATACK + [ FAST10 <> TRUE + LDYIM :MSB: DATACK + JMP WRXINT ;WAIT DATA ACK PACKET + | + JMP WRXNTF ; New fast code ! + ] + +DATACK + LDAIM AP + BIT SReg2 + BEQ TXBER1 ;AP EXPECTED + LDA RXBYTE + CMP STNID + BNE TXBER1 ;NO SOURCE ADDRESS MATCH + LDAIM :LSB: WDAAKS + [ FAST11 <> TRUE + LDYIM :MSB: WDAAKS + JMP WRXINT ;WAIT FOR 1 BYTE OF SOURCE + | + JMP WRXNTF ; New fast code ! + ] + +WDAAKS ;WAIT FOR SCOUT ACK SOURCE ADDRESS + BIT SReg2 + BPL TXBER1 ;RXDA EXPECTED + LDA RXBYTE ;NET NUMBER MUST BE ZERO + BNE TXBER1 ;NO SOURCE ADDRESS MATCH + BIT SReg1 ;QUICK IRQ POLL TO SAVE TIME + BMI WDAAKD + LDAIM :LSB: WDAAKD + [ FAST12 <> TRUE + LDYIM :MSB: WDAAKD + JMP WRXINT ;WAIT FOR 2BYTES DEST + | + JMP WRXNTF ; New fast code ! + ] + +WDAAKD ;WAIT FOR SCOUT ACK DESTINATION + BIT SReg2 + BPL TXBER1 ;RXDA EXPECTED + LDA RXBYTE + CMP TXDELO + BNE TXBER1 ;NOT FROM STATION SCOUT WAS SENT TO + LDA RXBYTE + CMP TXDEHI + BNE TXBER1 ;NOT FROM NET SCOUT WAS SENT TO + + LDA NSTATE + BPL NODATA + JMP RXINF +NODATA + LDAIM FV ;TEST FOR SCOUT ACK END + BIT SReg2 + BEQ TXBER1 ;NOT FRAME VALID PACKET + +UPTXCB + LDAIM ZERO ;GOOD UPDATE OF TX CONTROL BYTE + BRA TXERRE + +;ERROR IN RECEIVED DATA ACK PACKET +TXBER1 + LDAIM &41 ;AP/RXDA EXPECTED.NO MATCH ON DATA ACK SOUR/DEST ADDR.BAD CRC +TXERRE + LDYIM CBCNTL + STAIY TXCBPT + JMP NOUPD2 ;WAIT TO RECEIVE A NEW PACKET + +ENCT2 ;LENGTH OF IMMED SCOUT BUFFERS + = &0E ;PEEK SCOUT LENGTH + = &81 ;NET STATE OF IM OPS + = &0E ;POKE SCOUT LENGTH + = &00 ;NET STATE OF IM OPS + = &0A ;ROUTINE SCOUT LENGTH + = &00 ;NET STATE OF IM OPS + = &0A ;PROCEDURE EVENT SCOUT LENGTH + = &00 ;NET STATE OF IM OPS + = &0A ;PROCEDURE HIGH LEVEL SCOUT LENGTH + = &00 ;NET STATE OF IM OPS + = &06 ;STOP SCOUT LENGTH + = &01 ;NET STATE OF IM OPS + = &06 ;START SCOUT LENGTH + = &01 ;NET STATE OF IM OPS + = &0A ;MACHINE TYPE SCOUT LENGTH + = &81 ;NET STATE OF IM OPS + +ADCALC + LDYIM CBSALO ;SET UP ADDRESSES + LDAIY RXCBPT + LDYIM CBEALO + SEC + SBCIY RXCBPT + STA TXYOFF + + LDYIM CBSAHI + LDAIY RXCBPT + SBCIM ZERO + STA TXDAPT + ONE + + LDYIM CBEALO + LDAIY RXCBPT + STA TXDAPT + + LDYIM CBEAHI + LDAIY RXCBPT + SEC + SBC TXDAPT + ONE + STA TXPAGE + RTS + + LNK DOS01 + +; ******** + + [ :MSB: ENPAK <> :MSB: WCLM + [ FAST5 = TRUE + PAGE ERROR :MSB: ENPAK <> :MSB: WCLM ; FAST5 => FALSE + ] + | + [ FAST5 <> TRUE + PAGE OK :MSB: ENPAK = :MSB: WCLM ; FAST5 => TRUE + ] + ] + +; ******** + + [ :MSB: WSCACK <> :MSB: ENPAK + [ FAST6 = TRUE + PAGE ERROR :MSB: WSCACK <> :MSB: ENPAK ; FAST6 => FALSE + ] + | + [ FAST6 <> TRUE + PAGE OK :MSB: WSCACK = :MSB: ENPAK ; FAST6 => TRUE + ] + ] + +; ******** + + [ :MSB: WSCAKS <> :MSB: WSCACK + [ FAST7 = TRUE + PAGE ERROR :MSB: WSCAKS <> :MSB: WSCACK ; FAST7 => FALSE + ] + | + [ FAST7 <> TRUE + PAGE OK :MSB: WSCAKS = :MSB: WSCACK ; FAST7 => TRUE + ] + ] + +; ******** + + [ :MSB: WSCAKD <> :MSB: WSCAKS + [ FAST8 = TRUE + PAGE ERROR :MSB: WSCAKD <> :MSB: WSCAKS ; FAST8 => FALSE + ] + | + [ FAST8 <> TRUE + PAGE OK :MSB: WSCAKD = :MSB: WSCAKS ; FAST8 => TRUE + ] + ] + +; ******** + + [ FAST9 = TRUE + [ :MSB: NOUPDA <> :MSB: TXINFO + PAGE ERROR :MSB: NOUPDA <> :MSB: TXINFO ; FAST9 => FALSE + ] + [ :MSB: NOUPDA <> :MSB: TXINF2 + PAGE ERROR :MSB: NOUPDA <> :MSB: TXINF2 ; FAST9 => FALSE + ] + | + [ :MSB: NOUPDA = :MSB: TXINF2 + [ :MSB: NOUPDA = :MSB: TXINFO + PAGE OK :MSB: NOUPDA = :MSB: TXINFO ; FAST9 => TRUE + PAGE OK :MSB: NOUPDA = :MSB: TXINF2 ; FAST9 => TRUE + ] + ] + ] + +; ******** + + [ :MSB: DATACK <> :MSB: ENPAK + [ FAST10 = TRUE + PAGE ERROR :MSB: DATACK <> :MSB: ENPAK ; FAST10 => FALSE + ] + | + [ FAST10 <> TRUE + PAGE OK :MSB: DATACK = :MSB: ENPAK ; FAST10 => TRUE + ] + ] + +; ******** + + [ :MSB: WDAAKS <> :MSB: DATACK + [ FAST11 = TRUE + PAGE ERROR :MSB: WDAAKS <> :MSB: DATACK ; FAST11 => FALSE + ] + | + [ FAST11 <> TRUE + PAGE OK :MSB: WDAAKS = :MSB: DATACK ; FAST11 => TRUE + ] + ] + +; ******** + + [ :MSB: WDAAKD <> :MSB: WDAAKS + [ FAST12 = TRUE + PAGE ERROR :MSB: WDAAKD <> :MSB: WDAAKS ; FAST12 => FALSE + ] + | + [ FAST12 <> TRUE + PAGE OK :MSB: WDAAKD = :MSB: WDAAKS ; FAST12 => TRUE + ] + ] + diff --git a/FileStore/SRC/MOS/MOSASM b/FileStore/SRC/MOS/MOSASM new file mode 100644 index 0000000..c5278f2 --- /dev/null +++ b/FileStore/SRC/MOS/MOSASM @@ -0,0 +1 @@ +*|Assembly sequence for FileStore MOS > MOSAsm *|By Jes 3/9/84, Updated by Glenn 8/5/85 *|Updated by Mark Usher 7/4/21 *DIR $.MOS *LIB $.LIBRARY *TurMasm *OPT 1 1 STOP ON ASM MOS01 *CB CH."MOSMAKE" \ No newline at end of file diff --git a/FileStore/SRC/MOS/MOSASM.inf b/FileStore/SRC/MOS/MOSASM.inf new file mode 100644 index 0000000..db48725 --- /dev/null +++ b/FileStore/SRC/MOS/MOSASM.inf @@ -0,0 +1 @@ +$.MOSASM 00000000 00000000 000000C8 19 A341 122311 A24F 350114 diff --git a/FileStore/SRC/MOS/README b/FileStore/SRC/MOS/README new file mode 100644 index 0000000..89c2b58 --- /dev/null +++ b/FileStore/SRC/MOS/README @@ -0,0 +1,172 @@ +FileStore ROMs v1.31 +==================== + +This disc contains the source code for the Acorn FileStore E01 MOS ROM. + +Assembling the File Store Source Code +====================================== + +The source code will assemble on either a BBC with an Acorn Turbo (256K) +6502 Co-Processor and ADFS or on Arthur/RISC OS using the 6502 Turbo +Co-Processor emulator which is included here. +To assemble on a BBC, use SHIFT-BREAK or *EXEC !BOOT. On RISC OS, double +clicking the file GO will start the process. The assembled file "MOSrom" will be +placed in the root directory. The assembly process is significantly faster +when a hard drive is used instead of a floppy. + +Files +===== + +\ $ + !BOOT - BBC Routine to set library and call MOSASM + GO - RISC OS Routine to set library, load emulator and call MOSASM + MAKEROMS - BBC BASIC program to ensure the ROMs are correctly aligned and + create a single 64K ROM for the E01S. + MOSASM - Loads TurboMasm and starts the MOS binary assembly + README - This file + +\ LIBRARY + 65ARTHURT - The Turbo Co-processor emulator for RISC OS + CB - BASIC for the Turbo Co-processor + TURMASM - Turbo version of MASM assembler + +\ MOS + The source code files + MOSmake - BASIC program to put together the assembed parts and create + the MOS ROM binary "MOSROM" + +\ MOS\X + Location for the assembled parts. Do not delete or the assembler will fail. + + +Version 1.31 +============ + +Date - estimated 20/7/88. This was the latest date of a comment in the file +server ROM code. +The E01S first appeared in Technomatic adverts in Acorn User Jan 1989. + +Comments +======== +The MOS source code has been recreated from scratch using sources which +included the DNFS source code. It creates a full matching binary, however, +some of the variable and routine names are guesses. + +The FileStore MOS ROM appears to keep versioning in line with NFS versions. +BBC NFS is 3.34, DNFS reports 3.60. This has 3.3F. + +The MOS ROM still has debug code present. This was probably due to leaving the +assembler debug directive on before release code was produced. + +The original file server FSmake that puts together the assembled parts has been +adapted to put together the MOS parts. It first writes a &FF byte from 0 to +&6800 and then adds the assembled code to create a full 32K ROM file instead of +only the assembled code. + +v1.31 was the first release for the revised Acorn FileStore E01S model. +The E01S uses 1 x 64K ROM instead of 2 x 32K ROMs. There is no difference in +the code between the two systems. + +v1.31 is not listed in Acorn parts list. + +Depending on the options used, the FS ROM can overflow the 32K ROM as was the +case in later versions. There is space at the start of the MOS ROM for the +overflow but care must be taken with the start of workspace areas. +The file MAKEROMS will take any overflow bytes and add them to the start of the +MOS ROM, create a 32K FSROM, 32K MOSROM (for E01 filestores) and a single 64K +E01SROM (for E01S filestores). Copy both the FSROM and MOSROM into the same +directory, and run the program under Turbo Hi-BASIC. +*CB +CHAIN "MAKEROMS" + + +Changes (from v1.23) (MOS) +========================== + +HEADER FILE 1 + MOS01 Line 0014 Version change from &3C to &3F + MOS01 Line 0128 Some of the fast variables changed depending on + 0139 page boundary overlaps for faster network code + MOS01 Line 0141 Debug directive turned off + +MOS INITIALISATION + MOS03 Line 0069 Removed copying of memory spaces + 0000-01FF to E200-E3FF + E600-E7FF to E400-E5FF + MOS03 Line 0140 Remove zeroing of 0100-01FF + MOS04 Line 0357 Code optimization, move code block to routine in MOS5 + MOS04 Line 0502 Get Year and month + to 0505 + Line 0514 Change century calculation + to 0519 + MOS04 Line 0555 Optimize reading date/time from memory + to 0562 + MOS04 Line 0584 Code optimization. Remove unnecessary cycles for + to 0587 STAYY instruction + MOS04 Line 0593 Change century calculation + to 0606 + MOS04 Line 0609 Optimise writing date code + Line 0613 + Line 0617 + Line 0621 + MOS05 Line 0096 Code optimization, move code block to RXNEXT in MOS5 + Line 0217 Add Get next RX block subroutine (RXNEXT) + to 0228 + +FLOPPY DISK OPERATIONS + DOS01 Line 0084 Ensure a disk read takes place + DOS01 Line 0145 Get drive status for drive X before dropping into + to 0149 read write disk + DOS01 Line 0221 Get drive status first + to 0227 + DOS01 Line 0337 + to 0338 + DOS01 Line 0340 + to 0350 + DOS01 Line 0356 + DOS01 Line 0408 change timeout counter to 2.75s + to 0414 + DOS01 Line 0422 Force FDC interrupt if there is a timeout + to 0423 + DOS01 Line 0465 + to 0466 + DOS01 Line 0468 + DOS01 Line 0471 add a timeout loop + to 0476 + DOS01 Line 0561 Check for CRC Error + to 0562 + DOS01 Line 0565 + to 0568 + +HARD DISK OPERATIONS + DOS02 Line 0021 Osword&72 entry. New check for SCSI HD + to 0031 + DOS02 Line 0099 Code optimization + to 0100 + DOS02 Line 0146 + to 0152 + DOS02 Line 0169 + to 0177 + DOS02 Line 0193 change delay from 25us to 160us + to 0198 + DOS02 Line 0215 delay of 2 cycles + to 0216 + DOS02 Line 0220 + to 0223 + DOS02 Line 0227 + to 0231 + DOS02 Line 0236 + to 0285 + DOS02 Line 0300 Allow for more than 1 hard drive + to 0308 + DOS02 Line 0313 + to 0317 + DOS02 Line 0321 + DOS02 Line 0327 On success, return with Y=0 + to 0339 + DOS02 Line 0389 + to 0393 + +OTHER DISK OPERATIONS + DOS03 Line 0466 + to 0467 diff --git a/FileStore/SRC/MOS/README.inf b/FileStore/SRC/MOS/README.inf new file mode 100644 index 0000000..66f687d --- /dev/null +++ b/FileStore/SRC/MOS/README.inf @@ -0,0 +1 @@ +$.README FFFFFF59 18948126 000018E2 19 A544 352010 A24F 350116 diff --git a/FileStore/SRC/README b/FileStore/SRC/README deleted file mode 100644 index c1fe2f4..0000000 --- a/FileStore/SRC/README +++ /dev/null @@ -1,18 +0,0 @@ -Filestore ROMs v1.23 -==================== - -Date - estimated 1987 from the copyright string. - - -Binary Files (* denotes the official ACORN released version) -============ -* FSR-123 - Filestore ROM. Pseudo directory symbols No, Cachesw not disabled -* MOS-33C - MOS ROM for Filestore. - -Comments -======== -This is the first known version of the Filestore ROMs although it appears there -were pre-release versions given part numbers. - -The assembler creates the code at offset 0000. When programming to an EPROM it -must be placed at offset 0200. This is how the original files created it. diff --git a/FileStore/SRC/README.INF b/FileStore/SRC/README.INF deleted file mode 100644 index 483a080..0000000 --- a/FileStore/SRC/README.INF +++ /dev/null @@ -1 +0,0 @@ -README FFFFFF5A 606C56DF 0000025A WR diff --git a/FileStore/adfs/Filestore-123bin.adl b/FileStore/adfs/FS-131bin.adl similarity index 63% rename from FileStore/adfs/Filestore-123bin.adl rename to FileStore/adfs/FS-131bin.adl index dd7cf86..5c96d3b 100644 Binary files a/FileStore/adfs/Filestore-123bin.adl and b/FileStore/adfs/FS-131bin.adl differ diff --git a/FileStore/adfs/Filestore-123src.adl b/FileStore/adfs/FSFS-131src.adl similarity index 80% rename from FileStore/adfs/Filestore-123src.adl rename to FileStore/adfs/FSFS-131src.adl index e9ae19d..1c48c69 100644 Binary files a/FileStore/adfs/Filestore-123src.adl and b/FileStore/adfs/FSFS-131src.adl differ diff --git a/FileStore/adfs/FSMOS-131src.adl b/FileStore/adfs/FSMOS-131src.adl new file mode 100644 index 0000000..33aeb19 Binary files /dev/null and b/FileStore/adfs/FSMOS-131src.adl differ diff --git a/Level3/AcornL3v131-master.zip b/Level3/AcornL3v131-master.zip new file mode 100644 index 0000000..d232eff Binary files /dev/null and b/Level3/AcornL3v131-master.zip differ diff --git a/Level3/Binary Files/FS3-124 b/Level3/Binary Files/FS3-124 deleted file mode 100644 index 866b8a7..0000000 Binary files a/Level3/Binary Files/FS3-124 and /dev/null differ diff --git a/Level3/Binary Files/FS3-124.inf b/Level3/Binary Files/FS3-124.inf deleted file mode 100644 index 4545165..0000000 --- a/Level3/Binary Files/FS3-124.inf +++ /dev/null @@ -1 +0,0 @@ -$.FS3-124 00000400 00000400 diff --git a/Level3/Binary Files/FS3-124d b/Level3/Binary Files/FS3-124d deleted file mode 100644 index 3dcc007..0000000 Binary files a/Level3/Binary Files/FS3-124d and /dev/null differ diff --git a/Level3/Binary Files/FS3-124d.INF b/Level3/Binary Files/FS3-124d.INF deleted file mode 100644 index 88983c2..0000000 --- a/Level3/Binary Files/FS3-124d.INF +++ /dev/null @@ -1 +0,0 @@ -FS3-124d 00000400 00000400 0000846A WR diff --git a/Level3/Binary Files/FS3-124dp b/Level3/Binary Files/FS3-124dp deleted file mode 100644 index 73bfa48..0000000 Binary files a/Level3/Binary Files/FS3-124dp and /dev/null differ diff --git a/Level3/Binary Files/FS3-124dp.inf b/Level3/Binary Files/FS3-124dp.inf deleted file mode 100644 index 31a18e1..0000000 --- a/Level3/Binary Files/FS3-124dp.inf +++ /dev/null @@ -1 +0,0 @@ -$.FS3-124dp 00000400 00000400 diff --git a/Level3/Binary Files/FS3-124p b/Level3/Binary Files/FS3-124p deleted file mode 100644 index 7d01711..0000000 Binary files a/Level3/Binary Files/FS3-124p and /dev/null differ diff --git a/Level3/Binary Files/FS3-124p.inf b/Level3/Binary Files/FS3-124p.inf deleted file mode 100644 index 29708cb..0000000 --- a/Level3/Binary Files/FS3-124p.inf +++ /dev/null @@ -1 +0,0 @@ -$.FS3-124p 00000400 00000400 diff --git a/Level3/Binary Files/FS3-131 b/Level3/Binary Files/FS3-131 new file mode 100644 index 0000000..9a54d2c Binary files /dev/null and b/Level3/Binary Files/FS3-131 differ diff --git a/Level3/Binary Files/FS3-131.inf b/Level3/Binary Files/FS3-131.inf new file mode 100644 index 0000000..3770229 --- /dev/null +++ b/Level3/Binary Files/FS3-131.inf @@ -0,0 +1 @@ +$.FS3-131 00000400 00000400 diff --git a/Level3/Binary Files/FS3-131d b/Level3/Binary Files/FS3-131d new file mode 100644 index 0000000..457492b Binary files /dev/null and b/Level3/Binary Files/FS3-131d differ diff --git a/Level3/Binary Files/FS3-131d.inf b/Level3/Binary Files/FS3-131d.inf new file mode 100644 index 0000000..a073563 --- /dev/null +++ b/Level3/Binary Files/FS3-131d.inf @@ -0,0 +1 @@ +$.FS3-131d 00000400 00000400 diff --git a/Level3/Binary Files/FS3-131dp b/Level3/Binary Files/FS3-131dp new file mode 100644 index 0000000..f651a38 Binary files /dev/null and b/Level3/Binary Files/FS3-131dp differ diff --git a/Level3/Binary Files/FS3-131dp.inf b/Level3/Binary Files/FS3-131dp.inf new file mode 100644 index 0000000..2535c9f --- /dev/null +++ b/Level3/Binary Files/FS3-131dp.inf @@ -0,0 +1 @@ +$.FS3-131dp 00000400 00000400 diff --git a/Level3/Binary Files/FS3-131p b/Level3/Binary Files/FS3-131p new file mode 100644 index 0000000..720f918 Binary files /dev/null and b/Level3/Binary Files/FS3-131p differ diff --git a/Level3/Binary Files/FS3-131p.inf b/Level3/Binary Files/FS3-131p.inf new file mode 100644 index 0000000..4a172bb --- /dev/null +++ b/Level3/Binary Files/FS3-131p.inf @@ -0,0 +1 @@ +$.FS3-131p 00000400 00000400 diff --git a/Level3/Binary Files/Original binary/FS3-124 b/Level3/Binary Files/Original binary/FS3-124 deleted file mode 100644 index 73bfa48..0000000 Binary files a/Level3/Binary Files/Original binary/FS3-124 and /dev/null differ diff --git a/Level3/Binary Files/Original binary/FS3-124.INF b/Level3/Binary Files/Original binary/FS3-124.INF deleted file mode 100644 index 218f3d1..0000000 --- a/Level3/Binary Files/Original binary/FS3-124.INF +++ /dev/null @@ -1 +0,0 @@ -FS3-124 00000400 00000400 000084BE WR diff --git a/Level3/Binary Files/Original binary/FS3-131 b/Level3/Binary Files/Original binary/FS3-131 new file mode 100644 index 0000000..457492b Binary files /dev/null and b/Level3/Binary Files/Original binary/FS3-131 differ diff --git a/Level3/Binary Files/Original binary/FS3-131.INF b/Level3/Binary Files/Original binary/FS3-131.INF new file mode 100644 index 0000000..b15abb6 --- /dev/null +++ b/Level3/Binary Files/Original binary/FS3-131.INF @@ -0,0 +1 @@ +FS3-131 00000400 00000400 000084A1 WR diff --git a/Level3/Binary Files/Original binary/patched/FS124.adl b/Level3/Binary Files/Original binary/patched/FS124.adl deleted file mode 100644 index be2e2cc..0000000 Binary files a/Level3/Binary Files/Original binary/patched/FS124.adl and /dev/null differ diff --git a/Level3/Binary Files/Original binary/patched/FS3-124p b/Level3/Binary Files/Original binary/patched/FS3-124p deleted file mode 100644 index 1c55181..0000000 Binary files a/Level3/Binary Files/Original binary/patched/FS3-124p and /dev/null differ diff --git a/Level3/Binary Files/Original binary/patched/FS3-124p.INF b/Level3/Binary Files/Original binary/patched/FS3-124p.INF deleted file mode 100644 index 1ff7303..0000000 --- a/Level3/Binary Files/Original binary/patched/FS3-124p.INF +++ /dev/null @@ -1 +0,0 @@ -FS3-124p 00000400 00000400 000084BE WR diff --git a/Level3/Binary Files/Original binary/patched/PATCHFS b/Level3/Binary Files/Original binary/patched/PATCHFS deleted file mode 100644 index cedd327..0000000 Binary files a/Level3/Binary Files/Original binary/patched/PATCHFS and /dev/null differ diff --git a/Level3/Binary Files/Original binary/patched/PATCHFS.INF b/Level3/Binary Files/Original binary/patched/PATCHFS.INF deleted file mode 100644 index 0f20f4e..0000000 --- a/Level3/Binary Files/Original binary/patched/PATCHFS.INF +++ /dev/null @@ -1 +0,0 @@ -PATCHFS 00000800 00000800 0000027B WR diff --git a/Level3/Change Log.txt b/Level3/Change Log.txt new file mode 100644 index 0000000..c101650 --- /dev/null +++ b/Level3/Change Log.txt @@ -0,0 +1,682 @@ +Version 1.31 +============ + +Date - estimated July 1988. Dates in change comments since v1.24 include +4/29 April 1988, 22 May 1988, 1 Jun 1988 and 1/7/20 July 1988. + +Binary Files (* denotes the official ACORN released version) +============ + FS3-131 - Assembler options DONGLE absent, Pseudo directory symbols No +* FS3-131d - Assembler options DONGLE present, Pseudo directory symbols No + FS3-131p - Assembler options DONGLE absent, Pseudo directory symbols Yes + FS3-131dp - Assembler options DONGLE present, Pseudo directory symbols Yes +* FSR-131 - Filestore FS ROM. Pseudo directory symbols No, + Cachesw not disabled +* MOS-131 - MOS ROM for Filestore. NFS 3.3.3C + +Comments +======== +This is the original and unchanged source code. Since just before v1.20 the +FileStore had become an ACORN product which used the same code base as the Level3 file server. The original code was 3 directories + - L3 containing the Level3 file server code + - Filestore with the File Store file server code for the new E01 Filestore + - Fileserver which appears to be an unfinished attempt to merge the Level3 + file server and FileStore file server code base + +The merged code was based on 2 switches, Level3 (representing Level3 +file server) and CMOS (representing the Filestore which used the 65C02 processor +and its enhanced instruction set). The work to merge the code bases has now been +completed. As no Level3 binaries after v1.31 are known, the code changes in the +FileStore file server code can now be applied to Level3 file server. + +The FileStore software also has a big buffer cache option introduced for +replies. This may also have been in earlier versions. + +The original file FSMAKE that puts together the assembled parts has been +altered to insert 512 bytes at the start of the ROM so the image is ready +for use directly. This maps to 512 bytes of zero page workspace as the ROM +code executes from address 0x200. + +Changes (from v1.24) (Level3 source files) +========================================== + +HEADER FILE 1 + Uade01 Line 0064 VERLA, version changed from 2 to 3 +20/07/88 Uade01 Line 0065 VERLB, version changed from 4 to 1 + Uade01 Line 0194 SYNERR changed from &FE to &DC + +UTILITIES + Uade03 Line 0012 (C) date changed from 1987 to 1988 + +24/02/88 Uade04 Line 0243 changes made to date evaluation code + Uade04 Line 0244 ensuring day is not >31 + Uade04 Line 0256 + Uade04 Line 0274 + Uade04 Line 0275 + +FILE SERVER INITIALISATION + +24/03/88 Uade04 Line 0685 include the century in the date calculation +[typo 24/02/88?] to 0687 +24/02/88 Uade04 Line 0692 + Uade04 Line 0699 + to 0701 + Uade04 Line 0703 + Uade04 Line 0705 + Uade04 Line 0708 +24/02/88 Uade04 Line 0759 +24/02/88 to 0761 + Uade04 Line 0763 + Uade04 Line 0805 + Uade04 Line 0811 + to 0814 +24/02/88 Uade04 Line 0838 + to 0840 + Uade04 Line 0845 + Uade04 Line 0882 + Uade04 Line 0889 Leap year check + to 0891 + Uade04 Line 0926 Use carry flag to display leading 0 for hours + 0931 Use carry flag to display leading 0 for minutes +24/02/88 Uade04 Line 1012 + to 1015 + +24/02/88 Uade04 Line 0287 changes made to printing decimal numbers + Uade04 Line 0294 ensuring flag to print leading zeros is not lost + Uade04 Line 0297 + Uade04 Line 0304 + +USRMAN + Uade06 Line 0979 close down routine "LOGOFF" +01/06/88 to 0983 + Uade06 Line 0987 + Uade06 Line 0989 + Uade06 Line 0990 + Uade06 Line 0992 + Uade06 Line 0993 +01/06/88 Uade06 Line 0999 + + Uade06 Line 1073 routine GETUFD. change made to the how the root + Uade06 Line 1076 dir is created +07/07/88 to 1077 + Uade06 Line 1091 routine RTROOT + Uade06 Line 1093 + Uade06 Line 1114 store the users disc number in a variable instead + Uade06 Line 1116 of on the stack + Uade06 Line 1120 and use UMHLIB instead of USTEMP + to 1122 + Uade06 Line 1138 + Uade06 Line 1140 + Uade06 Line 1143 comment change to retrieve root again without + to 1144 checking if it already has been + Uade06 Line 1146 Clean up before doing the retrieve + Uade06 Line 1157 retrieve the previous user disc number + Uade06 Line 1159 +RNDMAN +29/04/88 Rman02 Line 0160 Change file size. code moved to a subroutine + Rman02 Line 0161 RDEXSZ in Rman04 to extend the file +29/04/88 Rman02 Line 0163 + Rman02 Line 0164 + +01/06/88 Rman02 Line 0383 bugfix: High water mark not increased when setting + the sequential file pointer, if it exceeded + the high existing high water mark + +23/03/88 Rman03 Line 0250 bugfix for the access mode for Putbytes/Getbytes + to 0254 operations + +29/04/88 Rman04 Line 0183 Set new file size and call the new subroutine + Rman04 Line 0184 RDEXSZ to extend the file +29/04/88 Rman04 Line 0215 Subroutine RDEXSZ + Rman04 Line 0253 + +DIRMAN +23/03/88 Uade0C Line 0021 New function 13 added. Check if object will preserve + Uade0C Line 0023 Increase the number of functions + Uade0C Line 0046 add routine to table +04/04/88 Uade0C Line 0127 call as a subroutine + Uade0C Line 0128 and use the DIRMAN exit function +04/04/88 Uade0C Line 0154 Routine DRRET2 set up the name, root character and 9 + to 0158 spaces + Uade0C Line 0171 add check for directory type and the locked bit + Uade0C Line 0172 + Uade0C Line 0174 + Uade0C Line 0175 + Uade0C Line 0177 + Uade0C Line 0178 + Uade0C Line 0181 +04/04/88 Uade0C Line 0256 Change to RTS as a subroutine exit + +04/04/88 Uade0C Line 0890 DRINFO most of the routine changed + to 0930 + + Uade0D Line 0153 check for : character removed as it was there twice +01/06/88 Uade0D Line 0580 compatibility for "^" ? + Uade0D Line 0581 + Uade0D Line 0584 + + Uade0D Line 0858 Code for RETPAR changed around in order of + Uade0D Line 0861 execution. + Uade0D Line 0865 + to 0912 + + Uade0E Line 0380 OUTZRO routine removed +24/02/88 Uade0E Line 0472 ensure only the day of the month is output + Uade0E Line 0473 + Uade0E Line 0479 + Uade0E Line 0480 set the value for the year + to 0483 + Uade0E Line 0494 +24/02/88 Uade0E Line 0501 ensure year 20xx compatable + to 0504 + Uade0E Line 0524 code optimised for character conversion + +01/06/88 Uade0E Line 0723 bugfix when outputting the access byte + Uade0E Line 0747 + to 0763 + +AUTMAN +22/03/88 Uade10 Line 0092 code moved to subroutine ATOPWF + Uade10 Line 0094 + to 0096 comments added +22/05/88 Uade10 Line 0189 new subroutine ATOPWF + to 0210 +22/03/88 Uade10 Line 0337 changed to use new open password file routine +22/03/88 Uade10 Line 0369 changed to use new open password file routine + + Uade10 Line 0814 check for alternative return code &FF instead of end + of file removed +01/06/88 Uade10 Line 0943 round up if part sector and skip check for page + to 0947 boundary at which was at 0978 (removed) + Uade10 Line 0979 remove unnecessary branch label +01/06/88 Uade10 Line 0982 check if password file is too big +01/06/88 Uade10 Line 0986 + to 0988 flush the now unwanted segment + + Uade10 Line 1027 code optimised to check for end of PW file + to 1036 + +01/06/88 Uade10 Line 1068 check if the password file will be too big before + to 1074 trying to enlarge it + +MAPMAN +24/02/88 Uade10 Line 0106 check added for write protect + to 0108 + + Uade10 Line 0705 code optimisation. keep a copy of the map block + 0709 pointer on the stack. +01/07/88 Uade10 Line 0721 and use it instead of making the calculation again + to 0724 + + Uade10 Line 0864 Code optimised to save having to get the drive + Uade10 Line 0869 number twice + Uade10 Line 0879 + Uade10 Line 0873 Comments reinstated + Uade10 Line 0875 + Uade10 Line 0877 + +05/03/88 Uade10 Line 0882 some checks and then.. + to 0891 code moved to a new subroutine MPRESZ +05/03/88 Uade10 Line 0918 new subroutine MPRESZ from previous code + to 0944 + +MAPMAN UTILITIES +06/07/88 Uade11 Line 0072 exit if Sector zero not retrieved +05/03/88 Uade11 Line 0092 code optimised to use the new routine MPRESZ +01/07/88 Uade11 Line 0498 code replaced by subroutine SETMB +01/07/88 Uade11 Line 0700 ?? + Uade11 Line 0703 + Uade11 Line 0711 + Uade11 Line 0719 branch labels changed + to 0756 + +MAPMAN UTILITIES II +01/07/88 Uade12 Line 0285 code optimised + to 0286 + Uade12 Line 0605 code optimised + to 0617 + +DSCMAN +24/02/88 Uade14 Line 0826 routine Testdv, mainly to check for write protect + to 0843 + +COMMAND PROCESSOR +23/03/88 Uade16 Line 0032 implement check for DIRMAN CHECKPRES (function 13) + Uade16 Line 0287 DRPRES routine moved and now shared with CHECKPRES + Uade16 Line 0288 + Uade16 Line 0320 Routine for CHECKPRES and DRPRES + to 0367 + + Uade16 Line 0039 ?? + to 0042 + + Uade16 Line 0061 code optimised + 0062 + + Uade19 Line 0019 code optimised + Uade19 Line 0043 + Uade19 Line 0053 + to 0070 + Uade19 Line 0085 label removed. no longer required + +23/03/88 Uade19 Line 0473 Check mode of access for file + Uade19 Line 0495 Ensure 0 returned if ok + +23/03/88 Uade19 Line 0580 Code optimised. Moved to new subroutine RMSUBR shared + Uade19 Line 0581 by Putbytes and Getbytes + Uade19 Line 0587 label removed. no longer required + Uade19 Line 0692 code moved to new subroutine RMSUBR + to 0719 + Uade20 Line 0088 Bugfix. Y not initialised to 0 when checking for a tx + on tx + +22/03/88 Uade20 Line 0544 code optimised. + Uade20 Line 0547 because of code reuse ensure X is preserved + Uade20 Line 0551 + to 0553 + Uade20 Line 0548 + Uade20 Line 0571 + Uade20 Line 0572 + + Uade20 Line 1022 New errors. SYNERR "Syntax" + Uade20 Line 1024 NUMERR "Bad Number" + Uade20 Line 1067 repeated for Italian language + Uade20 Line 1069 + + +------------------------------------------------------------------------------- + +Version 1.25 +============ + +Date - 20 Jan 2018 + +Patch for Acorn Level3 File Server to allow the use of dates after 1996. This +also allows the use of dates after 1999. In keeping with the 'Short Acorn Era', +any two-digit year 00 to 80 is defined as being 2000 to 2080. Any two-digit +year from 81 to 99 is defined as being 1981 to 1999. + +Binary Files (* denotes the official ACORN released version) +============ + FS3-125 - Assembler options: DONGLE=1 (absent) + FS3-125d - Assembler options: DONGLE=0 (present) + + +Comments +======== +This is NOT the Acorn released v1.25. It is the Acorn released v1.24 with a +date fix patch applied. + +This code has been created using the v1.24 source code and the BASIC patch +source code by J.G.Harston. + +The code has been updated to include the fix as an assembly option in file +Uade01. +Y2KPAT * 0 ; no(=0) Apply the JGH Patch (=1) + +Changes (from v1.24) +==================== +Option for assembly with date fix (file Uade01) +The version number is now 1.25 (file Uade01) +Allows startup entry of years from 1981 to 2080 (file Uade04) +Status line date displays years after 1996 correctly (file Uade04) +Years after 1996 in *INFO reports are displayed correctly (file Uade0E) + + +------------------------------------------------------------------------------- + +Version 1.24 +============ + +Date - estimated between Jun 87 and Feb 1988. + +Comments for the language switch in Italian 18/2/87 predate v1.06 comments +but this change is not in that code - this is likely a typo for 18/2/88 when +other comments were made. Other dates in comments in this version +include 1/2/12/15/26 June 1987, 1/9/24 July 1987, 8/18/24 Feb 1988 and +23 March 1988. + +Binary Files (* denotes the official ACORN released version) +============ + FS3-124 - Assembler options DONGLE absent, Pseudo directory symbols No + FS3-124d - Assembler options DONGLE present, Pseudo directory symbols No + FS3-124p - Assembler options DONGLE absent, Pseudo directory symbols Yes +* FS3-124dp - Assembler options DONGLE present, Pseudo directory symbols Yes + + +Comments +======== +This code has been created using the v1.31 source code. Within that code there +are options for Lang English/Italian (added Feb 1987) and the Pseudo directory +symbols (%, &, @). Pseudo directory symbols were definately available in v1.24, +but as the comment for the switch option is dated 1988, it is possible that it +was hard coded and later modified to be an option at assembly time. The switch +has been left in. + +Changes (from v1.06) +==================== +Numerous changes were made. Not all are detailed here as there are so many. +Leap year calculation. +It is thought that sometime before this version compatibility has been added +for AUN. +Protection now set at &3F for a service system instead of &FF +Pseudo directory symbols (%, &, @) + + +------------------------------------------------------------------------------- + +Version 1.07 +============ + +Date - estimated about May 1987. Only one change comment dated 20/5/87 + +Binary Files (* denotes the official ACORN released version) +============ + FS3-107 - Assembler options: DONGLE=1 (dongle absent) + FS3-107y - Assembler options: DONGLE=1 (dongle absent) + Y2KPAT=1 (date fix) + +Comments +======== +The version widely distributed having the version number v1.07 is the same as +v1.06 except it is assembled for the RTC dongle being absent. The differences +are the version number and the serial number in the binary. + +The code has been updated to include the date fix as an assembly option in +file Uade01. +Y2KPAT * 0 ; no(=0) Apply the JGH Patch (=1) + +Changes (from v1.06) +==================== +HEADER FILE 1 + Uade01 Line 0057 Option for assembly with date fix (file Uade01) + Uade01 Line 0060 VERLB, version changed from 6 to 7 + +Allows startup entry of years from 1981 to 2080 (file Uade04) +Status line date displays years after 1996 correctly (file Uade04) +Years after 1996 in *INFO reports are displayed correctly (file Uade04) +Dates are displayed as dd/mm/yy instead of dd:mm:yy (file Uade0E) + + +------------------------------------------------------------------------------- + +Version 1.06 +============ + +Date - estimated about May 1987. Only one change comment dated 20/5/87 + +Binary Files (* denotes the official ACORN released version) +============ + FS3-106 - Assembler options: DONGLE=1 (absent) + This has also been seen as a binary with version 1.07 +* FS3-106d - Assembler options: DONGLE=0 (present) + +Comments +======== +Some of these changes may have been made in v1.05, but there is no binary +available to investigate. This is the original and unchanged source code. + +Changes (from v1.04) +==================== + +HEADER FILE 1 + Uade01 Line 0060 VERLB, version changed from 4 to 6 + +MAPMAN + Uade10 Line 0300-0301 removed JSR FNDMAP, BNE MPCHJX + when changing the size of a chain on disc + Uade10 Line 0322 BCS branch removed + + +MAPMAN UTILS 2 +20/05/87 Uade12 Line 1086 bugfix: Map block not being marked as written + after blocks have been deleted + Uade12 Line 1054 moved CBNT code block from line 1129 to 1056 + inline with other code + Uade13 Line 0481 bugfix: in routine MPGTSZ - find size of object + Uade13 Line 0567 bugfix: PLA PLA removed from routine + + +------------------------------------------------------------------------------- + +Version 1.04 +============ + +Date - estimated sometime after June 1986. no dated comments after June 1986 + +Binary Files (* denotes the official ACORN released version) +============ + FS3-104 - Assembler options: DONGLE=1 (absent) +* FS3-104d - Assembler options: DONGLE=0 (present) + +Comments +======== + +Changes (from v1.03) +==================== + +HEADER FILE 1 + Uade01 Line 0060 VERLB, version changed from 3 to 4 + +MAPMAN + Uade10 Line 0300 JSR FNDMAP added to check before changing size of a chain + on disc + Uade10 Line 0322 BCS branch added + +MAP BLOCK AND BIT MAP MANAGEMENT + MBBMCM Line 0152 bugfix: Update the cache block descriptor after + getting a block to store + +DSCMAN + Uade14 Line 0754 changed disc error reporting text + 0754 " : Disc Error. " to "Disc Error N0. " + Uade14 Line 0759 " At " to " At Disc Address " + + +------------------------------------------------------------------------------- + +Version 1.03 +============ + +Date - estimated about June 1986. Last comment was 5/6/86 + +Binary Files (* denotes the official ACORN released version) +============ + FS3-103 - Assembler options: DONGLE=1 (absent) +* FS3-103d - Assembler options: DONGLE=0 (present) + +Comments +======== +A reference is made in file STRMAN to code from v1.02. + +Changes (from v1.01) +==================== + +HEADER FILE 1 + Uade01 Line 0060 VERLB, version changed from 1 to 3 + +STRMAN + Uade0B Line 0246 bugfix: introduced at v1.02. When removing objects + from the disc, age the entries on ensure and remove + them on destroy from cache + +DSCMAN +05/06/86 Uade14 Line 0743-0789 Report disk errors to screen + + +------------------------------------------------------------------------------- + +Version 1.01 +============ + +Date - estimated about Jan 1986 + +Binary Files (* denotes the official ACORN released version) +============ + FS3-101 - Assembler options: DONGLE=1 (absent) +* FS3-101d - Assembler options: DONGLE=0 (present) + +Comments +======== +The changes in the source code include all changes since the pre-release +version and may have occurred in any of the versions inbetween e.g. other +pre-release versions and 1.00 + +Changes (from v0.90 Pre-Release IV.05) +====================================== + +HEADER FILE 1 + Uade01 Line 0059 VERLA and VERLB, version changed from 90 to 01 + +HEADER FILE 2 + Uade02 Line 0016 User ID size expanded from MAXUNM to MAXUNM+1 +15/12/85 Uade02 Line 0209 Number of bit map cache blocks changed from 5 to 15 + Uade02 Line 0286 Check for free storage with dongle absent changed from + &8A00 to &8B00 and present &8B00 to &8C00 + +UTILIITES + Uade03 Line 0021 removed code start vector from binary + Uade03 Line 0029 Changes to major version number and version handling +21/10/85 Uade03 Line 0031 File server station number added to screen display + +File Server Initialisation +17/01/86 Uade04 Line 0262 CHKDTE Code that did nothing removed + +USRMAN +14/01/86 Uade06 Line 0630-0650 bugfix: reporting privileged users only to a + PRIV request + Uade06 Line 0679 JSR INCGPT re-instated to update the pointer with the + termination + +RNDMAN + Rman01 Line 0139 2 lines of redundant code removed + Rman02 Line 0472 unnecessary code removed +15/12/85 Rman05 Line 0045 Useless code updated + Rman05 Line 0195 JSR STRMAN changed to JMP STRMAN and unnecessary + RTS instruction removed + +STRMAN +03/12/85 Uade0B Line 0246 bugfix: age and ensure objects when removing them from + disc + +DIRMAN UTILITIES + Uade0D Line 0818 bugfix: Owner Locked bit not preserved on file access + +DIRMAN UTILITIES 2 + Uade0E Line 1071 JSR STRMAN changed to JMP STRMAN and unnecessary + RTS instruction removed + +AUTMAN + Uade0F Line 0071 bugfix: clear cache before password file operations + Uade0F Line 0281 bugfix: clear cache before password file operations + Uade0F Line 0347 bugfix: clear cache before password file operations + Uade0F Line 0382 bugfix: clear cache before password file operations + Uade0F Line 0458 bugfix: clear cache before password file operations + Uade0F Line 0463 No need to ensure PW file when setting flag + Uade0F Line 0546 ensure before flushing + Uade0F Line 0556 bugfix: clear cache before password file operations + Uade0F Line 0605 ensure before flushing + Uade0F Line 1035 routine APWIPE to clear cache + +24/10/85 Uade0F Line 0749 bugfix: would only check 1 terminator when checking + passwords +24/10/85 Uade0F Line 0776-0780 bugfix: checking for "." character + +MAPMAN UTILS 2 +27/01/86 Uade12 Line 0477 bugfix: Cylinder Pointer low byte not being + incremented + +MAP BLOCK AND BIT MAP MANAGEMENT +17/01/86 MBBMCM Line 0127-0154 Error not preserved when block retrieve fails + MBBMCM Line 0259 bugfix: + 0296-0300 + +DSCMAN + Uade14 Line 0096 ensure debug code is within the debug directive + Uade14 Line 0147 ensure debug code is within the debug directive + Uade14 Line 0577 return to start drive removed as unnecessary + +COMMAND PROCESSOR + Uade15 Line 0200 bugfix: wasn't allowing final function code + Uade15 Line 0281 Added CPWHO function to return client userid +14/01/86 Uade17 Line 1057 routine USERS Store user priviledge in the stack + Uade17 Line 1164 Change end of version number code from 13 to 6 + Uade18 Line 0033-0036 bugfix: in RENAME routine + Uade18 Line 0151-0158 + Uade18 Line 0389 bugfix: in FIND routine + Uade18 Line 0391-0397 + Uade18 Line 0423-0431 + Uade18 Line 0478-0485 + Uade19 Line 0112 change JMP COMRTS to JMP CPRDAX for PUTBYT routine + Uade19 Line 0187 change JMP ERROR to JMP CPRDAX + Uade19 Line 0452 bugfix: PUTBYTES routine use a 32 bit number to hold + Uade19 Line 0460 the amount transferred +26/02/85 Uade19 Line 0680 bugfix: GETBYTES routine use a 32 bit number to hold + Uade19 Line 0681 the amount transferred +19/03/85 Uade19 Line 0722-0749 CPWHO routine allowing an application to + determine the userid under which it is logged-on + + +------------------------------------------------------------------------------- + +Version 0.92 +============ + +Date - Dec 1998 + +Binary Files (* denotes the official ACORN released version) +============ + FS3-092 - Dongle absent + +Comments +======== +J.G.Harston released a fix in Dec 1998 for v0.90 to allow the use of dates +after 1996. This patched the above mentioned v0.90 Pre-Release IV.05 or +"BARSON COMPUTERS" binary. + +The code has been updated to include the fix as an assembly option in file +Uade01. +Y2KPAT * 0 ; no(=0) Apply the JGH Patch (=1) + +Changes +======= +Option for assembly with date fix (file Uade01) +The version number is now 0.92 (file Uade01) +Allows startup entry of years from 1981 to 2080 (file Uade04) +Status line date displays years after 1996 correctly (file Uade04) +Years after 1996 in *INFO reports are displayed correctly (file Uade04) +Dates are displayed as dd/mm/yy instead of dd:mm:yy (file Uade0E) + + +------------------------------------------------------------------------------- + +Version 0.90 Pre-Release IV.05 +============================== + +Date - estimated. May-Oct 1985 (possibly 4 May from the pre-release version). + Two comments are dated after that date but with code included in the + binary. The comments could have been added at a later date to already + existing code or versions were kept the same but the code was different. + That would date the code to Oct 1985. There are changes labelled + 15/12/85 that are not in this binary. The assembler directive file FSASM + has the comment updated by Glenn 8/5/85. + +Binary Files (* denotes the official ACORN released version) +============ +* FS3-090 - Dongle absent + FS3-090b - Dongle absent. BARSON COMPUTERS variant + +Comments +======== +There are two Trace debug pieces of code in the final binary although the +DEBUG directive is set to 0 (file Uade14) and the binary performs a simple RTS +when it is called. + +There is also a version of the same code with the banner displaying BARSON +COMPUTERS. Barson were one of Acorn's distributors in Australia and it looks +like the branding was probably done by hex editing the binary directly rather +than altering the code. + +Changes +======= +No previous version to compare to. diff --git a/Level3/SRC/L3/Mbbmcm b/Level3/SRC/L3/Mbbmcm new file mode 100644 index 0000000..4e8b90e --- /dev/null +++ b/Level3/SRC/L3/Mbbmcm @@ -0,0 +1,845 @@ + OPT MBBMCM ;> Mbbmcm + TTL File server file MBBMCM + +; +; MAP BLOCK AND BIT MAP MANAGEMENT +; +; +; INITIALISE THE MAP BLOCKS +; +; ALLOCATES CONTROL BLOCKS FOR THE BIT MAP CACHE +; AND THE MAP BLOCK CACHE +; +; USES MPTMPE,MPTMPD +; +INBKMN ROUT + LDYIM :LSB:SZMBCB + LDXIM :MSB:SZMBCB + JSR GETVEC ;GET SPACE FOR MAP BLOCK CHACHE DESCRIPTORS + STY MBCBPT ;SAVE POINTER TO AREA + STX MBCBPT+1 + LDYIM :LSB:SZBMCB + LDXIM :MSB:SZBMCB + JSR GETVEC ;GET SPACE FOR BIT MAP CACHE DESCRIPTORS + STY BMCBPT + STX BMCBPT+1 ;SAVE THIS POINTER + LDAIM :LSB:SZBMAR ;SIZE OF MEMORY AREA FOR THESE BLOCKS + STA MPTMPE + LDAIM :MSB:SZBMAR + STA MPTMPE+1 + JSR SETBM ;**25/12/86** + JSR SETCBS ;INITIALISE CONTROL BLOCKS + LDAIM :LSB:SZMBAR ;SIZE OF MAP BLOCK AREA + STA MPTMPE + LDAIM :MSB:SZMBAR + STA MPTMPE+1 + JSR SETMB + JSR SETCBS +00 RTS +; +; SETUP MAP BLOCK OR BIT MAP CONTROL BLOCKS +; +; ON ENTRY +; GNCBPT POINTS TO CONTROL BLOCK +; MPTMPE HOLDS SIZE OF DISC BLOCK CACHE +; NCBDB HOLDS NUMBER OF DISC BLOCK ENTRIES +; +SETCBS LDY MPTMPE + LDX MPTMPE+1 ;GET SIZE OF CACHE + JSR GETVEC ;GET THE SPACE + STY MPTMPE + STX MPTMPE+1 ; SAVE THE AREA + LDX NCBDB ;GET NUMBER OF ENTRIES +10 LDYIM CAFLG + LDAIM 0 + STAIY GNCBPT ;ZERO ALL FLAGS + LDYIM CBSA + LDA MPTMPE + STAIY GNCBPT ;SAVE ADDRESS OF STORE + INY + LDA MPTMPE+1 + STAIY GNCBPT + DEX + BEQ #00 ; FINISH + CLC + LDA MPTMPE ;Increment to next block of store + ADCIM :LSB:BTINBK + STA MPTMPE + LDA MPTMPE+1 + ADCIM :MSB:BTINBK + STA MPTMPE+1 + JSR ADGNCB ;POINT TO NEXT CONTROL BLOCK + JMP #10 ;TRY NEXT + +; +; GET BLOCK TO STORE +; +; ON ENTRY +; CBSIN HOLDS THE DISC ADDRESS +; GNCBPT POINTS TO RELEVANT CACHE DESCRIPTORS +; NCBDB HOLDS NUMBER OF CONTROL BLOCK ENTRIES +; MPDRVE HOLDS DRIVE NUMBER +; +; ON EXIT +; CBSTA HOLDS STORE ADDRESS OF BLOCK +; +GTBTS ROUT + LDA GNCBPT ;SAVE POINTER TO CONTROL BLOCKS + PHA + LDA GNCBPT+1 + PHA + JSR FNDBLK + BCC #30 +10 LDYIM CBSA ;IN STORE SO JUST GET ADDRESS + LDAIY GNCBPT + STA CBSTA + INY + LDAIY GNCBPT + STA CBSTA+1 + LDYIM CBAGE + LDAIM 0 + STAIY GNCBPT + PLA ;RESTORE POINTER + STA GNCBPT+1 + PLA + STA GNCBPT + JSR CAAGE ;AGE ALL ENTRIES + LDAIM 0 + RTS + +30 PLA ;NEED TO START AT BEGINNING AGAIN + TAX + PLA + STA GNCBPT + PHA + STX GNCBPT+1 + TXA + PHA ;KEEP POINTER IN CORRECT ORDER ON STACK + JSR GETFR ;GET A FREE POSITION + BNE #50 ;IF FAILED + LDYIM CBDA + LDA CBSIN + STAIY GNCBPT + INY + LDA CBSIN+1 + STAIY GNCBPT + INY + LDA CBSIN+2 + STAIY GNCBPT + LDYIM CBDR + LDA MPDRVE + STAIY GNCBPT + JSR RDBLK ;READ IN THE NEW BLOCK + BEQ #40 + LDAIM 2 ;READ ERROR + ORA ERRTYP + STA ERRTYP +40 LDYIM CAFLG + LDAIY GNCBPT + ORAIM 1 ;FLAG IN STORE + STAIY GNCBPT + BNE #10 + +50 TAX ; ** 13/12/85 ** + PLA + STA GNCBPT+1 + PLA ;Balance stack + STA GNCBPT + TXA + RTS + +; +; FIND A SPECIFIED DISC BLOCK IN STORE +; +; CBSIN HOLDS DISC ADDRESS +; MPDRVE HOLDS DRIVE NUMBER +; +; C SET IF FOUND +FNDBLK ROUT + LDA GNCBPT + PHA + LDA GNCBPT+1 + PHA + LDX NCBDB ;CHECK IF ALREADY IN STORE +10 LDYIM CBDA + LDAIY GNCBPT + CMP CBSIN + BNE #20 + INY + LDAIY GNCBPT + CMP CBSIN+1 + BNE #20 + INY + LDAIY GNCBPT + CMP CBSIN+2 + BNE #20 + LDYIM CBDR + LDAIY GNCBPT + CMP MPDRVE + BEQ #30 +20 DEX + BEQ #40 + JSR ADGNCB + JMP #10 + +30 LDYIM CAFLG ;CHECK IF IN STORE + LDAIY GNCBPT + ANDIM 1 + BEQ #20 + PLA + PLA + SEC + RTS + +40 PLA + STA GNCBPT+1 + PLA + STA GNCBPT + CLC + RTS +; +; READ/WRITE A BLOCK INTO STORE +; +; ON ENTRY +; GNCBPT POINTS TO ENTRY IN CACHE DESCRIPTOR +; + [ WINCH=0 +RDBLK ROUT + LDAIM &08 + BNE #00 +WRBLK LDAIM &0A +00 STA SAVCOM + LDYIM CBDR + LDAIY GNCBPT + STA DRIVNO + LDYIM CBDA + LDAIY GNCBPT + STA RBDA ; SAVE DISC ADDRESS + INY + LDAIY GNCBPT + STA RBDA+1 + INY + LDAIY GNCBPT + STA RBDA+2 +10 LDYIM MPSECS + LDA RBDA + CMPIY MAPPTR + INY + LDA RBDA+1 + SBCIY MAPPTR + INY + LDA RBDA+2 + SBCIY MAPPTR + BCC #20 + LDYIM MPADFT + CLC + LDA DRIVNO + ADCIY MAPPTR + STA DRIVNO + SEC + LDYIM MPSECS + LDA RBDA + SBCIY MAPPTR + STA RBDA + INY + LDA RBDA+1 + SBCIY MAPPTR + STA RBDA+1 + INY + LDA RBDA+2 + SBCIY MAPPTR + STA RBDA+2 + JMP #10 + +20 LDYIM CBSA + LDAIY GNCBPT + STA DCSTAD + INY + LDAIY GNCBPT + STA DCSTAD+1 + LDA DSCCB+TRADD+2 + PHA + LDAIM 0 + STA DSCCB+TRADD+2 + STA DSCCB+TRADD+3 + LDYIM CAFLG ;MARK NOT WRITTEN + LDAIY GNCBPT + ANDIM 3 + STAIY GNCBPT + LDA RBDA + ORA RBDA+1 + ORA RBDA+2 ;IF SECTOR ZERO CALCULATE CHECKSUM + BNE #40 + LDA GNCBPT + PHA + LDA GNCBPT+1 + PHA + LDA DCSTAD + STA GNCBPT + LDA DCSTAD+1 + STA GNCBPT+1 + LDYIM &FF + TYA + STAIY GNCBPT + LDAIM 0 + CLC +30 ADCIY GNCBPT + DEY + BNE #30 + ADCIY GNCBPT + DEY + STAIY GNCBPT + PLA + STA GNCBPT+1 + PLA + STA GNCBPT +40 JSR XFER ;Transfer block + TAX + PLA + STA DSCCB+TRADD+2 + STA DSCCB+TRADD+3 + TXA + RTS + | +RDBLK ROUT + LDAIM &53 ;VALUE FOR READ + BNE #10 + +WRBLK LDAIM &4B ;VALUE FOR WRITE +10 STA SAVCOM ;SAVE VALUE + LDYIM CBDR + LDAIY GNCBPT ;GET DRIVE NUMBER + STA DRIVNO + LDAIM 0 + STA CTRACK ;PREPARE TO CALCULATE TRACK AND SECTOR + STA CSECTR + LDYIM CBDA + LDAIY GNCBPT + STA RBDA ; SAVE DISC ADDRESS + INY + LDAIY GNCBPT + STA RBDA+1 + INY + LDAIY GNCBPT + STA RBDA+2 +20 LDYIM MPSECS + LDA RBDA + CMPIY MAPPTR + INY + LDA RBDA+1 + SBCIY MAPPTR + INY + LDA RBDA+2 + SBCIY MAPPTR + BCC #30 + LDYIM MPADFT + CLC + LDA DRIVNO + ADCIY MAPPTR + STA DRIVNO + SEC + LDYIM MPSECS + LDA RBDA + SBCIY MAPPTR + STA RBDA + INY + LDA RBDA+1 + SBCIY MAPPTR + STA RBDA+1 + INY + LDA RBDA+2 + SBCIY MAPPTR + STA RBDA+2 + JMP #20 + +30 LDYIM MPSPCY + LDA RBDA + CMPIY MAPPTR ; CHECK IF END REACHED + INY + LDA RBDA+1 + SBCIY MAPPTR + LDA RBDA+2 + SBCIM 0 + BCC #40 ;BRANCH WHEN CORRECT PLACE + INC CTRACK + LDYIM MPSPCY + SEC + LDA RBDA + SBCIY MAPPTR ; KEEP DECREMENTING + STA RBDA + INY + LDA RBDA+1 + SBCIY MAPPTR + STA RBDA+1 + LDA RBDA+2 + SBCIM 0 + STA RBDA+2 + JMP #30 + +40 LDA RBDA + STA CSECTR ; SAVE SECTOR + LDYIM CBSA + LDAIY GNCBPT + STA DCSTAD + INY + LDAIY GNCBPT + STA DCSTAD+1 + LDAIM 0 + STA DSCCB+TRADD+2 + STA DSCCB+TRADD+3 + LDYIM CAFLG ;MARK NOT WRITTEN + LDAIY GNCBPT + ANDIM 3 + STAIY GNCBPT + JMP XFER ;TRANSFER THE BLOCK + ] + + +; +; AGE ALL CHAIN ENTRIES +; +; ON ENTRY +; GNCBPT POINTS TO RELEVANT CACHE DESCRIPTOR +; NCBDB HOLDS NUMBER OF ENTRIES +; +CAAGE ROUT + LDA GNCBPT + PHA ; SAVE THE POINTER + LDA GNCBPT+1 + PHA + LDX NCBDB +10 LDYIM CBAGE ; GET CURRENT AGE + LDAIY GNCBPT + ADCIM 1 ;INCREMENT + STAIY GNCBPT + DEX + BEQ #20 ;CHECK FOR END + JSR ADGNCB + JMP #10 ;LOOK AT NEXT + +20 PLA ;GET POINTER BACK + STA GNCBPT+1 + PLA + STA GNCBPT + RTS + +; GET A FREE SPACE FOR A BLOCK +; +; ON ENTRY +; GNCBPT POINTS TO START OF CONTROL BLOCK +; NCBDB HOLDS NUMBER OF CONTROL BLOCK ENTRIES +; +; ON EXIT +; GNCBPT POINTS TO VACANT ENTRY +; +; USES CBSTA,CBTPPT +; +GETFR ROUT + LDA GNCBPT + PHA + LDA GNCBPT+1 + PHA + LDX NCBDB + LDAIM &FF + STA CBSTA ;CURRENT YOUNGEST + LDAIM 0 + STA CBTPPT ;CURRENT POINTER TO YOUNGEST + STA CBTPPT+1 +10 LDYIM CAFLG + LDAIY GNCBPT + ANDIM 4 ;check if written + BEQ #20 + LDAIY GNCBPT + ANDIM 2 ;check if locked + BNE #20 + LDYIM CBAGE + LDAIY GNCBPT + CMP CBSTA + BCS #20 + STA CBSTA + LDA GNCBPT + STA CBTPPT + LDA GNCBPT+1 + STA CBTPPT+1 +20 JSR ADGNCB + DEX + BNE #10 + LDA CBTPPT + STA GNCBPT + ORA CBTPPT+1 + BEQ #30 + LDA CBTPPT+1 + STA GNCBPT+1 + JSR WRBLK + BEQ #30 + LDAIM 1 + ORA ERRTYP + STA ERRTYP +30 PLA + STA GNCBPT+1 + PLA + STA GNCBPT + LDX NCBDB ;NUMBER OF ENTRIES + LDAIM 0 + STA CBSTA ;CURRENT OLDEST + STA CBTPPT ;CURRENT POINTER TO OLDEST + STA CBTPPT+1 +40 LDYIM CAFLG + LDAIY GNCBPT + RORA ;Test bit 0 + BCS #50 + LDXIM 1 ;FREE AREA SO FOOL INTO THINKING ITS END + BNE #60 + +50 RORA + BCS #70 + LDYIM CBAGE + LDAIY GNCBPT + CMP CBSTA + BCC #70 + STA CBSTA +60 LDA GNCBPT + STA CBTPPT + LDA GNCBPT+1 + STA CBTPPT+1 +70 DEX + BEQ #80 + JSR ADGNCB ;LOOK AT NEXT ENTRY + JMP #40 + +80 LDA CBTPPT ;CHECK IF ANYTHING FOUND + ORA CBTPPT+1 + BEQ #95 + LDA CBTPPT ;SAVE ADDRESS + STA GNCBPT + LDA CBTPPT+1 + STA GNCBPT+1 + LDYIM CAFLG ;CHECK IF ALLOCATED + LDAIY GNCBPT + RORA + BCC #90 + RORA + RORA ;CHECK IF IT HAS BEEN WRITTEN TO + BCC #90 + JSR WRBLK + BEQ #90 + LDAIM 1 + ORA ERRTYP + STA ERRTYP +90 LDAIM 0 + LDYIM CAFLG + STAIY GNCBPT + RTS + +95 LDAIM MPERRM ;FLAG ERROR + RTS +; +; SET THE WRITTEN BIT IN THE GIVEN CACHE DESCRIPTOR +; THE STORE ADDRESS IS GIVEN +; +; ON ENTRY +; GNCBPT POINTS TO RELEVANT CACHE DESCRIPTORS +; NCBDB HOLDS NUMBER OF DESCRIPTORS +; CBSTA HOLDS STORE ADDRESS OF BLOCK +; +; ON EXIT +; Z NON-ZERO IF FAILED +; +; +CASTWB ROUT + LDX NCBDB ;GET NUMBER OF DESCRIPTORS +10 LDYIM CBSA ;CHECK ADDRESS + LDAIY GNCBPT + CMP CBSTA + BNE #20 ;GO TO CHECK NEXT + INY + LDAIY GNCBPT + CMP CBSTA+1 + BEQ #30 +20 DEX ;CHECK FOR END + BEQ #40 + JSR ADGNCB + JMP #10 + +30 LDYIM CAFLG + LDAIY GNCBPT ;SET WRITTEN BIT + ORAIM 4 ;WRITTEN BIT + STAIY GNCBPT + LDYIM CBAGE + LDAIM 0 + STAIY GNCBPT + RTS ;Exit A=0, success + +40 LDAIM 1 + RTS ;NOT FOUND +; +; ENSURE ALL CACHED BLOCKS +; +; ON ENTRY +; GNCBPT POINTS TO CACHE DESCRIPTORS +; NCBDB HOLDS NUMBER OF DECRIPTORS +; +ENSBKS ROUT + LDX NCBDB ;NUMBER +10 LDYIM CAFLG + LDAIY GNCBPT + ANDIM 4 ;WRITTEN FLAG + BEQ #40 ;DON'T WRITE OUT IF NOT WRITTEN + TXA + PHA + LDYIM CBSA + LDAIY GNCBPT + STA GENPTR + INY + LDAIY GNCBPT + STA GENPTR+1 + LDYIM 16 +20 LDAIY GENPTR ;SAVE SOME OF BLOCK + STAAY DATARA + DEY + BPL #20 + JSR WRBLK + BEQ #30 + LDAIM 1 + ORA ERRTYP + STA ERRTYP + BNE #35 ;**26/2/87** Return now if any error + +30 JSR CHECKB +35 PLA + TAX +40 JSR ADGNCB + DEX + BNE #10 + RTS +; +; CHECK BLOCK JUST WRITTEN FOR VALIDITY +; +CHECKB ROUT + JSR RDBLK + BNE #30 + LDYIM CBSA + LDAIY GNCBPT + STA GENPTR + INY + LDAIY GNCBPT + STA GENPTR+1 + LDYIM 16 +10 LDAIY GENPTR + CMPAY DATARA + BNE #20 + DEY + BPL #10 + RTS + +20 LDAIM &F8 + JSR INTERR +30 CLC + RTS +; +; MAKE GNCBPT POINT TO NEXT ENTRY +; +ADGNCB ROUT + CLC + LDA GNCBPT + ADCIM CBSZ + STA GNCBPT + BCC #10 + INC GNCBPT+1 +10 RTS +; +; MARK WRITTEN BIT IN SPECIFIED CACHE DESCRIPTOR +; +; ON ENTRY +; CBSTA POINTS TO ADDRESS IN MEMORY +; +MBMWT ROUT + LDA BMCBPT ;GET POINTERS TO BIT MAP + STA GNCBPT + LDA BMCBPT+1 + STA GNCBPT+1 + LDAIM NOBTMP + STA NCBDB + JSR CASTWB + BEQ #10 + LDAIM &F5 + JSR INTERR +10 RTS +; +; MARK WRITTEN BIT IN SPECIFIED MAP BLOCK +; +; ON ENTRY +; CBSTA POINTS TO MAP BLOCK +; +; +MMBWT ROUT + LDA CBSTA + STA GNCBPT + LDA CBSTA+1 + STA GNCBPT+1 + LDYIM MBSQNO + CLC + LDAIY GNCBPT + ADCIM 1 + STAIY GNCBPT + CLC + LDA GNCBPT + ADCIM :LSB:LSTSQ + STA GNCBPT + LDA GNCBPT+1 + ADCIM :MSB:LSTSQ + STA GNCBPT+1 + LDYIM 0 + CLC + LDAIY GNCBPT + ADCIM 1 + STAIY GNCBPT + JSR SETMB + JMP CASTWB + +; +; ENSURE BIT MAPS +; +ENSBM ROUT + LDA BMCBPT + STA GNCBPT + LDA BMCBPT+1 + STA GNCBPT+1 + LDAIM NOBTMP + STA NCBDB + JMP ENSBKS + +; +; ENSURE MAP BLOCKS +; +ENSMB ROUT + JSR SETMB + JMP ENSBKS + +; +; FIND THE SPECIFIED MAP BLOCK +; +; CBSIN HOLDS THE SIN +; +; C SET IF FOUND +; +FNDMB ROUT + LDA MBCBPT + STA GNCBPT + LDA MBCBPT+1 + STA GNCBPT+1 + LDAIM NOMPBK + STA NCBDB + JMP FNDBLK + +; +; LOCK IN STORE +; +; BLOCK WHOSE STORE ADDRESS IS IN CBSTA +; GNCBPT POINTS TO CACHE BLOCKS +; NCBDB NUMBER OF DESCRIPTORS +; +; NON-ZERO IF NOT FOUND +; +LOCKIS ROUT + LDX NCBDB +10 LDYIM CBSA + LDAIY GNCBPT + CMP CBSTA + BNE #20 + INY + LDAIY GNCBPT + CMP CBSTA+1 + BEQ #30 +20 JSR ADGNCB + DEX + BNE #10 + LDAIM 1 + RTS + +30 LDYIM CAFLG + LDAIY GNCBPT + ORAIM 2 ;LOCK IN STORE + STAIY GNCBPT + LDAIM 0 + RTS +; +; UNLOCK ALL BLOCKS +; +; NCBDB HOLDS NUMBER OF BLOCKS +; GNCBPT POINTS TO LIST +; +UNLKBS ROUT + LDX NCBDB + LDYIM CAFLG +10 LDAIY GNCBPT + ANDIM &FD ;UNLOCK BLOCK + STAIY GNCBPT + JSR ADGNCB + DEX + BNE #10 + RTS +; +; +; MARK MAP BLOCK LOCKED +; +; MPMBPT HOLDS STORE ADDRESS OF MAP BLOCK +; NON-ZERO IF FAILED +; +MMBLKD ROUT + JSR SETMB + LDA MPMBPT + STA CBSTA + LDA MPMBPT+1 + STA CBSTA+1 + JMP LOCKIS +; +; MARK BIT MAP LOCKED +; +; MPscor POINTS TO BIT MAP +; +; +MBMLKD ROUT + JSR SETBM + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JMP LOCKIS +; +; UNLOCK ALL MAP BLOCKS +; +ULMB ROUT + JSR SETMB + JMP UNLKBS +; +; UNLOCK ALL BIT MAPS +; +ULBM ROUT + JSR SETBM + JMP UNLKBS +; +; SET VALUES FOR BIT MAP +; +SETBM ROUT + LDA BMCBPT + STA GNCBPT + LDA BMCBPT+1 + STA GNCBPT+1 + LDAIM NOBTMP + STA NCBDB + RTS +; +; SET VALUES FOR MAP BLOCKS +; +SETMB ROUT + LDA MBCBPT + STA GNCBPT + LDA MBCBPT+1 + STA GNCBPT+1 + LDAIM NOMPBK + STA NCBDB + RTS + + + LNK UADE14 diff --git a/Level3/SRC/L3/Rman01 b/Level3/SRC/L3/Rman01 new file mode 100644 index 0000000..f5cf789 --- /dev/null +++ b/Level3/SRC/L3/Rman01 @@ -0,0 +1,661 @@ + OPT RMAN01 ; FILE > Rman01 + TTL File server file RMAN01 + +RMNORG + + ORG RMNORG + +;Set up ORG address so second pass gets +;addresses right when doing 2nd pass only + +;Second pass also needs source and object +;drives correctly set. + + +;********************************* +;* R N D M A N * +;********************************* + + + +;RNDMAN: THE RANDOM ACCESS MANAGER IS RESPONSIBLE +;FOR MAINTAINING A LIST OF OPENED OBJECTS +;(HANDTB) & FOR KEEPING VARIOUS DETAILS +;ABOUT OPENED FILES (RANDTB). +;RNDMAN PROVIDES THE FOLLOWING FUNCTIONS:- + +;1) OPEN OBJECT (GIVE HANDLE) +;2) INFO (INDICATE WHETHER OPEN) +;3) CLOSE OBJECT +;4) RESTART +;5) CREATE A HANDLE FOR AN OBJECT WITH SPECD HANDLE +;6) DELETE ALL HANDLES FOR A GIVEN M/C +;7) READ BYTE FROM FILE +;8) WRITE BYTE TO FILE +;9) GETBYTES +;10) PUTBYTES +;11) Read args of open file +;12) Set args of open file +;13) Close all files for machine +;14) Set up for PUTBYTES/GETBYTES calls + + + +;THE HANDTB CONTAINS THE FOLLOWING +;INFO:- +;0) HANDLE +;1) MC/NO +;2) TYPE AND ACCESS +;3) DISC NUMBER +;4) SIN +;5) MODE - MULTIPLE READER/SINGLE WRITER +;6) RANDTB OFFSET + + + +;********* MAIN ROUTINE *********** + + + +RNDMAN ROUT + LDXIM &F ;RNDMAN HAS 15 ENTRY POINTS + LDAIM MODRND ;A:=NAME OF THIS MODULE + JSR ENTRY + LDAAX RDRTNS + STA RDJUMP+1 + LDAAX RDRTNS+1 + STA RDJUMP+2 + LDAIM &F + JSR SETFS ;SET FRAME SIZE +RDJUMP JMP RDJUMP +RDRTNS + & RDOPEN ;1 => OPEN OBJECT (ISSUE A HANDLE) + & RDINFO ;2 => INFO (INDICATE WHETHER OBJECT IS OPEN) + & RDCLOS ;3 => CLOSE OBJECT (INVALIDATE HANDLE) + & RDREST ;4 => RESTART + & RDCOPY ;5 => GENERATE ANOTHER HANDLE FOR AN OBJECT + & RDCLAL ;6 => DELETE ALL HANDLES FOR A USER + & RDRDCH ;7 => READCH + & RDWRCH ;8 => WRITECH + & RDGBTS ;9 => GETBYTES FROM FILE + & RDPBTS ;10 => PUTBYTES TO FILE + & RDRDAR ;11 => Read args of file + & RDSTAR ;12 => Set args of file + & RDCLAF ;13 => Close all files for machine + & RDSUBO ;14 => Set up for bytes operation + & RDEOF ;15 => Read "end of file" status + +RDEXIT JMP PREXIT + + + +;************ RDOPEN ************ + + +;RDOPEN: OPEN AN OBJECT & RETURN A HANDLE FOR IT. + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD = MODE(HOW OBJECT SHOULD BE OPENED) +;ARGE = TYPE & ACCESS ALLOWED TO OBJECT +;ARGF-G PTR TO OBJECT DETAILS + +;NOTE:- ARGD (MODE) +;BIT 0 => READ ACCESS NEEDED +;BIT 1 => WRITE ACCESS NEEDED +;BIT 7 => FILE JUST CREATED +;RNDMAN INFORCES MULTIPLE READER - SINGLE WRITER +;INTERLOCKS. + +;EXIT : ARGA = RC +;ARGB = HANDLE + +;FUNCTION: MAKE HANDTB ENTRY +;IF TYPE OF OBJECT = TYPFIL +;THEN MAKE NEW RANDTB ENTRY +;FI + + +RDOPEN ROUT + JSR INITRD ;INITIALISE MCNUMB,&GETPTR:=USERINFO,RNDPTR + +;SEE IF THIS MACHINE CAN OPEN ANOTHER FILE +;AND SEE WHETHER THERE IS ANY ROOM IN THE HANDTB + + JSR GETHND ;HNDPTR:=PTR TO A FREE HANDTB ENTRY + BNE #60 + LDYIM ARGE + LDAIY ARGPTR ;TYPE & ACCESS + ANDIM TYPDIR + BNE #50 + +;ITS A FILE SO SEE IF THERE IS ROOM IN RANDTB + +;The object is a file: must check that it can be opened +;for the requested access. (A file may be held open by +;a single writer, or by multiple readers). +;If it may be opened, then find a slot in RANDTB and +;fill it in. A pointer to the entry in RANDTB is +;put in HANDTB (stored in 2 bytes). + + JSR RDCKAC ;Check access allowed (corrupts HNDPTR) + BNE #60 ;not ok + JSR GETHND ;HNDPTR := free HANDTB entry + BNE #60 ;Didn't get one + JSR GETRND ;RTEPTR := free RANDTB entry + BNE #60 ;not got one + + LDA RTEPTR ;Store RANDTB entry ptr in HANDTB entry + LDYIM HTRPTR + STAIY HNDPTR + INY + LDA RTEPTR+1 + STAIY HNDPTR + +;Fill in new RANDTB entry (currently all zero) + + LDAIM &80 ;"In use" flag + seq num zero + LDYIM RTINUS + STAIY RTEPTR ;Mark entry "in use" + +;Current and old sequential file pointers +;already set to zero. +;High water mark and size both set from +;file size in object details. + + LDAIM RTFSZE + JSR #80 ;Little block move routine + +;High water mark used only if the object is open for +;update. If the file is new, then leave zero, otherwise +;set to file size. + + LDYIM ARGD ;Get mode byte + LDAIY ARGPTR + ANDIM FILEJC ;Test file just created + BNE #40 ;Jump if new file + +;File existed before: set HWM to size + + LDAIM RTHWM + JSR #80 + +40 +;Leave address of cache descriptor (hint) to +;be filled in on first read/write operation +;** END OF FILE CODE ** + + +;FIRST MARK HANDLE IN USE (IN USERTB ENTRY) + +50 JSR MHINUS ;MARK HANDLE IN USE - IN USERTB ENTRY + +;NOW COPY DETAILS (HANDLE,DISC NO,SIN, ETC.) +;INTO THE HANDTB (HNDPTR WAS SET BY GETHND) + + LDYIM HTHAND + LDA RNDTMP + STAIY HNDPTR ;HANDLE + + LDYIM HTMCNO + LDA MCNUMB + STAIY HNDPTR + INY + LDA MCNUMB+1 + STAIY HNDPTR + INY + LDA MCNUMB+2 ;**25/12/86** + STAIY HNDPTR ;MACHINE NUMBER + + LDYIM ARGE + LDAIY ARGPTR + LDYIM HTACC + STAIY HNDPTR ;TYPE & ACCESS + + LDXIM INFDIS + LDYIM HTDISC + LDAIM 2 + JSR #70 + + LDXIM INFSIN + LDYIM HTSIN + LDAIM 3 + JSR #70 + + LDYIM ARGD + LDAIY ARGPTR + LDYIM HTMODE + STAIY HNDPTR ;MODE + + LDAIM 0 ;RC := 0 + +60 PHA + LDA RNDTMP ;A:=HANDLE + LDYIM ARGB + STAIY ARGPTR + PLA + JMP RDEXIT + + +70 STX OFF1 + STY OFF2 + LDXIM RNDPTR ;Move stuff from RNDPTR + LDYIM HNDPTR ;To HNDPTR + JMP MOVBLK + + +80 STA OFF2 + LDAIM INFSZE ;Move size from + STA OFF1 ;RNDPTR to RTEPTR (offset already set) + LDXIM RNDPTR + LDYIM RTEPTR + LDAIM 3 + JMP MOVBLK + + +;************ RDINFO ************ + + +;RDINFO: SEARCH THE HANDTB TO DETERMINE WHETHER +;A PARTICULAR OBJECT IS OPEN. + +;ENTRY: ARGB = LS(DISC NO) +;ARGC = MS(DISC NO) +;ARGD = LS(SIN) +;ARGE = CS(SIN) +;ARGF = MS(SIN) + +;EXIT : ARGA = RC (0 => OBJECT OPEN) +; : ARGB = MODE OF ACCESS (**28/4/83**) + + +RDINFO ROUT + JSR INITHD ;HNDPTR:=HANDTB,X:=HTENTS + CLC + LDA ARGPTR + ADCIM ARGB + STA MOVFRM + LDA ARGPTR+1 + ADCIM 0 + STA MOVFRM+1 ;MOVFRM := ARGPTR + ARGB + +10 LDYIM HTHAND + LDAIY HNDPTR + BEQ #20 ;ENTRY IN USE ?? + CLC + LDA HNDPTR + ADCIM HTDISC + STA MOVTO + LDA HNDPTR+1 + ADCIM 0 + STA MOVTO+1 ;MOVTO := HNDPTR + HTDISC + + TXA + PHA + LDXIM 5 ;COMPARE DISC & SIN + JSR COMPAR + TAY + PLA + TAX + TYA + BEQ #30 + +20 JSR INCHND + BNE #10 + LDAIM RDERRE ;OBJECT NOT OPEN + +30 PHA ;save A + BNE #40 + + LDYIM HTMODE + LDAIY HNDPTR ;get mode from table + LDYIM ARGB + STAIY ARGPTR ;for return + JSR RDopat ;**20/5/87** set 'open at' details + +40 PLA + JMP RDEXIT + + + +;************ RDCLOS ************ + + +;RDCLOS: CLOSE - INVALIDATE A HANDLE + +;ENTRY: ARGB = LS(PTR TO USER INFO) +;ARGC = MS(PTR TO USER INFO) +;ARGD = HANDLE + +;EXIT : ARGA = RC + + +RDCLOS ROUT + JSR INITRD ;SETUP GENPTR & MCNUMB + LDYIM ARGD + LDAIY ARGPTR ;A := HANDLE + BNE #10 + LDAIM RDERRB ;BAD HANDLE + BNE #20 + +10 STA RNDTMP ;RNDTMP := HANDLE + JSR FNDHND ;SEARCH HANDTB FOR THE HANDLE + BNE #20 + + +;NOW CLEAR HANDTB (RANDTB) ENTRY +;and mark handle free in USERTB + + JSR CLRHTE + +20 JMP RDEXIT + + + +;************ RDREST ************ + + +;RDREST: RESTART +;CREATE BOTH HANDTB & RANDTB. +;THE VARIABLES HANDTB & RANDTB ARE INITIALISED +;TO POINT TO THE FIRST ENTRY OF BOTH +;TABLES. + +;NOTE - HANDLE TABLE HAS 6*USERS ENTRIES, +;AND RAND TABLE 5*USERS ENTRIES. + + +RDREST ROUT + LDA USERS ;First create handle table + LDXIM 5 + CLC +30 ADC USERS + BCS #40 + DEX + BNE #30 + BEQ #10 + +40 LDAIM &FF +10 CMPIM 9 + BCS #20 + LDAIM 9 +20 PHA + STA HTENTS + TAX + LDYIM HTENSZ + JSR SETTAB ;SET HANDLE TABLE + STY HANDTB + STX HANDTB+1 + + PLA + SEC + SBC USERS + STA RTNENT ;Store no. of RT entries + TAX + LDYIM RTENSZ + JSR SETTAB + STY RANDTB + STX RANDTB+1 + LDAIM 0 + JMP RDEXIT + + + +;************ RDCOPY ************ + + +;RDCOPY: CREATE ANOTHER HANDLE FOR AN OBJECT +;(OOF TYPE DIR). N.B. RNDMAN.RDCOPY IS +;USED BY USRMAN WHEN SELECTING A USER'S UFD. + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;AFGC = MS(PTR TO USERINFO) +;ARGD = HANDLE (FOR A DIR) + +;EXIT : ARGA = RC +;ARGE = NEW HANDLE + + +RDCOPY ROUT + JSR INITRD ;SETUP GENPTR & MCNUMB + LDYIM ARGD + LDAIY ARGPTR + JSR FNDHND + BNE #20 + LDA HNDPTR + STA MOVFRM + LDA HNDPTR+1 + STA MOVFRM+1 ;MOVFRM := PTR TO HANDTB ENTRY + LDYIM HTACC + LDAIY HNDPTR + ANDIM TYPDIR ;IS HANDLE FOR A DIR? + BNE #10 + LDAIM RDERRF ;RDCOPY ONLY AVAILABLE FOR DIRECTORIES + JSR INTERR +10 JSR GETHND ;HNDPTR:=PTR TO FREE HANDTB ENTRY + BNE #20 + JSR MHINUS ;MARK THE HANDLE IN USE IN USERTB + LDA HNDPTR + STA MOVTO + LDA HNDPTR+1 + STA MOVTO+1 + LDXIM HTENSZ + JSR MOVE ;COPY OBJECT DETAILS INTO NEW USERTB ENTRY + LDYIM ARGE + LDA RNDTMP ;A := HANDLE TO BE USED (SETBY GETHND) + STAIY ARGPTR + LDYIM HTHAND + STAIY HNDPTR ;PUT NEW HANDLE IN HANDTB ENTRY + LDAIM 0 ;RC:=0 +20 JMP RDEXIT + + + + +;************ RDCLEAR ALL ************* + + +;RDCLAL: DELETE ALL HANDLES BELONGING +;TO A MACHINE. + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) + +;EXIT: ARGA = RETURN CODE + + +RDCLAL ROUT + JSR INITRD ;SET GENPTR/MCNUMB/RDUPTR + JSR INITHD ;SET HNDPTR + +10 LDYIM HTMCNO ;M/C NUMBER + LDAIY HNDPTR + CMP MCNUMB + BNE #30 + INY + LDAIY HNDPTR + CMP MCNUMB+1 + BNE #30 + INY + LDAIY HNDPTR + CMP MCNUMB+2 ;**25/12/86** + BNE #30 + +;FOUND, SO DELETE + + LDA RDUPTR + STA GENPTR + LDA RDUPTR+1 + STA GENPTR+1 ;Ensure GENPTR pointing to right place + + TXA + PHA + JSR CLRHTE ;CLEAR TABLE ENTRY + TAX + PLA ;tidy up stack + TXA + BNE #40 +30 JSR INCHND ;INC. PTR + BNE #10 ;(X DEC'D IN INCHND) + + LDAIM 0 +40 JMP RDEXIT + + + + +;GETHND: CHOOSE A HANDLE & A SLOT IN THE HANDTB +;WHICH ARE FREE. +;NOTE THAT EACH MACHINE CAN HAVE UPTO 8 HANDLES. +;THE HANDLES CURRENTLY BEING USED BY A +;PARTICULAR MACHINE ARE RECORDED IN THE USERTB. + +;ENTRY: GENPTR = PTR TO USER INFO + +;EXIT : A = RC +;HNDPTR = POINTER TO A FREE HANDTB ENTRY +;RNDTMP = HANDLE TO BE USED + + +GETHND ROUT + LDYIM UTHNDB ;HANDLE BYTE HELD IN USERTB + LDAIY GENPTR + +;FIRST SEE IF THIS MACHINE HAS A FREE HANDLE + + CMPIM &FF + BNE #10 + LDAIM RDERRC ;HANDLE QUOTA EXHAUSTED + RTS + +10 LDYIM 1 + STY RNDTMP +20 LSRA + BCC #30 ;FOUND A FREE HANDLE + ASL RNDTMP + JMP #20 + +;NOW SEE IF THERE IS A FREE SLOT IN HANDTB + +30 JSR INITHD ;HNDPTR := HANDTB + LDYIM HTHAND +40 LDAIY HNDPTR + BEQ #50 + JSR INCHND + BNE #40 + LDAIM RDERRD ;HANDTB FULL +50 RTS + + +INITRD ROUT + LDYIM ARGB ;INIT GENPTR,MCNUMB,RNDPTR + LDAIY ARGPTR + STA GENPTR + STA RDUPTR ;Store extra copy of user pointer INY + INY + LDAIY ARGPTR ;(used by RDCLAL and RDCLAF) + STA GENPTR+1 ;GENPTR := PTR TO USERINFO + STA RDUPTR+1 ;Extra copy high byte + + LDYIM UTMCNO + LDAIY GENPTR + STA MCNUMB + INY + LDAIY GENPTR + STA MCNUMB+1 + INY + LDAIY GENPTR + STA MCNUMB+2 ;MCNUMB initialised **25/12/86** + + LDYIM ARGF + LDAIY ARGPTR + STA RNDPTR + INY + LDAIY ARGPTR + STA RNDPTR+1 ;RNDPTR := PTR TO OBJECT INFO(SEE DIRMAN.RETR) + RTS + + +MHINUS ROUT + LDYIM UTHNDB ;MARK A HANDLE IN USE IN USERTB + LDA RNDTMP ;A:=HANDLE (SEE GETHND) + ORAIY GENPTR + STAIY GENPTR + RTS + + +;Mark handle free in USERTB +;GENPTR points at USERTB entry +;A contains handle + +MHFREE ROUT + LDYIM UTHNDB ;Mark handle free in USERTB + EORIM &FF ;Invert handle in A + ANDIY GENPTR ;Clear handle bit + STAIY GENPTR ;Put back in USERTB + RTS + + + +CLRHTE ROUT ;CLRHTE + +;CLEAR HANDLE TABLE ENTRY POINTED TO +;BY HNDPTR. IF ENTRY IS FOR A FILE, +;CLEAR CORRESPONDING RANDOM TABLE ENTRY. +;The handle bit in the USERTB entry +;(pointed to by GENPTR) is cleared. + + LDYIM HTHAND ;Get handle in A + LDAIY HNDPTR + JSR MHFREE ;Mark handle free in USERTB + + LDYIM HTACC + LDAIY HNDPTR + ANDIM TYPE + CMPIM TYPDIR + BEQ #10 + JSR RDFLSH ;Flush object from cache + BNE #30 ;**** 17/3/83 **** + JSR RDSFSZ ;Set size from HWM + JSR CLRRTE ;Clear RANDTB entry + +10 LDYIM HTENSZ-1 ;Y := SIZE OF HANDTB ENTRY + LDAIM 0 +20 STAIY HNDPTR + DEY + BPL #20 ;A zero already + TAY +30 RTS + + + +;*** RDSFSZ *** + +;If the file is open for update, then set +;its size to the HWM recorded in RANDTB. + +;Entry: HNDPTR points to HANDTB entry for file + +;Exit: RC in A + +RDSFSZ + LDYIM HTMODE ;Get mode in which open + LDAIY HNDPTR + ANDIM WRITAC ;Open for writing ? + BEQ #30 ;Yes, exit A=0 and Z set + + JSR SETRPT ;Set RTEPTR + LDYIM RTHWM + LDAIY RTEPTR ;HWM LS + STA NEWFSZ + INY + LDAIY RTEPTR ;HWM CS + STA NEWFSZ+1 + INY + LDAIY RTEPTR ;HWM MS + STA NEWFSZ+2 + + JMP RDCHSZ ;Change size and exit + + + LNK RMAN02 diff --git a/Level3/SRC/L3/Rman02 b/Level3/SRC/L3/Rman02 new file mode 100644 index 0000000..d50bc0f --- /dev/null +++ b/Level3/SRC/L3/Rman02 @@ -0,0 +1,838 @@ + + OPT RMAN02 ;RNDMAN > Rman02 + TTL File server file RMAN02 + +;**************** RDRDCH **************** + +;RDRDCH: read one byte from an open file + +;Entry: ARGB = (LS) ptr to user info +;ARGC = (MS) ptr to user info +;ARGD = file handle +;ARGE = sequence no. (in LS bit) + +;Exit: ARGA = return code +;ARGB = byte read +;ARGC = end-of-file flag +;normally zero, +;#X80 if this is the last byte in file +;#XC0 if this is byte after end of file + +;1) Get HANDTB entry from handle +;2) Check that object is a file +;3) Get RANDTB entry +;4) Compare sequence no. in ARGD with that in RANDTB entry. +;Same => old seq. file ptr := current SFP +;increment sequence no. in RANDTB entry +;Different => repeat of last read; +;current SFP := old SFP +;5) Check sequential file pointer against file size +;SFP = size => return $FE and EOFFLG = $C0 +;SFP > size => end of file; return RC +;SFP < size => OK +;6) Work out disc address of block containing +;required byte, and offset of byte in block. +;7) Find / get required block in cache (STRMAN) +;8) Fetch required byte and return it +;Increment current SFP in RANDTB + +RDRDCH ROUT + JSR INITRD ;GENPTR := user info; MCNUMB := machine no. +;[RNDPTR := rubbish] + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #30 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #30 ;Not found (object not file) + + LDYIM HTMODE + LDAIY HNDPTR ;check that file is open for input + ANDIM READAC + BNE #10 + LDAIM RDERRO ;file not open for input ** 15/11/84 ** + BNE #30 + +10 JSR RDCSEQ ;Compare sequence numbers +;and choose file ptr; if equal +;then increment seq no. + JSR RDCKEX ;Check SFP against file length + BNE #30 ;End of file + LDAIM &FE ;Byte after last + BIT EOFFLG + BVS #20 ;Reading byte after last +;so return $FE + + JSR RDGBLK ;Get required block into cache +;GENPTR := store address + BNE #30 ;error + +;*** Assuming blocksize is 256 bytes *** +;Offset of required byte in block is given +;by LS byte of seq. file pointer. + + LDYIM RTCSFP + LDAIY RTEPTR ;LS byte of SFP + TAY + LDAIY GENPTR ;Get required byte +20 LDYIM ARGB + STAIY ARGPTR ;Return byte read + INY + LDA EOFFLG + STAIY ARGPTR ;Return end-of-file flag + + JSR RDISFP ;Increment Current SFP + + LDAIM 0 +30 JMP RDEXIT ;Exit: Rc in A + + +;**************** RDWRCH **************** + +;RDWRCH: write one byte to an open file + +;Entry: ARGB = (LS) ptr to user info +;ARGC = (MS) ptr to user info +;ARGD = file handle +;ARGE = sequence no. (in LS bit) +;ARGF = byte to be written + +;Exit: ARGA = return code + +;1) Get HANDTB entry from handle +;2) Check that object is a file +;3) Check file open for update +;4) Get RANDTB entry +;5) Compare sequence no. in ARGD with that +;in RANDTB entry. +;Same => old seq. file ptr := current SFP +;increment sequence no. in RANDTB entry +;Different => repeat of last read; +;current SFP := old SFP +;6) Check sequential file pointer against file size +;SFP >= size => end of file; extend file +;SFP < size => OK +;7) Work out disc address of block containing +;required byte, and offset of byte in block. +;8) Find / get required block in cache (STRMAN) +;9) Write byte to cache; mark cache buffer dirty +;(but do not cause it to be written to disc: this will +;happen when the cache space is needed for +;something else, or when the file is closed. +;The cache buffer is left unlocked between +;calls of RDWRCH). +;10) IF SFP > HWM THEN HWM := SFP +;11) Increment current SFP + +RDWRCH ROUT + JSR INITRD ;GENPTR := user info; MCNUMB := machine no. +;[RNDPTR := rubbish] + + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #40 ;Not found - exit + + LDYIM HTMODE ;Check file open for update + LDAIY HNDPTR ;Get mode + ANDIM WRITAC ;Extract write access bit + BNE #10 ;OK to write + + LDAIM RDERRN ;"File not open for update" + BNE #40 + +10 JSR SETRPT ;RTEPTR := RANDTB entry + BNE #40 ;Not found (object not file) + + JSR RDCSEQ ;Compare sequence numbers +;and choose file ptr; if equal +;then increment seq no. + JSR RDCKSP ;Check SFP against file length + BIT EOFFLG ;If PTR = EXT, need to extend + BVS #20 ;V set => PTR = EXT => extend + BEQ #30 ;Otherwise, Z set if inside file +;so don't extend + +;Must extend file +;Allocate another block (1K bytes) + +20 LDAIM 1 ;Ls byte of new size + STA NEWFSZ ;**29/4/88** central subroutine + LDAIM 0 + STA NEWFSZ+1 + JSR RDEXSZ ;**29/4/** Change file size + BNE #40 ;Error + +30 JSR RDGBLK ;Get required block into cache +;GENPTR := store address + BNE #40 ;error + +;*** Assuming blocksize is 256 bytes *** +;Offset of required byte in block is given +;by LS byte of seq. file pointer. + + LDYIM ARGF + LDAIY ARGPTR ;Byte to be written + TAX ;Save it + LDYIM RTCSFP + LDAIY RTEPTR ;LS byte of file pointer + TAY + TXA + STAIY GENPTR ;Write byte to cache + + JSR MRKDRT ;Mark buffer dirty (addr in GENPTR) + JSR RDISFP ;Increment Current SFP + JSR RDSHWM ;Set high water mark + + LDAIM 0 ;Success +40 JMP RDEXIT ;Return - RC in A + + +;****** RDRDAR ****** + +;RDRDAR: read RANDTB info on open file + +;Entry: ARGB (LS) ptr to user info +;ARGC (MS) ptr to user info +;ARGD = file handle + +;Exit: ARGA = return code +;ARGB = (LS) Seq file ptr +;ARGC = (CS) " " " +;ARGD = (MS " " " +;ARGE = (LS) File high water mark +;ARGF = (CS) " " " +;ARGG = (MS) " " " +;ARGH = (LS) File size +;ARGI = (CS) " " +;ARGJ = (MS) " " + +;The file handle is used to find the HANDTB +;entry, which points to the RANDTB entry +;from which the info is extracted. + +RDRDAR ROUT + JSR INITRD ;GENPTR:=ptr to user info + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #40 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #40 ;Not found + +;Return current seq file ptr + + LDYIM RTCSFP + LDAIY RTEPTR ;LS byte of SFP + LDYIM ARGB + STAIY ARGPTR + LDYIM RTCSFP+1 + LDAIY RTEPTR ;CS byte + LDYIM ARGC + STAIY ARGPTR + LDYIM RTCSFP+2 + LDAIY RTEPTR ;MS + LDYIM ARGD + STAIY ARGPTR + +;Copy 6 bytes from RANDTB entry to ARGPTR +;stack. (The 2 fields are in the same +;order in each place). + + LDXIM 6 ;Loop count + LDAIM ARGE ;1st stack offset + STA RNDTMP ;Temp workspace + LDYIM RTHWM ;Offset in RANDTB entry + +10 LDAIY RTEPTR ;Get data from RANDTB + STY RNDTMP+1 ;Save RANDTB entry offset + LDY RNDTMP ;Get stack offset + STAIY ARGPTR ;Put data on stack + INY + STY RNDTMP ;Save next stack offset + LDY RNDTMP+1 ;Restore entry offset + INY + DEX ;Loop count + BNE #10 ;Loop if not zero + JSR RDCKSP ;check for EOF ** 26/5/83 ** + BEQ #30 ;skip except on error + + LDYIM ARGJ + STY RNDTMP + LDYIM ARGD + LDXIM 2 ;copy size to pointer area +20 STY RNDTMP+1 + LDY RNDTMP + LDAIY ARGPTR ;move the data + LDY RNDTMP+1 + STAIY ARGPTR + DEC RNDTMP + DEY + DEX + BPL #20 ;three bytes + +30 LDAIM 0 ;All copied - set RC +40 JMP RDEXIT ;Return - RC in A + + +;****** RDSTAR ****** + +;RDSTAR: set sequential file ptr + +;Entry: ARGB = (LS) ptr to user info +;ARGC = (MS) " " " " +;ARGD = file handle +;ARGE = arg saying what to set +;0: SFP +;1: HWM ** 5/9/84 ** +;ARGF = (LS) New value to set +;ARGG = (CS) " " " " +;ARGH = (MS) " " " " +;ARGI = 4th byte if any + +;Exit: ARGA = return code + +;The file handle is used to find the RANDTB entry. +;The arg in ARGE is inspected to find +;out what is being set. + +RDSTAR ROUT + JSR INITRD ;GENPTR -> user info + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HANDPTR := HANDTB entry + BNE #10 ;error + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #10 ;Not found + +;Inspect arg in ARGE + + LDYIM ARGE + LDAIY ARGPTR + LSRA + BEQ #20 ;0 => set SFP + ;1 => set HWM + + LDAIM RDERRM ;"Bad arg to RDSTAR" +10 JMP #40 + +;Set seq file ptr + +;IF newSFP < size THEN oldSFP = newSFP +;ELIF openforwriting THEN resize file: HWM = newSFP: oldSFP = newSFP +;ELSE IF newSFP <> size THEN error ELSE oldSFP = newSFP + +20 BCS #50 ;A = 1 => set extent of file + SEC + LDYIM ARGF + LDAIY ARGPTR + LDYIM RTFSZE + SBCIY RTEPTR ;Do RNDTMP := SFP - size + STA RNDTMP + LDYIM ARGG + LDAIY ARGPTR + LDYIM RTFSZE+1 + SBCIY RTEPTR + STA RNDTMP+1 + LDYIM ARGH + LDAIY ARGPTR + LDYIM RTFSZE+2 + SBCIY RTEPTR + ORA RNDTMP + ORA RNDTMP+1 + BCC #35 ;Set SFP = new SFP as size > SFP + +;Here SFP >= size, so attempt to point +;outside file. If open for update, resize +;else if SFP <> size then error else set SFP = new SFP + +25 PHP ;Push Z flag indicating SFP = size + LDYIM HTMODE + LDAIY HNDPTR ;Mode handle opened for + ANDIM WRITAC ;Check if open for writing + BNE #30 ;Yes, so resize + + PLP ;Not open for writing, so check if SFP=size + BEQ #35 ;Yes, so set SFP + LDAIM RDERRL ;No => "attempt to point outside file" + BNE #40 ;Error exit + +30 PLP ;Restore stack, and resize file + LDYIM ARGH + LDAIY ARGPTR ;Set NEWFSZ to seq. ptr. + STA NEWFSZ+2 + DEY + LDAIY ARGPTR + STA NEWFSZ+1 + DEY + LDAIY ARGPTR + STA NEWFSZ + JSR RDCHSZ ;Change size of file + BNE #40 ;Error => exit + +;Copy SFP into RANDTB + +35 LDAIM ARGF + STA OFF1 + LDAIM RTCSFP + JSR #90 ;Set current seq. ptr. + LDAIM RTOSFP ;Set old seq. ptr. as well + JSR #90 + JSR RDSHWM ;**1/6/88** set HWM if SFP > old HWM +37 LDAIM 0 ;Return code +40 JMP RDEXIT ;Return - RC in A + +50 LDYIM HTMODE + LDAIY HNDPTR + ANDIM WRITAC + BNE #55 ;open for update + LDAIM RDERRN ;not open for update + BNE #40 + +55 LDYIM ARGF + LDXIM :LSB:-3 +60 LDAIY ARGPTR + STAAX NEWFSZ-:LSB:(-3) + INY + INX + BNE #60 + + LDYIM RTHWM+2 + LDXIM 2 +65 LDAIY RTEPTR + CMPAX NEWFSZ + BNE #70 + DEY + DEX + BPL #65 + BMI #80 ;All ok + +;exactly the same size so NOP here + +70 LDYIM RTHWM + LDAIY RTEPTR + STA TEMPA ;save current extent + ROLA + STA TEMPB ;save carry as well + +;C=0 => extending the file + + RORA + BCC #75 + +;if decreasing file then must flush all blocks +;else cache may be left with antiquated data + + LDAIM 5 + JSR SETRTN + JSR RDDSIN + JSR STRMAN ;flush all blocks + BNE #40 + +75 JSR RDCHSZ ;call changesize + BNE #40 + +80 JSR #88 ;Having resized file, set HWM to ptr. value + JMP #37 + +;Little space-saving routine + +88 LDAIM ARGF + STA OFF1 + LDAIM RTHWM +90 STA OFF2 + LDXIM ARGPTR + LDYIM RTEPTR + LDAIM 3 + JMP MOVBLK + + +;*** RDCHSZ *** + +;Change the size of a file to the 3-byte value +;in NEWFSZ. HNDPTR points at its HANDTB entry, +;and RTEPTR at the RANDTB entry. + +;MAPMAN.CHANGESIZE is called, and the new +;size is recorded in the RANDTB entry. + +;RC in A on exit. + + +RDCHSZ ROUT + JSR RDDSIN ;Put disc and SIN on stack + +;Put new size on stack + + LDA NEWFSZ ;LS byte + LDYIM ARGG + STAIY NEWARG + LDA NEWFSZ+1 + INY + STAIY NEWARG ;CS byte + LDA NEWFSZ+2 + INY + STAIY NEWARG ;MS byte + + JSR JUSINF ;** 3/10/84 ** + + LDAIM 3 ;MAPMAN.CHANGESIZE + JSR SETRTN + JSR MAPMAN + BNE #10 ;Failed, return code + +;zero the new area if needed + + JSR RDDSIN ;** 20/9/84 ** + + LDYIM RTFSZE + LDAIY RTEPTR + LDYIM ARGG + STAIY NEWARG + + LDYIM RTFSZE+1 + LDAIY RTEPTR + LDYIM ARGH + STAIY NEWARG + + LDYIM RTFSZE+2 + LDAIY RTEPTR + LDYIM ARGI + STAIY NEWARG + + LDAIM 13 + JSR SETRTN + JSR MAPMAN + BNE #10 ;failed, return code + +;Size changed: record in RANDTB + + LDAIM 6 + JSR SETRTN ;Ensure map on disc + JSR MAPMAN ;Note assumes disc no. still on stack + BNE #10 ;Error -> leave + + LDYIM RTFSZE + LDA NEWFSZ + STAIY RTEPTR ;LS byte + LDA NEWFSZ+1 + INY + STAIY RTEPTR ;CS byte + LDA NEWFSZ+2 + INY + STAIY RTEPTR ;MS byte + + LDAIM 0 ;RC +10 RTS + + +;*** SETRPT *** + +;Set RTEPTR to point to RANDTB entry + +;Entry: HNDPTR points at HANDTB entry + +;Exit: A = return code +;RTEPTR points to corresponding RANDTB entry + + +SETRPT ROUT + LDYIM HTACC + LDAIY HNDPTR ;A := type of object (& access) + ANDIM TYPE ;Mask type + CMPIM TYPFIL ;Is it a file? + BEQ #10 ;Jump if file + + LDAIM RDERRI ;"Object not a file" + RTS ;Return + +10 LDYIM HTRPTR + LDAIY HNDPTR ;LS byte + STA RTEPTR ;LS byte + INY + LDAIY HNDPTR + STA RTEPTR+1 ;MS byte + + LDAIM 0 ;return code + RTS + + +;*** RDDSIN *** + +;Put disc number and SIN on NEWARG +;stack from ARGB - ARGF. + +RDDSIN ROUT + LDAIM HTDISC ;"Move from" offset + STA OFF1 + LDAIM ARGB ;"move to" offset + STA OFF2 + LDXIM HNDPTR ;Move from + LDYIM NEWARG ;Move to + LDAIM 5 ;Size of disc no. + SIN + JMP MOVBLK ;Note -> assumes DISC/SIN contiguous + + +;*** RDCKEX *** + +;Check SFP against HWM (For read operation) + +RDCKEX ROUT + LDYIM RTHWM + BNE #10 ;share code with RDCKSP + + +;*** RDCKSP *** + +;Check sequential file pointer against file size + +;Entry: RTEPTR points to RANDTB entry + +;Exit: A = return code: 0 => OK, SFP < size +;EOFFLG = 0 normally +;= #X80 if this is last byte of file +;= $C0 If byte after last + +RDCKSP LDYIM RTFSZE +10 STY RNDTMP+2 + LDAIM 0 + STA EOFFLG ;First set EOFFLG to zero + SEC + LDY RNDTMP+2 ;Subtract SFP from file size + INC RNDTMP+2 + LDAIY RTEPTR ;LS byte of file size + LDYIM RTCSFP + SBCIY RTEPTR ;Subtract LS bytes + STA RNDTMP ;Use RNDTMP as workspace + LDY RNDTMP+2 + INC RNDTMP+2 + LDAIY RTEPTR + LDYIM RTCSFP+1 + SBCIY RTEPTR ;CS bytes + STA RNDTMP+1 + LDY RNDTMP+2 + INC RNDTMP+2 + LDAIY RTEPTR + LDYIM RTCSFP+2 + SBCIY RTEPTR ;Sets carry if SFP <= size + + TAX ;Save MS byte for EOFFLG test + ORA RNDTMP ;OR all 3 bytes of result + ORA RNDTMP+1 ;for zero test + BEQ #30 ;Jump if SFP = file size + BCC #40 ;Jump if SFP > file size + +;OK: SFP < file size | HWM +;Set EOFFLG to #X80 if this is the last +;byte of the file (size - SFP = 1) + + CMPIM 1 ;Is OR of all bytes 1? + BNE #20 ;No + TXA ;OR MS two bytes + ORA RNDTMP+1 ;CS byte + BNE #20 ;MS 2 bytes not both 0 + + LDAIM &80 ;(size - SFP)=1 so set + STA EOFFLG ;end-of-file flag + +20 LDAIM 0 ;OK: SFP <= file size + RTS + +;SFP = file size +;Set end of file marker to indicate +;reading/writing byte AFTER end of file. + +30 LDAIM &C0 ;Last AND one after last + STA EOFFLG + BNE #20 ;Exit, Z set, A=0 + +40 LDAIM RDERRJ ;"End of file" + RTS + + + +;*** RDCSEQ *** + +;Compare sequence number received with that recorded +;in RANDTB. If they are equal, then increment +;the sequence number in RANDTB and set +;old SFP := current SFP +;Otherwise, this is a repetition of the +;last operation, so don't change the sequence number +;and set current SFP := old SFP + +;Entry: RTEPTR points to RANDTB entry +;ARGE on ARGPTR stack holds received +;seq no (in LS bit) + +;Exit: Sequence number +;in RANDTB entry incremented if and only if +;sequence numbers matched. + +RDCSEQ ROUT + LDYIM ARGE + LDAIY ARGPTR ;A := received seq no. + LDYIM RTINUS ;Seq no. byte of RANDTB entry + EORIY RTEPTR ;A := XOR of seq nos. + ANDIM 1 ;Mask out "in use" bit + BEQ #20 ;Jump if seq nos. equal + +;Seq nos different, so back up SFP: +;current SFP := old SFP + +RDBACK LDYIM RTOSFP ;** 5/8/83 ** + LDAIY RTEPTR + LDYIM RTCSFP + STAIY RTEPTR + LDYIM RTOSFP+1 + LDAIY RTEPTR + LDYIM RTCSFP+1 + STAIY RTEPTR + LDYIM RTOSFP+2 + LDAIY RTEPTR + LDYIM RTCSFP+2 + STAIY RTEPTR + RTS ;Seq nos. different; return + +20 LDAIY RTEPTR ;Get seq. no. + EORIM 1 ;Flip seq no., leaving "in use" flag + STAIY RTEPTR + +;old SFP := current SFP + + LDYIM RTCSFP + LDAIY RTEPTR + LDYIM RTOSFP + STAIY RTEPTR + LDYIM RTCSFP+1 + LDAIY RTEPTR + LDYIM RTOSFP+1 + STAIY RTEPTR + LDYIM RTCSFP+2 + LDAIY RTEPTR + LDYIM RTOSFP+2 + STAIY RTEPTR + RTS ;Return + + +;*** RDISFP *** + +;Increment sequential file ptr (3 bytes) + +RDISFP ROUT + CLC + LDAIM 1 + LDYIM RTCSFP + ADCIY RTEPTR + STAIY RTEPTR ;LS byte + INY + LDAIY RTEPTR + ADCIM 0 + STAIY RTEPTR ;CS byte + INY + LDAIY RTEPTR + ADCIM 0 + STAIY RTEPTR ;MS byte + + RTS ;Return + + +;*** RDGBLK *** + +;Gets the required block into the cache. +;In order to speed up the operation, a means +;is provided of usually avoiding a call of STRMAN. +;Each entry in RANDTB contains a hint - in the form +;of a pointer to the cache descriptor for the block +;last used. STRMAN guarantees that this will +;continue to point to SOME cache descriptor, but if +;there has been a store crisis in the cache, then +;it may not still point to the block we want. +;Therefore the hint is carefully checked for validity +;before use. +;If the hint is no good, then the required block +;is read from disc by calling STRMAN.DISC ADDRESS-> +;STORE ADDRESS. The address of the cache descriptor +;is put in the RANDTB entry as the next hint. + +;Entry: HNDPTR points to handle table entry +;RTEPTR points to RANDTB entry + +;Exit: A = RC +;GENPTR contains store address of cache buffer. +;Hint field of RANDTB entry points to cache +;descriptor (or is zero). + +RDGBLK ROUT + JSR RDCHNT ;Check hint; set GENPTR if OK + BEQ #40 ;HINT OK, GO RETURN + JSR RDDSIN ;Put disc and SIN on stack + +;Logical block number of the block containing the +;current byte is given by the top 2 bytes of the +;sequential file pointer. +;*** This firmly assumes that the blocksize is +;*** 256 bytes (as does DIVIDE in MAPMAN). + + LDYIM RTCSFP+1 + LDAIY RTEPTR ;Seq file ptr (CS) + LDYIM ARGG + STAIY NEWARG ;Logical block no. (LS) + LDYIM RTCSFP+2 + LDAIY RTEPTR ;Seq file ptr (MS) + LDYIM ARGH + STAIY NEWARG ;Logical block no. (MS) + +;Ask for one block only. This simplifies the +;arithmetic elsewhere. +;(Would using units of > 1 block give a +;significant speed improvement?) + + LDAIM 0 + LDYIM ARGJ + STAIY NEWARG + LDAIM 1 ; A=1 + DEY + STAIY NEWARG + + JSR SETRTN ; A=1 STRMAN: Disc address -> store address + + JSR STRMAN ;*** STRMAN.DISC -> STORE ADDRESS ** + BNE #40 ;Failed, go return + LDYIM ARGB ;GENPTR := store address + LDAIY NEWARG + STA GENPTR ;(LS) + INY + LDAIY NEWARG + STA GENPTR+1 ;(MS) + + INY ;Store cache desc. addr. in RANDTB entry + LDAIY NEWARG ;LS byte + LDYIM RTDESC + STAIY RTEPTR + LDYIM ARGE + LDAIY NEWARG ;MS byte + LDYIM RTDESC+1 + STAIY RTEPTR + +;Must unlock cache window, so that it is not +;locked between byte transfers. Note that if +;parallelism is ever introduced into the file +;server, care must be taken that RNDMAN does +;not relinquish control between deciding that +;it has found a block in the cache and using it. + +;Very conveniently, STRMAN has left the buffer +;address in the right place on the stack. + + LDAIM 3 ;STRMAN.UNLOCKWINDOW + JSR SETRTN + + JSR STRMAN ;*** STRMAN.UNLOCKWINDOW ** + +40 RTS ;exit + + LNK RMAN03 + diff --git a/Level3/SRC/L3/Rman03 b/Level3/SRC/L3/Rman03 new file mode 100644 index 0000000..eea6db6 --- /dev/null +++ b/Level3/SRC/L3/Rman03 @@ -0,0 +1,262 @@ + OPT RMAN03 ;RNDMAN > Rman03 + TTL File server file RMAN03 + +;*** RDCHNT *** + +;Checks the cache descriptor hint in a +;RANDTB entry. + +;Entry: HNDPTR points to HANDTB entry +;RTEPTR points to RANDTB entry + +;Exit: A = RC: zero => hint used, GENPTR set +;non-zero=> must call STRMAN instead +;GENPTR points to cache buffer (iff RC=0) + +RDCHNT ROUT + LDYIM RTDESC ;GENPTR := Cache descriptor hint + LDAIY RTEPTR ;from RANDTB entry + STA GENPTR + INY + LDAIY RTEPTR + STA GENPTR+1 + +;Hint is invalid if it is zero (as it +;is when file first opened) + + ORA GENPTR ;OR both bytes of hint + BEQ #40 ;Hint no good (zero) + +;Must now check that the hint still points +;to the cache descriptor we want. (If it +;is not zero, it will always point to +;SOME cache descriptor). +;The descriptor is valid only if it has the +;right disc number and SIN, and if its start +;block is the one we want. + +;*** Assumptions: +;*** 1) Blocksize = 256 bytes (=> easy +;*** calculation of block number +;*** 2) Cache buffers contain only one +;*** disc block + +;Compare SINs first (more likely to +;be different than disc number). + + LDYIM HTSIN + LDAIY HNDPTR + LDYIM CESIN + CMPIY GENPTR ;Compare LS bytes + BNE #40 ;Different + LDYIM HTSIN+1 + LDAIY HNDPTR + LDYIM CESIN+1 + CMPIY GENPTR ;Compare CS bytes + BNE #40 ;Different + LDYIM HTSIN+2 + LDAIY HNDPTR + LDYIM CESIN+2 + CMPIY GENPTR ;Compare MS bytes + BNE #40 ;Different + +;SIN OK - check disc no. + + LDYIM HTDISC ;Compar disc nos. + LDAIY HNDPTR + LDYIM CEDISC + CMPIY GENPTR ;Compare LS bytes + BNE #40 ;Different - hint no good + LDYIM HTDISC+1 + LDAIY HNDPTR + LDYIM CEDISC+1 + CMPIY GENPTR ;Compare MS bytes + BNE #40 ;Different + +;Disc no. OK - Check block no. +;(should be equal to top 2 bytes of +;sequential file pointer). + + LDYIM CEBKNO + LDAIY GENPTR ;LS byte of block no. + LDYIM RTCSFP+1 + CMPIY RTEPTR ;Comp with CS byte of SFP + BNE #40 ;Different + LDYIM CEBKNO+1 + LDAIY GENPTR ;MS byte of block no. + LDYIM RTCSFP+2 + CMPIY RTEPTR ;Comp with MS byte of SFP + BNE #40 ;Different + +;The hint is OK. +;Copy buffer address to GENPTR (which +;currently points to cache descriptor). + + LDYIM CESTA + LDAIY GENPTR ;LS byte of buff addr + PHA ;Save for now + INY + LDAIY GENPTR ;MS byte of buff addr + STA GENPTR+1 ;GENPTR := buff addr + PLA + STA GENPTR ;LS byte + + LDAIM 0 ;Success - hint used + RTS + +40 LDAIM &FF ;Hint no good + RTS + + + +;************ RDCLAF ************ + + +;RDCLAF: Close all files for the calling machine + +;Entry: ARGB = Ptr to user info (LS) +;ARGC = Ptr to user info (MS) + +;Exit: ARGA = Return code + + +RDCLAF ROUT + JSR INITRD ;Set GENPTR & MCNUMB & RDUPTR (extra copy of user ptr.) + JSR INITHD ;Set HNDPTR and X + +10 LDYIM HTMCNO + LDAIY HNDPTR ;Get mc no. from HANDTB entry + CMP MCNUMB ;Same as client machine? + BNE #30 ;LS bytes differ + INY + LDAIY HNDPTR ;CS byte + CMP MCNUMB+1 + BNE #30 ;CS bytes differ + INY + LDAIY HNDPTR ;MS byte + CMP MCNUMB+2 + BNE #30 ;MS bytes differ **25/12/86** + +;Entry is for this machine. +;See if the object is a file. + + LDYIM HTACC + LDAIY HNDPTR ;Object type & access + ANDIM TYPE + CMPIM TYPDIR ;Is it a directory? + BEQ #30 ;Jump if yes + +;Entry is for a file for this mc. + + LDA RDUPTR + STA GENPTR + LDA RDUPTR+1 + STA GENPTR+1 ;Set pointer to user info (corrupted over CLRHTE) + + TXA + PHA + JSR CLRHTE ;Close the file + TAX + PLA + TXA + BNE #40 +30 JSR INCHND ;Inc pointer + BNE #10 ;Look at next entry + + LDAIM 0 ;Return code +40 JMP RDEXIT ;Return + + +;************ RDSUBO ************ + +;RDSUBO: Set up for PUTBYTES/GETBYTES operation + +;Entry: ARGB = LS ptr to user info +;ARGC = MS " " " " +;ARGD = file handle +;ARGE = Seq. no. received +;ARGF = Flag: 0 => use given offset +;NOT 0 => use SFP in RANDTB +;ARGG = LS total no. of bytes +;ARGH = CS " " " " +;ARGI = MS " " " " +;ARGJ = LS Offset in file +;ARGK = CS (only if flag=0) +;ARGL = MS " +; +;Exit: ARGA=RC +;ARGB = mode if access of file +; +; Side effect: +; OLDSZE is set to old HWM +; OLDSZE+3 is zero if area of disc has +; to be zeroed on a write +; +RDSUBO ROUT + LDAIM 1 + STA OLDSZE+3 + JSR INITRD + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #30 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #30 ;Not found + + JSR RDCSEQ ;Check seq no and set SFP accordingly + + LDYIM ARGF + LDAIY ARGPTR ;A := flag + BNE #20 ;Offset not supplied + +;Offset supplied : set SFP to offset + + LDYIM RTHWM ;GET CURRENT HWM + LDAIY RTEPTR + STA OLDSZE + INY + LDAIY RTEPTR + STA OLDSZE+1 + INY + LDAIY RTEPTR + STA OLDSZE+2 + LDAIM 0 + STA OLDSZE+3 ;Zero flag + LDYIM ARGJ ;CHECK IF NEW SIZE LARGER THAN OLD + LDA OLDSZE + CMPIY ARGPTR + INY + LDA OLDSZE+1 + SBCIY ARGPTR + INY + LDA OLDSZE+2 + SBCIY ARGPTR + BCC #10 + INC OLDSZE+3 +10 LDYIM ARGJ + LDAIY ARGPTR ;Offset (LS) + LDYIM RTCSFP + STAIY RTEPTR ;LS byte + LDYIM ARGK + LDAIY ARGPTR + LDYIM RTCSFP+1 + STAIY RTEPTR ;CS byte + LDYIM ARGL + LDAIY ARGPTR + LDYIM RTCSFP+2 + STAIY RTEPTR ;MS byte + +20 LDYIM HTMODE ;**23/3/88** return access mode + LDAIY HNDPTR + LDYIM ARGB + STAIY ARGPTR + + JSR RDCKSP ;Check SFP inside file + BEQ #30 ;SFP inside file + PHA + JSR RDBACK ;restore SFP to old SFP + PLA +30 JMP RDEXIT + + LNK RMAN04 diff --git a/Level3/SRC/L3/Rman04 b/Level3/SRC/L3/Rman04 new file mode 100644 index 0000000..18c1f5e --- /dev/null +++ b/Level3/SRC/L3/Rman04 @@ -0,0 +1,677 @@ + OPT RMAN04 ;RNDMAN > Rman04 + TTL File server file RMAN04 + +;************ RDGBTS ************ + + +;RDGBTS: Get bytes from file + +;Entry: ARGA = func code (9) +;ARGB) = ptr to user info (LS) +;ARGC) = " " " " (MS) +;ARGD = file handle +;ARGE) = buffer address (LS) +;ARGF) = " " (MS) +;ARGG) = no. of bytes (LS) +;ARGH) to be read (MS) + +;Exit: ARGA = rc +;ARGB) = no. of bytes actually read (LS) +;ARGC) (MS) +;ARGD = flag: normally zero +;$80 if this read includes +;the last byte OR if it is +;completely outside the file. + +;The read is done starting at the current SFP. +;A call of RNDMAN.RDSUBO must be done at the start of each +;external GETBYTES operation, followed by one or more calls +;of RDGBTS. + +;*** N.B. Attempting a read partially or +;completely outside the file is not an error +;here. Transfer completely outside file +;will have been deletected in RDSUBO. + +;1) Get HANDTB entry from handle +;2) Get RANDTB entry +;3) BTSLFT := file size - SFP (bytes left) +;4) EOFFLG := 0 (end of file flag) +;5) IF transfer size < BTSLFT +;THEN BTSLFT := transfer size +;ELSE EOFFLG := $80 (end-of-file) +;6) BTSXFD := BTSLFT (bytes transferred) +;7) The transfer is done in 3 parts (any of which +;may be null). +;If the start address is not badly aligned on +;a disc block boundary, then STRMAN is called to +;get the required disc block into the cache. +;(It may still be there from the last GETBYTES call). +;The relevant bytes are copied into the buffer. +;We are now aligned to a disc block boundary, so +;can do a direct read by calling DSCMAN, provided +;at least 256 bytes remain to be read. +;The final partial block (if any) is read through +;the cache. + +RDGBTS ROUT + JSR INITRD ;GENPTR := user info; MCNUMB := machine no. + + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #20 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #20 ;Not found (object not file) + + LDYIM HTMODE + LDAIY HNDPTR ;check that file open for reading + ANDIM READAC + BNE #10 + LDAIM RDERRO + BNE #20 + +10 CLC ;CHECK CORRECT LIMIT + JSR RDBLFT ;BTSXFD := BTSLFT := +;min(transfer size, bytes left in file) +;Also sets EOFFLG + + JSR RDSBFA ;Set RDBFAD + + JSR RDGBT1 ;Read first partial disc block + BNE #20 ;Failed + + JSR RDGBT2 ;Read complete disc blocks in middle + BNE #20 ;Failed + + JSR RDGBT3 ;Read final partial disc block + ;BNE #20 + +;Reading worked OK + + ;LDAIM 0 + +;Exit: error code in A +;Bytes transferred in BTSXFD + +20 PHA ;Save error code + + LDYIM ARGB ;Return bytes tranferred + LDA BTSXFD + STAIY ARGPTR ;LS byte + INY + LDA BTSXFD+1 + STAIY ARGPTR ;MS byte + + INY + LDA EOFFLG ;Return EOF flag + STAIY ARGPTR + + PLA ;Restore error code + JMP RDEXIT ;Exit: RC in A + + + +;************ RDPBTS ************ + + +;RDPBTS: Put bytes to file + +;Entry: ARGA = func code (10) +;ARGB) = (LS) ptr to user info +;ARGC) = (MS) +;ARGD = file handle +;ARGE) = (LS) buffer address +;ARGF) = (MS) +;ARGG) = (LS) number of bytes to be written +;ARGH) = (MS) + +;Exit: ARGA = RC + +;The write is done starting from the current SFP. +;The file is extended if necessary. +;A call of RNDMAN.RDSUBO must be done at the +;start of each external PUTBYTES operation, +;followed by one or more calls of RDPBTS. + +;1) Get HANDTB entry from handle +;2) Get RANDTB entry +;3) Check open for writing +;4) (abolished) +;5) BTSLFT := file size - SFP (bytes left) +;6) IF transfer size > BTSLFT +;THEN extend file +;BTSLFT := transfer size +;7) BTSXFD := BTSLFT (bytes transferred) +;8) The write is done in 3 parts +;(any of which may be null). +;They are (a) via the cache, +;(b) directly to disc, and +;(c) via the cache, as for RDGBTS (q.v.). +;9) Adjust file HWM + +RDPBTS ROUT + JSR INITRD ;GENPTR := user info; MCNUMB:=machine no. + + LDYIM ARGD + LDAIY ARGPTR ;A := handle + JSR FNDHND ;HNDPTR := HANDTB entry + BNE #10 ;Not found - exit + + JSR SETRPT ;RTEPTR := RANDTB entry + BNE #10 ;Not found - exit + + LDYIM HTMODE ;Check file open for update + LDAIY HNDPTR ;Get mode + ANDIM WRITAC ;Write access + BNE #20 ;OK to write + + LDAIM RDERRN ;"Not open for update" +10 BNE #40 + +20 SEC ;CHECK CORRECT LIMIT + JSR RDBLFT ;BTSXFD := BTSLFT := +;min(transfer size, bytes left in file) + + LDA EOFFLG ;Get end-of-file flag + BEQ #30 ;Not end of file + +;Must call MAPMAN to extend file + + LDYIM ARGG ;**29/4/88** + LDAIY ARGPTR + STA NEWFSZ + INY + LDAIY ARGPTR + STA NEWFSZ+1 + JSR RDEXSZ ;**29/4/88** Extend file + BNE #40 ;Failed + +30 LDYIM ARGG ;BTSLFT := xfer size + LDAIY ARGPTR + STA BTSLFT + INY + LDAIY ARGPTR + STA BTSLFT+1 + + JSR RDSBFA ;Set RDBFAD + + JSR RDPBT1 ;Write 1st partial block + BNE #40 ;Failed + + JSR RDPBT2 ;Write complete disc blocks + BNE #40 ;Failed + + JSR RDPBT3 ;Write final partial block + BNE #40 ;Failed + +;Writing worked OK + + JSR RDSHWM ;Adjust file HWM + LDAIM 0 ;=> successful return +40 JMP RDEXIT ;EXIT: RC IN A + +; Routine to extend file. Called with amount required +; in NEWFSZ, NEWFSZ+1. Adds 4K to round up. +; Exit Z set if OK, else error code in A. + +RDEXSZ ROUT ;**29/4/88** + CLC + LDYIM RTCSFP ;NEWFSZ := SFP + xfer size + LDAIY RTEPTR ;SFP LS byte + ADC NEWFSZ ;xfer size (LS) + STA NEWFSZ + INY + LDAIY RTEPTR + ADC NEWFSZ+1 + STA NEWFSZ+1 ;CS + INY + LDAIY RTEPTR + ADCIM 0 + STA NEWFSZ+2 ;MS + LDAIM &8A + BCS #40 ;**29/4/88** Error if overflowed + + LDAIM &FF ;Add 255 to round up + CMP NEWFSZ+2 ;**29/4/88** Unless reaching 24 bits + BEQ #50 + CLC + ADC NEWFSZ ;Don't want LS byte + LDAIM 4 ;Add extra 1K + ADC NEWFSZ+1 + STA NEWFSZ+1 + BCC #25 + INC NEWFSZ+2 +25 LDAIM 0 + STA NEWFSZ ;Clear LS byte +30 JSR RDCHSZ ;**29/4/88** call change size routine +40 RTS + +50 STA NEWFSZ ;**29/4/88** getting near max, + STA NEWFSZ+1 ;**29/4/88** round up now to max + BNE #30 + + +;*** RDBLFT *** + +;Initialize BTSLFT, BTSXFD & EOFFLG +;for PUTBYTES/GETBYTES. +;Carry is used as entry condition ** 24/1/84 ** + +RDBLFT ROUT + LDAIM 0 + STA EOFFLG ;EOFFLG=0 + LDYIM RTFSZE ;BTSLFT := filesize - SFP + BCS #10 ;C=1 -> use filesize, use HWM + LDYIM RTHWM + SEC + +10 LDAIY RTEPTR ;** 24/1/84 ** + INY + STY RNDTMP + LDYIM RTCSFP + SBCIY RTEPTR + STA BTSLFT ;LS byte + LDY RNDTMP ;** 24/1/84 ** + LDAIY RTEPTR + LDYIM RTCSFP+1 + SBCIY RTEPTR + STA BTSLFT+1 ;CS Byte + INC RNDTMP ;** 24/1/84 ** + LDY RNDTMP ;next byte + LDAIY RTEPTR + LDYIM RTCSFP+2 + SBCIY RTEPTR ;MS byte left in A + + BCS #20 ;Size >= SFP + +;If filesize < SFP set BTSLFT to 0 + + LDAIM 0 ;BTSLFT := 0 + STA BTSLFT + STA BTSLFT+1 + +;Test xfer size > bytes left +;> if A non-zero (MS byte) +;or if xfer size > BTSLFT + +20 BNE #30 ;A not 0 + + SEC ;BTSLFT - xfer size + LDA BTSLFT + LDYIM ARGG + SBCIY ARGPTR + STA RNDTMP ;Store LS byte + LDA BTSLFT+1 + INY + SBCIY ARGPTR + ORA RNDTMP ;for zero test + BEQ #40 ;BTSLFT = xfer size + BCC #40 ;BTSLFT < xfer size + +;BTSLFT > xfer size: transfer OK +;Set BTSLFT := xfer size + +30 LDYIM ARGG + LDAIY ARGPTR + STA BTSLFT + INY + LDAIY ARGPTR + STA BTSLFT+1 + JMP #50 + +;BTSLFT < xfer size: transfer too long +;or outside file +;Set EOFFLG to $80 + +40 LDAIM &80 + STA EOFFLG + +;BTSLFT now says how many bytes can be +;transferred: set BTSXFD to this. + +50 LDA BTSLFT + STA BTSXFD + LDA BTSLFT+1 + STA BTSXFD+1 + + RTS + + +;*** RDSBFA *** + +;Set RDBFAD from call stack + +RDSBFA ROUT + LDYIM ARGE + LDAIY ARGPTR + STA RDBFAD + INY + LDAIY ARGPTR + STA RDBFAD+1 + RTS + + +;*** RDGBT1 *** + +;Read the first partial block of a GETBYTES +;transfer, taking the SFP to a disc block +;boundary. + +RDGBT1 ROUT + JSR RDSZE1 ;Get no. of bytes in A + CMPIM 0 + BEQ #10 ;Exit if empty partial block + STA RNDTMP ;Save no. of bytes + + JSR RDGBLK ;Get required block in cache + BNE #20 ;Failed + +;Copy from cache buffer to user buffer + + LDA RDBFAD ;MOVETO := RDBFAD + STA MOVTO + LDA RDBFAD+1 + STA MOVTO+1 + + LDYIM RTCSFP ;Offset in cache blk + LDAIY RTEPTR ;given by LS byte of SFP + CLC + ADC GENPTR + STA MOVFRM + LDA GENPTR+1 + ADCIM 0 + STA MOVFRM+1 + + LDX RNDTMP ;No. of bytes to copy + JSR MOVE ;Copy + JSR RDADJ1 ;Adjust BTSLFT, RDBFAD, SFP +10 LDAIM 0 ;Return +20 RTS + + +;*** RDPBT1 *** + +;Write the first partial block of a PUTBYTES +;transfer, taking the SFP to a disc block +;boundary. + +RDPBT1 ROUT + JSR RDSZE1 ;Get no. of bytes in A + CMPIM 0 + BEQ #10 ; Exit if empty partial block + STA RNDTMP ;Save no. of bytes + + JSR RDGBLK ;Get required block in cache + BNE #20 ;Failed + +;Copy from user buffer to cache buffer + + LDA RDBFAD ;MOVFRM := RDBFAD + STA MOVFRM + LDA RDBFAD+1 + STA MOVFRM+1 + + LDYIM RTCSFP ;Offset in cache blk + LDAIY RTEPTR ;given by LS byte of SFP + CLC + ADC GENPTR + STA MOVTO + LDA GENPTR+1 + ADCIM 0 + STA MOVTO+1 + + LDX RNDTMP ;No. of bytes to copy + JSR MOVE ;Copy + JSR MRKDRT ;Mark cache buffer dirty + JSR RDADJ1 ;Adjust BTSLFT, RDBFAD, SFP +10 LDAIM 0 ; Return +20 RTS + +;*** RDSZE1 *** + +;Return size of 1st partial block in A. +;size1 := (0 - LS byte of SFP) mod 256 +;size := min(size1, BTSLFT) + +RDSZE1 ROUT + LDAIM 0 + SEC + LDYIM RTCSFP + SBCIY RTEPTR ;0 - LS(SFP) + + LDX BTSLFT+1 ;Is BTSLFT > 256 + BNE #10 ; Yes + CMP BTSLFT + BCC #10 ;A < BTSLFT + LDA BTSLFT ;A > BTSLFT +10 RTS + + +;*** RDADJ1 *** + +;Adjust BTSLFT, RDBFAD, SFP by RNDTMP + +RDADJ1 ROUT + SEC ;BTSLFT -:= RNDTMP + LDA BTSLFT + SBC RNDTMP + STA BTSLFT + BCS #10 + DEC BTSLFT+1 +10 CLC ;RDBFAD +:= RNDTMP + LDA RDBFAD + ADC RNDTMP + STA RDBFAD + BCC RDADJ3 + INC RDBFAD+1 + +;RDADJ3 entry adjusts SFP only + +RDADJ3 CLC ;SFP +:= RNDTMP + LDYIM RTCSFP + LDAIY RTEPTR + ADC RNDTMP + STAIY RTEPTR + INY + LDAIY RTEPTR + ADCIM 0 + STAIY RTEPTR + INY + LDAIY RTEPTR + ADCIM 0 + STAIY RTEPTR + RTS + + +;*** RDGBT2 *** and *** RDPBT2 *** + +;Do middle part of GETBYTES or PUTBYTES transfer +;i.e. that part consisting of whole disc blocks. + +;The code is identical apart from the disc action. + +RDGBT2 ROUT + LDAIM 1 ;DSCMAN.READ + BNE #10 + +RDPBT2 LDAIM 2 ;DSCMAN.WRITE - PUTBYTES entry +10 STA RNDTMP ;Store disc action for later +;Determine how many whole blocks there +;are to be transferred. +;*** Assumes blocksize = 256 bytes *** + + LDA BTSLFT+1 ;Blocks = ms byte of bytes left + BEQ #20 ;Nothing to do + +;Must flush all blocks of object from +;cache before doing direct transfer. + + JSR RDFALL ;Leaves DISC & SIN on NEWARG stack + BNE #30 ;Failed + +;Call DSCMAN to READ/WRITE directly from/to +;caller's buffer. + +;Start block no. is given by MS +;two bytes of SFP. + + LDYIM RTCSFP+1 + LDAIY RTEPTR ;SFP (CS) + LDYIM ARGG + STAIY NEWARG ;Block no. (LS) + LDYIM RTCSFP+2 + LDAIY RTEPTR ;SFP (MS) + LDYIM ARGH + STAIY NEWARG ;Block no. (MS) + +;Number of blocks is given by MS +;byte of BTSLFT. + + LDA BTSLFT+1 + INY + STAIY NEWARG + LDAIM 0 ;MS byte of block count + INY ;always zero (in 64K machine) + STAIY NEWARG + + LDA RDBFAD ;Put buffer address on stack + INY + STAIY NEWARG + LDA RDBFAD+1 + INY + STAIY NEWARG + +;Operation code was placed in RNDTMP +;on entry to this routine. + + LDA RNDTMP + JSR SETRTN + JSR DSCMAN ;*** DSCMAN.READ or DSCMAN.WRITE ** + BNE #30 ;Failed + +;Must adjust SFP in RANDTB, RDBFAD, and BTSLFT +;*** Assumes blocksize 256 bytes *** + + LDA BTSLFT+1 ;No. of blocks + LDYIM RTCSFP+1 ;Add to CS byte of SFP + CLC + ADCIY RTEPTR + STAIY RTEPTR ;Put back + INY + LDAIM 0 + ADCIY RTEPTR ;Carry to MS byte of SFP + STAIY RTEPTR ;Put back + +;Adjust MS byte of RDBFAD by no. of blocks + + LDA BTSLFT+1 ;No. of blocks + ADC RDBFAD+1 ;MS byte of buffer addr + STA RDBFAD+1 ;Put back + +;Only a partial block remains, so MS +;byte of BTSLFT is now zero + + LDAIM 0 + STA BTSLFT+1 + +20 LDAIM 0 ; Return +30 RTS + +;*** RDGBT3 *** + +;Read the last partial block of a GETBYTES +;transfer + +RDGBT3 ROUT + LDA BTSLFT ;Get no. of bytes in A + BEQ #10 ;Nothing to do + JSR RDGBLK ;Get required block in cache + BNE #20 ;Failed + +;Copy from cache buffer to user buffer + + LDA RDBFAD ;MOVTO := RDBFAD + STA MOVTO + LDA RDBFAD+1 + STA MOVTO+1 + + LDA GENPTR ;MOVFRM := GENPTR + STA MOVFRM + LDA GENPTR+1 + STA MOVFRM+1 + + LDX BTSLFT ;No. of bytes to copy + STX RNDTMP ;Store for RDADJ3 below + JSR MOVE ;Copy + JSR RDADJ3 ;Adjust SFP +10 LDAIM 0 +20 RTS + +;*** RDPBT3 *** + +;Write the last partial block of a PUTBYTES +;transfer + +RDPBT3 ROUT + LDA BTSLFT ;Get no. of bytes in A + BEQ #10 ;Nothing to do + JSR RDGBLK ;Get required block in cache + BNE #20 ;Failed + +;Copy from user buffer to cache buffer + + LDA RDBFAD ;MOVFRM := RDBFAD + STA MOVFRM + LDA RDBFAD+1 + STA MOVFRM+1 + + LDA GENPTR ;MOVTO := GENPTR + STA MOVTO + LDA GENPTR+1 + STA MOVTO+1 + + LDX BTSLFT ;No. of bytes to copy + STX RNDTMP ;For RDADJ3 call below + JSR MOVE ;Copy + JSR MRKDRT ;Mark cache buffer dirty + JSR RDADJ3 ;Adjust SFP +10 LDAIM 0 +20 RTS + +;********* RDEOF ***************** + +;RDEOF: read "end of file" condition + +;Entry: ARGA = fn. code (#0F) +;ARGB = ptr. to user info (LS) +;ARGC = ptr. to user info (MS) +;ARGD = handle + +;Exit : ARGA = RC +;ARGB = zero if SFP <= HWM +;#FF if SFP => HWM + +RDEOF ROUT + JSR INITRD + LDYIM ARGD + LDAIY ARGPTR + JSR FNDHND ;Check handle/machine pair + BNE #30 ;Error -> exit + JSR SETRPT ;Set Random table ptr. (& check is file) + BNE #30 ;Not a file -> exit + + JSR CMPHWP ;Compare HWM with PTR + BEQ #10 ;Ptr = HWM -> exit w/$FF + LDAIM 0 + BCS #20 ;Ptr < HWM -> exit w/zero + +10 LDAIM &FF + +20 LDYIM ARGB + STAIY ARGPTR ;Set result + LDAIM 0 ;Set return code +30 JMP RDEXIT ;Return + + LNK RMAN05 diff --git a/Level3/SRC/L3/Rman05 b/Level3/SRC/L3/Rman05 new file mode 100644 index 0000000..1b7d0f5 --- /dev/null +++ b/Level3/SRC/L3/Rman05 @@ -0,0 +1,244 @@ + OPT RMAN05 ;RNDMAN > Rman05 + TTL File server file RMAN05 + + +;** RNDMAN UTILS ** + +;*** GETRND *** + +;Get free slot in RANDTB. + +;Exit: A = RC +;RTEPTR = Ptr to free RANDTB entry + +GETRND ROUT + LDA RANDTB ;RTEPTR := RANDTB + STA RTEPTR + LDA RANDTB+1 + STA RTEPTR+1 + + LDX RTNENT ;X := no. of entries in RANDTB + LDYIM RTINUS ;Y := offset of "in use" byte in entry + +10 LDAIY RTEPTR ;Get an "in use" byte + BEQ #20 ;Free entry found - exit A=0, Z set + + CLC ;RTEPTR +:= entry size + LDAIM RTENSZ + ADC RTEPTR ;LS byte + STA RTEPTR + BCC #15 + INC RTEPTR+1 ;MS byte +15 DEX ;Any entries left? + BNE #10 ;Jump if yes + +;No entries left + + LDAIM RDERRG ;"RANDTB full" +20 RTS + + +;*** RDCKAC *** + +;Check that the requested access to a file is allowed. +;Check first that the access is allowed in +;the directory entry, and secondly that it can +;be granted within a multiple reader / single +;writer regime (by scanning HANDTB). + +;Entry: ARGD (on ARGPTR) = requested access +;ARGE = allowed access (from directory entry) +;RNDPTR points to object details + +;Exit: A = RC +;HNDPTR is corrupted + +RDCKAC ROUT + LDYIM ARGD + LDAIY ARGPTR ;Get requested access + ANDIM RDWRAC ;Mask out type bit + STA RNDTMP ;Keep masked copy + INY + ANDIY ARGPTR ;AND with allowed access + CMP RNDTMP ;Should equal requested access + BEQ #10 ;Access allowed + LDAIM RDERRK ;"Access not allowed" + RTS + +10 JSR INITHD ;HNDPTR := HANDTB; X := no. of entries + +20 LDYIM HTHAND + LDAIY HNDPTR ;Is this an empty entry? + BEQ #30 ;Skip if empty + +;A used HANDTB entry: check disc no. and SIN +;against those of file we want to open. + + LDYIM INFDIS ;Compare disc numbers + LDAIY RNDPTR + LDYIM HTDISC + CMPIY HNDPTR + BNE #30 ;LS bytes differ + LDYIM INFDIS+1 + LDAIY RNDPTR + LDYIM HTDISC+1 + CMPIY HNDPTR + BNE #30 ;MS bytes differ + + LDYIM INFSIN ;Compare SINs + LDAIY RNDPTR ;A := LS byte of SIN for OPEN + LDYIM HTSIN + CMPIY HNDPTR + BNE #30 ;LS bytes differ + LDYIM INFSIN+1 + LDAIY RNDPTR + LDYIM HTSIN+1 + CMPIY HNDPTR + BNE #30 ;CS bytes differ + LDYIM INFSIN+2 + LDAIY RNDPTR + LDYIM HTSIN+2 + CMPIY HNDPTR + BNE #30 ;MS bytes differ + +;Have found an existing HANDTB entry for the SIN +;we want to open. +;Open can be permitted only if it is for reading, +;and the file is not already open for writing. + + LDYIM HTMODE + LDAIY HNDPTR ;A := mode in which already open + LDYIM ARGD + ORAIY ARGPTR ;OR requested access with that already granted + ANDIM WRITAC ;Look at write access bit + BEQ #30 ;Both for reading - proceed with search + +;The file is already open, and: +;either the request includes write access, or the +;file is already open with write access. + + JSR RDopat ;record 'open at' details + LDAIM RDERRH ;"File in use" + RTS + +;Have not yet found a reason to disallow the +;OPEN. Keep looking! + +30 JSR INCHND ;Point HNDPTR at next entry; X -:= 1 + BNE #20 ;back to start of loop + +;Have searched all of HANDTB - open may proceed + + LDAIM 0 ;set RC + RTS + + + +;*** RDopat *** + +;Record details of station at which a file is open (for use in error +; messages). HNDPTR points to the handle table entry for the object. + +RDopat ROUT ;**20/5/87** + LDYIM HTMCNO + LDAIY HNDPTR + STA MCopat + INY + LDAIY HNDPTR + STA MCopat+1 + INY + LDAIY HNDPTR + STA MCopat+2 + RTS + + +;*** CLRRTE *** + +;Clear entry in RANDTB pointed to by HANDTB entry +;whose address is in HNDPTR. + +CLRRTE ROUT + JSR SETRPT ;RTEPTR := address of RANDTB entry + + LDYIM RTENSZ-1 ;Y := size of RANDTB entry + LDAIM 0 +10 STAIY RTEPTR ;Clear whole entry to zero + DEY + BPL #10 ;Loop if more to do + RTS ;No result + + + +;*** RDFLSH *** + +;Flush all blocks of an object from cache. +;Called from CLRHTE when closing a file. + +;Entry: HNDPTR contains address of HANDTB entry + +RDFALL ROUT + LDAIM 5 ;STRMAN.remove all blocks + BNE #10 +;** 5/8/83 ** +RDFLSH LDAIM 9 ;STRMAN.REMOVEALLDIRTYWONDOWS +10 JSR SETRTN + JSR RDDSIN ;Put disc and SIN on stack + + JMP STRMAN ;*** Call STRMAN ** + + +;*** RDSHWM *** + +;IF seq file ptr > high water mark +;THEN high water mark := seq file ptr + +;Entry: RTEPTR points to RANDTB entry + +RDSHWM ROUT + JSR CMPHWP + BCS #10 ;SFP <= HWM, return + + LDYIM RTCSFP ;SFP > HWM, so copy + LDAIY RTEPTR ;SFP to HWM field + LDYIM RTHWM + STAIY RTEPTR ;LS byte + LDYIM RTCSFP+1 + LDAIY RTEPTR + LDYIM RTHWM+1 + STAIY RTEPTR ;CS byte + LDYIM RTCSFP+2 + LDAIY RTEPTR + LDYIM RTHWM+2 + STAIY RTEPTR ;MS byte +10 RTS + + + +;Compare High Water Mark with Seq. file +;ptr. and return CC if SFP>HWM, CS if +;SFP<=HWM. +;Also returns Z flag indicating EQ or not. + +;NOTE - corrupts RNDTMP + +CMPHWP ROUT + SEC + LDYIM RTHWM ;Subtract SFP from HWM + LDAIY RTEPTR ;LS byte of HWM + LDYIM RTCSFP + SBCIY RTEPTR ;Subtract LS bytes + STA RNDTMP + LDYIM RTHWM+1 + LDAIY RTEPTR + LDYIM RTCSFP+1 + SBCIY RTEPTR ;Subtract CS bytes + STA RNDTMP+1 + LDYIM RTHWM+2 + LDAIY RTEPTR + LDYIM RTCSFP+2 + SBCIY RTEPTR ;Sets carry if SFP <= HWM + ORA RNDTMP + ORA RNDTMP+1 ;Return Z flag indicating EQ or not + RTS + + LNK UADE0A diff --git a/Level3/SRC/L3/Uade01 b/Level3/SRC/L3/Uade01 new file mode 100644 index 0000000..c7d9d1b --- /dev/null +++ b/Level3/SRC/L3/Uade01 @@ -0,0 +1,398 @@ + OPT 2 ; FILE > Uade01 + TTL File server file UADE01 + + ORG &400 + +;************************* +;printing on/off per file +;************************* + +ON * 4+1 ;printer on, new page +OFF * 2 ;printer off + +UADE01 * Off +UADE02 * Off +UADE03 * Off +UADE04 * Off +UADE05 * Off +UADE06 * Off +RMAN01 * Off +RMAN02 * Off +RMAN03 * Off +RMAN04 * Off +RMAN05 * Off +UADE0A * Off +UADE0B * Off +UADE0C * Off +UADE0D * Off +UADE0E * Off +UADE0F * Off +UADE10 * Off +UADE11 * Off +UADE12 * Off +UADE13 * Off +UADE14 * Off +MBBMCM * Off +UADE15 * Off +UADE16 * Off +UADE17 * Off +UADE18 * Off +UADE19 * Off +UADE20 * Off + + OPT UADE01 ;select allotted printer option + +;********************************* +;* H E A D E R F I L E 1 * +;********************************* + +; Supported languages + +English * 0 +Italian * 1 ; **18/2/87** + +BBC * &00 +Winch * &00 ;If Winchester discs +Sys * &FF ;flags to indicate which type of FS +Ztime * &FF +FS * &FF +Dongle * 0 ;Real Time Clock present(=0) absent(=1) + +Debug * 0 ;Make this +ve for debug letters + +Verla * "3" ;Version level .... two digits +Verlb * "1" ;Range 0-99 20/7/88 +Lang * English +Mask * &3F ;protection state (&3F for service system) +Yes * 0 +No * &FFFF +Pseudods * No ; **18/2/88** Pseudo-directory (%, &, @) switch + +;*** MODULE CODE NAMES *** + +;* NOTE WHENEVER A MODULE IS ENTERED * +;* IT PLACES ITS NAME ON THE ARGUMENT * +;* STACK (THIS IS DONE BY THE ENTER RTN) * + + +MODUSR * &10 ;=> USRMAN (THE USERTB MANAGER) +MODAUT * &20 ;=> AUTMAN (THE AUTHENTICATOR) +MODSTR * &30 ;=> STRMAN (THE STORE MANAGER) +MODDIR * &40 ;=> DIRMAN (THE DIRECTORY MANAGER) +MODMAP * &50 ;=> MAPMAN (THE MAP MANAGER) +MODRND * &60 ;=> RNDMAN (THE RANDOM ACCESS MANAGER) +MODDSC * &70 ;=> DSCMAN (THE DISC MANAGER) +MODCOM * &80 ;=> CMND. PROCESSOR PSEUDO NAME + +EXTER0 * &C0 ;=> external (BBC Machine) number + +;USRMAN RETURN CODES + +URERRA * EXTER0-1 ;MACHINE NUMBER NOT IN USERTB +URERRB * EXTER0-8 ;USERTB FULL +URERRD * MODUSR+4 ;OBJECT NOT A DIRECTORY +URERRE * EXTER0-&12 ;USER NOT LOGGED ON +URERRF * MODUSR+6 ;M/C NUMBER EQUALS ZERO + +;STRMAN RETURN CODES + +STERRB * MODSTR+2 ;SIN = 0 +STERRD * MODSTR+4 ;REF COUNT = $00 +STERRE * MODSTR+5 ;SIZE TOO BIG OR SIZE=0 ! +STERRF * MODSTR+6 ;INVALID WINDOW ADDRESS +STERRG * MODSTR+7 ;NO FREE CACHE DESCRIPTORS +STERRH * MODSTR+8 ;WINDOW REF COUNT > 0 +STERRK * MODSTR+&0B ;REF COUNT = $FF +STERRL * MODSTR+&0C ;STORE DEADLOCK !! +STERRM * MODSTR+&0D ;ARITH OVERFLOW IN TSTGAP + +;DIRMAN RETURN CODES + +DRERRA * &CC ;INVALID SEPARATOR IN FILE TITLE +DRERRB * MODDIR+2 ;BROKEN DIRECTORY +DRERRC * &D6 ;OBJECT NOT FOUND +DRERRD * EXTER0-2 ;OBJECT NOT A DIRECTORY +DRERRE * EXTER0-3 ;INSUFFICIENT ACCESS +DRERRF * MODDIR+6 ;WRONG ARG TO SET/READ OBJECT ATTRIBUTES +DRERRG * &C3 ;DIR ENTRY LOCKED +DRERRI * &C2 ;OBJECT IN USE (I.E. OPEN) +DRERRJ * EXTER0-&C ;DIR NOT EMPTY +DRERRK * EXTER0-&11 ;TYPES DON'T MATCH +DRERRL * MODDIR+12 ;NO WRITE ACCESS +DRERRM * EXTER0-&D ;MAX DIR SIZE REACHED +DRERRN * MODDIR+14 ;CLIENT ASKS FOR TOO MANY ENTRIES +DRERRO * MODDIR+15 ;BAD ARG. TO EXAMINE +DRERRP * MODDIR+1 ;cdir too big + +;AUTMAN RETURN CODES + +ATERRA * MODAUT+1 ;CANNOT FIND PASSWORD FILE +ATERRB * EXTER0- 4 ;USERID NOT FOUND IN PW FILE +ATERRC * EXTER0- 5 ;INCORRECT PASSWORD +ATERRD * EXTER0- 6 ;INSUFFICIENT PRIVILEGE +ATERRE * EXTER0- 7 ;SYNTAX ERROR IN PASSWORD +ATERRF * EXTER0-&F ;USERID ALREADY IN PASSWORD FILE +ATERRG * &AC ;bad user name in PW file**13/4/83** +ATERRH * EXTER0-&E ;PASSWORD FILE FULL UP +ATERRI * MODAUT+9 ;OBJECT '$.PASSWORDS' HAS WRONG TYPE + + +;RNDMAN RETURN CODES + +RDERRA * MODRND+1 ;RNDMAN.RESTART CALLED TWICE +RDERRB * &DE ;INVALID HANDLE +RDERRC * &C0 ;HANDLE QUOTA EXHAUSTED +RDERRD * MODRND+4 ;HANDTB FULL +RDERRE * RDERRA ;OBJECT NOT OPEN +RDERRF * MODRND+6 ;RNDMAN.COPY NOT FOR FILE OBJECTS +RDERRG * MODRND+7 ;RANDTB FULL +RDERRH * &C2 ;File already open +RDERRI * MODRND+9 ;Object not file +RDERRJ * &DF ;END OF FILE +RDERRK * DRERRE ;Insufficient access +RDERRL * EXTER0-&9 ;Attempt to point outside file +RDERRM * MODRND+&0D ;Invalid arg to RDSTAR +RDERRN * &C1 ;File not open for update +RDERRO * &D4 ;File not open for input ** 15/11/84 ** + + + +;MAPMAN RETURN CODES + +MPERRA * &C8 ;DISC NUMBER NOT FOUND +MPERRB * &C6 ;DISC SPACE EXHAUSTED +MPERRC * MODMAP+3 ;SIN NOT FOR START OF CHAIN +MPERRD * MODMAP+4 ;DISC NOT A FILE SERVER DISC +MPERRF * MODMAP+6 ;ILLEGAL DRIVE NUMBER +MPERRI * MODMAP+9 ;NEW MAP DOESN'T FIT IN OLD SPACE +MPERRJ * MODMAP+&0A ;DISC OF SAME NAME ALREADY IN USE ! +MPERRK * &D6 ;DISC NAME NOT FOUND +MPERRL * EXTER0-&A ;DISC ERROR ON MAP READ/WRITE +MPERRM * MODMAP+11 ;NO MORE SPACE IN MAP DESCRIPTORS +MPERRN * MODMAP+12 ;Insufficient user free space (yay!) + + +;DSCMAN RETURN CODES + +DCERRA * MODDSC+1 ;INVALID NUMBER OF SECTORS +DCERRB * MODDSC+2 ;STORE ADDRESS OVERFLOW +DCERRC * MODDSC+3 ;ACCESSING BEYOND END OF FILE +DCERRE * &C9 ;DISC PROTECTED +DCERRF * &C7 ;UNRECOVERABLE DISC ERROR + + +;COMMAND PROC Errors + +RNAMQQ * EXTER0-&10 ;Renaming across two discs +LODERA * EXTER0-&B ;Trying to load a directory +LODERB * DRERRE ;Insufficient access +SAVERA * MODCOM+3 ;Too much data sent from client +WAITER * MODCOM+4 ;Wait bombs out +COERRA * MODCOM+5 ;Invalid function code + +SAERRA * &CF ;Invalid setaccess string +SYNERR * &DC +NAMERR * &FD ;Bad file name etc. +NUMERR * &F0 ;Bad number +SAERRC * MODCOM+&0A ;File too big +WOTERR * &FE +SPERRA * MODCOM+&0C ;Bad privilege letter +PBERRA * MODCOM+&0D ;Excess data in PUTBYTES +INFERA * MODCOM+&0E ;Bad INFO argument. +ARGERR * MODCOM+&0F ;Bad arg to RDAR +DTERR * MODCOM+&10 ;Bad date and time + + +;INTERNAL ERRORS + +IERRAA * 1 ;(SETFS) FRAME SIZE TOO BIG +IERRAB * 2 ;(ENTRY) FUNCT CODE = 0 +IERRAC * 3 ;(ENTRY) UNKNOWN ENTRY REASON +IERRAD * 4 ;(GETVEC) SIZE TOO BIG +IERRAE * 5 ;(GETVEC) INSUFFICIENT SPACE +IERRAF * 6 ;(GETVEC) SIZE OF STORE REQUESTED = 0 +IERRAH * 8 ;(GETINT) NOT A DIGIT +IERRAI * 9 ; UNABLE TO OPEN RXCB +IERRAJ * 10 ;(RDBTMP) BIT MAP DISC ERROR +IERRAK * 11 ;writing to sector zero + + + ;NEW ERRORS FOR LEVEL3 + + ;F4 ;Memory map error + ;F5 ;Internal bit map cache error + ;F6 ;cached bit map holds no free sectors + ;F8 ;write error (data read <> data written) + ;F9 ;attempting to zero an illegal amount of disc + ;FA ;multiple block allocate fails + ;FB ;memory error during initial MEMTST + ;FC ;single block allocate fails + +;COMMAND CODES SENT TO CLIENT + +CCSAVE * 1 +CCLOAD * 2 +CCCAT * 3 +CCINF * 4 +CCLGON * 5 +CCSDIS * 6 +CCSDIR * 7 +CCCMND * 8 +CCSLIB * 9 +CCDSCS * &A +CCUSRS * &B + +;M A N I F E S T S +;ODDS AND ENDS +Oswrch * &FFEE ;BBC addresses here +Osrdch * &FFE0 +Oscrlf * &FFE7 +Oscli * &FFF7 +Osasci * &FFE3 +Osword * &FFF1 +Osbyte * &FFF4 + +Stksze * &FF ;Size of argument stack +FDcyls * 80 ;No of cylinders per floppy +FDside * 2 ;No of sides per disc +FDsecs * 16 ;No of sectors per track (side) +Maxuse * 80 ;Maximum number of users +Baseyr * 81 ;Base year for date = 1981 +Thisyr * 88 ;Earliest year acceptable + +ESC * &1B +ABTCH * "Q" +ACK * 6 +NACK * &15 + +;DIRTY MARKER (CLEAN=0) + +DIRTY * &FF +UNLKIT * &FF + +;INTER MODULE ARGUMENT STACK CONSTANTS + +FRAMSZ * 0 ;POSN OF FRAME SIZE ON ARGUMENT STACK +MODNME * 1 ;POSN OF MODULE NAME ON ARGUMENT STACK +ENTRES * 2 ;POSN OF MODULE ENTRY REASON ON ARGUMENT STACK +FINFO * ENTRES+1 ;SIZE OF INFO STORED ON ARGUMENT STACK + +ARGA * FINFO ;FOR FUNCTION CODE AND RETURN CODE +ARGB * ARGA+1 +ARGC * ARGB+1 +ARGD * ARGC+1 +ARGE * ARGD+1 +ARGF * ARGE+1 +ARGG * ARGF+1 +ARGH * ARGG+1 +ARGI * ARGH+1 +ARGJ * ARGI+1 +ARGK * ARGJ+1 +ARGL * ARGK+1 +ARGM * ARGL+1 +ARGN * ARGM+1 +ARGO * ARGN+1 +ARGP * ARGO+1 +ARGQ * ARGP+1 +ARGR * ARGQ+1 +ARGS * ARGR+1 +ARGT * ARGS+1 + +;DISC BLOCK SIZE +BLKSZE * &100 ;= 256 BYTES + + +;FLAGS AND MASKS (ACCESS BITS ETC.) +READAC * 1 ;BIT0 -> READ ACCESS +WRITAC * 2 ;BIT1 -> WRITE ACCESS +LOCKED * &10 ;BIT4 -> LOCK BIT +TYPE * &20 ;BIT5 -> TYPE BIT (DIR/FILE) +LOPRIV * &20 ;BIT5 -> Low privilege bit +OWNER * &40 ;BIT6 -> OWNER ACCESS BIT +SYSTPV * &40 ;BIT6 -> SYSTEM PRIVILEGE +NTSYST * &BF ;Complement of SYSTPV +INUSE * &80 ;BIT7 -> IN USE BIT +FILEJC * &80 ;BIT7 -> FILE JUST CREATED +TYPFIL * 0 ;OBJECT TYPE = FILE +TYPDIR * &20 ;OBJECT TYPE = DIRECTORY +ANYBDY * 0 ;ANYBODY ACCESS +RDWRAC * 3 ;READ WRITE ACCESS +RWLACC * &13 ;Read/write/locked access +ACCDEF * &C ;Owner RW, public no access +TXFLAG * &80 +RXFLAG * &7F +MONON * &FF +MONOFF * 0 ;Monitor switch + + +;D O S ROUTINES AND ADDRESSES + +TRADD * 1 +CMD * 5 +LENGTH * &B + +;PAGE ZERO + + ^ &B0 +ARGPTR # 2 ;PTR TO CUR STK ARGS +NEWARG # 2 ;PTR TO NEW ARGS + + ^ &20 +CLRPTR # 2 ;PTR USED BY CLRSTR RTN +MOVFRM # 2 ;PTR USED BY MOVE & COMPAR RTNS +MOVTO # 2 ;PTR USED BY MOVE & COMPAR RTNS +COMPTR # 2 ;PTR TO COMND LINE (RDLINE) +GENPTR # 2 ;PTR AVAILABLE TO ALL MODULES +USTPTR # 2 ;PTR TO USERTB (USRMAN/FINDMC) +URMPPT # 2 ;PTR TO USERINFO(USRMAN) +PREV # 2 ;PTR TO PREVIOUS CACHE ENTRY(STRMAN) +CRNT # 2 ;PTR TO CURRENT CACHE ENTRY(STRMAN) +CMPPTR # 2 ;PTR TO ARGUMENTS (STRMAN) +NAMPTR # 2 ;PTR TO FILE TITLE (DIRMAN) +PREVEN # 2 ;PTR TO PREVIOUS DIR ENTRY (DIRMAN) +CRNTEN # 2 ;CURRENT DIR ENTRY (DIRMAN) +TXTPTR # 2 ;USED TO PT TO CHARS IN TXTNAM(DIRMAN) +DIRFRE # 2 ;PTR TO FREE CHAIN PTR (DIRMAN) +INFPTR # 2 ;PTR TO STORE AREA FOR RETRIEVE INFO +DPTRLD # 2 ;PTR TO FIRST BYTE OF A DIR +DPTRTR # 2 ;PTR TO LAST BYTE OF DIR +DRUSIN # 2 ;PTR TO USERINFO +HNDPTR # 2 ;PTR TO HANDLE INFO (SET BY FNDHND) +RNDPTR # 2 ;PTR TO OBJECT DETAILS (RNDMAN) +RNDTMP # 3 ;Temp (RNDMAN) ** +AUTPTR # 2 ;POINTER TO USERID (AUTMAN) +PWFPTR # 2 ;PASSWORD FILE POINTER(AUTMAN) +ATUSPT # 2 ;PTR TO AUTMAN'S USERINFO AREA +JWORK # 2 ;Used in UADE14 +MAPPTR # 2 ;PTR TO BASE OF DISC MAP +MPSCPT # 2 ;POINTER INTO MAP +MPMBPT # 2 ;MAP BLOCK PTR +MAPENT # 2 ;PTR. TO MAP TABLE ENTRY +MPCYPT # 2 ;PTR TO CYLINDER MAP +MAPGEN # 2 ;GENERAL MAP MANAGER PTR +GNCBPT # 2 ;GENERAL CONTROL BLOCK POINTER +DNMPTR # 2 ;PTR TO DISC NAME (MAPMAN) +DNMBUF # &12 ;DISC NAME BUFFER +DSCTMP # 2 ;PTR TO A MAP'S DIRTY FLAG (DSCMAN) +CVTUPT # 2 ;USER INF. PTR. CVT. PROG. +SCTPTR # 2 ;PTR TO SECTOR ZERO (SEE STRTFS) +NETCB # 2 ;POINTER TO NET CONTROL BLOCK (C.PROC.) +RTEPTR # 2 ;Ptr. to RNDTAB entry +RDUPTR # 2 ;Ptr. to user id. in RNDPTR +COZERO # 12 ;12 byte area used by C.proc. + ;zero page used in RENAME 24/9/84 +LAST * COZERO +NAME * LAST+1 +ONAME * NAME+1 +RTYPE * ONAME+1 +PTR * RTYPE+1 +PTR1 * PTR+2 +REXIST * PTR1+2 + ;*** +VSTPTR # 2 ;are used by VSTRNG only +OLDEV # 2 +GP1 # 2 ;ANOTHER GENERAL POINTER + +BRKPTR * &FD ;2 byte pointer used in MOS BRK handling + + LNK UADE02 diff --git a/Level3/SRC/L3/Uade02 b/Level3/SRC/L3/Uade02 new file mode 100644 index 0000000..6eee948 --- /dev/null +++ b/Level3/SRC/L3/Uade02 @@ -0,0 +1,569 @@ + OPT UADE02 ; > Uade02 + TTL File server file UADE02 + +;********************************** +;* H E A D E R F I L E 2 * +;********************************** + +BRKVEC * &202 +BPUTV * &218 +TSTART * &F800 + +;*** STRMAN MANIFESTS *** +;CACHE ENTRY DESCRIPTOR OFFSETS + ^ 0 +CEDISC # 2 ;DISC NO +CESIN # 3 ;SIN OF OBJECT +CEBKNO # 2 ;START BLOCK NUMBER IN OBJECT +CEBLKS # 2 ;NUMBER OF BLOCKS OCCUPIED BY WINDOW +CESTA # 2 ;STORE ADDRESS OF OBJECT +CERCNT # 1 ;REFERENCE COUNT +CEAGE # 1 ;AGE FOR LRU REPLACEMENT ALGORITHM +CENEXT # 2 ;PTR TO NEXT DESCRIPTOR +CESIZE * @ ;SIZE OF A DESCRIPTOR +;THE ADDRESS OF DIRTY FLAG IS = STORE ADDRESS OF WINDOW - 1 + +;STRMAN BUFFER SIZE +LGBFSZ * 6 * BLKSZE ;SIZE OF A LARGE BUFFER(MUST BE MULTIPLE OF BLKSZE) +;** 6/12/84 ** + +;BUFFER AGES +LRU * 1 ;=> LEAST RECENTLY USED +MRU * &FF ;=> MOST RECENTLY USED + +;*** DIRMAN MANIFESTS *** +;DIRECTORY OFFSETS +;(HEADER INFORMATION) +;NOTE THAT A ONE BYTE SEQUENCE NUMBER (INCREMENTED WHEN +;WRITING A DIR TO DISC) BRACKETS A DIRECTORY. +;THE LEADING SEQUENCE NUMBER GOES AT BYTE OFFSET 2 +;AND THE TRAILING SQ NO IS THE LAST BYTE OF A DIR. +;THESE SQ NOS ARE USED TO DETECT DIRS WHICH HAVE NOT +;BEEN WRITTEN TO DISC COMPLETELY - +;NOTE DIRS CAN BE MULTI-SECTOR OBJECTS. +;SQ NOS ARE CHECKED WHENEVER A DIR IS LOADED. + ^ 0 +DRFRST # 2 ;PTR TO 1ST ENTRY (N.B. DON'T CHANGE THIS) +DRSQNO # 1 ;LEADING SEQUENCE NUMBER (1 BYTE) +DRNAME # &A ;(NAMLNT BYTES) DIRECTORY NAME +DRFREE # 2 ;PTR TO 1ST FREE ENTRY +DRENTS # 2 ;NUMBER OF DIRECTORY ENTRIES +DRSTAR # 0 ;FIRST ENTRY IN DIR +;(OFFSETS IN ENTRY) + ^ 0 +DRLINK # 2 ;PTR TO NEXT ENTRY (DON'T ALTER THIS) +DRTITL # &A ;TEXT NAME (PADDED WITH ZEROES) +DRLOAD # 4 ;LOAD ADDRESS +DREXEC # 4 ;EXECUTE ADDRESS +DRACCS # 1 ;ACCESS INFO +DRDATE # 2 ;DATE OF CREATION +DRSIN # 3 ;SIN OF OBJECT +DRENSZ * @ ;SIZE OF DIRECTORY ENTRY + +;OFFSETS FOR DETAILS RETRIEVED FROM A DIRECTORY +;NOTE THAT IF THE SIZE OF THE INFORMATION (INFNXT) IS +;EVER CHANGED YOU MUST CHANGE THE SIZE OF THE +;BUFFERS:- USWORK,ATUSRI + ^ 0 +INFNAM # &A ;FILE TITLE +INFLOA # 4 ;LOAD ADDRESS +INFEXE # 4 ;EXECUTE ADDRESS +INFACC # 1 ;ACCESS INFO (TYPE & ACCESS VECTOR) +INFDTE # 2 ;DATE OF CREATION +INFSIN # 3 ;SIN OF OBJECT +INFDIS # 2 ;DISC NUMBER +INFSZE # 3 ;SIZE OF OBJECT +INFNXT * @ ;NUMBER OF BYTES IN DETAILS + +;DIRMAN CONSTANTS +ACCMSK * &1F ;BITS 0 -> 4 (LWR/WR) +TLAMSK * &3F ;=> type/LWRWR mask +RWMSK * &F ;BITS 0 -> 3 (WR/WR) +DISCIN * ":" ;INDICATES DISC NAME IN FILE TITLE +TERMIN * &D ;STRING TERMINATOR +SEPART * "." ;FILE NAME SEPARATOR +NAMLNT * &A ;MAX LENGTH OF TEXT NAME (10 CHARS) +SPACE * " " ;SPACE CHARACTER +ROOT * "$" ;NAME OF ROOT DIRECTORY +MAXDIR * ((:MSB:(DRSTAR+255*DRENSZ))+1)*&100 + ;MAX SIZE A DIR IS ALLOWED TO BE +ENTTRM * 0 ;ENTRY TERMINATOR +EXTERM * &80 ;BLOCK TERMINATOR +JMPINS * &4C ;JMP INSTRUCTION +MAXENA * LGBFSZ / 27 ;NO. OF ENTRIES TYPE A +MAXENB * LGBFSZ / 68 ;"" "" " B +MAXENC * LGBFSZ / 11 ;"" "" " C +MAXEND * LGBFSZ / 18 ;"" "" " D + + +;*** AUTMAN & USRMAN MANIFESTS *** + +MAXPW * 6 ;MAX SIZE OF PASSWORD +MAXID * 10 ;MAXIMUM SIZE OF SINGLE USER ID +MAXUNM * 2 * MAXID+1 ;MAX USER IDS PLUS DOT +UTFRLN * 4 ;length of free space counter + +;PASSWORD FILE OFFSETS + ^ 0 +PWUSID # MAXUNM-1 ;USERID +PWPASS # MAXPW ;PASSWORD +PWFREE # UTFRLN ;free space for this user +PWFLAG # 1 ;FLAG (INUSE & SYSTEM PRIV) +PWENSZ * @ ;SIZE OF PASSWORD FILE ENTRY + +;*** USRMAN MANIFESTS *** +;USERTB OFFSETS + ^ 0 +UTMCNO # 3 ;START OF MACHINE NO **25/12/86* +UTUSID # MAXUNM+1 ;START OF USERID +UTDISC # 2 ;CURRENTLY SELECTED DISC NUMBER +UTPRIV # 1 ;SYSTEM PRIVILEGE & INUSE FLAG +UTHSLD # 1 ;HANDLE FOR SELECTED DIR + [ Pseudods = Yes +UTHUFD # 1 ;**26/6/87** handle for logon directory + ] +UTHNDB # 1 ;BYTE INDICATING HANDLES IN USE PER MC +UTFREE # UTFRLN ;User disc space allocation ** 2/10/84 ** +UTENSZ * @ ;SIZE OF A USERTB ENTRY +OPTMSK * &F ;Mask for user option bits +NTOPT * &F0 ;Complement of OPTMSK + + +;*** RNDMAN MANIFESTS *** +;HANDLE TABLE OFFSETS (HANDTB) + ^ 0 +HTHAND # 1 ;HANDLE NUMBER +HTMCNO # 3 ;MACHINE NUMBER OF OWNING M/C *25/12/86** +HTACC # 1 ;ACCESS TO & TYPE OF OBJECT +HTDISC # 2 ;DISC NUMBER OF OBJECT +HTSIN # 3 ;SIN OF OBJECT +HTMODE # 1 ;MODE OF USE FOR WHICH OPENED +HTRPTR # 2 ;Ptr. to RANDTB entry (2 bytes) +HTENSZ * @ ;SIZE OF A HANDTB ENTRY + +;RANDTB OFFSETS + ^ 0 +RTCSFP # 3 ;Current sequential file pointer +;Note RDSTAR in randman assumes that the +;two pointers are consecutive in this table +RTOSFP # 3 ;Old sequential file pointer +RTHWM # 3 ;HIGH WATER MARK +RTFSZE # 3 ;FILE SIZE +RTDESC # 2 ;ADDRESS OF CACHE DESCRIPTOR(HINT) +RTINUS # 1 ;INUSE+SEQ. NUMBER +RTENSZ * @ ;SIZE OF EACH RANDTB ENTRY + +;*** MAPMAN MANIFESTS *** +;MAPTB OFFSETS + ^ 0 +MPDCNO # 2 ;DISC NUMBER +MPNOCY # 2 ;NUMBER OF CYLINDERS +MPSECS # 3 ;NO. OF SECTORS PER DISC +MPDSCS # 1 ;NUMBER OF DISCS +MPSPCY # 2 ;SECTORS PER CYLINDER +MPBMSZ # 1 ;SIZE OF BIT MAP IN BLOCKS +MPADFT # 1 ;ADDED TO GET NEXT PHYSICAL DISC +MPDRNC # 1 ;INCREMENT TO NEXT LOGICAL DRIVE +MPRTSN # 3 ;SIN OF ROOT DIRECTORY +MPRTDT # 2 ;ROOT DATE +MPSCYL # 2 ;START CYLINDER +MP1BIT # 1 ;Non-zero if packed map, gives bytes/cyl +MPSZLN * @ ;End of part copied from sector zero +MPSCTT # 3 ;TOTAL NUMBER OF SECTORS +MPCYMP # 2 ;STORE ADDRESS OF CYLINDER MAP +MPTBSZ * @ ;SIZE OF MAPTB ENTRY + +;** SECTOR ZERO INFO ** + ^ 0 +MPDRNM # 4 ;POSN OF 'AFS0' IN SECTOR 0 +MPSZNM # &10 ;POSITION OF NAME IN SEC. ZERO +MPSZNC # 2 ;NUMBER OF CYLINDERS PER DISC +MPSZNS # 3 ;NUMBER OF SECTORS PER DISC +MPSZDN # 1 ;NUMBER OF DISCS +MPSZSC # 2 ;SECTORS PER CYLINDER +MPSZSB # 1 ;SIZE OF BIT MAP +MPSZAF # 1 ;ADDITION FOR NEXT PHYSICAL DISC +MPSZDI # 1 ;INCREMENT FOR NEXT LOGICAL DRIVE +MPSZSI # 3 ;SIN OF ROOT +MPSZDT # 2 ;DATE OF ROOT +MPSZSS # 2 ;START SECTOR +MPSZ1B # 1 ;Non-zero if packed map, gives bytes/cyl +SZOFF * &F6 ;OFFSET TO DRIVE DATA SECTOR + +; MAP BLOCK POINTERS + ^ 0 +BLKSN # 3 +BLKNO # 3 +MBSQNO # 1 +MGFLG # 1 +BILB # 2 +MBENTS * @ ;START OF MAP BLOCK ENTRIES +ENSZ * 5 ;BYTES IN MAP BLOCK ENTRY +MXENTS * 49 +LSTENT * MBENTS+(MXENTS-1)*ENSZ ;a better definition +LSTSQ * 255 +BTINBK * 256 ;BYTES IN A NORMAL DISC BLOCK +; +;BIT MAP FLAGS + +MPVAL * &FF ;offset of 'next bitmaps valid' flag + +; +; OFFSETS IN CACHE CONTROL BLOCK +; + ^ 0 +CAFLG # 1 +CBDA # 3 +CBSA # 2 +CBDR # 1 +CBAGE # 1 +CBSZ * @ +; +; INFORMATION ABOUT BIT MAP AND MAP BLOCK CACHES +; +NOBTMP * 5 ;NUMBER OF BIT MAP CACHE BLOCKS +NOMPBK * 15 ;NUMBER OF MAP BLOCK CACHE ENTRIES +SZBMAR * NOBTMP*BTINBK ; NUMBER OF BYTES IN BIT MAP CACHE +SZMBAR * NOMPBK*BTINBK ; NUMBER OF BYTES IN MAP BLOCK CACHE +SZBMCB * NOBTMP*CBSZ ; SIZE OF CACHE CONTROL BLOCK ENTRIES +SZMBCB * NOMPBK*CBSZ ; DITTO FOR MAP BLOCKS + +;NAME TABLE OFFSETS ETC. +DNAMLN * &10 ;SIZE OF DISC NAME +NTSIZE * 7 ;NO. OF ENTRIES +USED * 0 ;IN USE VALUE +UNUSED * &FE ;MOST RECENTLY USED VALUE + ^ 0 +NTNAME # DNAMLN ;DISC NAME +NTDNO # 2 ;DISC NO. +NTUSED # 1 ;IN USE PTR. +NTENSZ * @ ;SIZE OF ENTRY + +;PAGE ZERO ADDRESSES +;NOTE THAT DOS USES (AD,C9,CB,DA->FF) FOR DISC I/O + [ SYS=0 +SAVCOM * &AD ;DISC TRANSFER COMMAND(READ/WRITE) +TRACK * &DA +SECTOR * &DB +WORK * &DF ;(DISC DRIVER DESCRIPTOR BLOCK) +DDRSTA * WORK ;STORE ADDRESS FOR BLKRD & BLKWR +DDRSPA * DDRSTA + 2 ;SPARE (I.E. NOT USED BY DISC DRIVER) +DDRSZE * DDRSPA + 2 ;NUMBER OF BYTES (LS FIRST) TO BE TRANSFERED +DDRSCT * DDRSZE + 2 ;LOGICAL START SECTOR NUMBER (MS FIRST) +CNTA * &F1 ;NUMBER OF RETRIES STILL TO GO +SECTNO * &F2 ;NUMBER OF SECTORS TO TRANSFER +RAMADR * &F7 ;2 BYTE STORE ADDRESS + ] + +;*** COMMAND PROC. MANIFESTS *** +;CONSTANTS +RXBUFL * 127 ;**8/2/88** Receive buffer length (<=127) +COPORT * &99 +FIFLSZ * &400 ;Initial size of file created by FIND +BUFSZ * &500 ;TX BUFFER SIZE +;Function numbers +DRPRS * 1 ;Preserve in dir. man. +DRRTR * 2 ;Retrieve in dir. man +MAPCS * 1 ;Create map space +MAPFS * 2 ;Free map space +MAPENS * 6 +;Bits and pieces +WAITCL * &50 ;No. of msecs wait for client +ONEMS * 5 ;No. of loops to give 1 msec (see WAIT) + +PSAVD * COPORT+1 ;Data port in save +TXRPT * &FF ;Do 255 times +TXDLY * &14 ;Delay 20 msec +LF * &A +CR * &D +DOT * "." +FCCMND * 5 ;To recognise a command +FCCRET * 29 ; The create command 11/6/84 BC +HDRLEN * 5 ;Header of INCOMING message +MCTASK * &78 ;Mask for task number in control byte **1/5/86** +TXHDR * 2 ;Header length of OUTGOING message +CLIDLM * CR ;Delimiter in CLI table +CLIDL1 * CLIDLM-1 +SAVFTO * HDRLEN+&B +LODFTO * HDRLEN +EXAFTO * HDRLEN+3 +INFFTO * HDRLEN+1 +FNDFTO * HDRLEN+2 ;File find, not dir. find ?? + + +;STORE POINTERS + [ SYS=0 +FRESTR * &7A00 + | + [ WINCH=0 + [ DONGLE = 0 +FRESTR * &8A00 + | +FRESTR * &8B00 + ] + | +FRESTR * &7A00 ;FIRST FREE STORE LOCATION + ] + ] + +;STORE POINTERS + ^ FRESTR +STKPTR # 2 ;VAL OF HARDWARE STACK PTR (STOP) +FREPTR # 2 ;PTR TO FREE STORE (GETVEC) +ENDPTR # 2 ;PTR TO END OF FREE STORE (GETVEC) +BIGBUF # 2 ;PTR TO BIG BUFFER (STRMAN) +NUMBCE # 1 ;NO. OF CACHE DECRIPTORS +CACHSZ # 2 ;CACHE SIZE + +USERTB # 2 ;PTR TO START OF USERTB (USRMAN) +TITPTR # 2 ;PTR TO DIR NAME +USDISC # 2 ;HOLDS DISC NUMBER FOR USRMAN +USRACC # 1 ;ACCESS TO DIRECTORY +USRROT # 1 ;ROOT CHARACTER +USRSEP # 1 ;SEPARATOR CHARACTER +USRUFD # MAXUNM ;USERID +USRTER # 1 ;DIR NAME TERMINATOR +USRINF # INFNXT ;OBJECT DETAILS AREA(SEE DIRMAN.RETRV) +USWORK # 2 ;USRMAN WORK VARIABLE +USTEMP # 1 ;Temp general USRMAN store +UMHUFD # 1 ;Temp UFD store. +UMHCSD # 1 +UMHLIB # 1 +MCTEMP # 3 ;M/C NUMBER **25/12/86** +USERS # 1 ;NO. OF USERS +USSYS # 1 ;flag to indicate priv'd user logged on +CACHTB # 2 ;PTR TO FIRST CACHE ENTRY DESCRIPTOR +FRECHN # 2 ;PTR TO CHAIN OF FREE CACHE DESCRIPTORS +AMTNED # 2 ;AMOUNT OF STORE NEEDED FOR OBJECT +STRTMP # 2 ;STRMAN TEMP VARIABLE +BSTSTA # 2 ;BEST START POSITION +BSTEND # 2 ;BEST END POSITION +MINCST # 2 ;MINIMUM COST +COST # 2 +HANDTB # 2 ;PTR TO START OF HANDLE TABLE (RNDMAN) +RANDTB # 2 ;PTR TO START OF RANDOM ACCESS TABLE +RDBFAD # 2 ;Current buffer position (RNDMAN) +BTSXFD # 2 ;Bytes xferred in PB/GB (2 bytes) (RNDMAN) +BTSLFT # 2 ;Bytes left to transfer (2 bytes) +NEWFSZ # 3 ;New file size (arg to RDCHSZ routine) - 3 bytes +EOFFLG # 1 ;End-of-file flag (RNDMAN) +HTENTS # 1 ;NO. OF HAND. TBL. ENTRIES +RTNENT # 1 ;No. of RANDTB entries +INTEGR # 1 ;To hold an integer (RDINT) +GVWRKA # 2 ;GETVEC WORK VARIABLE +ENWRKA # 2 ;ENTRY WORK VAR +TEMPA # 2 +TEMPB # 2 +MCNUMB # 3 ;MC/NO LOOKED UP IN USERTB(USRMAN-FINDMC) **25/12/86** +DATE # 3 ;3 BYTE DATE VALUE Last byte = day + [ Dongle=0 +ORB # 1 +IRB # 1 +DDRB # 1 + ] +TIME # 5 ;TIME OF DAY +OTIME # 5 ;COMPARISON +NTIME # 5 ;WORK VARIABLE FOR TIME +SECS # 1 ;SECONDS +MINS # 1 ;MINUTES +HRS # 1 ;HOURS +DAYS # 1 +MUNTHS # 1 +REM # 1 ;DIVISION REMAINDER +DVSOR # 1 ;DIVISOR +DATBUF # &C ;Buffer for time chip data +LASTNM # 2 ;PTR TO 1ST CHAR OF LAST TEXT NAME(DIRMAN) +DRDSNM # &11 ;BUFFER TO HOLD DISC NAME(17BYTES) +DIRACC # 1 ;) TYPE & ACCESS TO DIR (OWNER/ANYBODY) +DRDISC # 2 ;) DISC NO OF CURRENT DIR +DIRSIN # 3 ;) SIN OF CURRENT DIR +DIRSTT # 2 ;) START BLK NO OF DIRECTORY (=0) +DIRBKS # 2 ;) NO OF BLKS IN DIR +DIRSTA # 2 ;STORE ADDRESS OF DIR +DIRSZE # 3 ;3 BYTE VARIABLE HOLDING SIZE OF DIR +TXTNAM # NAMLNT+1 ;TEXT NAME (PADDED WITH SPACES) +DIRTMP # 3 ;3 BYTE TEMPORARY VARIABLE +DMTEMP # 3 +OBJSIN # 3 ;TEMP VAR HOLDING SIN OF OBJECT +OBJACC # 1 ;TEMP VAR HOLDING ACC INFO FOR OBJECT +EXARG # 1 +EXENTR # 1 +EXENTS # 1 +DMSTX # 1 ;1 BYTE +DRCNT # 1 ;1 BYTE LOCN. +EXRTN # 3 ;3 BYTES +TDATE # 2 +DIRWC # 1 ;FLAG FOR WILD CARDS +WILD1 # 1 ;USED IN FNDTEX +WILD2 # 1 +DIRFLG # 1 +ATDRIV # 1 ;DRIVE NUMBER(AUTMAN) +ATSTRA # 2 ;STORE ADDRESS OF PW FILE +ATINF # INFNXT ;INFORMATION FROM DIRMAN +ATUSRI # UTENSZ ;USERINFO VECTOR FOR AUTMAN +ATWORK # 1 ;AUTMAN WORK VARIABLE +DOTFLG # 1 ;FLAG DOT HAS OCCURED +DRIVES # 1 ;NUMBER OF DRIVES ATTACHED TO FS +MAPTB # 2 ;HOLDS ADDRESS OF MAP TABLE(MAPMAN) +DIVPAR # 3 +DIVTMP # 3 ;HOLDS BLOCKS TO ALLOCATE +NAMETB # 2 ;NAME TABLE +MAPTMP # 3 ;TEMP VARIABLE +MPTMPA # 3 +MPTMPB # 3 +MPTMPC # 3 +TMPSPC # 3 ;TEMPORARY SECTORS PER CYLINDER +MPSZEQ # 1 ;Indicates if zero length chain +MPCHFL # 1 ;HOLDS END OF CHAIN FLAGS +MPDRVE # 1 ;HOLDS CURRENT DRIVE NUMBER +MPDSNO # 2 ;CURRENT DISC NO +MPSCST # 2 ;POINTER TO START OF DISC???? +MPTMPD # 3 ;GENERAL PURPOSE VARIABLE +MPTMPE # 3 ;GENERAL PURPOSE VARIABLE +MKENVA # 3 +SAVSC # 3 +SAVPTB # 3 ;SAVE POINTER POSITION +SAVPTA # 3 ;SAVE POINTER +MBCBPT # 2 ;POINTER TO MAP BLOCK CONTROL BLOCKS +BMCBPT # 2 ;PONTER TO BIT MAP CONTROL BLOCK +NCBDB # 2 ;NUMBER OF CURRENT CONTROL BLOCK ENTRIES +CBSIN # 3 ;CURRENT CB SIN +CBSTA # 2 ;CURRENT CB STORE ADDRESS +CBTPPT # 2 ;CB TEMPORARY POINTER +RBDA # 3 ;TRANSFER BLOCK DISC ADDRESS +ERRTYP # 1 ;READ OR WRITE DISC ERROR +DNDLTE # 1 ;DELETE CURRENT MAP BLOCK? +RSTFLG # 1 ;CYLINDER MAP STARTUP FLAG +CURDSC # 2 ;CURRENT DISC NO. +NXTDNO # 2 ;NEXT DISC NO. ALLOCATION +CURDRV # 1 ;CURRENT DRIVE +LDRNB # 1 ;LOGICAL DRIVE NUMBER (DSCMAN) +DCSECT # 3 ;SECTOR NUMBER +DRIVNO # 1 ;ACTUAL DRIVE NUMBER TO BE SELECTED +DCSTAD # 2 ;STORE ADDRESS +NBLKS # 2 ;NUMBER OF DISC BLOCKS TO BE TRANSFERED +DATARA # 16 ;AREA FOR TEST OF DISC BLOCK VALIDITY +OLDFDR # 1 ;LAST FDRIVE USED +OLDSZE # 4 +CTRACK # 1 ;COPY OF TRACK NUMBER +CSECTR # 1 ;COPY OF 1 BYTE SECTOR NUMBER +CADDR # 2 ;COPY OF STORE ADDRESS +SECTSD # 2 ;NUMB OF SECTORS ON A SIDE OF DISC +SECTS # 2 ;NO. OF SECTS TO XFER +DCRASH # 1 ;DISC CRASH INDICATION + [ BBC=0 +DSCCB # Length+4 +SAVCOM # 1 +TRACK # 1 +SECTOR # 1 +DDRSTA # 2 +DDRSPA # 2 +DDRSZE # 2 +DDRSCT # 2 +CNTA # 1 +SECTNO # 1 +DFNAME # 10 +DFLOAD # 2 +DFEXEC # 2 +DFSIZE # 3 +DFQUAL # 10 +DFSECT # 10 +RAMADR # 2 + ] +INTROT # 2 ;USED FOR A FILE TITLE (INIT) +USERNM # MAXUNM+1 ;HOLDS A USERID +BREGA # 3 + [ BBC=0 +RXTAB # 1 +RXCBN # 1 + ] +RXCBV # 0 ;RECEIVE CONTROL BLOCK VECTOR +CBFLG # 1 ;RECEIVE C.B. FIELDS +CBPORT # 1 +CBSTID # 2 + [ SYS=0 +CBBUF # 2 +CBBUFE # 2 + | +CBBUF # 4 +CBBUFE # 4 + ] +RXBUF # 1 ;Receive buffer +FCODE # 1 ;FN. code +CPUFD # 1 +CPCSD # 1 +CPLIB # 1 +MIDRX # RXBUFL+RXBUFL+1-(MIDRX-RXBUF) ;**8/2/88** +RXBUFT # 1 +TXBUF # 0 +CCODE # 1 ;Command code +RTCODE # 1 +MIDTX # &2E + + +;OTHER VARIABLES +COTEMP # 2 +COWORK # 0 +DETRAM # 0 +DETNAM # INFNXT ;DETAILS FROM RETRIEVE +DETACC * DETNAM+INFACC +DETSIN * DETNAM+INFSIN +DETDIS * DETNAM+INFDIS +DETSZ * DETNAM+INFSZE +TOSEND # 3 +OFFSET # 3 +GBBXFD # 3 ;Bytes xfd in CP GETBYTES (3 bytes) +GBEFLG # 1 ;End of file flag (CP GETBYTES) +TXTBUF # RXBUFL ;file title buffer +MAPTBF * TXTBUF ;Buffer MAPTB information in MAPMAN.MPREDR +QPTR # 1 +BPTR # 1 +CURBLK # 2 +OUTBSZ # 2 +BBUF # 2 +BBSIZE # 2 +BBEND # 2 +DANDS # 5 +DSCERR # 1 +RPLYPT # 1 +DATAIN # 3 +FINFLG # 1 +FILLFL # 1 +TIMER # 1 +TIMER1 # 1 +TIMER2 # 1 +QUOTED # 1 +TXJ # 1 +TXD # 1 +TXF # 1 +MONFLG # 1 +OLDRXB # 2 +CDIRTB # 2 +CVTDRV # 1 +FSDNO # 2 +HNDROT # 1 +QUALIF # 1 +TXBYTS # 2 +TXBLKS # 2 +MEMEND # 2 + [ 1=0 +TSTACK # 1 ;Store stack pointer in MAPMAN & CONVERT + ] +OLDBRK # 2 ;Store BRK vector in MAPMAN & CONVERT +OFF1 # 1 ;ARG TO MOVBLK +OFF2 # 1 ;ARG TO MOVBLK +STRPTR # 2 ;Ptr. used in AUTMAN +PTREND # 2 ;Ptr. used in AUTMAN +RIPPLE # 1 +EVCHAR # 1 +IOBUF # 2 ;new big buffer +IOBSIZ # 2 +IOEND # 2 +ODSCMN # 11 +MPNWFR # UTFRLN ;user free space calculation +MPscor # 2 ;Bitmap sector origin (MAPMAN) +MCopat # 3 ;"Already open at station m.n" + +DYNSTA * @ ;START OF DYNAMICALLY ALLOCATED STORE + + LNK UADE03 diff --git a/Level3/SRC/L3/Uade03 b/Level3/SRC/L3/Uade03 new file mode 100644 index 0000000..036628c --- /dev/null +++ b/Level3/SRC/L3/Uade03 @@ -0,0 +1,1328 @@ + OPT UADE03 ;FILE > Uade03 + TTL File server file UADE03 + +;********************************** +;* U T I L I T I E S * +;********************************** + +ENPT ROUT + CMPIM 1 + BEQ START + RTS + NOP + = &60 + = COPYRIGHT + = 0 ;SOFTWARE VERSION NUMBER + = "Winchester File Server" +COPYRIGHT + = 0,"(C) 1988 Acorn",CR,0 + +; & ENPT +; & 0 + +START ROUT + + JSR VSTRIN + = 22, 7 ;select mode 7 + = CR,"Acorn File Server Level " +VERSN = "3 Version 1.",VERLA,VERLB,CR + = 21,"Version string",6 ;software protection + = " File server station " + NOP + + LDXIM 11 ;**9/7/87** set up to get net number +00 LDAAX CTABA + STAAX Rxcbv + DEX + BPL #00 + LDAIM &9C ;correct port + STA CBport + LDAIM 0 + STA Rxcbn + STA Rxbuf ;zero net in case no reply + STA Qptr + LDXIM :LSB:Rxcbn + LDYIM :MSB:Rxcbn + LDAIM &11 + JSR OSword ;set up receive + LDXIM 12-1 ;now set up broadcast +10 LDAAX #90 + STAAX CBflg + DEX + BPL #10 + LDAIM :LSB:Rxcbv + STA Netcb + LDAIM :MSB:Rxcbv + STA Netcb+1 + JSR SendX ;send off broadcast + LDXIM 2 ;short wait + JSR WaitX ;wait for response + LDA Rxbuf ;first reply byte is net id + STA CBstid+1 + + LDAIM &08 ;Print station number LH 21/10/85 + STA &0100 + LDAIM &13 + LDXIM &00 + LDYIM &01 + JSR OSWORD + LDA &0101 + STA CBstid +; LDA &0102 +; STA CBstid+1 + LDAIM 0 ;**12/6/87** zero task number for now + STA CBFLG + JSR PRTMC + + JSR VSTRIN + = 28, 0, 21, 39, 4 ;define a window + NOP + LDXIM WCMD + LDYIM /WCMD + JSR OSCLI + LDXIM WDCMD + LDYIM /WDCMD + JSR OSCLI + + + JMP STRTFS ; .. here we go .. + +90 = &82, &9C, &FF, &FF + = "BRIDGE" + = &9C, 0 + +DOBRK ROUT + JSR CURSON + JSR VSTRIN + = 28,0,23,39,0 + NOP + +;ammended BRK handling ** 30/9/84 ** + PLA ;get P + PLA + STA BRKPTR + PLA ;get address from stack + STA BRKPTR+1 ;standard places to put them + + LDYIM 0 +10 LDAIY BRKPTR + BEQ #20 + JSR OSASCI ;print the error message + INY + BNE #10 + +20 JMP TSTART + +;Store old value of BRKVEC +;and set new value to X/Y +; +;Called from MAPMAN and CONVERT block read routine + +SETBRK ROUT + LDA BRKVEC + STA OLDBRK + LDA BRKVEC + 1 + STA OLDBRK + 1 +SETBK1 SEI + STX BRKVEC + STY BRKVEC + 1 + CLI + RTS + +WCMD = "ADFS",CR ;SET WINCHESTER FILING SYSTEM +WDCMD = "DIR :0",CR ;SELECT DRIVE ZERO +PROT = 5,MASK ;SET PROTECTION except USER procedure + +TRACE ROUT + [ DEBUG > 0 + PHA + LDAIM DEBUG + BEQ #10 + PLA + JMP OSWRCH + +10 PLA + ] + RTS + +;I N P U T - O U T P U T R O U T I N E S + +;Returns CC if digit or char. + +ISDCHA ROUT + PHA + CMPIM "0" + BCC #10 ;Fail + CMPIM "9"+1 + BCC #20 ;Succeed + PLA ;Now check if is char + +;Returns CC if is alpha (upper or lower) + +ISCHAR PHA + ANDIM &DF + CMPIM "A" + BCC #10 ;=> char < A + CMPIM "Z"+1 + BCC #20 ;=> char <= Z +10 SEC +20 PLA + RTS + +OSECHO ROUT + JSR OSRDCH + BCC #10 + LDAIM &7E ;escape found so ack and return bad char + JMP OSBYTE +10 JMP OSASCI ;read & echo a char + +VSTRIN ROUT + PLA + STA VSTPTR + PLA + STA VSTPTR + 1 + LDYIM 0 +10 INC VSTPTR + BNE #20 + INC VSTPTR + 1 +20 LDAIY VSTPTR + BMI #30 + JSR OSASCI + JMP #10 +30 JMI VSTPTR ;continue execution + + +WHEX ROUT + PHP ;WRITE A AS TWO HEX DIGITS + PHA + LSRA + LSRA + LSRA + LSRA + JSR #10 + PLA + PHA + ANDIM &F + JSR #10 + PLA + PLP + RTS + +WHEXD +10 CMPIM 10 + BMI #20 + CLC + ADCIM 7 +20 ADCIM "0" + JMP OSWRCH + + +;THE FOLLOWING ROUTINES READ A LINE OF TEXT +;TYPED AT A KEYBOARD INTO THE COMMAND LINE BUFFER (DOS=256) +;THE PAGE ZERO REGISTER COMPTR IS USED TO POINT +;INTO THE INPUT BUFFER. +;THE INDEX REGISTER Y IS USED TO REFER TO +;CHARACTERS IN THE INPUT BUFFER. +;THE ROUTINE GETINT READS CHARS FROM INPUT BUFFER +;AND CONVERTS THEM INTO INTEGERS (PLACED IN INTEGR). + + +SETCOM LDAIM 0 ;COMPTR := ADDR OF INPUT BUFFER + STA COMPTR + LDAIM 1 + STA COMPTR+1 + RTS + + +INCCOM ROUT + INC COMPTR ;COMPTR +:= 1 + BNE #10 + INC COMPTR+1 +10 RTS + + +RDLINE ROUT + JSR SETCOM + LDAIM &86 + JSR OSBYTE + STX OFF1 + JSR CURSON + LDXIM RDLNBK + LDYIM /RDLNBK + LDAIM 0 + JSR OSWORD + BCC #20 + LDAIM &7C + JSR OSBYTE + LDAIM &86 + JSR OSBYTE + SEC + TXA + SBC OFF1 + TAY +10 CPYIM 0 + BEQ RDLINE + STY OFF1 + JSR VSTRIN + = 8,32,8 + NOP + LDY OFF1 + DEY + JMP #10 + +20 JMP CURSOF +; +RDLNBK = 0,1,40,32,&80 +; + +;Turn Cursor On +; +CURSON JSR VSTRIN + = 23,1,1,0,0,0,0,0,0,0 + NOP + RTS + +;Turn Cursor off +; +CURSOF JSR VSTRIN + = 23,1,0,0,0,0,0,0,0,0 + NOP + RTS + + +;GETINT: READ A DECIMAL INTEGER INTO INTEGR. +;NOTE COMPTR IS LEFT POINTING TO THE CHARACTER +;FOLLOWING THE INTEGER. +;EXIT: A = RC (<>0 => NOT A DECIMAL INTEGER) + +GETINT ROUT + LDYIM 0 + TYA + STA TEMPB ;TEMPB := CHAR COUNT + STA INTEGR + STA INTEGR + 1 ;INTEGR := 0 + +10 LDAIY COMPTR + CMPIM "0" + BCC #20 + CMPIM ":" ;(':='9+1) + BCC #30 +20 LDA TEMPB ;FIRST CHAR ? + BNE #80 + LDAIM IERRAH + BNE #90 +30 SEC + SBCIM "0" + PHA ;PUSH DIGIT + INC TEMPB ;TEMPB +:= 1 + LDA INTEGR + ASLA + STA TEMPA + LDA INTEGR + 1 + ROLA + STA TEMPA + 1 ;TEMPA := INTEGR * 2 + LDXIM 3 +40 LDA INTEGR + ASLA + STA INTEGR + LDA INTEGR + 1 + ROLA + STA INTEGR + 1 + DEX + BNE #40 ;INTEGR * 8 + CLC + LDA INTEGR + ADC TEMPA + STA INTEGR + LDA INTEGR + 1 + ADC TEMPA + 1 + STA INTEGR + 1 + CLC + PLA ;PULL DIGIT + ADC INTEGR + STA INTEGR + LDA INTEGR + 1 + ADCIM 0 + STA INTEGR + 1 + JSR INCCOM ;COMPTR +:= 1 + JMP #10 + +80 LDAIM 0 ;RC:= 0 +90 RTS + + +;E R R O R H A N D L I N G + +USRERR ROUT ;USRERR + PHA + JSR OSCRLF + PLA + JSR LOOKER ;Get error msg. in MIDTX + LDXIM 0 +10 LDAAX MIDTX + JSR OSASCI + INX + CMPIM CR + BNE #10 + RTS + + + +;STOP: THIS ROUTINE BRINGS THE FILE +;SERVER TO A GRACEFULL HALT. +;IT PUSHES, ONTO THE HARDWARE +;STACK, P,A,X,Y AND REMEMBERS +;THE VALUE OF THE STACK PTR IN +;STKPTR (SEE HEADER FILE). + + +STOP PHP ;PUSH P,A,X,Y REMEMBER STK PTR + PHA + TXA + PHA + TYA + PHA + TSX + STX STKPTR + [ 1=0 + BRK +STOPER = &00,CR,"STOP",CR + = 0 + | + JSR OSCRLF + JMP TSTART ;cant use BRK cos it's intercepted ** 28/9/84 ** + ] + +INTERR PHP + PHA + TXA + PHA + TYA + PHA +; STA STOPER + JSR VSTRIN + = CR,"FS internal error #" + NOP + PLA + TAY + PLA + TAX + PLA + PLP + JSR WHEX + JSR VSTRIN + = CR,"AT ADDRESS " + NOP + PLA + TAX + PLA + JSR WHEX + TXA + JSR WHEX + JMP STOP + + + +;COMPAR: COMPARE TWO AREAS OF STORE, +;BYTE-BY-BYTE. + +;ENTRY: MOVFRM = PTR TO 1ST AREA +;MOVTO = PTR TO 2ND AREA +;X = NO. OF BYTES TO BE COMPARED + +;EXIT: A = 0 IF IDENTICAL +;<>0 IF NOT IDENTICAL +;N.B. STATE BITS (Z ETC) ARE ALSO SET. +;NOTE X,Y,A ARE DESTROYED. + + +COMPAR ROUT + TXA + TAY +10 DEY + LDAIY MOVFRM + CMPIY MOVTO + BNE #20 + DEX + BNE #10 +20 TXA + RTS + + +;F R E E S P A C E M A N A G E M E N T + + +;SPACE IS ALLOCATED FROM A +;CONTIGUOUS AREA OF MEMORY. N.B. +;THAT SPACE CANNOT BE RETURNED TO +;THE FREE POOL. + + +;GETVEC: RETURNS A POINTER TO A FREE +;AREA OF MEMORY. +;THE PAGE ZERO POINTER, +;FREPTR POINTS TO THE BEGINNING +;OF FREE SPACE. + + +;ENTRY: Y,X = SIZE (Y=LS) +;EXIT: Y,X = PTR TO VECTOR + +;FUNCTION:- + +;IF FREPTR+SIZE > ENDPTR +;THEN ERROR(INSUFFICENT SPACE) +;ELSE FREPTR +:=:= SIZE +;FI + +GETVEC ROUT + TXA ;FIRST CHECK THAT SIZE REQUESTED <> 0 + BNE #10 + TYA + BNE #10 + LDAIM IERRAF ;SIZE = 0 +00 JSR INTERR +10 CLC + TYA + ADC FREPTR + STA GVWRKA ;GETVEC WORK VARIABLE A + TXA + ADC FREPTR+1 + STA GVWRKA+1 + BCC #20 + LDAIM IERRAD ;X,Y TOO BIG! + BNE #00 +20 LDA ENDPTR ;IS GVWRKA > ENDPTR + CMP GVWRKA + LDA ENDPTR+1 + SBC GVWRKA+1 + BCS #30 + LDAIM IERRAE ;INSUFFICIENT SPACE + BNE #00 +30 LDY FREPTR + LDX FREPTR+1 + LDA GVWRKA + STA FREPTR + LDA GVWRKA+1 + STA FREPTR+1 + RTS + + +;CLRSTR: CLEARS A SPECIFIED STORE AREA TO ZERO. + +;ENTRY:- CLRPTR (PAGE ZERO) = START ADDRESS +;X,Y = NUMBER OF BYTES (Y=LS) +;NOTE A & TEMPA ARE DESTROYED BY THIS RTN + +CLRSTR ROUT + LDAIM 0 + STA TEMPA+1 + STY TEMPA + TYA + BEQ #20 + LDAIM 0 +10 DEY + STAIY CLRPTR + BNE #10 +20 TXA + BEQ #30 + CLC + LDA CLRPTR + ADC TEMPA + STA CLRPTR + LDA CLRPTR+1 + ADC TEMPA+1 + STA CLRPTR+1 + LDYIM 1 + STY TEMPA+1 + DEY ;zero + TYA + STY TEMPA + DEX + JMP #10 + +30 RTS + + +;MOVBLK: MOVE DATA FROM PTR AT X OFFSET BY OFF1, TO +; PTR AT Y OFFSET BY OFF2. A CONTAINS THE AMOUNT +; TO MOVE. USEFUL FOR MOVING TO AND FROM THE STACK +; TO TABLES IN DYNAMIC AREA. +; + +MOVBLK ROUT + + PHA ;Push amount to move + CLC + LDAAX 0 + ADC OFF1 + STA MOVFRM ;Set "from" pointer + LDAAX 0001 + ADCIM 0 + STA MOVFRM+1 + + CLC + LDAAY 0 + ADC OFF2 ;Set "to" pointer + STA MOVTO + LDAAY 0001 + ADCIM 0 + STA MOVTO+1 + + PLA + TAX ;Set length for MOVE + +;And drop into MOVE + +;MOVE: MOVE DATA FROM ONE AREA OF MEMORY TO A NEW AREA +;N.B. DATA AREAS SHOULD NOT OVERLAPP!!!!! + +;ENTRY: MOVFRM - PAGE ZERO FROM ADDRESS +;MOVTO - PAGE ZERO TO ADDRESS +;X - AMOUNT TO BE MOVED + +;NOTE THAT A,X,Y ARE DESTROYED BY THIS ROUTINE + +MOVE LDYIM 0 + TXA + BEQ #20 ;If zero to move, exit + +10 LDAIY MOVFRM + STAIY MOVTO + INY + DEX + BNE #10 +20 RTS + + +;MRKDRT: MARK A STORE BUFFER DIRTY + +;ENTRY: GENPTR => STORE ADDRESS OF BUFFER + +;SAVED: A,X,Y +;DESTROYED: GENPTR + + +MRKDRT ROUT + PHA ;PUSH A + TYA + PHA ;PUSH Y + JSR DCGEN ;INITITIALISE GENPTR & Y + LDAIM DIRTY + STAIY GENPTR + PLA + TAY ;PULL Y + PLA ;PULL A + RTS + + +;MRKCLE: MARK A STORE BUFFER CLEAN + +;ENTRY: GENPTR => STORE ADDR OF BUFFER +;SAVED: A,X,Y +;DESTROYED: GENPTR + +;MRKCLE PHA ;PUSH A +;PHY ;PUSH Y +;JSR DCGEN ;INITIALISE GENPTR & Y:=0 +;TYA +;STAIY GENPTR +;PLY ;PULL Y +;PLA ;PULL A +;RTS + + +DCGEN ROUT + LDA GENPTR + BNE #10 + DEC GENPTR+1 +10 DEC GENPTR + LDYIM 0 + RTS + + +;I N T E R M O D U L E C O M M U N I C A T I O N + + +;ARGUMENTS ARE PASSED AROUND ON +;A SOFTWARE STACK. WHEN IN A +;MODULE ARGUMENTS SETUP BY THE +;CALLER (AND THOSE TO BE PASSED +;BACK) ARE POINTED TO BY THE +;PAGE ZERO REGISTER, ARGPTR. +;PARAMETERS FOR THE NEXT MODULE +;TO BE CALLED ARE POINTED TO BY +;THE PAGE ZERO REGISTER, NEWARG. +;THE POSN OF NEWARG RELATIVE TO +;ARGPTR IS SET BY THE SETFS ROUTINE. +;SETFS MUST BE CALLED +;BEFORE A MODULE IS CALLED. + + +;SETFS: SET FRAME SIZE. THIS RTN +;SETS UP THE CORRECT VALUE +;OF THE PAGE ZERO POINTER, +;NEWARG. +;ON ENTRY A = NUMBER OF ARGUMENT +;STACK POSNS TO BE SET ASIDE. +;IT ALSO PLACES ZERO IN THE REMEMBER ENTRY REASON SLOT. + + +;FUNCTION:- + +;NEWARG := ARGPTR+A+FINFO +;[NEWARG] := A+FINFO +;[NEWARG+ENTRES] := 0 + + +SETFS ROUT + CLC + ADCIM FINFO ;A:=FINFO+A + BCC #10 + LDAIM IERRAA ;FRAME SIZE TOO BIG + JSR INTERR ;INTERNAL ERROR +10 PHA ;PUSH A + ADC ARGPTR ;A:=A+LS(ARGPTR) + STA NEWARG ;LS(NEWARG) := A + LDA ARGPTR+1 ;A:=MS(ARGPTR) + ADCIM 0 + STA NEWARG+1 ;MS(NEWARG):=A + PLA ;PULL ACCUMULATOR + LDYIM FRAMSZ ;Y:=POSN OF FRAME SIZE INFO + STAIY NEWARG ;[NEWARG] :=A + LDYIM ENTRES ;Y:= POSN OF ENTRY REASON TO BE REMEMBERED + LDAIM 0 + STAIY NEWARG ;ENTRY REASON := 0 AT THE MOMENT + RTS + + + +;ENTRY: THIS RTN MUST BE CALLED ON +;EVERY ENTRY TO A MODULE. IT +;CHECKS THAT THE ENTRY CODE +;0 < (ARG0) >= A. IT ALSO PLACES +;THE NAME OF THE CALLED MODULE +;AND THE VALUE OF ARGA (THE ENTRY REASON) +;ON THE ARGUMENT STACK (THIS IS USEFUL WHEN DEBUGGING). + +;ON ENTRY:- + +;X = NUMB OF MODULE ENTRY POINTS +;A= NUMBER OF MODULE + +;FUNCTION:- + +;ARGPTR := NEWARG +;X := JUMP TABLE OFFSET +;NEWARG := $FFFF (SHOULD BE SET BY SETFS RTN) + + +ENTRY ROUT + LDYIM MODNME + STAIY NEWARG ;PUSH NAME OF CALLED MODULE ON ARG STACK + TXA ;A:= NUMBER OF EXPECTED ENTRY POINTS + LDYIM ARGA ;Y:=ARGA + CMPIY NEWARG + BPL #10 + LDAIM IERRAC ;UNKNOWN ENTRY REASON +00 JSR INTERR +10 LDAIY NEWARG ;A:=[NEWARG+ARGA] + BNE #20 + LDAIM IERRAB ;FUNCTION CODE = 0 + BNE #00 + +;NOW MAKE ARGPTR := NEWARG + +20 LDA NEWARG ;A:= LS(NEWARG) + STA ARGPTR ;LS(ARGPTR):=A + LDA NEWARG+1 ;A:=MS(NEWARG) + STA ARGPTR+1 ;MS(ARGPTR):=A +;NOW WORKOUT JUMP TABLE OFFSET + LDAIY ARGPTR + LDYIM ENTRES + STAIY ARGPTR ;COPY OF ARGA (THE ENTRY REASON) + STA ENWRKA ;ENWRKA:=[ARGPTR+ARGA] + DEC ENWRKA ;ENWRKA -:= 1 + ASL ENWRKA ;ENWRKA *:= 2 + LDX ENWRKA ;X := JUMP TABLE OFFSET + LDAIM &FF + STA NEWARG + STA NEWARG+1 ;NEWARG := $FFFF + RTS + + + +;EXIT: THIS RTN SHOULD BE +;CALLED BY EVERY MODULE, JUST +;BEFORE IT RETURNS TO ITS CALLER. + +;FUNCTION:- + +;NEWARG := ARGPTR +;ARGPTR := ARGPTR-[ARGPTR] +;A := [NEWARG+ARGA] +;Y := ARGA + +PREXIT LDYIM ARGA ; Common return sequence + STAIY ARGPTR ; Falls into EXIT + +EXIT ROUT + LDYIM FRAMSZ ;Y:=POSN OF FRAME SIZE INFO + LDA ARGPTR ;A:=LS(ARGPTR) + STA NEWARG ;LS(NEWARG):=A + LDA ARGPTR+1 + STA NEWARG+1 ;NOW NEWARG=ARGPTR + SEC + LDA ARGPTR ;A:=LS(ARGPTR) + SBCIY ARGPTR ;A:=A-SIZE OF PREVIOUS STACK FRAME + STA ARGPTR ;LS(ARGPTR):=A + BCS #10 + DEC ARGPTR+1 ;MS(ARGPTR)-:=1 +10 LDYIM ARGA ;Y:=ARGA + LDAIY NEWARG ;A:=[NEWARG+ARGA] I.E. RETURN CODE + RTS + + +;A R I T H M E T I C R O U T I N E S + + +MULTBS ROUT + LDXIM 8 ;BREGA *:= BLKSZE +10 ASL BREGA + ROL BREGA+1 + ROL BREGA+2 + DEX + BNE #10 + RTS + + [ 1=0 + +MULT10 STA TEMPA + ASLA + ASLA + ASLA + CLC + ADC TEMPA + ADC TEMPA + RTS + ] + + +;SETTAB + +;ENTRY: X - NO. OF ENTRIES IN TABLE +;Y - SIZE OF EACH ENTRY + +;EXIT: Y -> TABLE (LO) +;X -> TABLE (HI) + +;TABLE IS CLEARED TO ZERO AFTER +;GETTING SPACE FROM GETVEC. + +SETTAB ROUT + LDAIM 0 + STA TEMPA + STA TEMPA+1 +10 CLC + TYA + ADC TEMPA + STA TEMPA + BCC #20 + INC TEMPA+1 +20 DEX + BNE #10 + + LDY TEMPA + LDX TEMPA+1 + JSR GETVEC ;*** GET SPACE ** + TYA + PHA ;DONT' TRUST CLRSTR WITH X/Y + TXA + PHA + STY CLRPTR + STX CLRPTR+1 + LDY TEMPA + LDX TEMPA+1 + JSR CLRSTR + PLA + TAX + PLA + TAY + RTS + + +GETBB ROUT + LDAIM 7 + LDYIM ARGA + STAIY NEWARG + JSR STRMAN ;Do get big buffer + BNE #20 + + LDXIM 3 + LDYIM ARGE +10 LDAIY NEWARG + STAAX BBUF ;Set address and size + DEY + DEX + BPL #10 + CLC + LDA BBUF + ADC BBSIZE + STA BBEND ;Set end address + LDA BBUF+1 + ADC BBSIZE+1 + STA BBEND+1 + +;declare a new I/O side buffer for file transfers +;Nb 2nd processor FS only + LDXIM 0 + STX IOBUF ;even page boundary + LDYIM &FF + LDAIM 180 + JSR OSBYTE ;read I/O OSHWM + + STX RXBUF+1 ;ready for i/o routine + [ 1=0 + STX CODTB1 ;modify table a bit + STX CODTB4 + ] + [ ZTIME=0 + STX CODTX4 + STX CODTX7 + STX CODTX8 + ] + + INX ;result returned in X + STX IOBUF+1 ;base of buffer + + LDAIM 135 + JSR OSBYTE ;read a char, get screen mode in Y + TYA + TAX ;read the bottom of display + LDAIM 133 + JSR OSBYTE ;result in X,Y + + STX IOEND + STY IOEND+1 + + SEC + TXA + SBC IOBUF + STA IOBSIZ ;get buffer size + TYA + SBC IOBUF+1 + STA IOBSIZ+1 ;two bytes + +;when reading unwritten sectors of disc, the store must be +;set to zero. This is to be done in the I/o side by a +;dubious bit of code, called by intercepting the OSBPUT vector +;The code itself is poked over in the following section + + LDXIM &FF + STX ODSCMN ;illegal value for big buffer cache + STX ODSCMN+1 + + STX RXBUF+2 + STX RXBUF+3 ;high order address + INX + STX RXBUF ;lo byte of address, hi byte already set up + + LDAIM 0 +20 RTS + + [ 1=1 + +GETBLA LDX RXBUF + LDAAX CODTAB + CMPIM &EA + BEQ GETBLB ;end marker + STA RXBUF + 4 ;byte to put in + + JSR GETBW ;do call + INC RXBUF + BNE GETBLA + +GETBLB LDAIM BPUTV + STA RXBUF + LDAIM /(BPUTV ) + STA RXBUF + 1 + LDAIM 0 + STA RXBUF + 4 ;data lo + JSR GETBW + INC RXBUF + LDA CODTB1 + STA RXBUF + 4 ;data hi + JSR GETBW + + [ ZTIME=0 + LDAIM &0216 + STA RXBUF + LDAIM /(&0216 ) + STA RXBUF + 1 + LDAIM CODTX1-CODTAB + STA RXBUF + 4 ;data lo + JSR GETBW + INC RXBUF + LDA CODTB1 + STA RXBUF + 4 ;data hi + JSR GETBW + ] + + RTS + +GETBW LDXIM RXBUF + LDYIM /(RXBUF ) + LDAIM 6 + JMP OSWORD ;call to ammend store + +CODTAB = &8D,&0B +CODTB1 = &00 ;ammended to buffer start + = &8C,&0A +CODTB4 = &00 +; STA CODTB2 +%2 ;ammend hi byte of address +; STY CODTB2 +%1 ;ammend hi byte of address + LDAIM 0 + TAY +CODTB2 STAAY &7C00 ;hi byte ammended + INY + BNE CODTB2 + RTS +;CODTB3 * CODTB2 +%2 + + [ ZTIME=0 +CODTX6 EORIM &FF ;invert input + PHA + LSRA + LSRA + LSRA + LSRA + = &20 ;JSR + = . - CODTAB + 3 +CODTX4 = &00 + PLA +CODTX2 ANDIM &0F + ORAIM &30 + CMPIM &3A + BCC CODTX3 + ADCIM &06 +CODTX3 JMP &E0A4 ;call wrch direct + +CODTX1 TAX + BEQ CODTX5 + LDA &FE64 + PHA + LDA &FE65 + = &20 + = CODTX6-CODTAB +CODTX7 = &00 + PLA + = &20 + = CODTX6-CODTAB +CODTX8 = &00 + LDAIM &20 + JSR &E0A4 +CODTX5 LDAIM 0 + STA &FE6B + LDAIM &FF + STA &FE64 + STA &FE65 + RTS + ] + NOP ;end marker + [ ZTIME=0 +RDTIME LDAIM &FF + JMP &FFD7 + +WRTIME LDAIM 0 + JMP &FFD7 + ] + ] ;*** 17/9/84 + +INCGPT INC GENPTR + BNE #30 + INC GENPTR+1 +30 RTS + + +MEMTST ROUT ;MEMTST + +;First find end of memory. Then test memory +;several times with random numbers and once each +;with %0 and $FF. + + JSR VSTRIN + = CR,"Testing Memory",CR + NOP + + LDAIM :LSB:FRESTR + STA GENPTR ;NOTE ASSUMES FRESTR ON PAGE BOUNDARY + LDAIM :MSB:FRESTR + STA GENPTR+1 + LDYIM 0 +10 LDAIM &55 + STAIY GENPTR + LDAIM &FF + INY + STAIY GENPTR ;Clear address lines + INY + STAIY GENPTR + DEY + DEY + LDAIY GENPTR + CMPIM &55 + BNE #20 ;NE if found + LDX GENPTR+1 + INX + STX GENPTR+1 ;use page sized jumps + CPXIM &F8 ;look for start of NET code + BNE #10 + +20 DEY + CLC + TYA + STA NEWARG + LDA GENPTR+1 + SEC + SBCIM 1 + STA NEWARG+1 + JSR VSTRIN + = CR,"Last free location = " + NOP + LDA NEWARG+1 + JSR WHEX + LDA NEWARG + JSR WHEX + JSR OSCRLF + +;NOW TEST MEMORY + + LDAIM &44 ;Set "random number" + STA COZERO + LDAIM &55 + STA COZERO+1 + STA COZERO+2 + LDAIM 0 + STA ARGPTR ;Use ARGPTR as an error flag + LDXIM 3 +30 JSR RMTSTA ;Rajdom number test + DEX + BNE #30 + LDAIM 0 + JSR RMTSTB + LDAIM &FF + JSR RMTSTB + + LDA NEWARG + STA MEMEND + LDA NEWARG + 1 + STA MEMEND + 1 + LDA ARGPTR ;Error flag + RTS + + +RMTSTA ROUT ;RMTSTA + +;Test from FREPTR to NEWARG using pseudo rand. nos. +;in COZERO +00/01/02 + + LDAIM :LSB:FRESTR + STA GENPTR + LDAIM :MSB:FRESTR + STA GENPTR+1 + +10 LDA COZERO + STA COZERO+3 ;Store for checking pass + LDA COZERO+1 + STA COZERO+4 + LDA COZERO+2 + STA COZERO+5 + LDYIM 0 +20 LDA COZERO + STAIY GENPTR + JSR RANDUM + INY + BNE #20 + +;Reset rand. no. and check page. + + LDA COZERO+3 + STA COZERO + LDA COZERO+4 + STA COZERO+1 + LDA COZERO+5 + STA COZERO+2 +30 LDA COZERO + CMPIY GENPTR + BEQ #40 ;OK, continue + JSR MEMERR +40 JSR RANDUM + INY + BNE #30 + +;Finished testing one page, do next one. + + INC GENPTR+1 + LDA NEWARG+1 + CMP GENPTR+1 + BCS #10 ;G/ptr >= NEWARG, continue. + RTS + + +RMTSTB ROUT ;RMTSTB + +;Test memory using value in A. + + STA COZERO + LDAIM :LSB:FRESTR + STA GENPTR + LDAIM :MSB:FRESTR + STA GENPTR+1 +10 LDYIM 0 + LDA COZERO +20 STAIY GENPTR + INY + BNE #20 ;Fill a page +30 LDAIY GENPTR + CMP COZERO + BEQ #40 ;OK, continue + JSR MEMERR +40 INY + BNE #30 + + INC GENPTR+1 + LDA NEWARG+1 + CMP GENPTR+1 + BCS #10 + RTS + + +RANDUM ROUT ;RANDUM + +;Generate next random number + + LDA COZERO + EORIM 2 + LSRA + LSRA + ROR COZERO + ROR COZERO+1 + ROR COZERO+2 + RTS + + +MEMERR ROUT ;MEMERR + +;Print error location and set flag + + + PHA + LDAIM &FF + STA ARGPTR ;Set error flag + TYA + PHA + JSR VSTRIN + = "Fails at: " + NOP + + LDA GENPTR+1 + JSR WHEX + CLC + PLA + TAY + ADC GENPTR + JSR WHEX + JSR OSCRLF + + PLA + RTS + + [ DONGLE=1 ; Keep track of days without dongle +INCDAY LDA DATE + CMPIM 28 + BCS #20 +10 INC DATE + JMP PRDTE + +20 LDA DATE+1 + ANDIM &F + CMPIM 2 + BEQ #60 + LDA DATE + CMPIM 30 + BCC #10 + LDXIM 4 + LDA DATE+1 + ANDIM &F +30 CMPAX MW30D-1 + BEQ #40 + DEX + BNE #30 + LDA DATE + CMPIM 31 + BNE #10 +40 LDA DATE+1 + ANDIM &F + CMPIM 12 + BEQ #50 + CLC + ADCIM 1 + TAX + LDA DATE+1 + ANDIM &F0 + STA DATE+1 + TXA + ORA DATE+1 + STA DATE+1 + LDAIM 1 + STA DATE + JMP PRDTE + +50 LDA DATE+1 + LSRA + LSRA + LSRA + LSRA + CLC + ADCIM 1 + ASLA + ASLA + ASLA + ASLA + ORAIM 1 + STA DATE+1 + LDAIM 1 + STA DATE +55 JMP PRDTE +60 LDA DATE + CMPIM 29 + BEQ #40 + LDA DATE+1 + LSRA + LSRA + LSRA + LSRA + CLC + ADCIM BASEYR + ANDIM &3 + BNE #40 + JMP #10 + ] + +MW30D = 4,6,9,11 + +JUSINF ROUT ;pass userinfo pointer to CHANGESIZE + + LDYIM ARGB + LDAIY ARGPTR + TAX + INY + LDAIY ARGPTR + + LDYIM ARGK + STAIY NEWARG + DEY + TXA + STAIY NEWARG + RTS ;** 3/10/84 ** + + LNK UADE04 diff --git a/Level3/SRC/L3/Uade04 b/Level3/SRC/L3/Uade04 new file mode 100644 index 0000000..e2d960a --- /dev/null +++ b/Level3/SRC/L3/Uade04 @@ -0,0 +1,1240 @@ + OPT UADE04 ; FILE > Uade04 + TTL File server file UADE04 + + +;********************************* +;* FILE SERVER INITIALISATION * +;********************************* + + +INIT ROUT + LDAIM 7 + JSR SETRTN + JSR MAPMAN ;MAPMAN.RESTART + BNE #10 + + LDAIM 4 + JSR SETRTN + JSR USRMAN ;USRMAN.RESTART + BNE #10 + + LDAIM 4 + JSR SETRTN + JSR RNDMAN ;RNDMAN.RESTART + BNE #10 + + LDXIM &1F + LDYIM 2 + JSR SETTAB ;Table of qualifiers/directory handles + STY CDIRTB ;for DOS conversion. + STX CDIRTB+1 + + LDAIM 6 + JSR SETRTN + JSR STRMAN ;STRMAN.RESTART +00 BEQ #20 +10 PHA + JSR USRERR + PLA +20 RTS + +RSTAUT LDAIM 6 + JSR SETRTN ;AUTMAN.RESTART + JSR AUTMAN + JMP #00 + +STRTFS ROUT + + CLD + + JSR MEMTST ;Test memory. + BEQ ASKDAT ;OK + + JSR VSTRIN + = "Memory fault found",CR + = "File Server unable to start",CR + = "Ended",CR + NOP + RTS ;STOP !! + +ASKDAT ROUT + [ DONGLE=0 + JSR RTC + BEQ #10 + JSR VSTRIN + = CR,"Clock Failure",CR + NOP + JMP TSTART ; .. that's all folks .. + + | + + JSR STDATE ;FIND OUT THE DATE if no RTC + + ] +10 JSR RDTIME + JSR RDDRVS ;HOW MANY DRIVES? + + + +INITCO ROUT ;INITCO + +;Main start point of any FS command. +;Resets ENDPTR, FREPTR and re-allocates all tables. +;NOTE !! It is therefore assumed that maps etc. +;have been ensured to disc !! + + LDAIM :LSB:DYNSTA + STA FREPTR + LDAIM :MSB:DYNSTA + STA FREPTR+1 ;FREPTR := DYNSTA + + LDA MEMEND + STA ENDPTR + LDA MEMEND+1 + STA ENDPTR+1 + +;GET SOME SPACE FOR THE ARGUMENT STACK AND SETUP ARGPTR + + LDYIM :LSB:STKSZE + LDXIM :MSB:STKSZE + JSR GETVEC + STY ARGPTR + STX ARGPTR+1 + +;NOW CLEAR THE ARGUMENT STACK TO ZERO + + STY CLRPTR + STX CLRPTR+1 ;CLRPTR:=ADDR OF ARGUMENT STACK + LDYIM :LSB:STKSZE + LDXIM :MSB:STKSZE + JSR CLRSTR + + JSR VSTRIN + = CR,"Command :" + NOP + JSR CURSON + JSR OSECHO + PHA + JSR CURSOF + PLA + LDXIM 4 +10 CMPAX FSCTBA + BEQ #20 + DEX + BPL #10 + + JSR VSTRIN + = CR,"S, A, * ONLY" + NOP + JMP INITCO + +20 TXA + ASLA + TAX + LDAAX FSCTBB + STA TEMPA + LDAAX FSCTBB+1 + STA TEMPA+1 + JMI TEMPA + +FSCTBA = "SA*sa" + +FSCTBB & STRTUP + & ASKDAT + & OSCMD + & STRTUP + & ASKDAT + +OSCMD JSR RDLINE + LDXIM 0 + LDYIM 1 + JSR OSCLI + JMP INITCO + +;NORMAL FILE SERVER STARTUP +STRTUP ROUT + JSR RDUSRS + LDAIM 1 + JSR SETFS + JSR INIT + BEQ #10 + JMP INITCO ;Error => do again + +10 LDXIM :LSB:DOBRK + LDYIM :MSB:DOBRK + JSR SETBRK + JSR RSTAUT ;RESTART AUTMAN + JMP CMND ;JUMP TO FILE SERVER COMMAND PROCESSOR + + + +RDDRVS ROUT + JSR VSTRIN ;FINDOUT HOW MANY DRIVES THERE ARE + = CR,"Number of drives:" + NOP + JSR RDLINE + JSR GETINT ;INTEGR:=NUMBER OF DISCS + BNE RDDRVS + LDA INTEGR + 1 + BNE RDDRVS + LDA INTEGR + BEQ RDDRVS + STA DRIVES ;DRIVES:=NUMBER OF DRIVES ATTACHED TO FS + RTS + + + +STDATE ROUT + + [ DONGLE=1 ;ie dongle absent + +;If here, no time chip, so prompt for date + +10 JSR VSTRIN ;SETUP THE DATE + = CR,"Date (DD/MM/YY) = " + NOP + + JSR RDLINE ;READ A COMPLETE LINE + JSR GETINT ;GET DAY +20 BNE #10 + LDA INTEGR+1 + BNE #10 + LDA INTEGR + STA DATE ;LS(DATE) := DAY + LDAIY COMPTR + CMPIM "/" +30 BNE #20 + JSR INCCOM ;COMPTR +:=1 + JSR GETINT ;GET MONTH + BNE #30 + LDA INTEGR+1 + BNE #30 + LDA INTEGR + ANDIM &F0 + BNE #10 + LDA INTEGR + ANDIM &F + STA DATE+1 ;LS(DATE+01) := MONTH + LDAIY COMPTR + CMPIM "/" + BNE #30 + JSR INCCOM ;COMPTR +:=1 + JSR GETINT ;GET YEAR + BNE #30 + LDA INTEGR+1 +40 BNE #30 + LDA INTEGR + SEC + SBCIM BASEYR ;SUBTRACT 81 + BCS #50 ;**24/2/88** br if 19xx + ADCIM 100 ;**24/2/88** correct if 20xx +50 JSR SETYR ;Set year nybble + LDAIM 0 + STA DATE+2 ;With no time chip, day = 0 + JSR CHKDTE + BNE #40 + JSR PRDTE + ] + RTS + +CHKDTE ROUT + LDA DATE + STA DAYS + ANDIM 31 ;**24/2/88** isolate day of month + TAX + BEQ #40 + CMPIM 32 + BCS #40 + LDA DATE+1 + STA MUNTHS + ANDIM &F + BEQ #40 + CMPIM 13 + BCS #40 + CMPIM 2 + BEQ #20 ; br to check leap year + TXA + CMPIM 31 + BCC #30 + LDXIM 4 + LDA DATE+1 + ANDIM &F +10 CMPAX MW30D-1 + BEQ #40 + DEX + BNE #10 + BEQ #30 + +20 TXA + CMPIM 29 + BCC #30 + CMPIM 30 + BCS #40 + LDA DATE+1 + ADCIM :LSB:(BASEYR*16) + ANDIM 3*16 + BNE #40 +30 LDAIM 0 + RTS + +40 LDAIM 1 + RTS + +;PRNTDG: PRINT A DECIMAL NUMBER < 100 +;ENTRY A:= NUMBER. C clear if to print leading zeroes + +PRNTDG ROUT + PHP ;**24/2/88** Save C + LDXIM &FF + SEC +10 INX + SBCIM &0A + BCS #10 + ADCIM &0A + PLP ;**24/2/88** Reset C + PHA + TXA ;OUTPUT TOP DIGIT + BCC #15 ;**24/2/88** br to ignore zero check + BEQ #20 +15 JSR #40 + JMP #30 +20 LDAIM " " + JSR OSWRCH +30 PLA +40 ORAIM "0" ;CONVERT TO CHAR + JMP OSWRCH + + +RDUSRS ROUT + JSR VSTRIN + = CR,"Stations:" + NOP + + JSR RDLINE + JSR GETINT + BNE RDUSRS + LDA INTEGR+1 + BNE RDUSRS + LDA INTEGR + BEQ RDUSRS + STA USERS + + CMPIM MAXUSE+1 ; USRLIM + BCS RDUSRS + RTS + + [ DONGLE=1 + +RDTIME ROUT + JSR VSTRIN + = CR,"Time (HH:MM:SS) = " + NOP + + JSR RDLINE ;INPUT TIME + JSR GETINT ;GET HOURS + BNE RDTIME + LDA INTEGR+1 + BNE RDTIME + LDA INTEGR + CMPIM 24 ;CHECK LESS THAN 24 HOURS + BCS RDTIME + STA HRS + LDAIY COMPTR + CMPIM ":" ;CHECK CORRECT SEPARATOR + BNE RDTIME + JSR INCCOM ;NEXT INTEGER + JSR GETINT + BNE RDTIME + LDA INTEGR+1 +10 BNE RDTIME + LDA INTEGR + CMPIM 60 +20 BCS RDTIME + STA MINS + LDAIY COMPTR + CMPIM ":" ;CHECK FOR SEPARATOR + BNE #10 + JSR INCCOM + JSR GETINT ;GET SECONDS + BNE #10 + LDA INTEGR+1 + BNE #10 + LDA INTEGR + CMPIM 60 ;CHECK LESS THAN 60 + BCS #20 + STA SECS + +SETTME ROUT + LDAIM 0 + LDXIM 4 +10 STAAX TIME + DEX + BPL #10 + JSR ZEROTM + LDA HRS + STA OTIME ;PREPARE TO CALCULATE CENTISECONDS + JSR M60 ;MULTIPLY BY 60 + JSR M60 ;DITTO + JSR M100 ;TO GET CENTISECONDS + JSR TIMADD ;KEEP TRACK OF TIME + JSR ZEROTM + LDA MINS + STA OTIME + JSR M60 + JSR M100 ;TO GET CENTISECONDS + JSR TIMADD ;KEEP TOTAL + JSR ZEROTM + + LDA SECS + STA OTIME + JSR M100 ;FOR CENTISECONDS + JSR TIMADD ;KEEP TOTAL + JSR TMTOT + LDXIM TIME + LDYIM /(TIME) + LDAIM 2 + JMP OSWORD + +TMTOT ROUT + LDXIM 4 +10 LDAAX TIME + STAAX OTIME + DEX + BPL #10 + RTS + +ZEROTM ROUT + LDAIM 0 + LDXIM 4 +10 STAAX OTIME + DEX + BPL #10 + RTS + +TIMADD ROUT + CLC + LDYIM 4 + LDXIM 0 +10 LDAAX TIME + ADCAX OTIME + STAAX TIME + INX + DEY + BPL #10 + RTS + +M60 ROUT + JSR TXOTN + LDXIM 6 + JSR SHNTBX + LDXIM 2 + JSR SHOTBX + SEC + LDXIM 0 + LDYIM 4 +10 LDAAX NTIME + SBCAX OTIME + STAAX OTIME + INX + DEY + BPL #10 + RTS + +M100 ROUT + JSR TXOTN + LDXIM 6 + JSR SHNTBX + LDXIM 2 + JSR SHOTBX + CLC + LDXIM 0 + LDYIM 4 +10 LDAAX NTIME + ADCAX OTIME + STAAX NTIME + INX + DEY + BPL #10 + LDXIM 3 + JSR SHOTBX + CLC + LDYIM 4 + LDXIM 0 +10 LDAAX NTIME + ADCAX OTIME + STAAX OTIME + INX + DEY + BPL #10 + RTS + + +TXOTN ROUT + LDXIM 4 +10 LDAAX OTIME + STAAX NTIME + DEX + BPL #10 + RTS + +SHNTBX ROUT + ASL NTIME + ROL NTIME+1 + ROL NTIME+2 + ROL NTIME+3 + ROL NTIME+4 + DEX + BNE SHNTBX + RTS + +SHOTBX ROUT + ASL OTIME + ROL OTIME+1 + ROL OTIME+2 + ROL OTIME+3 + ROL OTIME+4 + DEX + BNE SHOTBX + RTS + +PRTIM ROUT +PRTIME LDXIM :LSB:TIME + LDYIM :MSB:TIME + LDAIM 1 + JSR OSWORD + JSR DIV100 + JSR DIV60 + LDA REM + STA SECS + JSR DIV60 + LDA REM + STA MINS + JSR DIV24 + LDA REM + STA HRS + LDAIM &86 + JSR OSBYTE + STX POS + STY VPOS + JSR DWIND ;*** setup the window + JSR VSTRIN + = 31,30,1 + NOP + LDA HRS + CLC + JSR PRNTDG + LDAIM ":" + JSR OSWRCH + LDA MINS + CLC + JSR PRNTDG + LDAIM ":" + JSR OSWRCH + LDA SECS + CLC + JSR PRNTDG + JSR MWIND ;*** reset the window + LDXIM 4 + LDAIM 0 +10 ORAAX TIME + DEX + BPL #10 + TAX + BEQ #20 + LDXIM :LSB:TIME + LDYIM :MSB:TIME + LDAIM 1 + JSR OSWORD + SEC + LDA TIME+1 ;GONE PAST MIDNIGHT SO SET BACK TO APROX. ZERO + SBCIM &D6 + STA TIME+1 + LDA TIME+2 + SBCIM &83 + STA TIME+2 + LDA TIME+3 + SBCIM 0 + STA TIME+3 + LDA TIME+4 + SBCIM 0 + STA TIME+4 + LDXIM :LSB:TIME + LDYIM :MSB:TIME + LDAIM 2 + JSR OSWORD + JSR INCDAY +20 RTS + +TDVD ROUT + STA DVSOR + LDAIM 0 + LDXIM 4 +10 STAAX OTIME + DEX + BPL #10 + LDYIM &28 +20 DEY + BEQ #80 + ASL TIME + ROL TIME+1 + ROL TIME+2 + ROL TIME+3 + ROL TIME+4 + BPL #20 +30 + LDXIM :LSB:-5 +40 ROLAX TIME-:LSB:-5 + INX + BNE #40 + LDXIM :LSB:-5 +50 ROLAX OTIME-:LSB:-5 + INX + BNE #50 + SEC + LDA OTIME + SBC DVSOR + PHA + LDA OTIME+1 + SBCIM 0 + PHA + LDA OTIME+2 + SBCIM 0 + PHA + LDA OTIME+3 + SBCIM 0 + TAX + LDA OTIME+4 + SBCIM 0 + BCC #60 + STA OTIME+4 + STX OTIME+3 + PLA + STA OTIME+2 + PLA + STA OTIME+1 + PLA + STA OTIME + BCS #70 +60 PLA + PLA + PLA +70 DEY + BNE #30 +80 LDA OTIME + STA REM + RTS + +DIV100 ROUT + LDAIM 100 +DODVD JSR TDVD + LDXIM 0 + LDYIM 4 +10 ROLAX TIME + INX + DEY + BPL #10 + RTS + +DIV60 LDAIM 60 + BNE DODVD + +DIV24 LDAIM 24 + BNE DODVD + ] + + [ DONGLE=0 +RDTIME + ] +PRDTE + [ DONGLE=0 + JSR RDDONG + ] + +SCDATE + JSR DWIND ;set window + + JSR VSTRIN + = 12,31,0,1 + NOP + JSR DATE1 + JSR MONTH + JSR YR + + ;reset the window + +MWIND ;set window for monitor + JSR VSTRIN + = 28,0,21,39,4,31 +POS = 0 +VPOS = 0 + NOP + RTS + +DWIND ;set window for printing the date in + + LDAIM &86 + JSR OSBYTE ;read cursor position + STX POS + STY VPOS + JSR VSTRIN + = 28, 0, 24, 39, 22 + NOP + RTS + +YR ROUT + LDA Date ;**24/3/88** isolate year high order + ANDIM &E0 + STA Rem + LDA DATE+1 + LSRA + LSRA + LSRA + ORA Rem ;**24/2/88** include high order + LSRA + CLC + ADCIM BASEYR + PHA + CMPIM 100 + BCC #10 + PLA + SBCIM 100 + PHA + LDAIM 20 + BNE #20 +10 LDAIM 19 +20 CLC + JSR PRNTDG + PLA + CLC + JMP PRNTDG + + +MONTH ROUT + LDA DATE+1 + ANDIM &F + TAX + LDYAX MTAB1-1 +10 LDAAY MONTHS + BEQ #20 + JSR OSWRCH + INY + BNE #10 +MONOUT +20 LDAIM &20 + JMP OSWRCH + + +MONTHS +JAN = "January", 0 +FEB = "February", 0 +MAR = "March", 0 +APR = "April", 0 +MAY = "May", 0 +JUN = "June", 0 +JUL = "July", 0 +AUG = "August", 0 +SEP = "September", 0 +OCT = "October", 0 +NOV = "November", 0 +DEC = "December", 0 + +MTAB1 = JAN-MONTHS + = FEB-MONTHS + = MAR-MONTHS + = APR-MONTHS + = MAY-MONTHS + = JUN-MONTHS + = JUL-MONTHS + = AUG-MONTHS + = SEP-MONTHS +MTAB2 + = OCT-MONTHS + = NOV-MONTHS + = DEC-MONTHS + + + +DATE1 ROUT + LDA DATE + ANDIM &1F ;**24/2/88** isolate day of month + PHA + SEC ;**24/2/88** strip leading zero + JSR PRNTDG + PLA + CMPIM 10 + BCC #20 + SBCIM 10 + CMPIM 10 + BCC #30 +10 SBCIM 10 + CMPIM 10 + BCS #10 +20 TAY + CPYIM 1 + BEQ #40 + CPYIM 2 + BEQ #40 + CPYIM 3 + BEQ #40 +30 LDYIM 4 +40 DEY + LDXAY #80 +50 LDAAX #70 + BEQ #60 + JSR OSWRCH + INX + BNE #50 +60 LDAIM &20 + JMP OSWRCH + +70 +71 = "st", 0 +72 = "nd", 0 +73 = "rd", 0 +74 = "th", 0 + + +80 = #71-#70 + = #72-#70 + = #73-#70 + = #74-#70 + + + +SETYR ASLA + STA Rem + ASLA + ASLA + ASLA + ORA DATE+1 + STA DATE+1 ;Year is top nibble of DATE +01 + LDA Rem + ANDIM &E0 ;**24/2/88** Plus 3 high order bits in DATE + ORA Date + STA Date + RTS + + [ DONGLE=0 + ; Dongle has 4 time set registers :- MINS,HOURS,DATE,MONTH + ; Also has 4 alarm registers which are treated as RAM + ; to store YEAR and OLDMONTH to try to deal with year changes + ; Because cursed chip can not handle years. + ; All number are BCD coded in the chip + + ; DESIGNATION AS FOLLOWS :- + + ; TIME SET REGISTERS, + ; 0=MONTH 2=DATE 4=HOURS 6=MINS + + ; RAM REGISTERS, + ; 1=YEAR in lower 7 bits + ; 3=OLDMONTH and bit &10 to indicate LEAP pending (Was date) + ; + ; 5=Not Used + ; 7=Used to determine presence of chip (Was Mins) + + +SETTME ROUT + LDA DAYS ;**24/2/88** get year high order + ANDIM &E0 + STA Rem + LDA MUNTHS + LSRA + LSRA + LSRA + ORA Rem + LSRA + LDXIM 1 + JSR #95 ;set Year + +SETTM1 LDA MUNTHS + ANDIM &F + LDXIM 0 + JSR #95 ;set month + + LDA MUNTHS ; *** LH 15/1/86 *** + JSR SETMFX ; Fix year and month to form for register + LDXIM 3 + JSR #95 ; Set oldmonth to month and flag + + LDA MINS + LDXIM 6 + JSR #95 + + LDA HRS + LDXIM 4 + JSR #95 + + LDA DAYS + ANDIM 31 ;**24/2/88** isolate day of month + LDXIM 2 + JSR #95 + + JMP SCDATE ; SHOW DATE ON SCREEN + +SETMFX ; FIX MONTH AND FLAG ON SET TIME + PHA ; stack month and year + ANDIM &0F ; Mask MONTH + CMPIM 2 + BCC SETJAN ; Branch if Jan + BNE LHNOF ; >JAN so no flag pending + LDA DAYS + ANDIM 31 ;**24/2/88** isolate day of month + CMPIM 29 + BCS LHNOF ; >= 29 so no flag pending + +SETJAN ; befor Feb 29 so check for leap + PLA ; Retreive year + PHA + CLC + ADCIM :LSB:(BASEYR*16) + ANDIM 3*16 ; Leap year check + BNE LHNOF ; Not leap so flag clear + PLA + ANDIM &0F ; Otherwise + ORAIM &10 ; set flag on month + RTS + +LHNOF PLA + ANDIM &0F + RTS + +PRTIM INC OTIME ;** avoid tube failure 25/1/85 ** + BNE RTCX ;exit + INC OTIME+1 + BMI RTCX + SEC + ROR OTIME+1 +PRTIME JSR RDDONG + LDA HRS + ORA MINS + BNE PRTIM1 ;midnight + ORA SECS ;check not already done + BNE PRTIM2 + + INC SECS + JSR PRDTE ;reprint the date + JMP PRTIM2 + +PRTIM1 LDAIM 0 + STA SECS +PRTIM2 JSR DWIND ;set up window + JSR VSTRIN + = 31,30,1 + NOP + LDA HRS + CLC + JSR PRNTDG + LDAIM ":" + JSR OSWRCH + LDA MINS + CLC + JSR PRNTDG + JMP MWIND ;reset window and return + +RTC ;check that the read time clock is present + + LDXIM 7 + LDAIM &71 + JSR #95 ;write the minutes alarm register + + LDXIM 7 ;read the same register + JSR #00 + JSR #70 + EORIM &0D ;devious eh + BNE RTCX ;fail + + LDXIM 7 + JSR #95 ;write zero as well + + LDXIM 7 + JSR #00 ;read result + CMPIM 0 +RTCX RTS ;returns EQ if dongle present + +RDDONG + + LDXIM 6 ;read minutes + JSR #00 + JSR #70 + STA MINS + + LDXIM 4 ;hours + JSR #00 + JSR #70 + STA HRS + + LDXIM 2 ;days + JSR #00 + JSR #70 + STA DATE + + LDXIM 0 ;months + JSR #00 + JSR #70 + STA DATE+1 + + LDXIM 3 ;oldmonth + JSR #00 + JSR #70 + STA OTIME+2 ; somewhere but where + + + LDXIM 1 ;year (in alarm register) + JSR #00 + JSR #70 + JSR SETYR + ; JSR REDFIX ; Fix year and month if neccessary *** LH *** + ; *** 15/1/86 *** + ; RTS + + +REDFIX ; FIX year changes + ; Fix date on reading dongle + ; ENTRY DATE+1 has perceived month and year + ; OTIME+2 has OLDMONTH and Flag + ; OTIME+3 used + + LDA OTIME+2 + ANDIM &0F + STA OTIME+3 + LDA DATE+1 + ANDIM &0F ; A has month + CMP OTIME+3 + BCS LHLYCK ; Months are ok so leap year checks + ; Here month has decreased so reset year + LDA DATE+1 + CLC + ADCIM &10 ; Increment year will loop sometime + ; but who cares as product should + ; be dead by then + STA DATE+1 + BCC RFIXX2 ; **24/2/88** No carry from low order + LDA Date + ADCIM &1F ; **24/2/88** continue carry into high order + STA Date + BNE RFIXX2 ; Branch always (year <>0) + ; REWRITE DONGLE +LHLYCK LDA OTIME+2 + ANDIM &10 + BEQ RTCX ; No flag so exit + +LHFXNX + LDA DATE+1 ; Load new Month + ANDIM &0F + CMPIM 3 + BCC RTCX ; Not MAR yet so exit + ; Here it is March (or Later) in a leap year + ; So fix dates + DEC DATE ; DEC DAYS + BNE RFIXX2 ; RE WRITE DONGLE + + ; DAYS Became ZERO ! + DEC DATE+1 ; Decrement month is ok + LDA DATE+1 + ANDIM &0F ; Get new month saves confusion + CMPIM 2 + BNE LHNFEB ; IS NOT FEB SO CHECK OTHERS + LDAIM 29 ; Must be 29th + BNE RFIXEX ; Re Write DONGLE (ALWAYS) + +LHNFEB + LDXIM 4 +LHCHKL CMPAX MW30D - 1 + BEQ LHCKLX ; FOUND SO EXIT + DEX + BNE LHCHKL + LDAIM 31 + BNE RFIXEX + +LHCKLX LDAIM 30 +RFIXEX + + STA DATE +RFIXX2 + JSR CHKDTE + JMP SETTME + + +00 PHP ;same as POKE + TXA + JSR #05 + LDAIM &06 ;bits 7,5 are POWERFAIL and ALARM + STA DDRB + JSR #55 ;write DDRB + JSR #10 + LDXIM 2 + CLC + JSR #20 + NOP + NOP + JSR #50 + LDA IRB ;read IRB + ANDIM 1 + CLC + RORA + RORA + LDYIM 6 +25 PHA + TXA + ORAIM 1 + TAX + CLC + JSR #40 + NOP + NOP + JSR #50 + LDA IRB + LSRA + PHP + TXA + ANDIM &FE + TAX + CLC + JSR #40 + PLP + PLA + RORA + DEY + BNE #25 + CLC + RORA + PHA + JSR #15 + JSR #50 + LDX IRB + PLA + PLP + RTS ;all done + +05 LDXIM &A7 + STX DDRB + JSR #55 ;write DDRB + LDYIM 4 + ASLA + LDXIM 2 ;fall thru' + +30 RORA + JSR #35 + DEY + BNE #30 + RTS ;write bits one at a time + +10 JSR #15 + NOP + NOP + CLC + JSR #35 + NOP + NOP + RTS + +35 PHA + PHP + TXA + ORAIM 1 + TAX + JSR #40 + TXA + ANDIM &FE + TAX + PLP + JSR #40 + PLA + RTS + +15 LDXIM 0 + STX ORB + BEQ #45 + +40 NOP + NOP + NOP + NOP +20 TXA + ROLA + STA ORB + +45 PHP + PHA + TXA + PHA + TYA + PHA + LDAIM 151 + LDXIM &60 + LDY ORB + JSR OSBYTE + JMP #60 + +50 PHP + PHA + TXA + PHA + TYA + PHA + LDAIM 150 + LDXIM &60 + JSR OSBYTE + STY IRB + JMP #60 + +55 PHP + PHA + TXA + PHA + TYA + PHA + LDAIM 151 + LDXIM &62 + LDY DDRB + JSR OSBYTE +60 PLA + TAY + PLA + TAX + PLA + PLP + RTS + +95 PHP ;Set routine + JSR #85 ;convert to BCD (without corrupting X) + CPXIM 0 ;detect writing munths + BNE #99 + ORAIM &40 +99 PHA + TXA + JSR #05 + PLA + LDYIM 7 + JSR #30 + JSR #10 + JSR #15 + PLP + RTS + +70 LDYIM 0 + TAX + BEQ #75 +80 CLD + INY + SED + SEC + SBCIM 1 + BNE #80 + CLD +75 TYA + RTS + +85 TAY ;make BIN to BCD + BEQ #94 + LDAIM 0 + SED +90 CLC + ADCIM 1 + DEY + BNE #90 +94 CLD + RTS + ] + LNK UADE05 diff --git a/Level3/SRC/L3/Uade05 b/Level3/SRC/L3/Uade05 new file mode 100644 index 0000000..755415e --- /dev/null +++ b/Level3/SRC/L3/Uade05 @@ -0,0 +1,200 @@ + OPT UADE05 ;> Uade05 + TTL File server file UADE05 + +;********************************* +;* G L O R T N * +;* AND DOS CONVERSION * +;********************************* + +;***** R N D M A N R O U T I N E S ***** + +;FNDHND: SEARCHES THE HANDLE TABLE (HANDTB) +;FOR A SPECIFIED HANDLE. + +;ENTRY: A = HANDLE +;MCNUMB = MACHINE NUMBER + +;EXIT : A = RC +;HNDPTR - LEFT POINTING TO PARTICULAR ENTRY +;CONTAINING SPECIFIED (HANDLE,MC/NO). +;NOTE A,X,Y,RNDTMP ARE DESTROYED. + +FNDHND ROUT + STA RNDTMP ;RNDTMP := HANDLE + TAY + BEQ #40 ;INVALID HANDLE + JSR INITHD ;HNDPTR:=HANDTB;X:=HTENTS + +;FIRST SEE IF MACHINE NUMBER MATCHES + +20 LDYIM HTMCNO ;LSIG BYTE FIRST + LDAIY HNDPTR + CMP MCNUMB + BNE #30 + INY + LDAIY HNDPTR + CMP MCNUMB+1 + BNE #30 + INY + LDAIY HNDPTR + CMP MCNUMB+2 + BNE #30 + +;NOW SEE IF HANDLE MATCHES + + LDYIM HTHAND + LDA RNDTMP + CMPIY HNDPTR + BNE #30 + +;FOUND + + LDAIM 0 ;RC := 0 + RTS + +30 JSR INCHND ;MOVE HNDPTR TO NEXT ENTRY,DEX + BNE #20 +40 LDAIM RDERRB + RTS + + +INITHD LDA HANDTB ;HNDPTR := HANDTB + STA HNDPTR + LDA HANDTB+1 + STA HNDPTR+1 + LDX HTENTS ;X := HTENTS + RTS + + +INCHND ROUT + CLC ;HNDPTR +:= HTENSZ + LDA HNDPTR + ADCIM HTENSZ + STA HNDPTR + BCC #10 + INC HNDPTR+1 +10 DEX ;X -:= 1 + RTS + + +;USRMAN ROUTINES + +;FINDMC: FIND A USERTB ENTRY - SEARCH +;USERTB FOR AN ENTRY CONTAINING A +;GIVEN MACHINE NUMBER. +;NOTE THAT FINDMC MAY BE CALLED +;BY ANY MODULE. +;(THIS FUNCTION WILL PROBABLY +;NEED SPEEDING UP - POSSIBLY USING +;A HASH TABLE FOR USERTB) + +;ENTRY: THE VARIABLE, MCNUMB, +;SHOULD CONTAIN THE +;NUMBER OF THE MACHINE +;TO BE LOOKED UP IN USERTB. + +;EXIT: A = RC +;IF A = 0 +;THEN USTPTR (PAGE ZERO) IS +;LEFT POINTING TO THE USERTB ENTRY +;FI + + +FINDMC ROUT + JSR INITUS ;USTPTR:=USERTB,X:=UTENTS +10 LDA MCNUMB ;LS(MC/NO) + LDYIM UTMCNO + CMPIY USTPTR + BNE #20 + INY + LDA MCNUMB+1 + CMPIY USTPTR + BNE #20 + INY + LDA MCNUMB+2 + CMPIY USTPTR + BNE #20 + LDYIM UTPRIV + LDAIY USTPTR + ANDIM INUSE + BEQ #20 + + LDAIM 0 ;RETURN CODE + RTS + +20 JSR INCUST ;USTPTR+:=UTENSZ,X-:=1 + BNE #10 + LDAIM URERRA ;RC:=MACHINE NOT LOGGED ON + RTS + + +INITUS LDA USERTB ;USTPTR:=USERTB,X:=USERS + STA USTPTR + LDA USERTB+1 + STA USTPTR+1 + LDX USERS + RTS + + +INCUST ROUT + CLC ;USTPTR+:=UTENSZ,X-:=1 + LDA USTPTR + ADCIM UTENSZ + STA USTPTR + BCC #10 + INC USTPTR+1 +10 DEX + RTS + + +DRVINF LDYIM ARGB ;A := DRIVE NUMBER + STAIY NEWARG + DEY ;Y := ARGA + LDAIM 8 ;MAPMAN.DRIVEINFO + STAIY NEWARG + JMP MAPMAN + + +;Flushes store and ensures map for drive +;passed in A. + +FLUDRV ROUT + JSR DRVINF ;GET DISC NO. + BNE #10 ;ABORT IF ERROR + + LDAIM 8 + JSR SETRTN + JSR STRMAN ;*** FLUSH STORE ** + BNE #10 + + LDAIM 6 + JSR SETRTN + JSR MAPMAN ;*** ENSURE DISC ** +10 RTS + + +;Flushes all drives in system, so it is +;safe to start from scratch !! + +FLUSYS ROUT + LDA DRIVES +10 SEC + SBCIM 1 + BMI #20 + PHA + JSR FLUDRV + BNE #30 +15 PLA + JMP #10 + +20 LDAIM 16 + JSR SETRTN + JMP MAPMAN ;MAPMAN.FLUSYS to empty map caches + +30 CMPIM MPERRF ;Bad drive no? + BEQ #15 ;yes, ignore (inter-disc gap) + JSR USRERR + PLA + RTS + + LNK UADE06 diff --git a/Level3/SRC/L3/Uade06 b/Level3/SRC/L3/Uade06 new file mode 100644 index 0000000..eb119ec --- /dev/null +++ b/Level3/SRC/L3/Uade06 @@ -0,0 +1,1186 @@ + OPT UADE06 ;FILE > Uade06 + TTL File server file UADE06 + + +;********************************** +;* U S R M A N * +;********************************** + +;USRMAN: USRMAN (THE USER TABLE MANAGER) +;KEEPS INFORMATION ABOUT LOGGED ON USERS. +;USRMAN MAINTAINS A DATA STRUCTURE +;KNOWN AS THE USERTB. THIS TABLE +;CONTAINS INFORMATION ABOUT WHICH +;USERS ARE LOGGED ON, THE +;NUMBER OF THE MACHINE, HANDLES +;FOR UFD & CURRENTLY SELECTED DIRECTORY, +;AND OTHER USER STATE INFORMATION. + +;THE USERTB CONTAINS THE FOLLOWING INFO:- +;0) MACHINE NUMBER +;1) USERID +;2) CURRENT SELECTED DISC NUMBER +;3) SYSTEM PRIVILEGE FLAG +;4) HANDLE FOR UFD (USER FILE DIR) +;5) HANDLE FOR SELECTED DIR +;6) HANDLE BYTE (A RECORD OF WHICH HANDLES ARE INUSE) + + +;************ MAIN ROUTINE ************ + + +USRMAN ROUT + LDXIM 10 ;USRMAN HAS 10 ENTRY POINTS + LDAIM MODUSR ;A:=NAME OF THIS MODULE + JSR ENTRY + LDAAX USRTNS + STA USJUMP+1 + LDAAX USRTNS+1 + STA USJUMP+2 + LDAIM 15 + JSR SETFS +USJUMP JMP USJUMP +USEXIT JMP PREXIT +USRTNS + & USNWMC ;1 => REGISTER A MACHINE(LOGON) + & USDLMC ;2 => DELETE MACHINE FROM USERTB(LOGOFF) + & USSDSC ;3 => SELECT DISC + & USREST ;4 => RESTART + & USSDIR ;5 => SELECT DIRECTORY + & USUSER ;6 => USER INFO (PRIV & MC/NO OF GIVEN USERID) + & USUSRS ;7 => LOGGED ON USERS + & USQUIT ;8 => update all users free space ** 3/10/84 ** + & USFREE ;9 => update single user allocation + & USDALL ;10=> delete all machines in USERTB ** 11/1/85 ** + + +;************ USNWMC ************ + +;USNWMC: USRMAN.NEW MACHINE (LOGON) +;ENTRY: ARGB,C,D = (MC/NO) +;ARGE,F = (PTR TO USERID FOLLOWED BY PASSWORD) + +;EXIT : ARGA = RC +;ARGB,C = (PTR TO USERINFO) +;ARGD = UFD HANDLE +;ARGE = CSD HADLE +;ARGF = LIB HANDLE +;ARGG = Option bits (bottom two) +;ARGH = Privilege ** 27/9/84 ** + +;FUNCTION: - + +;IF machine already in USERTB (I.E. LOGGED ON) +;THEN close all open files, +;close all open dirs; +;remove USERTB entry +;FI; + +;check validity of password;read option bits + +;FOR each drive WHILE NOT found +;DO IF $.USERID exists +;THEN get handles for ufd, library and selected dir; +;found := TRUE +;FI +;OD; + +;IF NOT found +;THEN use root dir for ufd, library & selected dir +;FI + +USNWMC ROUT + JSR CHKMC ;Logged on? + BEQ #05 ;Br if it is + +;FIND A FREE USERTB ENTRY + + LDA MCTEMP ;MCTEMP SET BY CHKMC + ORA MCTEMP+1 + ORA MCTEMP+2 ;**25/12/86** + BNE #10 + LDAIM URERRF ;RC:=M/C NUMBER = ZERO + BNE #25 + +;CHECK PASSWORD + +05 JSR LOGOFF ;log previous session off +10 LDAIM 2 ;AUTMAN.CHECKPW + JSR SETRTN + LDYIM ARGF ;**25/12/86** + LDAIY ARGPTR + DEY + STAIY NEWARG ;MS(PTR TO USERID FOLLOWED BY PW) + LDAIY ARGPTR + DEY + STAIY NEWARG ;LS(PTR TO USERID) + JSR AUTMAN + BNE #25 + + JSR INITUS ;USTPTR:=USERTB,X:=USERS + LDYIM UTPRIV +15 LDAIY USTPTR ;HOLDS THE INUSE FLAG + BEQ #30 + JSR INCUST + BNE #15 + LDAIM URERRB ;RC:=USERTB FULL +25 JMP #70 + +;SETUP USERTB ENTRY + +30 LDYIM ARGF + LDAIY NEWARG ;Read PW Flag byte + STA USTEMP ;Store so can return option bits + ORAIM INUSE ;and mark in use. + LDYIM UTPRIV + STAIY USTPTR ;:= INUSE + privileges flags *** 25/5/86 *** + LDA MCTEMP ;(MCTEMP SET BY CHKMC) + LDYIM UTMCNO + STAIY USTPTR + LDA MCTEMP+1 + INY + STAIY USTPTR + LDA MCTEMP+2 + INY + STAIY USTPTR ;MACHINE NUMBER + + LDAIM ARGB ;copy disc space into table + STA OFF1 + LDAIM UTFREE + STA OFF2 + LDXIM NEWARG + LDYIM USTPTR + LDAIM UTFRLN + JSR MOVBLK ;** 2/10/84 ** + + LDYIM ARGE ;**25/12/86** + LDAIY ARGPTR + STA MOVFRM + INY + LDAIY ARGPTR + STA MOVFRM+1 + CLC + LDA USTPTR + ADCIM UTUSID + STA MOVTO + LDA USTPTR+1 + ADCIM 0 + STA MOVTO+1 + LDXIM UTDISC-UTUSID + JSR MOVE ;COPY USERID INTO USERTB + + LDAIM 0 + LDYIM UTHNDB + STAIY USTPTR + +;NOW TRY TO FIND A UFD FOR THIS USER +;SO TRY TO RETRIEVE $.USERID BY SEARCHING ALL THE DRIVES + + LDAIM &FF ;**14/06/86** + STA USWORK+1 ;**14/06/86** USWORK+1 := -1 + STA USWORK ;USWORK := -1 := DEVICE NO **25/12/86** + LDYIM ARGG ;**25/12/86** + LDAIY NEWARG ;**25/12/86** disc containing user pw file +40 JSR DRVINF ;MAPMAN.DRIVEINFO + BNE #55 ;**14/06/86** + BIT USWORK+1 ;**14/06/86** + BPL #42 ;**14/06/86** skip if disc already found + LDA USWORK ;**14/06/86** else set lowest disc found + STA USWORK+1 ;**14/06/86** + +42 JSR SUSRDI ;Set users disc no. + JSR GETUFD ;GET HANDLES FOR UFD + BEQ #70 + +;haven't matched full name here, so see about partial match **18/9/84** + + LDYIM MAXID+UTUSID+1 ;look for a "." +45 LDAIY USTPTR + CMPIM SEPART + BEQ #50 + DEY + CPYIM UTUSID + BNE #45 ;look right through the string + BEQ #55 + +50 LDAIM TERMIN ;abbreviate the name string + STAIY USTPTR + TYA + PHA ;save pointer across call + + LDA USWORK + JSR DRVINF ;get drive info + JSR SUSRDI ;set up the info + JSR GETUFD + TAX ;save RC + + PLA + TAY + LDAIM SEPART + STAIY USTPTR ;restore the string to its former glory + + TXA ;restore RC + BEQ #70 ;all ok here + +55 INC USWORK ;USWORK +:=1 + LDA USWORK ;**14/06/86** + CMP DRIVES ;**14/06/86** check all drives + BCC #40 ;**14/06/86** try next logical drive + + +;If a UFD does not exist on any disc then +;make UFD := selected dir := root dir on the +;lowest logical drive + + LDA USWORK+1 ; ** 14/06/86 ** + JSR DRVINF + JSR SUSRDI ;Set user disc no. + JSR GTROOT + BEQ #70 + JSR LOGOFF ;CLEAN UP if no dirs available + +70 LDYIM ARGB + PHA ;Store return code + LDA USTPTR + STAIY ARGPTR + INY + LDA USTPTR+1 + STAIY ARGPTR + INY + JSR MOVHND + LDA USTEMP ;Read PW flag byte + PHA + ANDIM OPTMSK ;Mask off option bits + LDYIM ARGG + STAIY ARGPTR + PLA + INY + ANDIM SYSTPV ;** 27/9/84 ** + STAIY ARGPTR ;return user's privilege + PLA ;Restore return code + JMP USEXIT + + +SUSRDI LDYIM ARGB + LDAIY NEWARG + LDYIM UTDISC + STAIY USTPTR + LDYIM ARGC + LDAIY NEWARG + LDYIM UTDISC+1 + STAIY USTPTR ;DISC NUMBER + RTS + + +;************ USDLMC ************ + + +;USDLMC: DELETE USERTB ENTRY FOR GIVEN MACHINE NUMBER + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) + +;EXIT: ARGA = RC + +;FUNCTION: FIND USERTB ENTRY AND MARK IT NOT IN USE. + + +USDLMC ROUT + JSR SETUTP + JSR LOGOFF + LDAIM 0 + JMP USEXIT + + + +;************ USSDSC ************ + + +;USSDSC: USRMAN.SELECT DISC + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) +;ARGD = LS(DISC NO) +;ARGE = MS(DISC NO) +;ARGF = CURRENT UFD HANDLE +;ARGG = CURRENT CSD HANDLE +;ARGH = CURRENT LIB HANDLE + +;EXIT : ARGA = RC +;ARGB = NEW UFD +;ARGC = NEW CSD +;ARGD = NEW LIB + +;FUNCTION:- +;IF specified disc loaded +;THEN close ufd, library & selected dir; +;IF $.USERID exists on selected dir; +;THEN get handles for ufd, library & selected dir +;ELSE ufd:=selected dir:=library:=root dir +;FI + + +USSDSC ROUT + JSR SETUTP ;SETUP USTPTR TO POINT INTO USERTB + +;FIRST, SEE WHETHER SPECIFIED DISC IS LOADED + + LDYIM ARGD + LDAIY ARGPTR + STA USDISC + INY + LDAIY ARGPTR + STA USDISC+1 ;USDISC:=SELECTED DISC NUMBER + + LDYIM ARGC + STAIY NEWARG + DEY ;Y:=ARGB + LDA USDISC + STAIY NEWARG + DEY ;Y:= ARGA + LDAIM 4 ;MAPMAN.SINOFROOT + STAIY NEWARG + JSR MAPMAN + BNE #10 + +;NOW CLOSE THREE HANDLES FOR +;OLD DISC + + LDYIM ARGF + LDAIY ARGPTR + JSR CLOSE + BNE #10 + LDYIM ARGG + LDAIY ARGPTR + JSR CLOSE + BNE #10 + LDYIM ARGH + LDAIY ARGPTR + JSR CLOSE + BNE #10 +;PUT SELECTED DISC NUMBER INTO THE USERTB + + LDYIM UTDISC + LDA USDISC + STAIY USTPTR + INY + LDA USDISC+1 + STAIY USTPTR + +;SEE IF A UFD EXISTS IN THE ROOT DIR FOR THIS USER + + JSR GETUFD + BEQ #10 + +;OTHERWISE MAKE THE ROOT DIR THE UFD, LIB & SELECTED DIR + + JSR GTROOT + +10 LDYIM ARGB + JSR MOVHND ;PUT HANDLES ON STACK + JMP USEXIT + + + +;************ USREST ************ + + +;USREST: RESTART +;1) CALL GETVEC TO GRAB AN AREA +;OF STORE FOR THE USERTB. +;2) SETUP THE VARAIBLE (USERTB) +;TO POINT TO THIS AREA. +;3) CALL CLRSTR TO INITIALISE THE +;WHOLE TABLE TO ZERO. + + +USREST ROUT + LDX USERS + LDYIM UTENSZ + JSR SETTAB + STY USERTB + STX USERTB+1 + LDAIM 0 + STA USSYS ;priv'd user logged-on flag + JMP USEXIT + + + +;************ USSDIR ************ + + +;USSDIR: USRMAN.SELECT DIRECTORY + +;ENTRY: ARGB = LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) +;ARGD = LS(PTR TO DIR TITLE) +;ARGE = MS(PTR TO DIR TITLE) +;ARGF = UFD HANDLE +;ARGG = CURRENT SEL. DIR. HND + +;EXIT : ARGA = RC +;ARGB = HANDLE FOR NEW CSD + +;FUNCTION:- + +;IF dir title = null string +;THEN make the current selected dir=ufd +;ELIF directory exists +;THEN open selected dir; +;close old selected dir +;ELSE return error +;FI + + +USSDIR ROUT + JSR SETUTP ;SETUP USTPTR + + LDYIM ARGF + LDAIY ARGPTR + STA UMHUFD + INY + LDAIY ARGPTR + STA UMHCSD +;FIRST, RETRIEVE THE DIRECTORY + + LDYIM ARGD + LDAIY ARGPTR + STA TITPTR + STA GENPTR + INY + LDAIY ARGPTR + STA TITPTR+1 ;TITPTR := ADDR OF DIR NAME + STA GENPTR+1 ;GENPTR := PTR TO DIR TITLE + + LDYIM 0 + LDAIY GENPTR + CMPIM TERMIN + BNE #10 + +;NOW CALL RNDMAN TO CREATE A COPY OF THE HANDLE +;FOR THE UFD. + + LDA UMHCSD + JSR CLOSE ;CLOSE OLD SELECTED DIR. + BNE #30 + + LDAIM 5 ;RNDMAN.COPY + JSR SETUSA ;**25/12/86** + INY + LDA UMHUFD ;SET USER ROOT TO COPY + STAIY NEWARG ;ARGD = HANDLE OF UFD + JSR RNDMAN ;RNDMAN.COPY + BNE #30 + + LDYIM ARGE + LDAIY NEWARG ;HANDLE FROM RNDMAN + JMP #20 + +10 LDAIM &C1 ;accept all wild cards + JSR RETRV ;CALL DIRMAN.RETRV & CHECK THAT ITS A DIR + BNE #30 + +;NOW GET A HANDLE FOR IT + + JSR OPEN ;USRHND:=HANDLE FOR NEW SELECTED DIR + BNE #30 + PHA + +;NOW CLOSE THE OLD SELECTED DIR + + LDA UMHCSD + JSR CLOSE + BNE #40 ;If this close fails, close new one too + PLA + +20 LDYIM ARGB + STAIY ARGPTR ;Set new handle + LDAIM 0 + +30 JMP USEXIT + +40 STA TEMPA ;Store rcode + PLA ;Pull new csd + JSR CLOSE ;Close it + LDA TEMPA ;Restore rcode + BNE #30 ;End + + + +;************ USUSER ************ + + +;USUSER: USER INFO + +;ENTRY: ARGB=LS(PTR TO USERINFO) +;ARGC = MS(PTR TO USERINFO) +;ARGD = LS(PTR TO USERID) +;ARGE = MS(PTR TO USERID) + +;EXIT : ARGA = RC +; ARGB = USER PRIVILEDGE +; ARGC-E machine number **25/12/86** +; ARGF,G pointer to userid information ** 5/10/84 ** + + +USUSER ROUT + JSR INITUS + LDYIM ARGD + LDAIY ARGPTR + STA URMPPT ;Pointer to User Id to check + INY + LDAIY ARGPTR + STA URMPPT+1 + +10 LDYIM UTPRIV ;Check if entry in use + LDAIY USTPTR + BPL #50 ;Nope -> continue + +;NOW SEE IF USERIDS MATCH + + LDAIM UTUSID + STA OFF2 ;Offset in user-table + LDYIM 0 ;Offset of argument name + +20 LDAIY URMPPT + STY OFF1 + CPYIM 21 ;Max user length + BNE #30 ;Not at end yet -> go on + + CMPIM TERMIN ;At end, check user name given is terminated + BEQ #40 ;Yes -> found + BNE #50 ;No -> continue search + +30 LDY OFF2 + EORIY USTPTR + INC OFF2 ;Increment USTPTR offset for next time + ANDIM &DF ;Complete comparison + BNE #50 ;Not the same -> go on to next one + + LDY OFF1 ;Point to char. offset from USTPTR + LDAIY URMPPT ;The same => check if end of string + INY ;Increment for next time + + CMPIM TERMIN + BNE #20 ;Not terminators => continue search + +;FOUND IT - SO COPY PRIV & MC/NO INTO STACK + +40 LDYIM UTPRIV + LDAIY USTPTR + ANDIM SYSTPV+LOPRIV ;**25/5/86** + LDYIM ARGB + STAIY ARGPTR ;Privileges flags + + LDYIM UTMCNO + LDAIY USTPTR + LDYIM ARGC + STAIY ARGPTR + LDYIM UTMCNO+1 + LDAIY USTPTR + LDYIM ARGD + STAIY ARGPTR + LDYIM UTMCNO+2 + LDAIY USTPTR + LDYIM ARGE + STAIY ARGPTR ;MC/NO + INY + LDA USTPTR + STAIY ARGPTR + INY + LDA USTPTR+1 + STAIY ARGPTR ;**5/10/84** + + LDAIM 0 + BEQ #60 + +50 JSR INCUST + BNE #10 + LDAIM URERRE +60 JMP USEXIT + + +;**************** USUSRS ************ + +;ENTRY: ARGB = Start entry +;ARGC = No. of entries +;ARGD-E Result buffer +;ARGF = Caller privilege flag +;ARGG = M/C mode flag. Zero for job/task nos, +- if not + +;EXIT : +;ARGB = No. of entries found +;ARGC-D Result end ptr. + +;V. similar to examine and discs. Given entry point +;to list of users and number of entries required, +;supplies info. on as many as possible, returning +;the number found and a pointer to the byte after +;the info. for use in transmitting the data +;out to client. + + +USUSRS ROUT + JSR INITUS ;Set USTPTR and X + LDYIM ARGB + LDAIY ARGPTR + STA TEMPA ;Start entry + INY + LDAIY ARGPTR + STA TEMPA+1 ;No. of entries wanted + INY + LDAIY ARGPTR + STA GENPTR ;Result ptr. + INY + LDAIY ARGPTR + STA GENPTR+1 + + LDAIM &FF + STA TEMPB ;Entry pt. counter + LDAIM 0 + STA TEMPB+1 ;No. of entries found + +10 LDYIM UTPRIV + +;First loop round finding entries in use until +;ENTRY = TEMPA = START ENTRY + + LDAIY USTPTR + BPL #30 ;Not in use, don't count + +;** skip privileged users (27/9/84) +;** unless caller is privileged (16/1/85) + + ANDIM SYSTPV ;privileged, + BEQ #20 + LDYIM ARGF ;unless caller privileged then + LDAIY ARGPTR ;these "dont exist" + BEQ #30 + +20 INC TEMPB ;Inc. current entry + LDA TEMPB + CMP TEMPA ;Current >= start entry ? + BCS #40 ;Yes => start copying to result + +30 JSR INCUST ;Jump to next entry + BNE #10 ;If not off end of table, do again + BEQ #70 ;Otherwise, finish + +40 TXA + PHA + LDXIM 0 + LDYIM UTMCNO + LDAIY USTPTR + STAIX GENPTR + INY + JSR INCGPT + LDAIY USTPTR + STAIX GENPTR ;Set m/c number + INY ;**20/5/87** + JSR INCGPT + LDAIY USTPTR + LSRA ;**20/5/87** position job/task number + LSRA + LSRA + STAIX GENPTR ;**20/5/87** Set job/task number + LDYIM ARGG + LDAIY ARGPTR + BNE #45 ;**20/5/87** Skip increment if not wanted + JSR INCGPT +45 LDYIM UTUSID ;User id. offset +50 LDAIY USTPTR + STAIX GENPTR + JSR INCGPT + CMPIM CR ;Is terminated ?? + BEQ #60 + + INY + CPYIM UTUSID+MAXUNM ;Finished ? + BNE #50 ;**23/4/85** + LDAIM CR ;**16/1/85** + STAIX GENPTR + JSR INCGPT + +60 LDYIM UTPRIV ;Get privilege byte + LDAIY USTPTR + ANDIM SYSTPV ; +LOPRIV ;**25/5/86 + 31/10/86** + STAIX GENPTR + JSR INCGPT ;Point to next entry + PLA + TAX ;Restore table entry count + + INC TEMPB+1 ;Inc. no. found + LDA TEMPA+1 + CMP TEMPB+1 ;No. found = no. requested ? + BEQ #70 ;Yes => stop + + JSR INCUST ;Step through table + BNE #10 ;Do again + +70 LDYIM ARGB + LDA TEMPB+1 + STAIY ARGPTR + INY + LDA GENPTR + STAIY ARGPTR + INY + LDA GENPTR+1 + STAIY ARGPTR + LDAIM 0 + JMP USEXIT + + +;******************* + +USQUIT ROUT + JSR INITUS ;setup USTPTR +10 LDYIM UTPRIV ;scan for inuse entries + LDAIY USTPTR + BEQ #20 + TXA ;preserve X over LOGOFF call + PHA + JSR USENS ;ensure all free space entries up to date + PLA + TAX +20 JSR INCUST + BNE #10 + JMP USEXIT ;end of routine + + +USFREE ROUT ;** 6/2/85 ** + + LDA USTPTR + PHA + LDA USTPTR+1 + PHA ;save this value over call + + JSR INITUS ;update all incarnations of a user free space + STX USTEMP ;save counter + +10 LDYIM ARGB + LDAIY ARGPTR + STA GENPTR + INY + LDAIY ARGPTR + STA GENPTR+1 ;pointer to supplied name + + LDYIM UTPRIV + LDAIY USTPTR + BPL #50 ;not in use so skip + + LDXIM 0 + LDYIM UTUSID +20 LDAIY USTPTR + EORIX GENPTR + ANDIM &DF + BNE #50 + LDAIY USTPTR + CMPIM TERMIN + BEQ #40 ;end of name + + INC GENPTR + BNE #30 + INC GENPTR+1 + +30 INY + CPYIM MAXID+UTUSID+1 + BNE #20 ;continue + +40 LDAIM ARGD ;update the free space + STA OFF1 + LDXIM ARGPTR + LDAIM UTFREE + STA OFF2 + LDYIM USTPTR + LDAIM 4 ;arguments supplied on stack + JSR MOVBLK + +50 JSR INCUST + DEC USTEMP + BNE #10 ;not end of table + + PLA + STA USTPTR+1 + PLA + STA USTPTR + + LDAIM 0 + JMP USEXIT + +;**************** USDALL **************** + +;ENTRY: none + +;EXIT: none + +;USES: USTPTR + +;All logged on users are logged off. + +USDALL ROUT + JSR INITUS ;Set up to scan all users + LDAIM 0 ;Assume return code + PHA +10 LDYIM UTPRIV + LDAIY USTPTR ;See if slot in use + BPL #20 + PLA ;Current worst return code + TAY + TXA + PHA ;Save index + TYA + JSR LOGOFF ;Logoff this machine + TAY + PLA + TAX ;Reload index + TYA + PHA ;Save new worst return code +20 JSR INCUST ;Attempt to logoff all users + BNE #10 + PLA ;Return code + JMP USEXIT + + + +SETUTP LDYIM ARGB ;SETUP USTPTR + LDAIY ARGPTR + STA USTPTR + INY + LDAIY ARGPTR + STA USTPTR+1 + RTS + + +CHKMC LDYIM ARGB ;SEE IF MACHINE LOGGED ON + LDAIY ARGPTR + STA MCNUMB ;N.B. USE MCTEMP BECAUSE MCNUMB IS USED GLOBALLY + STA MCTEMP ;=LS(MC/NO) + INY + LDAIY ARGPTR + STA MCNUMB+1 + STA MCTEMP+1 ;=CS(MC/NO) + INY + LDAIY ARGPTR ;**25/2/86** + STA MCNUMB+2 + STA MCTEMP+2 ;=MS(MC/NO) + JMP FINDMC + + +RETRV ROUT + LDYIM ARGH ;A passed in call + STAIY NEWARG ;wild card flag + + LDAIM 2 ;DIRMAN.RETRIEVE + JSR SETUSA ;MOVE USTPTR ONTO NEWARG STACK + INY + LDA TITPTR + STAIY NEWARG ;ARGD + INY + LDA TITPTR+1 + STAIY NEWARG ;PTR TO DIR NAME + INY + LDAIM :LSB:USRINF + STAIY NEWARG + INY + LDAIM :MSB:USRINF ;ADDRESS OF DETAILS AREA + STAIY NEWARG + JSR DIRMAN + BNE #20 + LDYIM ARGB + LDAIY NEWARG + STA USRACC ;USRACC:=ACCESS TO OBJECT + ANDIM TYPDIR + BNE #10 + LDAIM URERRD ;RC:=OBJECT NOT A DIR + RTS + +10 LDAIM 0 ;RC := 0 +20 RTS + + +SETUID ROUT + LDYIM UTUSID ;Copy userid from USERTB to USRUFD +10 LDAIY USTPTR ;Copies all chars regardless of termination + STAAY USRUFD-UTUSID + INY + CPYIM UTUSID+MAXUNM + BNE #10 + RTS + + +MAKHDS ROUT + JSR OPEN ;MAKE HANDLES FOR UFD & SELECTED DIR + BNE #20 + + STA UMHUFD ;make this the handle for the UFD + [ Pseudods = Yes + LDYIM UTHUFD ;**26/6/87** and store in user table + STAIY USTPTR + ] + + JSR OPEN ;now get a handle for selected dir + BEQ #10 + PHA + JSR CLUFDR ;CLOSE UFD + PLA + RTS + +10 STA UMHCSD + LDAIM 0 +20 RTS + + + +OPEN ROUT + LDAIM 1 ;CALL RNDMAN.OPEN FOR DIR IN USRINF + JSR SETUSA ;COPY USTPTR ONTO NEWARG STACK + INY + LDAIM 0 ;MODE := 0 + STAIY NEWARG + INY ;Y:=E + LDA USRACC + STAIY NEWARG + INY ;Y:=ARGF + LDAIM :LSB:USRINF + STAIY NEWARG + INY + LDAIM :MSB:USRINF + STAIY NEWARG ;PTR TO OBJECT DETAILS + JSR RNDMAN + BNE #10 + LDYIM ARGB + LDAIY NEWARG + LDYIM 0 +10 RTS + +; SETUSA: Move Arg, USTPTR onto NEWARG stack +; SETUSR: Move just USTPTR onto NEWARG stack +; Exit: Y=ARGC + +SETUSA ROUT ;Move Arg in A onto NEWARG stack **25/12/86** + JSR SETRTN +SETUSR LDYIM ARGB ;MOVE USTPTR ONTO NEWARG STACK + LDA USTPTR + STAIY NEWARG + INY + LDA USTPTR+1 + STAIY NEWARG + RTS + + +;LOGOFF: CLOSE ALL HANDLES OPENED BY M/C & FREE USERTB ENTRY +;Return code as entered, or replaced by any LOGOFF error code + +LOGOFF ROUT + PHA + LDAIM 6 + JSR SETUSA + JSR RNDMAN ;*** CLOSE ALL ENTRIES ** + BEQ #10 + TAY + PLA ;**1/6/88** stack bad return code + TYA + PHA + +;NOW CLEAR USERTB ENTRY TO ZERO + +10 JSR USENS ;update all free space entries + BEQ #20 + TAY + PLA ;**1/6/88** stack bad return code + TYA + PHA +20 LDYIM UTPRIV ;check for priv'd user + LDAIY USTPTR ;** 27/9/84 ** + ANDIM SYSTPV + BEQ #30 ;not priv'd + DEC USSYS ;decrement counter +30 LDAIM 0 + LDYIM UTENSZ-1 ;**1/6/88** +40 STAIY USTPTR + DEY + BPL #40 + PLA + RTS + + +USENS CLC ;** 2/10/84 ** + LDYIM ARGD + LDA USTPTR + ADCIM :LSB:UTUSID + STAIY NEWARG ;nb ARGB,C unused here + + INY + LDA USTPTR+1 + ADCIM :MSB:UTUSID + STAIY NEWARG + + LDAIM UTFREE + STA OFF1 + LDAIM ARGF + STA OFF2 + LDXIM USTPTR + LDYIM NEWARG + LDAIM UTFRLN + JSR MOVBLK + + LDAIM 8 ;ensure free store in PW file + JSR SETRTN + JMP AUTMAN + + +CLOSE PHA + LDAIM 3 ;RNDMAN.CLOSE + JSR SETUSA ;PLACE PTR TO USERINFO ON NEWARG STACK + INY + PLA + STAIY NEWARG ;**25/12/86** + JMP RNDMAN + + +CLUFDR ROUT + LDA UMHUFD ;CLOSE UFD + BEQ #10 + JSR CLOSE + PHA + LDAIM 0 + STA UMHUFD + PLA +10 RTS + + +CLSLDR LDA UMHCSD + BEQ #10 + JSR CLOSE + PHA + LDAIM 0 + STA UMHCSD + PLA +10 RTS + + +;GETUFD: SEE IF THERE IS A UFD IN THE ROOT DIR ON +;CURRENTLY SELECTED DISC. +;IF THERE IS A UFD THEN MAKE HANDLES FOR +;THE UFD & THE CURRENTLY SELCECTED DIRECTORY. +;ALSO SEARCH FOR LIB. IF FOUND, GET HANDLE +;FOR IT, IF NOT LIB:=CSD/UFD + +;EXIT: A := RC + + +GETUFD ROUT + JSR SETUID ;COPY USERID INTO USRUFD + LDAIM TERMIN + STA USRTER + LDAIM SEPART + JSR #20 ;**7/7/88** complete title and retrieve + BNE #10 + LDAIM OWNER + ORA USRACC + STA USRACC ;OWNER ACCESS TO UFD + BNE #00 ;Common code + +GTROOT JSR RTROOT + BNE #10 +00 JSR MAKHDS ;MAKE HANDLES + BNE #10 + JSR GETLBH ;LOOK FOR LIB FILE +10 RTS + +RTROOT LDAIM TERMIN +20 STA USRSEP + LDAIM ROOT + STA USRROT + LDAIM :LSB:USRROT + STA TITPTR + LDAIM :MSB:USRROT + STA TITPTR+1 + LDAIM 0 ;no wild cards here + JMP RETRV ;RETRIEVE ROOT DIR + + + +;TRY TO RETRIEVE FILE "LIBRARY". +;IF FOUND, OPEN AND PUT HANDLE +;IN LIB. LOCATION. IF NOT, OPEN +;ROOT, WHICH WILL BE LIBRARY + +;** 15/9/83 ** + +GETLBH ROUT + LDYIM UTDISC + LDAIY USTPTR + STA USDISC + INY + LDAIY USTPTR + STA USDISC+1 ;save users disc number + + LDAIM 0 + STA UMHLIB ;spare counter +10 LDA UMHLIB + JSR DRVINF ;drive exists ? + BNE #20 ;no + JSR SUSRDI + + LDAIM :LSB:DEFLIB ;PTR. TO LIB. TITLE + STA TITPTR + LDAIM :MSB:DEFLIB + STA TITPTR+1 + + LDAIM 0 ;no wild cards here + JSR RETRV + + BEQ #30 ;OK, FOUND SO OPEN + CMPIM DRERRC + BNE #50 ;IF ERROR NOT "NOT FOUND", ABORT + +20 INC UMHLIB + LDA UMHLIB ;**14/06/86** + CMP DRIVES ;**14/06/86** + BCC #10 ;loop until all drives tried + +;Retrieve root again. Then open and return +;handle for lib. + + JSR #40 + JSR RTROOT ;Otherwise, retrieve + BNE #50 + +30 JSR OPEN + BNE #50 ;ABORT IF ERROR + STA UMHLIB ;STORE HANDLE + LDAIM 0 ;GIVE Z SET + +40 TAX + LDYIM UTDISC+1 ;restore the old values + STA USDISC+1 + STAIY USTPTR + DEY + STA USDISC + STAIY USTPTR + TXA ;restore return code + RTS + +50 PHA + JSR CLUFDR + JSR CLSLDR + PLA + BNE #40 + +DEFLIB = "$.library",CR + +MOVHND ROUT + PHA + INY + INY + LDXIM 2 +10 LDAAX UMHUFD + STAIY ARGPTR + DEY + DEX + BPL #10 + PLA + RTS + + LNK RMAN01 diff --git a/Level3/SRC/L3/Uade0A b/Level3/SRC/L3/Uade0A new file mode 100644 index 0000000..d9cf80b --- /dev/null +++ b/Level3/SRC/L3/Uade0A @@ -0,0 +1,567 @@ + OPT UADE0A ;FILE > Uade0A + TTL File server file UADE0A + +;********************************** +;* S T R M A N * +;********************************** + + +;STRMAN: THE STORE MANAGER IS RESPONSIBLE +;FOR MAINTAINING A CACHE OF +;VARIABLE LENGTH (BUT AN INTEGRAL NUMBER +;OF DISC BLOCKS) OBJECT WINDOWS. + +;THE CONTENTS OF THE CACHE IS DESCRIBED BY +;A ONE WAY CHAIN OF DESCRIPTORS. +;THESE DESCRIPTORS ARE KEPT IN AN ORDER WHICH +;DESCRIBES THE POSITION OF THE WINDOWS IN MEMORY. +;NOTE THAT EACH OBJECT IN THE CACHE +;IS PRECEEDED BY A ONE BYTE DIRTY MARKER. + + +;********* MAIN ROUTINE ********* + +STRMAN ROUT + LDXIM 9 ;STRMAN HAS 9 ENTRY POINTS + LDAIM MODSTR ;A:=NAME OF THIS MODULE + JSR ENTRY + LDAAX STRTNS + STA STJUMP+1 + LDAAX STRTNS+1 + STA STJUMP+2 + LDAIM &F + JSR SETFS ;SET FRAME SIZE +STJUMP JMP STJUMP +STRTNS + & STDTSA ;1 => DISC ADDRESS TO STORE ADDRESS + & STENWD ;2 => ENSURE WINDOW + & STULWD ;3 => UNLOCK CACHED WINDOW + & STFLWD ;4 => FLUSH WINDOW + & STRALL ;5 => REMOVE ALL BLOCKS OF AN OBJECT FROM CACHE + & STREST ;6 => RESTART + & STGBB ;7 => GET BIG BUFFER + & STEMPT ;8 => EMPTY THE CACHE OF ALL OBJECTS FROM A DISC + & STRDRT ;9 => REMOVE ALL DIRTY BLOCKS OF AN OBJECT +STEXIT JMP PREXIT + + +;************ STDTSA ************ + + +;STDTSA: DISC ADDRESS TO STORE ADDRESS + +;ENTRY: ARGB = LS(DISC NUMBER) +;ARGC = MS(DISC NUMBER) +;ARGD = LS(SIN) +;ARGE = CS(SIN) +;ARGF = MS(SIN) +;ARGG = LS(LOGICAL BLOCK NUMBER) +;ARGH = MS(LOGICAL BLOCK NUMBER) +;ARGI = LS(NO OF BLOCKS) +;ARGJ = MS(NO OF BLOCKS) + +;EXIT: ARGA = RC +;ARGB = LS(STORE ADDRESS) +;ARGC = MS(STORE ADDRESS) +;ARGD = LS(STORE ADDR OF CACHE DESCR) +;ARGE = MS(STORE ADDR OF CACHE DESCR) + + +;FUNCTION: THE CACHE IS SEARCHED TO SEE IF +;THE SPECIFIED WINDOW IS IN MEMORY. +;IF IT IS NOT IN THE CACHE THEN IT +;HAS TO BE READ FROM DISC. +;WHEN THE WINDOW IS IN THE CACHE +;THE ENTRY'S REFERNCE COUNT IS INCREMENTED +;AND ITS AGE SET TO MRU. +;NOTE IF THE WINDOW IS NOT FOUND +;IN THE CACHE IT IS NECESSARY TO +;FIND A STORE BUFFER INTO WHICH +;IT MAY BE READ FROM DISC-THIS CAN +;INVOLVE ONE, OR MORE, OLD WINDOWS +;BEING WRITTEN OUT TO CREATE SPACE. + +;IF WINDOW IN CACHE +;THEN AGE OF BLOCK := MRU; +;REFERENCE COUNT OF WINDOW +:= 1 +;ELSE GET A FREE STORE BUFFER; #THIS IS A LITTLE INVOLVED# +;READ OBJECT FROM DISC; +;AGE OF OBJECT := MRU; +;REFERENCE COUNT OF WINDOW := 1 +;FI + + + +STDTSA ROUT + JSR TSTSIN + BNE #20 + JSR INSRCH ;INIT PREV,CRNT,CMPPTR +10 LDXIM 9 + JSR COMP ;COMPARE DISC NO,SIN,BLK NO,NO OF BLOCKS + BNE #30 + +;ITS IN THE CACHE + + JSR INCCNT ;REF COUNT +:= 1 + LDYIM CEAGE + LDAIM MRU ;MARK IT MRU + STAIY CRNT + JSR RETSTA ;RETURN STORE ADDR & ADDR OF CRNT DESCR + LDAIM 0 +20 JMP #60 + +30 JSR NXTCRN ;CRNT:=NEXT OF CRNT + BNE #10 + +;ITS NOT IN THE CACHE SO GET SOME FREE SPACE +;AND HAVE THE OBJECT READIN. + + LDYIM ARGI + LDAIY ARGPTR + STA BREGA + INY + LDAIY ARGPTR + STA BREGA+1 + LDAIM 0 + STA BREGA+2 + JSR MULTBS ;BREGA *:=BLKSZE + LDA BREGA+2 + BEQ #40 + LDAIM STERRE ;SIZE TO BIG + BNE #60 + +40 LDA BREGA + STA AMTNED + LDA BREGA+1 + STA AMTNED+1 ;AMTNED := BREGA + JSR FREEST ;GET AMTNED WORTH OF FREE STORE + BNE #60 + +;AT THIS POINT CRNT PTS TO A CACHE ENTRY +;DESCRIPTOR. NOW COPY DISC NO, SIN, +;BLKNO, NO OF BLOCKS INTO CRNT. + + CLC + LDA ARGPTR + ADCIM ARGB + STA MOVFRM + LDA ARGPTR+1 + ADCIM 0 + STA MOVFRM+1 ;MOVFRM := ARGPTR + ARGB + LDA CRNT + STA MOVTO + LDA CRNT+1 + STA MOVTO+1 + LDXIM 9 + JSR MOVE + +;READ OBJECT FROM DISC & INITIALISE REF COUNT & AGE + + JSR RETSTA ;PUT STORE ADDR ON ARGPTR STACK + JSR READ ;READ OBJECT FROM DISC + BEQ #50 + PHA ;Store return code + LDYIM CERCNT + LDAIM 0 + STAIY CRNT ;Make sure ref. count = 0 + PLA ;return code stored over REMVIT + JSR REMVIT + BNE #60 + +50 LDYIM CERCNT + LDAIM 1 + STAIY CRNT ;REF COUNT := 1 + LDYIM CEAGE + LDAIM MRU + STAIY CRNT ;AGE := MRU + LDAIM 0 ;RC := 0 +60 JMP STEXIT + + + +;************ STENWD ************ + + +;STENWD: ENSURE WINDOW. THIS ENSURES THAT A GIVEN +;WINDOW IS UPTO DATE ON DISC. + +;ENTRY: ARGB = LS(WINDOW STORE ADDRESS) +;ARGC = MS(WINDOW STORE ADDRESS) +;ARGD = 0 => DON'T DECREMENT REF COUNT +;<> 0 => DECREMENT REF COUNT + +;EXIT : ARGA = RC + +;FUNCTION: 1) SEARCH CACHTB FOR ENTRY +;2) IF DIRTY WRITE TO DISC & MARK IT CLEAN +;3) DECREMENT ITS REFERENCE COUNT IF NEED BE + + + +STENWD ROUT + JSR FNDSTA + BEQ #10 + JSR INTERR +10 JSR ENSURE ;ENSURE WINDOW UPTO DATE ON DISC + PHA + LDYIM ARGD + LDAIY ARGPTR ;IS USE COUNT TO BE DECREMENTED + BEQ #20 + JSR DECCNT +20 PLA + BEQ #30 ;skip if all ok + JSR REMVIT ;else remove the object from the cache +30 JMP STEXIT ;RC preserved + + + + +;************ STULWD ************ + + +;STULWD: UNLOCK BUFFER. THIS FUNCTION DECREMENTS +;A STORE BUFFER'S REFERENCE COUNT. + +;ENTRY: ARGB = LS(BUFFER STORE ADDRESS) +;ARGC = MS(BUFFER STORE ADDRESS) + +;EXIT : ARGA = RC + +;FUNCTION: 1) SEARCH THE CACHE FOR SPECIFIED BUFFER. +;2) DECREMENT THE BUFFER'S REFERENCE COUNT. + +;NOTE THIS OPERATION WILL NOT WRITE THE BLOCK +;TO DISC EVEN IF IT IS MARKED DIRTY. + + +STULWD ROUT + JSR FNDSTA + BEQ #10 + JSR INTERR +10 JSR DECCNT + LDAIM 0 + JMP STEXIT + + + +;************ STFLWD ************ + + +;STFLWD:FLUSH WINDOW. THIS FUNCTION INFORMS +;STRMAN THAT A STORE BUFFER WILL PROBABLY NOT +;BE NEEDED IN THE NEAR FUTURE. + +;ENTRY: ARGB = LS(BUFFER STORE ADDRESS) +;ARGC = MS(BUFFER STORE ADDRESS) + +;EXIT : ARGA = RC + +;FUNCTION: 1) SEARCH CACHTB FOR THE BUFFER +;AND THEN DECREMENT ITS REFERENCE COUNT +;2) IF BUFFER MARKED 'DIRTY' +;THEN WRITE IT TO DISC +;3) AGE OF BUFFER := LRU (I.E. VERY OLD) +;4) IF REFCOUNT=0 THEN REMOVE OBJ FROM CACHE + + +STFLWD ROUT + JSR FNDSTA + BEQ #10 + JSR INTERR +10 JSR ENSURE + PHA + JSR DECCNT + LDYIM CEAGE + LDAIM LRU + STAIY CRNT + JSR TSTCNT + BNE #20 + JSR REMVIT +20 PLA ;RC from ENSURE + JMP STEXIT + + + +;************ STRALL ************ + + +;STRALL: REMOVES ALL THE BLOCKS, BELONGING TO +;A SPECIFIED FILE, FROM THE CACHE. +;NOTE IT IS ASSUMED THAT STEPS ARE TAKEN, +;BEFORE STRALL IS CALLED, TO +;AVOID BLOCKS OF THE FILE BEING LOADED. + + +;ENTRY: ARGB = LS(DISC NUMBER) +;ARGC = MS(DISC NUMBER) +;ARGD = LS(SIN) +;ARGE = CS(SIN) +;ARGF = MS(SIN) + +;EXIT : ARGA = RC + +;FUNCTION: 1) SCAN THE CACHTB REMOVING ALL THE +;WINDOWS BELONGING TO THIS FILE. +;2) THE WINDOWS MARKED DIRTY ARE WRITTEN TO DISC. +;3) THE WINDOWS ARE THEN REMOVED FROM +;THE CACHE. + + +STRALL ROUT + JSR TSTSIN + BNE #10 + + LDXIM 5 ;COMPARE DISC NUMBER & SIN + JSR EXPELL ;REMOVE ALL OBJECTS WITH GIVEN DISC NO & SIN + +10 JMP STEXIT + + +;************ STREST ************ + + +;STREST: RESTART +;1)GETVEC SPACE FOR +;a)THE BIG BUFFER +;b)FIRST CACHE ENTRY DESCRIPTOR & MAKE +;CACHTB PT TO IT. +;c)NUMBCE+1 CACHE ENTRY DESCRIPTORS & PUT +;THEM ON THE FREE CHAIN (FRECHN). +;d)THE CACHE ITSELF (CACHSZ BYTES) + + + + +STREST ROUT + LDYIM :LSB:LGBFSZ ;Y:=LS(SIZE OF BIG BUFFER) + LDXIM :MSB:LGBFSZ ;X:=MS(SIZE OF BIG BUFFER) + JSR GETVEC ;Get big buffer + STY BIGBUF + STX BIGBUF+1 ;BIGBUF:=ADDR OF BIG BUFFER + +;CREATE THE FIRST CACHE DESCRIPTOR (CACHTB) + + JSR CRDESC + LDA CRNT + STA CACHTB + LDA CRNT+1 + STA CACHTB+1 ;CACHTB := ADDR OF DESC. FOR 1ST ENTRY + +;NOW CALCULATE NO. OF CACHE DESCRIPTORS +;AND CACHE SIZE. + +;CACHSZ := ENDPTR-FREPTR +;CACHSZ -:= (DESC. SIZE) * 2 +;NO. OF OBJECTS := CACHSZ / (OBJECT SIZE+DESC. SIZE) +;CACHSZ -:= DESC.SIZE*NO. OF OBJECTS + + + LDAIM CESIZE + ROLA + STA TEMPA ;TEMPA := DESC. SIZE * 2 + SEC + LDA ENDPTR + SBC FREPTR + SBC TEMPA + STA DIVPAR + STA CACHSZ + LDA ENDPTR+1 + SBC FREPTR+1 + STA DIVPAR+1 + STA CACHSZ+1 + + LDXIM 0 +10 SEC + LDA DIVPAR + SBCIM CESIZE ;(Object size + desc. size) lo + STA DIVPAR + LDA DIVPAR+1 + SBCIM 1 ;(Object size + desc. size) hi + STA DIVPAR+1 + BCC #20 + INX + ORA DIVPAR + BEQ #20 + BCS #10 +20 STX NUMBCE ;No. of cache objects : +30 SEC ;NOW SUBTRACT C.D. SIZE, NUMBCE TIMES + LDA CACHSZ + SBCIM CESIZE + STA CACHSZ + BCS #35 + DEC CACHSZ+1 +35 DEX + BNE #30 + + JSR VSTRIN + = CR,"Cache size - " + NOP + + LDA CACHSZ+1 + JSR WHEX + LDA CACHSZ + JSR WHEX + + JSR VSTRIN + = " objects - " + NOP + + LDA NUMBCE + JSR WHEX + JSR OSCRLF + + +;NOW CREATE (NUMBCE+1) DESCRIPTORS & PLACE THEM ON +;THE FREE CHAIN. + + LDAIM 0 + STA FRECHN + STA FRECHN+1 ;FRECHN := 0 + LDX NUMBCE + INX ;X:=NUMBCE+1 +40 JSR CRDESC ;CREATE A DESCRIPTOR + JSR MKFREE ;PLACE IT ON THE FREE CHAIN + DEX + BNE #40 + +;NOTE THAT THE FOLLOWING CODE IS ONLY TEMPORARY +;EVENTUALLY WE WANT TO USE THE REMAINDER OF FREE STORE +;FOR THE CACHE (N.B. CREATEING SUFFICIENT DESCRIPTORS). + +;NOW CREATE THE CACHE AREA ITSELF + + LDY CACHSZ ;Y:=LS(SIZE OF CACHE AREA) + LDX CACHSZ+1 ;X:=MS(SIZE OF CACHE AREA) + JSR GETVEC + STY CLRPTR + STX CLRPTR+1 + +;MAKE FIRST DESCRIPTOR PT TO FIRST FREE CACHE BYTE + + JSR STCRNT ;PREV:=CACHTB + LDYIM CESTA + LDA CLRPTR + STAIY PREV + LDA CLRPTR+1 + INY + STAIY PREV ;STORE OF PREV := PTR TO FIRST FREE BYTE + + JSR FRDESC ;GET A FREE DESCRIPTOR + LDYIM CENEXT + LDA CRNT + STAIY PREV + LDAIM 0 + STAIY CRNT + INY + LDA CRNT+1 + STAIY PREV ;NEXT OF PREV := CRNT + LDAIM 0 + STAIY CRNT ;NEXT OF CRNT := 0 + +;MAKE LAST DESCRIPTOR POINT TO LAST+1 FREE BYTE + + LDYIM CESTA + SEC ;BECAUSE WE WANT TO ADD 1 + LDA CLRPTR + ADC CACHSZ + STAIY CRNT + LDA CLRPTR+1 + ADC CACHSZ+1 + INY ;Y := CESTA + 01 + STAIY CRNT + +;NOW CLEAR WHOLE OF THE CACHE TO ZERO + + LDY CACHSZ + LDX CACHSZ+1 + JSR CLRSTR + + LDAIM 0 ;RC := 0 + JMP STEXIT + + + +;************ STGBB ************* + + +;STGBB: GET BIG BUFFER +;THIS FUNCTION SUPPLIES THE STORE ADDRES +;AND SIZE OF A LARGE BUFFER. +;THIS BUFFER SHOULD BE USED FOR LARGE +;TRANSFERS TO AND FROM THE DISC. +;ENTRY: +;EXIT : ARGB = LS(BUFFER STORE ADDRESS) +;ARGC = MS(BUFFER STORE ADDRESS) +;ARGD = LS(SIZE OF BUFFER) +;ARGE = MS(SIZE OF BUFFER) + + + +STGBB ROUT + LDYIM ARGB + LDA BIGBUF + STAIY ARGPTR ;LS(BUFFER ADDRESS) + INY ;Y:=ARGC + LDA BIGBUF+1 + STAIY ARGPTR ;MS(BUFFER ADDRESS) + INY ;Y:=ARGD + LDAIM :LSB:LGBFSZ + STAIY ARGPTR ;LS(BUFFER SIZE) + INY ;Y:= ARGE + LDAIM :MSB:LGBFSZ + STAIY ARGPTR ;MS(BUFFER SIZE) + LDAIM 0 + JMP STEXIT + + + +;************ STEMPT ************ + + +;STEMPT: EMPTY THE CACHE OF ALL THE OBJECTS WHICH +;CAME FROM A SPECIFIED DISC. + +;ENTRY: ARGB = LS(DISC NUMBER) +;ARGC = MS(DISC NUMBER) + +;EXIT : ARGA = RC + + +STEMPT ROUT + LDXIM 2 ;COMPARE DISC NUMBER + JSR EXPELL ;REMOVE ALL OBJECTS ON SPECIFIED DISC FROM CACHE + JMP STEXIT + +;STRDRT: REMOVES ALL THE DIRTY BLOCKS, BELONGING TO +;A SPECIFIED FILE, FROM THE CACHE. +;NOTE IT IS ASSUMED THAT STEPS ARE TAKEN, +;BEFORE STRALL IS CALLED, TO +;AVOID BLOCKS OF THE FILE BEING LOADED. + + +;ENTRY: ARGB = LS(DISC NUMBER) +;ARGC = MS(DISC NUMBER) +;ARGD = LS(SIN) +;ARGE = CS(SIN) +;ARGF = MS(SIN) + +;EXIT : ARGA = RC + +;FUNCTION: 1) SCAN THE CACHTB REMOVING ALL THE DIRTY +;WINDOWS BELONGING TO THIS FILE. +;2) THE WINDOWS MARKED DIRTY ARE WRITTEN TO DISC. +;3) THE WINDOWS ARE THEN REMOVED FROM +;THE CACHE. + + +STRDRT ROUT + JSR TSTSIN + BNE #10 + + LDAIM &FF ;=> Only remove DIRTY windows + LDXIM 5 ;COMPARE DISC NUMBER & SIN + JSR EXPELA ;REMOVE ALL DIRTY OBJECTS +;WITH GIVEN DISC NO & SIN +10 JMP STEXIT + + LNK UADE0B diff --git a/Level3/SRC/L3/Uade0B b/Level3/SRC/L3/Uade0B new file mode 100644 index 0000000..73b9b31 --- /dev/null +++ b/Level3/SRC/L3/Uade0B @@ -0,0 +1,711 @@ + OPT UADE0B ;FILE > Uade0B + TTL File server file UADE0B + + +;********************************** +;* STRMAN UTILITIES * +;********************************** + + +CRDESC ROUT + TYA ;CREATE A NEW DESCRIPTOR + PHA + TXA + PHA + LDYIM CESIZE + LDXIM 0 + JSR GETVEC + STY CRNT + STY CLRPTR + STX CRNT+1 ;CRNT := ADDR OF NEW DESCRIPTOR + STX CLRPTR+1 + LDYIM CESIZE + LDXIM 0 + JSR CLRSTR ;CLEAR DESCRIPTOR TO ZERO + PLA + TAX + PLA + TAY + RTS + +MKFREE ROUT + TXA + PHA ;PUSH X + LDXIM CESIZE ;CLEAR CRNT DESCRIPTOR + LDAIM 0 + TAY +10 STAIY CRNT + INY + DEX + BNE #10 + LDA FRECHN ;PLACE CRNT DESCRIPTOR ON FREE CHAIN + LDYIM CENEXT + STAIY CRNT + LDA FRECHN+1 + INY + STAIY CRNT ;NEXT OF CRNT := (FRECHN) + LDA CRNT + STA FRECHN + LDA CRNT+1 + STA FRECHN+1 ;FRECHN := CRNT + PLA + TAX ;PULL X + RTS + + +FRDESC ROUT + LDA FRECHN ;REMOVE A DESCRIPTOR FROM FREE CHAIN + STA CRNT + LDA FRECHN+1 + STA CRNT+1 ;CRNT := PTR TO A FREE ENTRY + ORA CRNT + BNE #10 + LDAIM STERRG ;NO FREE CACHE DESCRIPTORS + JSR INTERR +10 LDYIM CENEXT + LDAIY CRNT + STA FRECHN + INY + LDAIY CRNT + STA FRECHN+1 ;FRECHN:=NEXT OF CRNT + RTS + + +STCRNT LDA CACHTB ;PREV:=CACHTB;CRNT:=NEXT OF PREV + STA PREV + LDA CACHTB+1 + STA PREV+1 + LDYIM CENEXT + LDAIY PREV + STA CRNT + INY + LDAIY PREV + STA CRNT+1 + RTS + + +INSRCH JSR STCRNT ;INITIALISE CRNT,CMPPTR + CLC + LDA ARGPTR + ADCIM ARGB + STA CMPPTR + LDA ARGPTR+1 + ADCIM 0 + STA CMPPTR+1 + RTS + + +NEXTCE ROUT + LDYIM CENEXT ;PREV:=CRNT;CRNT:=NEXT OF CRNT + LDAIY CRNT + INY + ORAIY CRNT + BEQ #10 ;NO MORE ENTRIES (A=0) + LDA CRNT + STA PREV + LDA CRNT+1 + STA PREV+1 + DEY ;Y := CENEXT + LDAIY CRNT + TAX + INY + LDAIY CRNT + STA CRNT+1 + TXA + STA CRNT + LDAIM &FF ;A INDICATES THAT THERE ARE MORE ENTRIES +10 RTS + + +COMP ROUT + TXA ;COMPARE CRNT ENTRY WITH X ARGS + TAY +10 DEY + LDAIY CMPPTR + CMPIY CRNT + BNE #20 + DEX + BNE #10 +20 TXA + RTS + + +TSTSIN ROUT + LDYIM ARGD + LDAIY ARGPTR + INY + ORAIY ARGPTR + INY + ORAIY ARGPTR + BNE #10 + LDAIM STERRB ;SIN = 0 + RTS + +10 LDAIM 0 + RTS + + +RETSTA LDYIM CESTA + LDAIY CRNT + LDYIM ARGB + STAIY ARGPTR ;LS(STORE ADDRESS) + LDYIM CESTA+1 + LDAIY CRNT + LDYIM ARGC + STAIY ARGPTR ;MS(STORE ADDRESS) + INY ;Y := ARGD + LDA CRNT + STAIY ARGPTR + INY + LDA CRNT+1 + STAIY ARGPTR ;ADDRESS OF CRNT DESCRIPTOR + RTS + + +READ JSR MRKCLN ;MARK BUFFER CLEAN + LDAIM 1 ;READ OBJECT + JSR SETRTN ;DSCMAN.READ + JMP TRANSF + + +ENSURE ROUT + JSR TSTMRK ;IS IT DIRTY? + BEQ #10 + LDAIM 2 + JSR SETRTN + JSR TRANSF ;WRITE IT TO DISC + BNE #10 + JSR MRKCLN ;preserve return code from TRANSF +10 RTS + + +TRANSF LDA CRNT + STA MOVFRM + LDA CRNT+1 + STA MOVFRM+1 + CLC + LDA NEWARG + ADCIM ARGB + STA MOVTO + LDA NEWARG+1 + ADCIM 0 + STA MOVTO+1 + LDXIM &B ;DISC NO -> STORE ADDRESS + JSR MOVE + JMP DSCMAN + + +REMVIT ROUT + PHA ;PUSH A + JSR TSTCNT + BEQ #10 + LDAIM STERRH + JSR INTERR +10 LDYIM CENEXT ;REMOVE CRNT FROM IN USE CHAIN + LDAIY CRNT + STAIY PREV + PHA + INY + LDAIY CRNT + STAIY PREV ;NEXT OF PREV := NEXT OF CRNT + PHA + JSR MKFREE ;PLACE IT ON FREE CHAIN + PLA + STA CRNT+1 + PLA + STA CRNT ;CRNT := NEXT OF PREV + PLA ;PULL A + RTS + + +;EXPELL: ROUTINE TO REMOVE OBJECTS FROM THE CACHE. +;ENTRY: X := 2 => MATCH ON DISC NUMBER (I.E. ARGB&ARGC) +;X := 5 => MATCH ON DISC NUMBER + SIN + +;THE ENTRY EXPELA IS USED FROM STRDRT WITH +;A NON-ZERO TO INDICATE THAT ONLY DIRTY +;BLOCKS SHOULD BE REMOVED FROM THE CACHE. + +EXPELL ROUT + LDAIM 0 ;=> REMOVE ALL BLOCKS REGARDLESS +EXPELA PHA + STX STRTMP ;STRTMP := X + JSR INSRCH +20 LDX STRTMP + JSR COMP ;COMPARE DISC NUMBER & (POSSIBLY) SIN + BNE #60 + JSR TSTCNT + BEQ #30 + LDAIM STERRH ;REF COUNT > 0 + JSR INTERR + +;ENSURE THE OBJECT & THEN REMOVE IT FROM THE CACHE + +30 PLA + PHA + BEQ #50 ;EQ => REMOVE ALL BLOCKS + JSR TSTMRK ;NZ => REMOVE DIRTY BLOCKS ONLY + BEQ #60 ;NOT DIRTY, GO TO NEXT BLOCK + + JSR ENSURE ;ENSURE ITS UPTO DATE ON DISC + PHA ;save error code (4/4/86) + LDYIM CEAGE ;Age entry considerably (16/1/85) + LDAIM &80 + STAIY CRNT + PLA + BNE #70 ;br if error + BEQ #60 + +50 JSR ENSURE ;Ensure up to date on disc + JSR REMVIT ;Destroy file so remove all + BNE #70 ;Detect disc errors + LDYIM CENEXT ;REMVIT compacted everything + LDAIY CRNT + INY + ORAIY CRNT + BNE #20 +60 JSR NEXTCE ;PREV:=CRNT;CRNT:=NEXT OF CRNT + BNE #20 + PLA ;RESTORE STACK + LDAIM 0 ;RC:=0 + RTS + +70 TAX ;save A, clean stack + PLA + TXA + RTS + + +FNDSTA ROUT + LDYIM ARGB ;FIND CACHE ENTRY WITH GIVEN STORE ADDRESS + LDAIY ARGPTR + STA STRTMP + INY + LDAIY ARGPTR + STA STRTMP+1 + JSR STCRNT +10 LDYIM CESTA + LDAIY CRNT + CMP STRTMP + BNE #20 + INY + LDAIY CRNT + CMP STRTMP+1 + BEQ #30 +20 JSR NEXTCE + BNE #10 + LDAIM STERRF ;INVALID WINDOW ADDRESS +30 RTS + + +DECGEN SEC + LDYIM CESTA + LDAIY CRNT + SBCIM 1 + STA GENPTR + INY + LDAIY CRNT + SBCIM 0 + STA GENPTR+1 + RTS + + +MRKCLN PHA ;MARK STORE BUFFER CLEAN + TYA ;SAVE A & Y + PHA + JSR DECGEN ;GENPTR SHOULD CONTAIN ADDRESS OF BUFFER + LDAIM 0 ;A := 0 + TAY + STAIY GENPTR ;[GENPTR] := 0 + PLA + TAY ;PULL Y + PLA ;PULL A + RTS + + +TSTMRK JSR DECGEN ;TEST DIRTY MARKER - NOTE THIS RTN DESTROYS A & Y + LDYIM 0 + LDAIY GENPTR ;A:=[GENPTR] + RTS + + +INCCNT ROUT + LDYIM CERCNT ;INCREMENT REFERENCE COUNT + LDAIY CRNT + CMPIM &FF + BNE #10 + LDAIM STERRK ;REFERENCE COUNT = $FF + JSR INTERR +10 CLC + ADCIM 1 + STAIY CRNT + RTS + + +DECCNT ROUT + LDYIM CERCNT ;DECREMENT REFERENCE COUNT + LDAIY CRNT + BNE #10 + LDAIM STERRD ;REFERENCE COUNT = 0 + JSR INTERR +10 SEC + SBCIM 1 + STAIY CRNT + RTS + +TSTCNT LDYIM CERCNT ;TEST VALUE OF REFERNENCE COUNT + LDAIY CRNT + RTS + + +;FREEST: GET AMTNED WORTH OF FREE STORE. +;EXIT : A = RC +;CRNT POINTS TO DESCRIPTOR WITH STORE ADDRESS SET + +;FUNCTION:- +;1) AGE ALL THE ENTRIES IN THE CACHE +;2)FIND OUT THE MOST COST EFFECTIVE AREA +;OF MEMORY TO USE. + +;WHILE crnt <> 0 AND min cost <> 0 +;DO IF amount needed<=(storeaddrOFcrnt-storeaddrOFprev +;- lengthOFprev-2) +;THEN IF cost<min cost +;THEN min cost := cost; +;best start := prev; +;best end := crnt +;FI; +;prev:=nextOFprev; +;cost:=cost-costOFprev +;ELSE IF ref count OF crnt <> 0 +;THEN prev := crnt; +;cost := 0 +;ELSE cost +:= cost OF crnt +;FI; +;crnt := next OF crnt +;FI +;OD; + +;WHILE crnt <> best end +;DO ensure(crnt); #ENSURE WINDOW UPTO DATE ON DISC# +;remove(crnt) #REMOVE CRNT FROM IN USE CHAIN# +;OD; + +;crnt := get free descriptor; +;straddrOFcrnt:=straddrOFprev+lengthOFprev+1 + +FREEST ROUT + LDA AMTNED + ORA AMTNED+1 + BNE #05 + LDAIM STERRE + RTS + +;FIRST,AGE EACH OBJECT IN THE CACHE + +05 JSR STCRNT ;PREV:=CACHTB;CRNT:=NEXT OF PREV + +10 LDYIM CEAGE + LDAIY CRNT + CMPIM LRU + BEQ #15 + SEC + SBCIM 1 + STAIY CRNT ;AGE OF CRNT -:= 1 +15 JSR NXTCRN + BNE #10 + +;NOW SEE WHICH IS THE BEST AREA OF MEMORY TO USE + + JSR STCRNT + LDAIM 0 + STA BSTSTA + STA BSTSTA+1 ;BSTSTA : = 0 + STA BSTEND + STA BSTEND+1 ;BSTEND := 0 + STA COST + STA COST+1 ;COST := 0 + LDAIM &FF + STA MINCST + LDAIM &7F + STA MINCST+1 ;MINCST := $7FFF + +20 JSR TSTGAP + BEQ #22 + JMP #45 + +;SEE IF COST < MIN COST + +22 LDXIM &FF ;X<>0 here + LDA COST + PHA + LDA COST+1 + PHA ;save cost for new algorithm + + LDYIM CENEXT + LDAIY PREV + STA GP1 + INY + LDAIY PREV + STA GP1+1 ;intermediate pointer + + LDAIY GP1 + CMP CRNT+1 + BNE #30 + DEY + LDAIY GP1 + CMP CRNT + BNE #30 ;skip if not single slot + + LDYIM CEAGE + LDAIY GP1 ;get the age + TAX + STA COST ;make new account + LDAIM 0 + STA COST+1 + + LDY AMTNED+1 + LDA AMTNED + BEQ #25 + INY + +25 DEY + BEQ #30 + CLC + TXA + ADC COST + STA COST + BCC #25 + INC COST+1 + BNE #25 + +30 LDA COST + CMP MINCST + LDA COST+1 + SBC MINCST+1 + BCS #35 + + LDA PREV + STA BSTSTA + LDA PREV+1 + STA BSTSTA+1 ;BSTSTA := PREV + LDA CRNT + STA BSTEND + LDA CRNT+1 + STA BSTEND+1 ;BSTEND := CRNT + LDA COST + STA MINCST + LDA COST+1 + STA MINCST+1 ;MINCST := COST + ORA MINCST + TAX + +35 PLA + STA COST+1 + PLA + STA COST ;restore old value of COST + TXA + BEQ #65 ;I.E. FOUND A GAP + LDYIM CENEXT + LDAIY PREV + TAX + INY + LDAIY PREV + STA PREV+1 + TXA + STA PREV ;PREV := NEXT OF PREV + + LDYIM CEBLKS + LDAIY PREV ;get length + TAX ;count around the loop + +40 SEC + LDA COST + LDYIM CEAGE + SBCIY PREV + STA COST + BCS #43 + DEC COST+1 ;cost -:= cost OF prev*length OF prev +43 DEX + BNE #40 ;count for length of blocks + JMP #20 + +45 JSR TSTCNT + BEQ #50 + +;COST := 0; PREV := CRNT + + LDAIM 0 + STA COST + STA COST+1 + LDA CRNT + STA PREV + LDA CRNT+1 + STA PREV+1 + JMP #55 + +50 LDYIM CEBLKS + LDAIY CRNT ; grab length (one byte only) + TAX +52 CLC ;cost +:=(cost OF crnt)*(length OF crnt) + LDA COST + LDYIM CEAGE + ADCIY CRNT + STA COST + BCC #54 + INC COST+1 +54 DEX + BNE #52 + +55 JSR NXTCRN ;CRNT := NEXT OF CRNT + BEQ #60 + JMP #20 + +;FIRST SEE IF WE FOUND AN AREA OF MEMORY TO USE + +60 LDA BSTSTA + ORA BSTSTA+1 + BNE #65 + LDAIM STERRL ;STORE DEADLOCK !!!! + RTS ;**15/6/87** return to client (was JSR INTERR) + +;NOW REMOVE ALL THE OBJECTS IN THE GAP + +65 LDA BSTSTA + STA PREV + LDA BSTSTA+1 + STA PREV+1 ;PREV := BSTSTA + LDYIM CENEXT + LDAIY PREV + STA CRNT + INY + LDAIY PREV + STA CRNT+1 ;CRNT := NEXT OF PREV + +;NOW CREATE THE GAP (IF NECESSARY) + + LDAIM 0 + PHA ;save RC +70 LDA BSTEND ;WE MUST DO THIS TEST FIRST + CMP CRNT + BNE #80 + LDA BSTEND+1 + CMP CRNT+1 + BNE #80 + + JSR NEWDES ;GET FREE DESCR,CHAIN IT IN,CALC STORE ADDR + PLA ;RC here + RTS + +80 JSR ENSURE + BEQ #85 + + CMPIM &C9 ;look for protected disc + BEQ #90 ;skip as object is now removed anyway + + JSR INTERR +85 JSR REMVIT + JMP #70 + +90 TAX + PLA ; change old RC + BNE #95 + TXA +95 PHA ;change return code + JMP #85 + + +NEWDES ROUT + JSR FRDESC ;CRNT := NEW DESCRIPTOR + +;storeaddrOFcrnt:=storeaddrOFprev+lengthOFprev+1 + + JSR LNTPRE + SEC ;BECAUSE WE WANT TO ADD 1 + LDYIM CESTA + LDAIY PREV + ADC BREGA + STAIY CRNT + INY + LDAIY PREV + ADC BREGA+1 + STAIY CRNT + +;NOW CHAIN IT IN + + LDYIM CENEXT + LDAIY PREV + STAIY CRNT + INY + LDAIY PREV + STAIY CRNT ;NEXT OF CRNT := NEXT OF PREV + DEY ;Y:=CENEXT + LDA CRNT + STAIY PREV + INY + LDA CRNT+1 + STAIY PREV ;NEXT OF PREV := CRNT + RTS + + +LNTPRE LDYIM CEBLKS ;BREGA := LENGTH OF PREV (IN BYTES) + LDAIY PREV + STA BREGA + INY + LDAIY PREV + STA BREGA+1 + JMP MULTBS + + +;TSTGAP: A:= IF amount needed <= storeaddrOFcrnt- +;storeaddrOFprev-lengthOFprev-2 +;THEN 0 +;ELSE FF +;FI + +TSTGAP ROUT + JSR LNTPRE ;BREGA := LENGTH OF PREV(IN BYTES) + CLC + LDYIM CESTA + LDAIY CRNT + SBCIY PREV + STA STRTMP + INY + LDAIY CRNT + SBCIY PREV + STA STRTMP+1 ;STRTMP:=straddrOFcrnt-straddrOFprev-1 + SEC + LDA BREGA + ADC AMTNED + STA BREGA + LDA BREGA+1 + ADC AMTNED+1 + STA BREGA+1 ;BREGA:=amountneeded+lengthOFprev+1 + BVC #10 + LDAIM STERRM ;OVERFLOW!!! + JSR INTERR +10 SEC + LDA STRTMP + SBC BREGA + LDA STRTMP+1 + SBC BREGA+1 + BMI #20 + LDAIM 0 ;I.E. GAP BIG ENOUGH + RTS + +20 LDAIM &FF ;I.E GAP TOO SMALL + RTS + + +NXTCRN LDYIM CENEXT ;CRNT := NEXT OF CRNT + LDAIY CRNT + TAX + INY + LDAIY CRNT + STA CRNT+1 + TXA + STA CRNT + ORA CRNT+1 ;A:= CRNT ! CRNT +01 + RTS + + LNK UADE0C diff --git a/Level3/SRC/L3/Uade0C b/Level3/SRC/L3/Uade0C new file mode 100644 index 0000000..5d03cde --- /dev/null +++ b/Level3/SRC/L3/Uade0C @@ -0,0 +1,1047 @@ + OPT UADE0C ;FILE > Uade0C + TTL File server file UADE0C + +;********************************** +;* D I R M A N * +;********************************** + +;DIRMAN: THE DIRECTORY MANAGER. +;1) PRESERVE SIN OF AN OBJECT IN A DIR +;2) RETRVE SIN OF AN OBJ WITH GIVEN FILE TITLE +;3) DELETE - REMOVE A DIR ENTRY +;4) SETATTRIBS +;5) CREATE DIR +;6) CHANGE OBJECT SIZE +;7) EXAMINE +;8) FORMATTED DETAILS OF DIR ENTRY +;9) MAKE DIRECTORY removed ** 3/10/84 ** +;10) GIVE DISC NAME FROM FILE TITLE +;11) Remove a directory ** 24/9/84 ** +;12) Preserve object (without DELCHK) ** 25/9/84 ** +;13) Check if object will preserve **23/3/88** + +DIRMAN LDXIM 13 + LDAIM MODDIR + JSR ENTRY + LDAAX DRRTNS + STA DRJUMP+1 + LDAAX DRRTNS+1 + STA DRJUMP+2 + LDAIM &19 + JSR SETFS +DRJUMP JMP DRJUMP +DRRTNS + & DRPRES ;1 => PRESERVE OBJECT + & DRRETR ;2 => RETRIEVE OBJECT + & DRDELT ;3 => DELETE OBJECT + & DRSACC ;4 => SET ATTRIBUTES + & DRCRDR ;5 => CREATE DIRECTORY + & DRCHSZ ;6 => CHANGE SIZE OF OBJECT + & DREXAM ;7 => GIVE DETAILS FOR EXAMINE + & DRINFO ;8 => DETAILS OF OBJECT(CHAR STRING FORMAT) + & DRMAKE ;9 => MAKE A DIR (DON'T PRESERVE) + & DRFTDN ;10 => FILE TITLE -> DISC NO. + & DRDELT ;11 => Remove a directory + & DRPRES ;12 => Preserve object without delchk + & DRPRES ;13 => Check if object will preserve +DREXIT JMP PREXIT ;**25/12/86** + +;*********** DRPRES *********** + +;DRPRES: PRESERVE THE SIN OF AN OBJECT WITH A GIVEN TITLE + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE +;ARGF-I LOAD ADDR +;ARGJ-M EXEC ADDR +;ARGN = TYPE AND ACCESS (TLWR/WR) +;ARGO-P DATE CREATED +;ARGQ-S SIN +;ARGT = WILD CARD FLAG + +;EXIT : +;ARGA = RC +;ARGB-C DISC NO +;ARGD-E SIN OF OBJECT TO BE DELETED +;ARGG = Access byte + +;N.B. IF ARGD!ARGE!ARGF = 0 THEN NO DELETE NEEDED + + +DRPRES ROUT + LDYIM ARGT ;get wild card flag + LDAIY ARGPTR + STA DIRWC ;save flag for decoding routines + JSR INITDV ;INIT VARIABLES + BNE #10 + +;CHECK FOR OWNER ACCESS + + JSR TSTOWN + BNE #10 + +;RETRIEVE APPROPRIATE DIR + + JSR RETDIR + BNE #10 + + LDYIM ARGA + LDAIY ARGPTR ;check entry code + EORIM 12 ;dont do DELCHK in retain + JSR RETA12 ;special case +10 PHA ;**25/12/86** + LDA OBJACC + LDYIM ARGG + STAIY ARGPTR + PLA + JMP DREXIT ;**25/12/86** + + +;************ DRRETR ************ + +;DRRETR: RETRIEVE DETAILS OF A SPECIFIED OBJECT + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE +;ARGF-G ADDRESS OF STORE AREA TO CONTAIN DETAILS +;ARGH = Wild card flag + +;EXIT: ARGA = RC +;ARGB = TYPE OF OBJECT & MAX ACCESS ALLOWED TO IT +; Also contains "lock" bit and OWNER/PUBLIC bit + +;DETAILS INCLUDE:- +;FILE TITLE (10 BYTES) +;LOAD ADDR (4BYTES), +;EXEC ADDR (4BYTES), +;ACC INFO (1 BYTE), +;CREATION DATE (2 BYTE), +;SIN (3BYTES), +;DISC NO (2BYTES), Set after any non-syntax error ** 14/10/86 ** +;SIZE (3BYTES). + + +DRRETR ROUT + JSR DRRET2 ;**4/4/88** call as subroutine + JMP DREXIT + +DRRET2 LDYIM ARGH + LDAIY ARGPTR + ORAIM &02 ;**2/6/87** "^" allowed at end + STA DIRWC ;get wild card flag + JSR INITDV + BEQ #00 + JMP #60 + +00 JSR SETINF ;**08/02/87** + + LDYIM INFDIS ;in case fail later still make some details + LDA DRDISC ;point to disc number (if any) as this is + STAIY INFPTR ;needed by RENAME + INY + LDA DRDISC+1 + STAIY INFPTR ;end ** 14/10/86 ** + +;RETRIEVE RELEVENT DIR + + JSR TSTROT ;TEST FOR <root><terminator> + BNE #20 + +;SUPPLY DETAILS OF ROOT DIR + + LDAIM ROOT ;**4/4/88** Set up name + JSR OUTCH + LDXIM 9 + JSR OUTSPS + JSR SETINF ;Reset INFPTR + +05 LDYIM INFLOA + LDXIM 8 + LDAIM 0 +10 STAIY INFPTR ;LOAD ADDRESS:=EXEC ADDR:=0 + INY + DEX + BNE #10 + + LDA DIRACC + LDYIM ARGB + STAIY ARGPTR ;ACCESS TO ROOT DIR + LDYIM INFACC + LDAIM TYPDIR+LOCKED + STAIY INFPTR + INY + LDA TDATE ;(DATE OF CREATION ROOT) + STAIY INFPTR + INY + LDA TDATE+1 + STAIY INFPTR + LDA DIRSIN + INY + STAIY INFPTR + LDA DIRSIN+1 + INY + STAIY INFPTR + LDA DIRSIN+2 + INY + STAIY INFPTR + JSR DIROBJ ;**08/02/87** Copy DIRSIN to OBJSIN + JSR RETDSZ ;PLACE DISC NO & SIZE IN INFPTR + JMP #50 + +20 JSR TSTPAR ;**23/1/87** check if ^ for parent + BNE #25 +; JSR RETPAR ;**23/1/87** retrieve parent directory +; BNE #40 +; JSR UNLOCK +21 CLC ;**20/5/87** copy name of parent directory + LDA DIRSTA + ADCIM DRNAME + STA MOVFRM + LDA DIRSTA+1 + ADCIM 0 + STA MOVFRM+1 + LDYIM NAMLNT-1 +22 LDAIY MOVFRM + STAIY INFPTR + DEY + BPL #22 + BMI #05 ;**23/1/87** complete info entry a la root + + [ Pseudods = Yes +25 LDYIM 1 ;**20/5/87** check lone pseudo-directory + LDAIY NAMPTR + CMPIM TERMIN + BNE #27 + DEY + LDAIY NAMPTR + JSR Testpd + BNE #27 + JSR LOADDR ;**20/5/87** load directory + BNE #60 + | +25 BNE #27 + ] +26 JSR UNLOCK + JMP #21 ;**20/5/87** go update details + +27 LDYIM ARGH ;get flag + LDAIY ARGPTR + RORA + BCC #30 + JSR RETEND ;get directory + JMP #40 +30 JSR RETENT +40 BNE #60 + JSR Tsparn ;**2/6/87** parent at end? + BEQ #26 ;**2/6/87** yes, extract details now + +;COPY DETAILS INTO STORE AREA POINTED TO BY INFPTR + + JSR DETALS + PHA ;Push return code + +;NOW CALCULATE CALLER'S ACCESS TO THE OBJECT + + JSR MAXACC + + LDYIM ARGB + STAIY ARGPTR ;TYPE & MAX ACCESS ALLOWED TO OBJECT + JSR UNLOCK ;STRMAN.UNLOCK (DIR) + PLA ;Pull DETALS return code + BNE #60 ;Error + +50 LDAIM 0 ;RC:=0 +60 RTS ;**4/4/88** + +;MAKE INFPTR POINT TO DETAILS AREA + +SETINF ROUT + LDYIM ARGF + LDAIY ARGPTR + STA INFPTR + INY + LDAIY ARGPTR + STA INFPTR+1 + INY + RTS + + + +;************ DRDELT ************ + + +;DRDELT: DELETE + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE + +;EXIT : +;ARGA = RC +;ARGB-C DISC NO +;ARGD-F SIN OF OBJECT TO BE DELETED + + +DRDELT ROUT + LDYIM ARGG + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV ;INIT VARIABLES + BNE #20 + +;CHECK FOR OWNER ACCESS + + JSR TSTOWN + BNE #20 + +;RETRIEVE APPROPRIATE DIR ENTRY + + JSR RETENT ;RETRIEVE REQ'D ENTRY + BNE #20 + +;FIRST CHECK THAT ENTRY MAY BE DELETED + + LDYIM ARGA ;check entry code + LDAIY ARGPTR ;** 24/9/84 ** + CMPIM 11 + BEQ #10 ;skip delete check if 'remove' called + + JSR DELCHK + BEQ #10 + JSR UNLOCK + BNE #20 + +;NOW REMEMBER DISC NO & SIN OF OBJECT TO BE DELETED + +10 JSR CRNSIN ;OBJSIN := SIN OF CRNTEN + JSR ARGDSN ;PLACE DISC NO & SIN ON ARGPTR STACK + +;NOW UNCHAIN CURRENT DIR ENTRY & PLACE +;IT ON THE FREE CHAIN + + LDYIM DRLINK + LDAIY CRNTEN + STAIY PREVEN + INY + LDAIY CRNTEN + STAIY PREVEN ;[PREVEN] := [CRNTEN] + + JSR FREECH ;PLACE CRNTEN ENTRY ON FREE CHAIN + +;NOW DECREMENT COUNT OF NUMBER OF DIR ENTRIES + + JSR SETGEN ;GENPTR := [DIRSTA] + SEC + LDYIM DRENTS + LDAIY GENPTR + SBCIM 1 + STAIY GENPTR + INY + LDAIY GENPTR + SBCIM 0 + STAIY GENPTR ;[DIRSTA + DRENTS] -:= 1 + +;ENSURE UPTO DATE ON DISC + + JSR ENSRIT + +20 JMP DREXIT ;**25/12/86** + + +;************ DRSACC ************ + + +;DRSACC: SET ATTRIBUTES + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE +;ARGG = FN +; FN = 1 => SET LOAD/EXEC & ACCESS +; FN = 2 => SET LOAD ADDR +; FN = 3 => SET EXEC ADDR +; FN = 4 => SET ACCESS BYTE +; FN = 5 => SET DATE +;ARGH +n (depending on ARGF) = ATTRIBUTES TO SET + +;EXIT : ARGA = RC + + +;FORMAT OF ACCESS BYTE:- + +;BIT0->PUBLIC HAS READ ACCESS +;BIT1->PUBLIC HAS WRITE ACCESS +;BIT2->OWNER HAS READ ACCESS +;BIT3->OWNER HAS WRITE ACCESS +;BIT4->ENTRY IS LOCKED + +DRSAT1 = DRLOAD ;Offsets in directory entry + = DRLOAD + = DREXEC + = DRACCS + = DRDATE + +DRSAT2 = 9 ;Length of data + = 4 + = 4 + = 1 + = 2 + +DRSACC ROUT + LDAIM 0 + STA DMTEMP+2 ;save space for Access arg + LDYIM ARGF + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV ;INITIALISE VARIABLES + BNE #50 + + LDYIM ARGG ;CHECK IF JUST DATE UPDATE + LDAIY ARGPTR + CMPIM 5 + BEQ #10 ;NO NEED FOR OWNER ACCESS + +;CHECK FOR OWNER ACCESS + + JSR TSTOWN + BNE #50 + +;RETRIEVE APPROPRIATE DIR ENTRY + +10 JSR RETENT + BNE #50 + +20 LDYIM ARGG + LDAIY ARGPTR + STA DMTEMP+1 ;Store for later + LDYIM ARGH ;Position of access if A=4 + CMPIM 4 ;If SETACCESS, must mask off access bits + BEQ #25 ;Is SETACCESS -> check access byte + CMPIM 5 ;** 31/1/85 ** + BEQ #55 + CMPIM 1 + BNE #40 ;Is "all attribs" so check access + LDYIM ARGP ;Position of access if A = 1 + +25 STY DMTEMP ;Store offset of access + LDAIY ARGPTR ;Read access byte + ANDIM ACCMSK ;Mask off access bits + ORA DMTEMP+2 + STA DMTEMP+2 + STAIY ARGPTR + TAX ;Store for later + +;** 15/11/84 ** w/ access illegal + ANDIM &0C ;owner bits set + BEQ #35 + ANDIM &04 ;at least r bit set + BNE #35 + LDAIM SAERRA ;'bad attribute' error + BNE #45 + +35 JSR ISDIR + BNE #55 ;Is not a directory, so continue + TXA + ANDIM ACCMSK-RWMSK ;just the lock bit + ORAIM TYPDIR ;Or in directory info. if a dir. + LDY DMTEMP + STAIY ARGPTR ;Stuff access argument + LDA DMTEMP+1 ;Load function no. + CMPIM 1 + BNE #55 ;Check not setting load/exec. of a dir. + +40 JSR ISDIR ;Check if is directory + BNE #55 ;Cannot set load/exec address of dir., so error + LDAIM DRERRF ;Bad arg. + +45 JSR UNLOCK ;Otherwise, error +50 JMP #65 ;Error exit + +55 LDYIM ARGG ;Here, all checks made, so set attribs + LDAIY ARGPTR + TAY + LDAIM ARGH ;Set args for block move from stack + STA OFF1 ;to some offset in CRNTEN + LDAAY DRSAT1-1 ;Get offset in dir. entry + STA OFF2 ;"Move to" offset + LDAAY DRSAT2-1 ;Length to move + LDXIM ARGPTR ;"Move from" ptr. + LDYIM CRNTEN ;"Move to" ptr. + JSR MOVBLK ;Move args to stack + + LDYIM ARGG + LDAIY ARGPTR + CMPIM 5 ;DON'T SET ALL DATES + BEQ #60 + + JSR FNDTEZ ;try for any more entries + BNE #60 + JMP #20 + +60 JSR ENSRIT ;Ensure directory and exit + +65 JMP DREXIT ;**25/12/86** + + + +;************ DRCRDR ************ + + +;DRCRDR: CREATE & PRESERVE A NEW DIRECTORY + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE +;ARGF = Size of directory ** 15/9/83 ** +;ARGG = Wild card flag + +;EXIT : +;ARGA = RC +;ARGB-C DISC NO +;ARGD-F SIN OF OBJECT TO BE DELETED + +DRCRDR ROUT + LDYIM ARGG + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV + BNE #40 + +;CHECK FOR OWNER ACCESS + + JSR TSTOWN + BNE #40 + +;Load parent directory and save SIN **23/1/87** + + JSR RETDIR + BNE #40 + LDA DIRSIN + STA EXRTN + LDA DIRSIN+1 + STA EXRTN+1 + LDA DIRSIN+2 + STA EXRTN+2 + JSR UNLOCK ;release parent pro tem + JSR TSTPAR ;prohibit new name of "^" + BEQ #50 + [ Pseudods = Yes + LDYIM 0 ;**20/5/87** prohibit new names of "&", "%", "@" + LDAIY NAMPTR + JSR Testpd + BNE #15 + JSR TSTTER + BEQ #50 + ] +15 LDYIM ARGG + LDAIY ARGPTR + STA DIRWC ;**24/7/87** get wild card flag again + JSR INITDV ;reinitialise variables + BNE #40 + +;CREATE A VIRGIN DIRECTORY + + LDYIM ARGF + LDAIY ARGPTR + STA DIRTMP+1 ;DIRTMP := SIZE OF DIRECTORY REQD. + LDAIM 0 + STA DIRTMP + STA DIRTMP+2 + JSR MAKDIR ;SETUP ARGPTR ARGUMENTS FOR DIRMAN.PRESERVE + BNE #40 + +;NOW UNLOCK THE CREATED DIR - THE RETAIN RTN +;ENSURES THAT ITS UPTO DATE ON DISC + + JSR UNLOCK + +;NOW HAVE IT RETAINED + + JSR INITDV ;REINITIALISE VARIABLES + BEQ #30 + +;OBJSIN:=SIN OF NEW DIR(RETAIN DESTROYS OBJSIN) +20 JSR DELOBJ ;**** 17/3/83 **** + JMP #40 + +;LOAD APPROPRATE DIR + +30 JSR RETDIR + BNE #20 + +;NOW HAVE IT RETAINED IN THIS DIR + + JSR RETAIN + BNE #20 +40 JMP DREXIT + +50 LDAIM DRERRA ;Can't use name "^" + BNE #40 + + + +;************ DRCHSZ ************ + +;DRCHSZ: CHANGE SIZE OF A FILE + +;ENTRY: ARGB = LS +;ARGC = MS(PTR TO USERINFO) +;ARGD = LS +;ARGE = MS(PTR TO FILE TITLE) +;ARGF = LS +;ARGG = CS +;ARGH = MS(NEW SIZE) + +;EXIT : ARGA = RC + +;FUNCTION:- +;REMOVE ALL OF THE OBJECT FROM THE CACHE; +;IF TYPE OF OBJECT = FILE +;THEN CHECK FOR WRITE ACCESS; +;CHECK THAT FILE IS NOT OPEN; +;CHANGE SIZE; +;ENSURE OBJECT MAP UPTO DATE ON DISC +;ELIF TYPE OF OBJECT = DIR +;THEN RC:=WRONG TYPE #AUTOMATICALLY DONE IN RETAIN# +;FI + +DRCHSZ ROUT + [ 1=1 + LDAIM IERRAC ;Not used in FileStore ** 29/09/86 ** + JMP INTERR + | + LDYIM ARGI + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV + BNE #40 + +;RETRIEVE DIR ENTRY + + JSR RETENT + BNE #40 + + JSR CRNSIN ;OBJSIN := SIN OF CURRENT DIR ENTRY + JSR MAXACC ;OBJACC := TYPE & ACCESS HELD FOR OBJECT + JSR UNLOCK ;UNLOCK DIR + JSR REMOVE ;REMOVE OBJSIN FROM THE CACHE + BNE #40 ;error trap **** 17/3/83 **** + LDA OBJACC + ANDIM TYPE + CMPIM TYPDIR + BNE #10 + LDAIM DRERRF ;WRONG TYPE + BNE #40 + +;DEAL WITH A FILE + +10 LDA OBJACC + ANDIM WRITAC + BNE #20 + LDAIM DRERRL ;NO WRITE ACCESS ! + BNE #40 + +;CHECK THAT THE FILE IS NOT OPEN + +20 LDAIM 2 ;RNDMAN.INFO + JSR SETDSA ;PLACE ARG, OBJECT DISC NO & SIN ONTO NEWARG STACK + JSR RNDMAN + BNE #30 + LDAIM DRERRI + BNE #40 + +;NOW CALL MAPMAN TO HAVE THE SIZE CHANGED + +30 LDAIM 3 + JSR SETDSA + LDYIM ARGF + LDAIY ARGPTR + LDYIM ARGB + STAIY NEWARG ;LS(NEW SIZE) + LDYIM ARGG + LDAIY ARGPTR + LDYIM ARGC + STAIY NEWARG ;CS(NEW SIZE) + LDYIM ARGH + LDAIY ARGPTR + LDYIM ARGD + STAIY NEWARG ;MS(NEW SIZE) + + JSR JUSINF ;** 3/10/84 pass userinfo ptr + + JSR MAPMAN + BNE #40 + JSR ENSOMP ;ENSURE OBJECT MAP + +40 JMP DREXIT + ] + +;******** EXAMINE ROUTINE ******** + +;DREXAM : GIVE DETAILS OF ENTRY(S) IN A DIR. +;ENTRY: +;ARGB/C PTR TO USER INFO +;ARGD/E PTR TO FILE TITL +;ARGF/G ADDRESS OF STORE FOR RESULT +;ARGH = TYPE OF RESULT REQURIED +;0 => ALL INFO, M/C READABLE +;1 => ALL INFO, CHAR STRING +;2 => FILE TITLE + FILE NAME LENGTH, M/C +;3 => ACCESS+FILE TITLE, CHAR STRING +;4 => GIVE LAST COMPONENT F.T. ONLY +;ARGI = ENTRY POINT TO DIR. +;ARGJ = NO. OF ENTRIES (0=> ALL DIR.) +;ARGK = wild card flag + +;EXIT : +;ARGB/C PTR TO BYTE AFTER RESULT END +;ARGD = NO. OF ENTRIES +;ARGE = SEQ. NO. OF DIRECTORY BEING EXAMINED + +;WHEN ARGH IS 4, ARGD IS MAX. ACCESS TO DIR, +;ARGE IS SEQUENCE NUMBER OF DIR., AND +;ARGF/G ARE DISC. NO LO/HI + +;TABLE OF EXAMINE ROUTINE ENTRY POINTS + +DEXTAB & EXRTNA + & EXRTNB + & EXRTNC + & EXRTND + +DREXAM ROUT + LDAIM 0 + STA DIRFLG + LDYIM ARGK + LDAIY ARGPTR + ORAIM &02 ;**2/6/87** "^" allowed at end of name + STA DIRWC ;get wild card flag + RORA ;look at bit0 + BCC #10 + LDAIM &80 + STA DIRFLG +10 JSR INITDV + BNE #20 + + JSR SETINF ;STORE RESULT PTR. + + LDAIY ARGPTR + CMPIM 5 + BCC #15 ;IF <5, OK + LDAIM DRERRO ;BAD ARG. TO EXAMINE + BNE #20 + +15 STA EXARG ;TYPE OF RESULT + INY + LDAIY ARGPTR + STA EXENTR ;ENTRY TO DIR. + INY + LDAIY ARGPTR + JSR CHKENS + BCC #25 ;OK + LDAIM DRERRN ;TOO MANY ENTRIES REQUESTED +20 JMP #75 + +25 STA EXENTS ;NO. OF ENTRIES + JSR GETDRD ;LOAD APPROPRIATE DIR + BNE #20 + LDAIM 4 + CMP EXARG + BNE #35 + +;IF HERE, COPY FILE NAME FROM DIRECTORY +;INTO RESULT AREA. + + LDYIM DRNAME ;OFFSET IN DIR. + LDXIM 0 +30 LDAIY DPTRLD + STAIX INFPTR + INY + JSR INCIPT + CPYIM DRFREE + BNE #30 + + LDYIM DRSQNO + LDAIY DPTRLD ;Read dir. sequence number + PHA ;Store for later use + + LDA DIRACC + LDYIM ARGD + STAIY ARGPTR + PLA ;Pull sequence number + INY + STAIY ARGPTR + LDA DRDISC + INY + STAIY ARGPTR + INY + LDA DRDISC+1 + STAIY ARGPTR + JMP #70 + +35 JSR INTPRE ;PREVEN := DIRSTA + +;FOR I=0 TO EXENTR DO +;$( SET CURRENT := NEXT(PREV. ENTRY) +;IF END OF DIR...EXIT WITH RC SET +;PREVENTRY := CURRENT ENTRY +;$) + +40 JSR SETCRN + BEQ #60 ;Zero => end of dir => exit + LDA EXENTR + DEC EXENTR + TAX + BEQ #45 ;LOOP FINISHED + JSR MOVCRN ;PREVEN := CRNTEN + JMP #40 + +;SET ROUTINE TO BE USED, DEPENDING +;ON EXARG. +;EXRTN := JMP <examine routine> + +45 LDA EXARG + ASLA + TAX + LDAAX DEXTAB + STA EXRTN+1 + LDAAX DEXTAB+1 + STA EXRTN+2 + LDAIM JMPINS + STA EXRTN + LDAIM 0 ;NO. OF ENTRIES + +;LOOP ROUND EXAMINE ROUTINE, DECREMENTING +;EXENTS, AND CHAINING THROUGH DIR. + +50 PHA ;STORE NO. OF ENTRIES + JSR EXRTN ; call routine + BEQ #55 + TAX + PLA ;Restore stack + TXA + JSR UNLOCK + BNE #75 ;Error -> exit [always jump] + +55 PLA + CLC + ADCIM 1 ;ADD NO. OF ENTS. + PHA + LDA CRNTEN + STA PREVEN + LDA CRNTEN+1 + STA PREVEN+1 + JSR SETCRN ;CURRENT := NEXT(PREV) + BEQ #65 ;NOT OK, FINISH LOOP + PLA + CMP EXENTS + BNE #50 + +;FINALLY, SET END OF BLOCK INDICATOR. +60 PHA +65 LDAIM EXTERM + LDYIM 0 + STAIY INFPTR + JSR INCIPT ;INCREMENT POINTER TO END OF BLOCK (USED IN TXCB). + LDYIM ARGB + LDA INFPTR + STAIY ARGPTR + INY + LDA INFPTR+1 + STAIY ARGPTR + INY + PLA ;GET NO. OF ENTRIES + STAIY ARGPTR + + LDYIM DRSQNO + LDAIY DPTRLD ;Get sequence no. of examined dir. + LDYIM ARGE + STAIY ARGPTR ;And return it + +70 JSR UNLOCK + + LDAIM 0 ;OK EXIT +75 JMP DREXIT + + + +;******** DRINFO ******** + +;DRINFO: RETRIEVE DETAILS OF A GIVEN OBJECT IN +;FORMATTED FORM. + +;ENTRY: +;ARGB-C PTR TO USER INFO +;ARGD-E PTR TO FILE TITLE +;ARGF-G ADDRESS OF RESULT AREA +;ARGH Wild Card Flag + +;EXIT: +;ARGB-C ADDRESS OF BYTE AFTER RESULT AREA + +;BYTE AFTER RESULT AREA IS USED TO +;SET UP BUFFER POINTERS IN TXCB AFTER +;DETAILS CALL. + + +DRINFO ROUT + JSR DRRET2 ;**4/4/88** Retrieve info to output area + BNE #40 + + JSR SETINF ;Set pointer to result area + LDA INFPTR ;Set up to copy details + STA MOVFRM ;(as we will overwrite output area) + LDA INFPTR+1 + STA MOVFRM+1 + SEC + LDAIM :LSB:DETNAM + STA MOVTO + SBCIM :LSB:DRTITL + STA CRNTEN ;Save for use in EXAM routines + LDAIM :MSB:DETNAM + STA MOVTO+1 + SBCIM :MSB:DRTITL + STA CRNTEN+1 + LDXIM INFNXT ;Move all details + JSR MOVE + + JSR MOVEFT ;Copy info as text, name first + JSR OUTSP + JSR OUTLEX + LDAIM 0 + STA FILLFL + LDA DETSZ+2 + JSR OUTBYT + LDA DETSZ+1 + JSR OUTBYT + LDA DETSZ + JSR OUTBYT + LDXIM 3 + JSR OUTSPS + JSR OUTEN2 ;Rest of entry common with EXAM + +;END OF ENTRY. PUT CR AT END TO FORCE +;A NEW LINE IF OSASCII'ING AT THE +;CLIENT END, AND EXTERM CHAR. TO +;INDICATE END OF DATA. + + LDAIM CR + JSR OUTCH + LDAIM EXTERM + JSR OUTCH + + LDYIM ARGB ;PUT INFPTR ON STACK AS RESULT + LDA INFPTR + STAIY ARGPTR + INY + LDA INFPTR+1 + STAIY ARGPTR + + LDAIM 0 + +40 JMP DREXIT + +;Copy DIRSIN to OBJSIN + +DIROBJ ROUT + LDA DIRSIN + STA OBJSIN ;SET SIN FOR SIZE ROUTINE + LDA DIRSIN+1 + STA OBJSIN+1 + LDA DIRSIN+2 + STA OBJSIN+2 + RTS + + + +;************ DRMAKE ************ + + +;DRMAKE: MAKE THE ROOT DIRECTORY-BUT DON'T RETAIN IT. +;USED IN DISC INITIALISATION. + +;ENTRY: ARGB-ARGD = APPROX SIZE OF DIR(IN BYTES) +;N.B. DRDISC MUST = DISC NUMBER + +;EXIT : ARGA = RC +;ARGF-ARGS SAME AS DIRMAN.PRESERVE'S ENTRY ARGS + +DRMAKE ROUT + [ 1=0 + LDAIM 0 + STA DIRWC ;get wild card flag + LDYIM ARGB + LDAIY ARGPTR + STA DIRTMP + INY + LDAIY ARGPTR + STA DIRTMP+1 + INY + LDAIY ARGPTR + STA DIRTMP+2 + LDAIM 0 + STA EXRTN ;**23/1/87** no parent directory + STA EXRTN+1 + STA EXRTN+2 + JSR MAKDIR + +;MOVE "$" INTO THE HEADER + + BNE #40 + LDXIM NAMLNT + LDYIM DRNAME + LDAIM ROOT +10 STAIY DPTRLD + LDAIM SPACE + INY + DEX + BNE #10 + +;NOW ENSURE THE DIR UPTO DATE ON DISC AND ENSURE +;THE DISC MAP + + JSR ENSRIT ;ENSURE & UNLOCK IT + BEQ #30 + +20 JSR DELOBJ ;DELETE IT + JMP #40 + +30 JSR ENSOMP ;OBJSIN MUST = SIN OF DIR + BNE #20 +40 JMP DREXIT + | + LDAIM &FF + JMP DREXIT ;**3/10/84** + ] + +;************* DRFTDN **************** + +;GIVEN FILE TITLE, ANALYSE TO GET DISC NUMBER +;AND RETURN. USED BY SAVE IN C.PROC TO +;RESOLVE ON WHAT DISC TO SAVE A FILE + +;ENTRY: +;ARGB-C PTR TO USER INFO +;ARGD-E PTR TO FILE TITLE + +;EXIT: +;ARGB-C DISC NUMBER + +DRFTDN ROUT + LDYIM ARGF + LDAIY ARGPTR + STA DIRWC ;get wild card flag + JSR INITDV + BNE #10 + LDYIM ARGB + LDA DRDISC + STAIY ARGPTR + INY + LDA DRDISC+1 + STAIY ARGPTR + LDAIM 0 ;=> success +10 JMP DREXIT + + LNK UADE0D diff --git a/Level3/SRC/L3/Uade0D b/Level3/SRC/L3/Uade0D new file mode 100644 index 0000000..ff26ff0 --- /dev/null +++ b/Level3/SRC/L3/Uade0D @@ -0,0 +1,1279 @@ + OPT UADE0D ;FILE > Uade0D + TTL File server file UADE0D + +;******************************** +;* DIRMAN UTILITIES * +;******************************** + +;******** GETDIR ROUTINE ********* + +;GETDIR: LOADS THE DIRECTORY SPECIFIED BY A FILE TITLE. + +;EXIT: A = RC +;DIRSTA = ADDR OF DIR IN MEMORY + +;IF TITLE = <root><terminator> OR +;TITLE = <terminator> +;THEN load 'current dir' #set by INITDV# +;ELSE call RETENT #retrieve entry# +;check that entry is for a directory +;DIRSIN := SIN of current entry +;load new current directory +;FI + +;NOTE that GETDIR in cases where an error occurs +;will UNLOCK anything that it loaded. + + [ 1=0 +GETDIR + LDAIM 0 + STA DIRFLG + ] +GETDRD ROUT + JSR TSTROT ;<root>$<terminator>? + BEQ #50 + JSR TSTERM ;<terminator>$? + BEQ #50 + + INY ;**20/5/87** test pseudo-directory + LDAIY NAMPTR + DEY + CMPIM TERMIN ;**20/5/87** single char only + BNE #20 + LDAIY NAMPTR + JSR Testpd + BEQ #50 + +20 BIT DIRFLG + BMI #30 + JSR RETENT + JMP #40 + +30 JSR RETEND +40 BNE #60 + JSR Tsparn ;See if it is parent + BEQ #45 + JSR TSTDIR ;SEE IF ITS A DIR-TSTDIR WILL UNLOCK IF REQD. + BNE #60 + JSR SETSIN +45 JSR UNLOCK +50 JSR LOADDR ;Unlocked if any error +60 RTS + +;CHKTIT: CHECKS THE SYNTAX OF A FILE TITLE. +;ENTRY: NAMPTR => PTR TO FILE TITLE, +;TO BE RECOGNISED. + +;EXIT : A = RC (0=>SUCCESS) +;LASTNM => ADDRESS OF THE LAST +;TEXT NAME IN THE FILE TITLE. + +;<file title>::=$<title component>|<file name> +;<file name)::= <text name><title component> +;<title component>::=<terminator>|<separator><file name> + +CHKTIT ROUT + LDA DIRWC + ANDIM &C3 + STA DIRWC ;top bits only + LDYIM 0 ;Y:=PTR TO CHAR + STY DIRTMP ;counter for loop here + JSR SETLST ;SETUP LASTNM + LDAIY NAMPTR + CMPIM ROOT + BEQ #00 ;**20/5/87** check pseudo-directories also + JSR Testpd + BNE #20 ;SEE IF ITS A <file name> +00 INY + LDAIY NAMPTR + CMPIM SEPART ;IS IT A <separator> + BEQ #10 + CMPIM TERMIN ;IS IT A <terminator> + BEQ #40 + BNE #55 ;RC:=INVALID SEPARATOR + +;TRY TO RECOGNISE <file name> + +10 INY +20 STY DIRTMP+1 ;save offset + JSR SETLST ;SETUP LASTNM +30 JSR CHKTEX ;RECOGNISE <text name> + BNE #60 + LDAIY NAMPTR + CMPIM TERMIN + BNE #50 + + INC DIRTMP + LDX DIRTMP + CPXIM 2 + BEQ #40 ;match here + + LDA DIRWC ;last level here + ANDIM &3F + BIT DIRWC + BVC #35 + ORAIM &80 +35 STA DIRWC + LDY DIRTMP+1 ;restore Y + JMP #30 ;do loop again + +40 LDAIM 0 ;RC := 0 + RTS + +50 CMPIM SEPART + BEQ #10 +55 LDAIM DRERRA +60 RTS + +;CHKTEX: RTN TO RECOGNISE <text name> + +CHKTEX ROUT + LDXIM NAMLNT ;X:=MAX NO. OF CHARS IN <text name> +10 LDAIY NAMPTR + CMPIM &21 + BCC #40 + CMPIM &7F + BCS #40 ;Nope => error + + BIT DIRWC + BPL #20 + CMPIM "*" + BEQ #30 + CMPIM "#" + BEQ #30 + +20 CMPIM """" ;** 21/9/83 ** + BEQ #40 + CMPIM ":" + BEQ #40 + CMPIM "*" + BEQ #40 + CMPIM "." + BEQ #40 + CMPIM "#" + BEQ #40 ;Nope => error + CMPIM "$" + BEQ #40 ;** 18/9/84 ** + +30 INY + DEX + BNE #10 +40 LDAIM 0 + CPXIM NAMLNT ;TEST LENGTH OF <text name> + BNE #50 + LDAIM DRERRA ;INVALID TEXT NAME +50 TAX ;SET FLAGS + RTS + +SETLST ROUT + TYA ;RTN TO SETUP LASTNM + CLC + ADC NAMPTR + STA LASTNM + LDA NAMPTR+1 + ADCIM 0 + STA LASTNM+1 + RTS + +;FNDTEX: SEARCH CUR DIR FOR NAME IN TXTNAM. +;N.B. DIR ENTRIES ARE SORTED, +;KEY=<file title>. + +;ENTRY: DIRSTA=STORE ADDR OF DIR TO BE SEARCHED. + +;EXIT : A=0 => NAME FOUND +;PREVEN => PTR TO PREVIOUS ENTRY +;CRNTEN => PTR TO CURRENT ENTRY + +FNDTEX ROUT + JSR INTPRE ;PREVEN := addr of 1st entry + LDAIM 0 + STA WILD1 ;flag for wild cards +10 JSR SETCRN + BEQ #30 ;end of dir ? + LDYIM DRTITL + LDXIM 0 + + JSR #50 ;look up name with wild cards + BCS #40 + PHP + LDA WILD1 + BNE #15 + PLP + BMI #30 + PHP +15 PLP +FNDTEZ JSR MOVCRN + JMP #10 ;repeat until end + +30 LDAIM DRERRC + RTS + +40 LDAIM 0 + RTS ;exit ok + +50 LDAAX TXTNAM + CMPIM "*" + BNE #80 + INC WILD1 + INX +60 TXA + PHA + TYA + PHA + JSR #50 + PLA + TAY + PLA + TAX + BCS #95 + INY + CPYIM 12 + BCC #60 + +70 LDAAX TXTNAM + CMPIM &20 + BEQ #95 + CMPIM &0D + BEQ #95 + CPXIM 10 ;returns C=1 at end-of-name + RTS + +80 CPYIM 12 + BCS #70 + JSR CPCHAR + BNE #90 + INX + INY + BNE #50 + +90 CLC +95 RTS + +CPCHAR ROUT + CMPIM "#" + BEQ #10 + JSR CAPS + PHA + LDAIY CRNTEN + JSR CAPS + STA WILD2 + PLA + CMP WILD2 + RTS + +10 INC WILD1 ;set flag + LDAIY CRNTEN ;must NOT match a space + CMPIM SPACE + PHP + PLA + EORIM 2 ;flip Z flag + PHA + PLP ;return Z=1 if not a space + RTS + +CAPS ROUT + STA WILD2 + CMPIM "A" + BCC #10 + CMPIM "z"+1 + BCS #10 + CMPIM "Z"+1 + BCC #30 + CMPIM "a" + BCS #20 +10 SEC + BCS #30 + +20 CLC +30 LDAIM &F9 + RORA + RORA + RORA + AND WILD2 + RTS + +INTPRE LDA DIRSTA ;PREVEN := DIRSTA + STA PREVEN + LDA DIRSTA+1 + STA PREVEN+1 + RTS + +MOVCRN LDA CRNTEN ;PREVEN := CRNTEN + STA PREVEN + LDA CRNTEN+1 + STA PREVEN+1 + RTS + +SETCRN CLC ;RTN TO SETUP CRNTEN (CURRENT ENTRY) PTR + LDYIM DRLINK + LDAIY PREVEN + ADC DIRSTA + STA CRNTEN + INY + LDAIY PREVEN + ADC DIRSTA+1 + STA CRNTEN+1 + LDYIM 0 + LDAIY PREVEN + INY + ORAIY PREVEN ;IF [PREVEN] = 0 THEN A:=0 + RTS + +;INITDV: INITIALISES SEVERAL DIRMAN VARIABLES. + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO FILE TITLE + +;FUNCTION:- + +;DRUSIN => PTR TO USERINFO +;MCNUMB => MACHINE NO OF CALLER +;NAMPTR => PTR TO FILE TITLE +;DRDISC => SELECTED DISC NUMBER +;DIRACC => IF CHAR[0] OF FILE TITLE = ROOT +; THEN IF SYST PRIVILEGED +; THEN OWNER ACCESS +; ELSE ANYBODY ACCESS +; FI +; ELIF CHAR[0] OF FILE TITLE = "^" +; THEN ACCESS OF PARENT DIRECTORY +; ELIF CHAR[0] OF FILE TITLE = "&" +; THEN OWNDER ACCESS +; ELIF CHAR[0] OF FILE TITLE = "%" +; THEN CURRENT ACCESS TO LIBRARY DIRECTORY +; ELSE ACCESS TO CURRENTLY SELECTED DIR +; FI ! TYPDIR + +;DIRSIN => IF DISC NAME PRESENT +; THEN SIN OF ROOT DIRECTORY ON NAMED DISC +; ELIF CHAR[0] OF FILE TITLE = ROOT +; THEN SIN OF ROOT DIRECTORY +; ELIF CHAR[0] OF FILE TITLE = "^" +; THEN SIN OF PARENT DIRECTORY +; ELIF CHAR[0] OF FILE TITLE = "&" +; THEN SIN OF UFD +; ELIF CHAR[0] OF FILE TITLE = "%" +; THEN SIN OF LIBRARY +; ELSE SIN OF CURRENTLY SELECTED DIR +; FI +;TDATE => IF ROOT DIR IMPLIED +; THEN DATE ROOT DIR CREATED (SEE MAPTB) +; FI +;DIRSTT := 0 START BLK NO + +;EXIT: A = RC + +INITDV ROUT + LDYIM ARGB + LDAIY ARGPTR + STA DRUSIN + INY + LDAIY ARGPTR + STA DRUSIN+1 ;DRUSIN:=PTR TO USER INFO + + INY + LDAIY ARGPTR + STA NAMPTR + INY + LDAIY ARGPTR + STA NAMPTR+1 ;NAMPTR := PTR TO FILE TITLE + + LDYIM UTMCNO + LDAIY DRUSIN + STA MCNUMB + INY + LDAIY DRUSIN + STA MCNUMB+1 + INY + LDAIY DRUSIN ;**25/12/86** + STA MCNUMB+2 ;MCNUMB := MACHINE NO OF CALLER + +;PRECEEDED BY A DISC NAME? + + LDYIM 0 + LDAIY NAMPTR + CMPIM DISCIN ;DISC NAME PRESENT?? + BEQ #00 + JMP #60 + +00 LDXIM DNAMLN ;X:=MAX LENGTH OF DISC NAME + LDAIM :LSB:DRDSNM + STA MOVTO + LDAIM :MSB:DRDSNM + STA MOVTO+1 ;MOVTO:=PTR TO DRDSNM BUFFER + + INC NAMPTR + BNE #05 + INC NAMPTR+1 ;NAMPTR+:=1 + +05 LDAIY NAMPTR +10 STAIY MOVTO ;COPY DISC NAME INTO DRDSNM + CMPIM TERMIN ;TERMINATOR? + BEQ #40 + CMPIM SEPART ;SEPARATOR? + BNE #20 + LDAIM TERMIN + STAIY MOVTO ;TERMINATE DISC NAME + INY + LDAIY NAMPTR ;**20/5/87** disc name, must prohibit "^","&", "%" + CMPIM "^" ;**20/5/87** as these have a disc name implied + [ Pseudods = Yes + BEQ #15 + CMPIM "&" + BEQ #15 + CMPIM "%" + ] + BNE #40 +15 INY + LDAIY NAMPTR ;**20/5/87** check single char names only + DEY + CMPIM TERMIN + BEQ #22 + CMPIM SEPART + BEQ #22 + BNE #40 + +20 INY + LDAIY NAMPTR + DEX + BNE #10 + LDAIM TERMIN + STAIY MOVTO ;TERMINATE DISC NAME + LDAIY NAMPTR + CMPIM TERMIN + BEQ #40 + CMPIM SEPART + BEQ #30 +22 LDAIM DRERRA ;BAD FILE TITLE +25 RTS + +30 INY +40 CLC + TYA + ADC NAMPTR + STA NAMPTR + BCC #50 + INC NAMPTR+1 ;NAMPTR:=PTR TO FILE TITLE + +;GET DISC NUMBER OF NAMED DISC + +50 LDAIM &A + JSR SETRTN + INY + LDAIM :LSB:DRDSNM + STAIY NEWARG + INY + LDAIM :MSB:DRDSNM + STAIY NEWARG ;PTR TO DISC NAME + JSR MAPMAN ;MAPMAN.DISCNAME->DISCNUMB + BNE #25 + LDYIM ARGB + LDAIY NEWARG + STA DRDISC + INY + LDAIY NEWARG + STA DRDISC+1 + JMP #65 + +;WAS ROOT DIR SPECIFIED + +60 JSR TSROOT ;IS ROOT DIR SPECIFIED? + BNE #75 + LDYIM UTDISC + LDAIY DRUSIN + STA DRDISC + INY + LDAIY DRUSIN + STA DRDISC+1 ;DRDISC:=SELECTED DISC NUMBER +65 LDAIM ANYBDY+TYPDIR + STA DIRACC ;DIRACC:=ANYBDY!TYPDIR + LDYIM UTPRIV + LDAIY DRUSIN + ANDIM SYSTPV + BEQ #70 + LDAIM OWNER+TYPDIR + STA DIRACC ;DIRACC:=OWNER!TYPDIR + +;GET SIN OF ROOT ON SELECTED DISC + +70 LDAIM 4 ;(SIN OF ROOT) + JSR SETDSA ;PLACE DISC NO ON NEWARG STACK + JSR MAPMAN ;CALL MAPMAN.SINOFROOT + BNE #84 + LDYIM ARGB + LDAIY NEWARG + STA DIRSIN + INY + LDAIY NEWARG + STA DIRSIN+1 + INY + LDAIY NEWARG + STA DIRSIN+2 ;DIRSIN:=SIN OF ROOT + INY + LDAIY NEWARG + STA TDATE ;TDATE:=DATE OF ROOT + INY + LDAIY NEWARG + STA TDATE+1 + JMP #82 + +;LOOK UP ACCESS, DISC NUMBER, & SIN OF SELECTED DIR + + [ Pseudods = Yes +72 LDA UMHUFD ;**20/5/87** "&", get ufd + JMP #78 + +74 LDA UMHLIB ;**20/5/87** "%", get lib + JMP #78 + ] + +75 INY ;**20/5/87** check pseudo-directory names + LDAIY NAMPTR ;**20/5/87** single char only + CMPIM SEPART + BEQ #76 + CMPIM TERMIN + BNE #77 +76 DEY + LDAIY NAMPTR + CMPIM "^" ;**20/5/87** parent directory + BEQ #85 + [ Pseudods = Yes + CMPIM "&" ;**20/5/87** ufd + BEQ #72 + CMPIM "%" ;**20/5/87** lib + BEQ #74 + ] +77 LDYIM UTHSLD ;OFFSET OF HANDLE FOR SELECTED DIR + LDAIY DRUSIN ;A:=HANDLE FOR SELECTED DIR +78 JSR FNDHND ;FIND HANDLE IN HANDTB + BNE #84 + + LDYIM HTACC ;check that its a dir + LDAIY HNDPTR + ANDIM TYPDIR + BNE #80 + LDAIM DRERRD ;OBJECT NOT A DIR + RTS + +80 CLC + LDA HNDPTR ;HNDPTR SETUP BY FNDHND + ADCIM HTACC + STA MOVFRM + LDA HNDPTR+1 + ADCIM 0 + STA MOVFRM+1 + LDAIM :LSB:DIRACC + STA MOVTO + LDAIM :MSB:DIRACC + STA MOVTO+1 + LDXIM 6 ;DIRACC,DRDISC,DIRSIN + JSR MOVE ;COPY INFO FROM HANDTB INTO DIRMAN VARIABLES + +82 LDAIM 0 + STA DIRSTT + STA DIRSTT+1 ;DIRSTT:=0 +84 RTS + +85 JSR #77 ;**20/5/87** initialise to current directory + LDYIM HTDISC ;**1/6/88** "^" for parent directory + LDAIY HNDPTR ;**1/6/88** get current disc + STA DRDISC + INY + LDAIY HNDPTR + STA DRDISC+1 + JSR RETPAR ;**20/5/87** retrieve parent + BNE #84 + JSR UNLOCK + BEQ #82 + +LDDR ROUT + LDAIM 5 + JSR SETRTN + JSR SETDIR + JSR MAPMAN ;MAPMAN.SIZEINFO + BNE #10 + LDYIM ARGB + LDAIY NEWARG + STA DIRSZE + INY + LDAIY NEWARG + STA DIRSZE+1 ;DIRSZE:=SIZE OF DIR IN BYTE + INY + LDAIY NEWARG + STA DIRSZE+2 + INY + LDAIY NEWARG + STA DIRBKS + INY + LDAIY NEWARG + STA DIRBKS+1 ;DIRBKS:=NO OF BLOCKS USED BY DIR + LDAIM 0 + STA DIRSTT + STA DIRSTT+1 ;DIRSTT:=0(START ADDR IN DIR) + JSR SETDIR + LDAIM 1 + JSR SETRTN ;STRMAN.DISC ADDR TO STORE ADDR + JSR STRMAN + BNE #10 + LDYIM ARGB + LDAIY NEWARG + STA DIRSTA + STA DPTRLD + INY + LDAIY NEWARG + STA DIRSTA+1 + STA DPTRLD+1 ;DPTRLD:=PTR TO 1ST BYTE OF DIR + LDAIM 0 ;RC:=0 +10 RTS + +; Load directory. It will be locked if return code is zero, unlocked if not. + +LOADDR ROUT + JSR LDDR ;TRY AND LOAD THE DIR + BNE #20 + +;SEE IF LEADING AND TRAILING SEQUENCE NUMBERS MATCH +;IN THE PROCESS SETUP DPTRTR (PTR TO LAST BYTE OF DIR) + + LDYIM DRSQNO + LDAIY DPTRLD + TAX ;X:=LEADING SQ. NO. + SEC + LDA DPTRLD + SBCIM 1 + STA DPTRTR + LDA DPTRLD+1 + SBCIM 0 + STA DPTRTR+1 ;DPTRTR:=DPTRLD-1 + CLC + LDA DPTRTR + ADC DIRSZE + STA DPTRTR + LDA DPTRTR+1 + ADC DIRSZE+1 + STA DPTRTR+1 ;DPTRTR:=PTR TO LAST BYTE OF DIR + TXA + LDYIM 0 + CMPIY DPTRTR ;A:=TRAILING SQ. NO. + BEQ #10 + LDAIM DRERRB ;BROKEN DIR + JMP UNLOCK ;Unlock and return **25/12/86** + +10 LDYIM ARGA + LDAIY NEWARG ;RC +20 RTS + +SETDIR LDAIM :LSB:DRDISC ;MOVE DISC NO->DIRBKS ONTO NEWARG STACK + STA MOVFRM + LDAIM :MSB:DRDISC + STA MOVFRM+1 + CLC + LDA NEWARG + ADCIM ARGB + STA MOVTO + LDA NEWARG+1 + ADCIM 0 + STA MOVTO+1 + LDXIM 9 + JMP MOVE + +STAARG LDA DIRSTA ;MOVE DIRSTA ONTO ARG STACK FOR STRMAN + LDYIM ARGB + STAIY NEWARG + STA GENPTR ;SETUP GENPTR FOR MRKDRT RTN + LDA DIRSTA+1 + INY + STAIY NEWARG + STA GENPTR+1 + RTS + +UNLOCK ROUT + PHA + LDAIM 3 ;CALL STRMAN.UNLOCK + JSR SETRTN + JSR STAARG + JSR STRMAN + BEQ #10 + JSR INTERR +10 PLA + RTS + +ENSRIT LDAIM 2 ;CALL STRMAN.ENSURE FOR DIR + JSR SETRTN + JSR STAARG + JSR MRKDRT + LDYIM ARGD + LDAIM UNLKIT + STAIY NEWARG ;ENSURE AND UNLOCK THE OBJECT + +;NOW INC SEQ. NOS. + + LDYIM DRSQNO + LDAIY DPTRLD + TAX + INX + TXA ;A:=NEW SQ NO + STAIY DPTRLD ;1ST SQ NO + LDYIM 0 + STAIY DPTRTR ;LST SQ NO + + JMP STRMAN + + +;RETDIR: RETRIEVE DIR BEFORE LAST COMPONENT OF FILE TITLE. + +;EXIT: A = RC +;NAMPTR = PTR TO LAST TEXT NAME. +;DIRSTA = ADDR OF DIR IN MEMORY + +;FUNCTION: IF SYNTAX OF FILE TITLE OK +;THEN RETRIEVE PENULTIMATE DIR +;FI + +RETDIR ROUT + JSR CHKTIT ;CHECK SYNTAX OF FILE TITLE + BNE #70 + +;attempts to delete "$" fail in eyecatching manner +;**20/5/87** and "^", "&", "%" and "@" too! + + JSR ISLAST ;**23/1/87** check if name is last + BNE #10 + JSR TSTROT ;look for ROOT here + BEQ #02 + JSR TESTPD ;**20/5/87** check pseudo-directories also + BNE #10 + JSR TSTTER + BNE #10 +02 LDAIM DRERRC ;'not found', well it cant be can it ! +05 RTS ;exit with error + +10 JSR LOADDR ;LOAD CURRENT DIR + BNE #05 ;Fail, return (dir not locked **25/12/86**) + +;IF THE FIRST NAME=ROOT or "^" or "$" or "%" or "@" +;THEN WE HAVE TO ADJUST NAMPTR + + JSR TSROOT ;SEE IF FIRST NAME COMPONENT=ROOT + BEQ #15 + JSR Testpd ;**20/5/87** or pseudo-directory + BNE #20 + INY + LDAIY NAMPTR + CMPIM SEPART ;**20/5/87** must be single char + BNE #20 +15 CLC + LDA NAMPTR + ADCIM 2 + STA NAMPTR + BCC #20 + INC NAMPTR+1 ;NAMPTR+:=2 + +20 JSR ISLAST ;Check if last text name + BEQ #60 + +;COPY NEXT TEXT NAME COMPONENT INTO TXTNAM +;& MOVE NAMPTR TO NEXT COMPONENT + + JSR LOADTX + + JSR Tsparn ;**2/6/87** test for parent "^" + BNE #30 + JSR Unlock + JSR Retpar ;**2/6/87** retrieve parent + BEQ #20 + RTS + +;CHECK DIR EXISTS + +30 JSR FNDTEX ;SEARCH DIR FOR TEXT NAME + BNE #45 + +;FIRST CHECK THAT ITS A DIR + +40 JSR ISDIR + BEQ #50 + JSR FNDTEZ ;try on next match + BEQ #40 +45 JMP UNLOCK ;unlock the entry + +;NOW PREPARE FOR NEXT DIR TO BE LOADED, AND +;UNLOCK THE CURRENT ONE + +50 JSR SETSIN ;DIRSIN := SIN OF NEXT DIR TO BE LOADED +55 JSR UNLOCK ;UNLOCK CURRENT DIR + JSR LOADDR ;**2/6/87** load next directory + BNE #70 + BEQ #20 + +60 LDAIM 0 +70 RTS + +ISDIR LDYIM DRACCS + LDAIY CRNTEN ;check type found + ANDIM TYPDIR + CMPIM TYPDIR + RTS + +ISLAST ROUT ;Test if name is last + LDA NAMPTR + CMP LASTNM + BNE #10 + LDA NAMPTR+1 + CMP LASTNM+1 +10 RTS ;Exit with Z set correctly + +RETENT ROUT + JSR RETDIR ;FIND APPROPRIATE DIR + BNE #10 + JSR LOADTX ;COPY LAST TEXTNAME INTO TXTNAM + LDAIM &02 ;**2/6/87** is "^" allowed? + BIT Dirwc + BEQ #00 + JSR Tsparn ;**2/6/87** test for parent "^" + BNE #00 + JSR Unlock + JMP Retpar + +00 JSR FNDTEX ;SEARCH FOR LAST TEXT NAME + BEQ #10 +05 JSR UNLOCK +10 RTS + +RETEND JSR RETENT ;**20/5/87** + BNE #10 + JSR Tsparn ;**8/8/87** test for parent "^" + BEQ #10 +20 JSR ISDIR + BEQ #10 + JSR FNDTEZ + BEQ #20 + BNE #05 + +Tsparn ROUT ;**1/6/87** + LDA TXTNAM ;**1/6/87** test for parent "^" + CMPIM "^" + BNE #10 + LDA TXTNAM+1 + CMPIM &20 +10 RTS + +; Retrieve parent directory **23/1/87** + +RETPAR ROUT + JSR LOADDR ;**23/1/87** load current directory + BNE #50 + LDYIM DRSTAR+DRLINK ;**23/1/87** special unchained entry? + LDAIM &FF + CMPIY DPTRLD + BNE #60 + INY + CMPIY DPTRLD + BNE #60 + LDYIM DRSTAR+DRSIN ;**23/1/87** extract parent SIN only + LDAIY DPTRLD + STA DIRSIN + INY + LDAIY DPTRLD + STA DIRSIN+1 + INY + LDAIY DPTRLD + STA DIRSIN+2 + JSR UNLOCK ;release current directory + + LDYIM UTPRIV ;now select access + LDAIY DRUSIN + ANDIM SYSTPV ;same as now if system user + BNE #30 + LDAIM 4 ;MAPMAN.SINOFROOT + JSR SETDSA + JSR MAPMAN ;**1/6/88** revised tests + BNE #70 ;fail if can't locate root + LDYIM ARGB ;check if parent is root directory + LDAIY NEWARG + CMP DIRSIN + BNE #30 ; no, will use same access as child + INY + LDAIY NEWARG + CMP DIRSIN+1 + BNE #30 + INY + LDAIY NEWARG + CMP DIRSIN+2 + BNE #30 + LDAIM TYPDIR+ANYBDY ;root, access reverts now to public + STA DIRACC + +30 JSR LOADDR ;load parent directory + BNE #50 + LDAIM 0 +50 RTS + +60 LDAIM DRERRC ;parent not found +70 JMP UNLOCK ;unlock and exit + + +TSTDIR ROUT + JSR ISDIR ;Test CRNTEN for directory + BEQ #10 + JSR UNLOCK ;UNLOCK CURRENT DIR IF ENTRY NOT FOR A DIR + LDAIM DRERRD ;RC := OBJECT NOT A DIR +10 RTS + +SETSIN LDYIM DRSIN ;DIRSIN := SIN OF CRNTEN + LDAIY CRNTEN + STA DIRSIN + INY + LDAIY CRNTEN + STA DIRSIN+1 + INY + LDAIY CRNTEN + STA DIRSIN+2 + RTS + +;MAXACC: CALC ACCESS TO A PARTICULAR DIR ENTRY +;EXIT: A:=OBJACC:= TYPE & MAX ACCESS TO OBJECT + +MAXACC ROUT + LDYIM DRACCS + LDAIY CRNTEN + ANDIM TLAMSK + STA OBJACC ;OBJACC:=TYPE & ACCESS SPECIFIED IN DIR ENTRY + ANDIM TYPDIR + BEQ #10 + +;ITS A DIR SO OBJACC := TYPDIR!DIRACC + + LDA DIRACC + ANDIM OWNER ;** 30/9/84 ** + ORA OBJACC + JMP #30 + +;ITS A FILE SO +;IF (DIRACC & OWNER) = OWNER +;THEN TYPFIL!((OBJACC SHR 2)&RDWRACC)!(OBJACC&RDWRAC) +;ELSE TYPFIL ! (OBJACC & RDWRAC) +;FI + +10 LDA DIRACC + ANDIM OWNER + BEQ #20 ;BRANCH IF ANYBODY + +;OWNER ACCESS + + LDA OBJACC + LSRA + LSRA + ANDIM RDWRAC + TAX ;X:= A & RDWRAC + LDA OBJACC + ANDIM LOCKED ;** 28/3/85 ** + STA OBJACC + TXA + ORA OBJACC + JMP #30 + +;ANYBODY ACCESS + +20 LDA OBJACC + ANDIM RWLACC ;ANYBODY ACCESS +30 STA OBJACC + LDA DIRACC + ANDIM OWNER + ORA OBJACC ;Include owner bit in result + STA OBJACC + RTS + +LOADTX ROUT + LDAIM :LSB:TXTNAM ;MOVE TEXT NAME INTO TXTNAM + STA TXTPTR + LDAIM :MSB:TXTNAM + STA TXTPTR+1 + LDYIM 0 +10 LDAIY NAMPTR + CMPIM TERMIN + BEQ #20 + CMPIM SEPART + BEQ #20 + STAIY TXTPTR ;MOVE CHAR INTO TXTNAM + INY + JMP #10 + +;MAKE NAMPTR PT TO 1ST CHAR AFTER <terminator>|<separator> + +20 TYA + SEC ;ADD 1 + ADC NAMPTR + STA NAMPTR + BCC #30 + INC NAMPTR+1 + +;FILL REMAINDER OF TXTNAM WITH SPACES + +30 CPYIM NAMLNT+1 ;** 5/9/84 ** + BEQ #40 + LDAIM SPACE + STAIY TXTPTR + INY + BNE #30 +40 RTS + +SETFRE ROUT + CLC ;SETUP DIRFRE (ADDR OF FREE CHAINPTR IN DIR) + LDA DIRSTA + ADCIM DRFREE + STA DIRFRE + LDA DIRSTA+1 + ADCIM 0 + STA DIRFRE+1 + LDYIM 0 ;TEST FOR [DIRFRE]=0 + LDAIY DIRFRE + INY + ORAIY DIRFRE ;A=0 IF NO FREE ENTRIES + RTS + +;DELCHK: RTN TO CHECK WHETHER A DIR ENTRY MAY BE DELETED + +;EXIT: A = RC + +;FUNCTION: IF ENTRY 'LOCKED' +;THEN ERROR (I.E. A>0) +;ELIF OBJECT OPEN +;THEN ERROR +;ELIF TYPE = TYPDIR ANDF NOT EMPTY +;THEN ERROR +;ELSE OBJECT MAY BE DELETED (I.E. A = 0) +;FI + +DELCHK ROUT + LDYIM DRACCS + LDAIY CRNTEN + ANDIM LOCKED + BEQ #10 + LDAIM DRERRG + RTS + +;SAVE SIN OF OBJECT TO BE DELETED + +10 JSR CRNSIN ;OBJSIN := SIN OF OBJECT + +;SEE IF THE OBJECT TO BE DELETED IS OPEN + + LDAIM 2 + JSR SETDSA ;SETUP DISC NO AND SIN ON NEWARG STACK + JSR RNDMAN ;RNDMAN.INFO + BNE #20 + LDAIM DRERRI ;CANNOT DELETE OPENED OBJECT + RTS + +;IF IT IS DIR MAKE SURE THAT IT IS EMPTY + +20 LDYIM DRACCS + LDAIY CRNTEN + ANDIM TYPDIR + BEQ #50 ;Exit; A=0 and Z set + +;LOAD FIRST BLOCK OF THE DIR +;TO SEE IF IT IS EMPTY + + LDAIM 1 + JSR SETDSA ;PLACE DISC NO AND SIN ON NEWARG STACK + LDYIM ARGG + LDAIM 0 + STAIY NEWARG ;LS + INY + STAIY NEWARG ;MS(BLK NO) START BLOCK NO := 0 + INY ;Y:=ARGI + LDAIM 1 + STAIY NEWARG + INY + LDAIM 0 + STAIY NEWARG ;NO OF BLOCKS TO BE LOADED := 1 + JSR STRMAN + BNE #50 + LDYIM ARGB + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 ;GENPTR:=STORE ADDRESS OF LOADED DIR + LDYIM DRFRST ;PTR TO FIRST DIR ENTRY IN USE + LDAIY GENPTR + INY + ORAIY GENPTR + PHA ;PUSH A + LDAIM 4 + JSR SETRTN + JSR STRMAN ;STRMAN.FLUSH WINDOW + BEQ #40 + TAX + PLA + TXA + RTS + +40 PLA + BEQ #50 + LDAIM DRERRJ +50 RTS + +FREECH ROUT + JSR SETFRE + LDYIM 0 ;RTN TO PLACE ENTRY ON FREE CHAIN + LDAIY DIRFRE + STAIY CRNTEN + INY + LDAIY DIRFRE + STAIY CRNTEN ;[CRNTEN] := [FREE ENTRY PTR] + + SEC ;CALC RELATIVE ADDRESS OF CRNTEN + LDA CRNTEN + SBC DIRSTA + LDYIM 0 + STAIY DIRFRE + LDA CRNTEN+1 + SBC DIRSTA+1 + INY + STAIY DIRFRE ;[DIRFRE] := DIR ENTRY + RTS + +; SETDSA: Put arg, DRDISC & OBJSIN on NEWARG stack +; SETDSN: Put just DRDISC & OBJSIN on NEWARG stack +; Exits: Y=ARGF + +SETDSA ROUT + JSR SETRTN ;Put arg on NEWARG stack **25/12/86** +SETDSN LDYIM ARGB ;PUT DISC NO & OBJSIN ON NEWARG STACK + LDA DRDISC + STAIY NEWARG + INY + LDA DRDISC+1 + STAIY NEWARG + INY + LDA OBJSIN + STAIY NEWARG + INY + LDA OBJSIN+1 + STAIY NEWARG + INY + LDA OBJSIN+2 + STAIY NEWARG + RTS + +ARGDSN LDYIM ARGB ;PLACE DISC NO & OBJSIN ON ARGPTR STACK + LDA DRDISC + STAIY ARGPTR + INY + LDA DRDISC+1 + STAIY ARGPTR + INY + LDA OBJSIN + STAIY ARGPTR + INY + LDA OBJSIN+1 + STAIY ARGPTR + INY + LDA OBJSIN+2 + STAIY ARGPTR + RTS + +CRNSIN LDYIM DRSIN ;OBJSIN := SIN OF CRNTEN + LDAIY CRNTEN + STA OBJSIN + INY + LDAIY CRNTEN + STA OBJSIN+1 + INY + LDAIY CRNTEN + STA OBJSIN+2 + RTS + +SINSZE LDAIM 5 ;CALL MAPMAN.SIZE FOR OBJSIN + JSR SETDSA + JMP MAPMAN + +RETDSZ LDYIM INFDIS ;MOVE DISC NO & SIZE INTO INFPTR + LDA DRDISC + STAIY INFPTR + INY + LDA DRDISC+1 + STAIY INFPTR + JSR SINSZE + PHA ;Record MAPMAN return code + LDYIM ARGB ;MOVE SIZE ON NEWARG STACK TO INFPTR + LDAIY NEWARG + LDYIM INFSZE + STAIY INFPTR + LDYIM ARGC + LDAIY NEWARG + LDYIM INFSZE+1 + STAIY INFPTR + LDYIM ARGD + LDAIY NEWARG + LDYIM INFSZE+2 + STAIY INFPTR ;MS(SIZE) + PLA ;Restore MAPMAN return code + RTS + +TSROOT ROUT + LDYIM 0 ;TEST FOR <root> + LDAIY NAMPTR + CMPIM ROOT + RTS + +TSTROT ROUT + JSR TSROOT ;TEST FOR <root><terminator> +00 BNE #10 +TSTTER INY +05 LDAIY NAMPTR + CMPIM TERMIN +10 RTS + +TSTERM LDYIM 0 ;is file title <term> omly? + BEQ #05 + +TSTPAR ;**23/1/87** + LDYIM 0 + LDAIY NAMPTR + CMPIM "^" ;check parent directory name + JMP #00 + +TESTPD ROUT ;**2/6/87** test pseudo-directory name + CMPIM "^" + [ Pseudods = Yes + BEQ #10 + CMPIM "&" + BEQ #10 + CMPIM "%" + BEQ #10 + CMPIM "@" + ] +10 RTS + +TSTOWN ROUT + LDA DIRACC ;TEST FOR OWNER ACCESS + ANDIM OWNER + CMPIM OWNER + BEQ #10 + LDAIM DRERRE ;INSUFFICIENT ACCESS +10 RTS + +SETGEN LDA DIRSTA ;GENPTR := [DIRSTA] + STA GENPTR + LDA DIRSTA+1 + STA GENPTR+1 + RTS + +;OUTPUT LOAD AND EXECUTE ADDRESSES +;FOR THE CURRENT ENTRY. + +OUTLEX LDYIM DRLOAD + JSR OUTHEX + JSR OUTSP + LDYIM DREXEC + JSR OUTHEX + LDXIM 3 + JMP OUTSPS ;SPACE AND EXIT + + LNK UADE0E diff --git a/Level3/SRC/L3/Uade0E b/Level3/SRC/L3/Uade0E new file mode 100644 index 0000000..e01f89d --- /dev/null +++ b/Level3/SRC/L3/Uade0E @@ -0,0 +1,1106 @@ + OPT UADE0E ;FILE > Uade0E + TTL File server file UADE0E +;******************************** +;* DIRMAN U T I L I T I E S 2 * +;******************************** + +DETALS ROUT + CLC ;COPY CRNTEN DETAILS INTO INFPTR + LDA CRNTEN + ADCIM DRTITL + STA MOVFRM + LDA CRNTEN+1 + ADCIM 0 + STA MOVFRM+1 + LDYIM INFDIS-1 ;COPY LOAD ADDR -> SIN +10 LDAIY MOVFRM + STAIY INFPTR + DEY + BPL #10 + +;COPY DISC NO & SIZE OF OBJECT INTO DETAILS AREA + + JSR CRNSIN ;OBJSIN := SIN OF CRNTEN + JMP RETDSZ + +;********** MAKDIR RTN ********** + +;MAKDIR : CREATE A VIRGIN DIR + +;ENTRY: DRDISC = DISC NUMBER +;DIRTMP := SIZE OF DIR REQUIRED(APPROX) +;EXRTN := SIN of parent, or zero if none (not coded) + +;EXIT: A := RC +;ARGPTR STACK INITIALISED FOR PRESERVE + + +MAKDIR ROUT + LDAIM 1 ;MapMan.CreateSpace + JSR SETDSA ;PUT DISC NO ON NEWARG STACK + LDYIM ARGD + LDA DIRTMP + STAIY NEWARG ;LS(SIZE) + INY + LDA DIRTMP+1 ;DIRTMP := SIZE OF NEW DIR + STAIY NEWARG ;CS(SIZE) + INY + LDA DIRTMP+2 + STAIY NEWARG ;MS(SIZE) + + JSR JUSING ;pass pointer to user info **3/10/84** + + JSR MAPMAN ;MAPMAN.CREATE SPACE + BNE #20 + +;SETUP DETAILS ON ARGPTR STACK FOR RETAIN RTN + + LDYIM ARGD + LDAIY NEWARG + STA DIRSIN + LDYIM ARGQ + STAIY ARGPTR + LDYIM ARGE + LDAIY NEWARG + STA DIRSIN+1 + LDYIM ARGR + STAIY ARGPTR + LDYIM ARGF + LDAIY NEWARG + STA DIRSIN+2 ;DIRSIN := SIN OF NEW DIR + LDYIM ARGS + STAIY ARGPTR + JSR DIROBJ ;OBJSIN := SIN OF NEW DIR + + LDYIM ARGF + LDAIM 0 +10 STAIY ARGPTR ;LOAD ADDR:=EXEC ADDR:=0 + INY + CPYIM ARGN + BCC #10 + + LDAIM TYPDIR+LOCKED + STAIY ARGPTR ;TYPE & ACCESS INFO + + INY + LDA DATE + STAIY ARGPTR + INY + LDA DATE+1 + STAIY ARGPTR ;DATE CREATED + + JSR LOADDR ;LOAD DIR INTO STORE + BEQ #30 + + CMPIM DRERRB + BEQ #25 ;Press on here, but relock directory + +;IF WE CANNOT LOAD IT THEN CLEAN UP + + PHA ;REMEMBER RC + JSR ARGOBJ ;OBJSIN:=SIN OF NEWDIR + JSR DELB ;FREE SPACE ALLOCATED IN DISC MAP + PLA +20 RTS + +;CLEAR DRFRST -> DRENTS + +25 JSR INCCNT ;Relock broken directory **25/12/86** + +30 LDA DIRSTA + STA CLRPTR + STA GENPTR + LDA DIRSTA+1 + STA CLRPTR+1 + STA GENPTR+1 + LDYIM DRSTAR+DRENSZ ;**23/1/87** zero first entry also + LDXIM 0 + JSR CLRSTR + +;Make dummy unchained first entry for parent ptr **23/1/87** + + LDYIM DRSTAR + LDAIM &FF + STAIY GENPTR ;mark entry not chained + INY + STAIY GENPTR + LDYIM DRSTAR+DRSIN + LDA EXRTN ;copy SIN of parent + STAIY GENPTR + INY + LDA EXRTN+1 + STAIY GENPTR + INY + LDA EXRTN+2 + STAIY GENPTR + +;NOW FORMAT IT + + CLC + LDA DIRSTA + ADCIM DRSTAR+DRENSZ ;**23/1/87** + STA CRNTEN + LDA DIRSTA+1 + ADCIM 0 + STA CRNTEN+1 ;CRNTEN PTS TO FIRST ENTRY TO BE MARKED FREE + JSR FORMAT + BEQ #40 + + JSR DELOBJ ;DELETE THE OBJECT + +40 RTS + +;FORMAT: RTN TO INCREASE THE NO OF FREE ENTRIES IN A DIR + +;ENTRY:OBJSIN = SIN OF DIR +;CRNTEN = PTR TO NEXT POSN TO BE PLACED ON FREE CHAIN +;DIRTMP = SIZE OF DIR (IN BYTES) +;DPTRLD = PTR TO FIRST BYTE OF DIR + +;EXIT : A = RC +;N.B. CRNTEN & DIRTMP ARE DESTROYED +;DPTRTR IS UPDATED + + +FORMAT ROUT + JSR DECCRN ;CRNTEN -:=DRENSZ + + CLC ;WE WANT TO SUBTRACT ONE AS WELL + LDA DIRTMP + SBCIM DRENSZ + STA DIRTMP + BCS #05 + DEC DIRTMP+1 ;N.B. WE SUBTRACT ONE FOR THE TRAILING SQ NO + +05 CLC + LDA DIRTMP + ADC DIRSTA + STA DIRTMP + LDA DIRTMP+1 + ADC DIRSTA+1 + STA DIRTMP+1 ;DIRTMP:=DIRSTA+DIRSIZE-DRENSZ-1 + +10 JSR INCCRN ;CRNTEN +:= DRENSZ + + LDA DIRTMP + CMP CRNTEN + LDA DIRTMP+1 + SBC CRNTEN+1 + BCC #20 ;BRANCH IF CRNTEN > DIRTMP + + JSR FREECH ;PLACE CRNTEN ON THE FREE CHAIN + JMP #10 + +;NOW SHRINK THE DIR TO AN 'EXACT' SIZE + +20 LDAIM 3 + JSR SETDSA ;PLACE DISCNO & OBJSIN ON NEWARG STACK + + LDA CRNTEN + STA DIRSZE + STA DPTRTR + LDA CRNTEN+1 + STA DIRSZE+1 ;DIRSZE := CRNTEN + STA DPTRTR+1 ;DPTRTR := PTR TO LAST BYTE OF DIR (SQ.NO.) + INC DIRSZE ;ADD ON 1 FOR TRAILING SQ. NO. + BNE #30 + INC DIRSZE+1 ;DIRSZE := CRNTEN + 1 +30 SEC + LDA DIRSZE + SBC DIRSTA + STA DIRSZE + LDYIM ARGG + STAIY NEWARG ;LS(SIZE) + LDA DIRSZE+1 + SBC DIRSTA+1 + STA DIRSZE+1 ;DIRSZE := CRNTEN + 1 - DIRSTA + INY + STAIY NEWARG ;CS(SIZE) + INY + LDAIM 0 + STAIY NEWARG + + JSR JUSINF ;** 3/10/84 ** + + JSR MAPMAN ;MAPMAN.CHANGESIZE + BNE #40 + +;NOW INSERT TRAILING SQ. NO. AND THEN + + LDYIM DRSQNO + LDAIY DPTRLD + LDYIM 0 + STAIY DPTRTR ;SET TRAILING SQ. NO. = LEADING SQ. NO. + +;NOTE FORMAT DOES NOT ENSURE THE DIR OR THE MAP. +;SO WE MARK THE DIR DIRTY IN CASE IT GETS REMOVED FROM THE CACHE. + + LDA DPTRLD + STA GENPTR + LDA DPTRLD+1 + STA GENPTR+1 + JSR MRKDRT ;MARK IT DIRTY + + LDAIM 0 ;RC := 0 + +40 RTS + +JUSING LDYIM ARGB ;21/12/84 + LDAIY ARGPTR ;passed in original call + TAX + INY + LDAIY ARGPTR + + LDYIM ARGH + STAIY NEWARG + DEY + TXA + STAIY NEWARG + RTS + +DECCRN ROUT + SEC ;CRNTEN -:= DRENSZ + LDA CRNTEN + SBCIM DRENSZ + STA CRNTEN + BCS #10 + DEC CRNTEN+1 +10 RTS + + + +;********* EXAMINE UTILS ******** + + +;ALL INFO IN MACHINE READABLE FORM +;AND FILE TITLE. + +;ON ENTRY, INFPTR POINTS TO RESULT +;AREA. ON EXIT, INFPTR POINTS TO +;BYTE AFTER RESULT. + +EXRTNA ROUT + JSR MOVEFT ;10 BYTE FILE TITLE + + LDYIM DRLOAD + LDXIM 0 + +;MOVE ALL OTHER INFO FROM DIR. TO +;RESULT AREA. + +05 LDAIY CRNTEN + STAIX INFPTR + JSR INCIPT + INY + CPYIM DRENSZ + BNE #05 + JSR CRNSIN ;GET SIN OF CURRENT ENTRY + JSR SINSZE ;GET SIZE ON STACK + BNE #20 + LDYIM ARGB ;COPY SIZE -> INFO AREA + LDXIM 0 +10 LDAIY NEWARG + STAIX INFPTR + JSR INCIPT + INY + CPYIM ARGE + BNE #10 + TXA ;Successful exit +20 RTS + + +;ALL INFORMATION, FORMATTED IN CHAR. STRING + +EXRTNB ROUT + JSR OUTENT ;Output entry details + BNE #10 + +ERTNBZ LDAIM ENTTRM ;Terminate string + JSR OUTCH + LDAIM 0 +10 RTS + + +OUTENT ROUT + JSR MOVEFT ;Print file title + JSR OUTSP + JSR OUTLEX + JSR OUTSZE + BNE #10 ;Map error +OUTEN2 JSR OUTACC + LDXIM 4 + JSR OUTSPS + JSR OUTDAT + JSR OUTSIN + LDAIM 0 ;Successful exit +10 RTS + + +;FILE TITLE + TITLE LENGTH, M/C READABLE + +EXRTNC ROUT + LDXIM 0 + LDAIM NAMLNT + STAIX INFPTR ;File title length + JSR INCIPT + JSR MOVEFT ;Note pointer to locn. after f.t. + LDAIM 0 + RTS ;Successful exit + + + +;FILE TITLE + ACCESS IN CHAR FORM + +EXRTND ROUT + JSR MOVEFT + JSR OUTSP + JSR OUTACC + JMP ERTNBZ + + +;*** MINOR UTILITIES *** + + +;MOVE FILE TITLE FROM DIRECTORY TO +;!INFPTR. ON EXIT, INFPTR POINTS TO +;BYTE AFTER FILE TITLE. + +MOVEFT ROUT + LDYIM DRTITL + LDXIM 0 +10 LDAIY CRNTEN + STAIX INFPTR + INY + JSR INCIPT + CPYIM DRTITL+NAMLNT + BCC #10 + RTS + + +OUTSPS JSR OUTSP + DEX + BNE OUTSPS + RTS + + + +;OUTPUT A SPACE AND INCREMENT INFPTR. + +OUTSP LDAIM SPACE +OUTCH STX DMSTX + LDXIM 0 + STAIX INFPTR + LDX DMSTX + JMP INCIPT ;INCREMENT POINTER + + +;FOUR BYTES IN REVERSE ORDER IN HEX +;FROM CURRENT DIR. ENTRY + +;Y POINTS TO CURRENT ENTRY DATA. + +OUTHEX INY + INY + INY + LDAIM 0 + STA FILLFL ;Set space fill ON + LDAIY CRNTEN + JSR OUTBYT ;TOP DIGIT + DEY + LDAIY CRNTEN + JSR OUTBYT + DEY + LDAIY CRNTEN + JSR OUTBYT ;TWO DIGITS + DEY + LDAIY CRNTEN ;Fall into OUTBYT + + +;OUTPUT TOP OF A IN HEX + +OUTBYT ROUT + PHA + LSRA + LSRA + LSRA + LSRA + JSR OUTDIG + + PLA +OUTDIG ANDIM &F + BNE #10 ;Non-zero, don't worry about fill + BIT FILLFL + BPL #10 ;Switch -ev => fill space + LDAIM SPACE + BNE OUTCH ;Space and exit + +10 PHA + LDAIM 0 + STA FILLFL ;Printing a digit, so switch leading 0's off + PLA + CMPIM &A + BCC #20 + ADCIM 6 +20 ADCIM &30 + BNE OUTCH + + +;THREE BYTE SIN IN HEX + +OUTSIN LDYIM DRSIN+2 + LDAIM 0 + STA FILLFL + + LDAIY CRNTEN + JSR OUTBYT + DEY + LDAIY CRNTEN + JSR OUTBYT + DEY + LDAIM 0 + STA FILLFL ;Switch leading spaces off + LDAIY CRNTEN + JMP OUTBYT + + +;OUTPUT DATE TO INFPTR IN DD/MM/YY FORMAT + +OUTDAT ROUT + LDYIM DRDATE + LDAIY CRNTEN + + PHA ;*24/2/88** + ANDIM &1F ;**24/2/88** Isolate day of month + JSR OUTDEC + + LDAIM ":" + JSR OUTCH + + PLA ;**24/2/88** + ANDIM &E0 ;**24/2/88** Year high order + STA Fillfl ;**24/2/88** + LDYIM DRDATE+1 + LDAIY CRNTEN + PHA + ANDIM &F + JSR OUTDEC ;MONTH + LDAIM ":" + JSR OUTCH + + PLA + LSRA + LSRA + LSRA + ORA Fillfl ;**24/2/88** + LSRA + CLC + +;ADD TO GET BASEYR + + ADCIM BASEYR + CMPIM 100 ;**24/2/88** Year 20xx? + BCC #10 + SBCIM 100 +10 JSR OUTDEC + JMP OUTSP + + + +;OUTPUT A IN DECIMAL. NOTE A IS +;ASSUMED <100 COZ ROUTINE ONLY +;USED IN WRITING DATE. + +OUTDEC ROUT + LDXIM &FF ;TOP DIGIT IS IN X + SEC +10 INX + SBCIM &A + BCS #10 ;IF >=10, CARRY ON + ADCIM &A + PHA + TXA ;OUTPUT TOP DIGIT + JSR #20 + PLA +20 ORAIM "0" ;CONVERT TO CHAR. + JMP OUTCH + + + +;OUTPUT ACCESS BYTE AS A PADDED +;CHAR STRING, 7 BYTE LONG. ON +;EXIT, INFPTR POINTS TO BYTE AFTER +;ACCESS STRING. + +OUTACC ROUT + LDYIM DRACCS ;OFFSET IN DIR. ENTRY + LDAIY CRNTEN + ASLA ;ONE LEFT SO ACCESS BITS ROTATED INTO B.7 + LDXIM 0 + LDYIM 0 + +;LOOP ROUND FIRST FOUR ACCESS FIELDS + +10 JSR OACCCH + INX + CPXIM 4 + BNE #10 + + PHA + LDAIM "/" + JSR OUTCH + PLA + + JSR OACCCH ;OWNER ACCESS WRITE + INX + +;FINALLY OWNER ACCESS READ + JSR OACCCH + +;NOW PAD TO THE RIGHT, Y BEING +;NO OF SPACES NEEDED. + +20 JSR OUTSP + DEY + BNE #20 + RTS + +ACCTAB = "DLWRWR" + +OACCCH ASLA + PHA + BMI #40 + INY ;ACCESS NOT SET, INC SPACE COUNT + PLA + RTS + +40 LDAAX ACCTAB + JSR OUTCH + PLA + RTS + + +;GET SIZE FROM MAP AND OUTPUT IN +;HEX (3 BYTES, 5 DIGITS). + +OUTSZE ROUT + JSR CRNSIN ;SET CURRENT SIN TO A VARIABLE + JSR SETDSN ;SET DISC NO. + SIN ON STACK + JSR SINSZE ;GET SIZE FROM MAP + BNE #20 ;ERROR ... EXIT + + LDYIM ARGD ;TOP BYTE OF SIZE + LDAIM 0 ;NO leading spaces + STA FILLFL + LDAIY NEWARG + JSR OUTBYT ;TOP DIGIT + + DEY + LDAIY NEWARG + JSR OUTBYT + + DEY + LDAIY NEWARG + JSR OUTBYT + LDXIM 3 + JSR OUTSPS + LDAIM 0 ;SUCCESSFUL EXIT + +20 RTS + + + +INCIPT ROUT + INC INFPTR + BNE #10 + INC INFPTR+1 +10 RTS + + + + +;CHECK THAT THE NUMBER OF ENTRIES +;ASKED FOR OF A CERTAIN TYPE OF +;EXAMINE IS LESS THAN MAX. NO. + +ENTTAB = MAXENA + = MAXENB + = MAXENC + = MAXEND + +CHKENS ROUT ;CHKENS + LDX EXARG + CPXIM 4 + BEQ #10 ;Asking for dir.name only, exit, C clear + CMPIM 0 ;**1/5/87** If zero, set to max + BEQ #05 + CMPAX ENTTAB + RTS + +05 LDAAX Enttab ;**1/5/87** load max for exam type +10 CLC + RTS + + + +;************ RETAIN ************* + +;RETAIN: RTN TO RETAIN A SIN IN A +;SPECIFIED DIRECTORY, WITH +;GIVEN FILE NAME. + +;ENTRY: ARGUMENTS ON ARGPTR STACK, AS SPECIFIED +;FOR DIRMAN.DRPRES. + +;EXIT : +;A = RC +;ARGB-C DISC NO +;ARGD-F SIN OF OBJECT TO BE DELETED + +;NOTE OBJSIN CAN BE DESTROYED BY RETAIN + +;FUNCTION: + +;IF TYPE = TYPDIR +;THEN PUT LAST COMPONENT OF FILE TITLE IN DIR HEADER +;FI; +;IF ENTRY ALREADY EXISTS +;THEN CHECK THAT IT MAY BE DELETED; +;CHECK THAT TYPES AGREE; +;CALL MAPMAN.ENSURE(MAP) +;NOTE SIN OF OBJECT TO BE DELETED; +;UPDATE DIR ENTRY (all except access - including name); +;ENSURE DIRECTORY UPTO DATE ON DISC; +;RETURN(success,disc no,sin) +;ELIF ROOM FOR A NEW ENTRY +;THEN CALL MAPMAN.ENSURE(MAP); +;UPDATE DIRECTORY; +;ENSURE DIR UPTO DATE ON DISC; +;RETURN(success,0,0) +;ELSE RETURN(directory full) +;FI + +RETAIN ROUT + LDAIM &FF +RETA12 STA TEMPA ;skip DELCHK entry point + JSR LOADTX + LDA TXTNAM ;**1/6/87** prohibit pseudo-directory names + JSR Testpd + BNE #10 + LDA TXTNAM+1 + CMPIM &20 + BNE #10 + LDAIM DRERRA + BNE #15 + +10 JSR FNDTEX ;DOES TEXT NAME ALREADY EXIST ? + BNE #40 + +;ENTRY ALREADY EXISTS + + LDA TEMPA ;check entry point + BEQ #25 ;skip if RENAME involved ** 25/9/84 ** + + JSR DELCHK ;CAN IT BE DELETED ? + BEQ #25 +15 JSR UNLOCK ;UNLOCK THE LOADED DIR +20 RTS + +;SEE IF TYPES MATCH + +25 LDYIM ARGN + LDAIY ARGPTR ;TYPE & ACCESS OF OBJECT TO BE PRESERVED + ANDIM TYPE + STA TEMPA + LDYIM DRACCS + LDAIY CRNTEN + STA OBJACC ;OBJACC:=OLD ACCESS FIELD IN DIR + ANDIM TYPE + CMP TEMPA + BEQ #30 + LDAIM DRERRK ;TYPES DON'T MATCH + BNE #15 + +30 JSR #45 ;**1/6/88** check entry code and update header + JSR CRNSIN ;OBJSIN:=SIN OF OBJECT TO BE DELETED + JSR COPYDT ;COPY OBJECT DETAILS INTO DIR + JSR COPYNM ;Copy name TXTNAM -> dir. entry + LDYIM DRACCS ;BUT KEEP OLD ACCESS FIELD + LDA OBJACC + STAIY CRNTEN + JSR ARGDSN ;MOVE DISC NO & OBJSIN ONTO ARGPTR STACK + JMP ENSRIT ;STRMAN.ENSURE(DIR) + +;MAKE A NEW DIR ENTRY + +40 JSR SETFRE ;DIRFRE := ADDR OF FREE ENTRY PTR + BNE #50 + JSR UNLOCK + +;THE DIR IS FULL SO TRY AND INCREASE ITS SIZE + + JSR CHZSZE ;INCREASE DIR SIZE + BNE #20 + JSR LOADDR ;RELOAD THE DIR + BEQ #10 ;TRY AGAIN + RTS ;Failed, exit (directory unlocked) **25/12/86** + +45 LDYIM ARGA ;**1/6/88** check if preserve-check only + LDAIY ARGPTR + EORIM 13 ;set zero if so + BEQ #47 ;and go unlock and return + JSR RATDIR ;IF DIR THEN UPDATE NAME IN HEADER + BNE #47 + JSR ENSMAP ;ENSURE MAP OF OBJECT TO BE RETAINED + BNE #47 + RTS + +47 TAY + PLA + PLA + TYA + JMP #15 + +50 JSR #45 ;**1/6/88** check entry code and update header + +;REMOVE ENTRY FROM FREE CHAIN AND INSERT +;IT IN APPROPRIATE POSITION, ON THE IN USE CHAIN. + + LDYIM DRLINK + LDAIY PREVEN +7 STA TEMPA + INY + LDAIY PREVEN + STA TEMPA+1 ;TEMPA := [PREVEN] + + DEY ;Y:= DRLINK + LDAIY DIRFRE + STAIY PREVEN + INY + LDAIY DIRFRE + STAIY PREVEN ;[PREVEN] := [DIRFRE] + + JSR SETCRN ;CRNTEN := STORE ADDRESS OF [DIRFRE] + + LDYIM DRLINK + LDAIY CRNTEN + STAIY DIRFRE + INY + LDAIY CRNTEN + STAIY DIRFRE ;[DIRFRE] := [CRNTEN] + DEY ;Y:=DRLINK + LDA TEMPA + STAIY CRNTEN + INY + LDA TEMPA+1 + STAIY CRNTEN ;[CRNTEN] := TEMPA + +;INCREMENT DIR ENTRY COUNT + + JSR SETGEN ;GENPTR := [DIRSTA] + + CLC + LDYIM DRENTS + LDAIY GENPTR + ADCIM 1 + STAIY GENPTR + INY + LDAIY GENPTR + ADCIM 0 + STAIY GENPTR ;[DIRSTA + DRENTS] +:= 1 + +;COPY TEXT NAME INTO DIR ENTRY + + JSR COPYNM + +;COPY DETAILS ON ARGPTR STACK INTO DIR ENTRY + + JSR COPYDT + JSR ENSRIT ;STRMAN.ENSURE(directory) + JSR ARGDSN ;Copy Disc & SIN to stack, then zero SIN + +;CLEAR SIN TO ZERO + + LDAIM 0 + LDYIM ARGD + LDXIM 3 +70 STAIY ARGPTR ;:=0 + INY + DEX + BNE #70 +80 RTS + + +;RATDIR: IF RETAINING A DIR - WE COPY INTO ITS HEADER +;THE LAST COMPONENT OF A FILE TITLE. +;THIS IS THE DIR'S NAME & PROVIDED FOR THOSE +;CLIENTS WANTING TO DISPLAY A DIR'S NAME +;DURING EXAMINE. + +RATDIR LDYIM ARGN + LDAIY ARGPTR + ANDIM TYPDIR + BEQ #80 + +;AS WE ARE RETAINING A DIR WE MUST COPY THE CONTENTS +;OF TXTNAM INTO THE HEADER OF THIS DIR. + + JSR ARGOBJ ;OBJSIN:=SIN OF OBJECT TO BE PRESERVED + JSR SINSZE ;FIND OUT THE DIR'S SIZE + BNE #80 + LDYIM ARGE + LDAIY NEWARG ;LS(NO OF BLOCKS) + PHA + INY + LDAIY NEWARG ;MS(NO OF BLOCKS) + PHA + LDAIM 1 + JSR SETDSA ;PUT DISCNO & OBJSIN ON NEWARG STACK + INY + LDAIM 0 + STAIY NEWARG + INY + STAIY NEWARG ;BLOCK NO. = 0 + PLA + LDYIM ARGJ + STAIY NEWARG ;MS(NO OF BLOCKS) + PLA + DEY ;Y:= ARGI + STAIY NEWARG ;LS(NO OF BLOCKS) + JSR STRMAN ;STRMAN.DISC ADDR->STORE ADDR + BNE #80 + +;NOW THE DIR IS LOADED - SO COPY THE CONTENTS OF +;TXTNAM INTO THE HEADER OF THE DIR + + LDYIM ARGB + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 + CLC + LDA GENPTR + ADCIM DRNAME + STA MOVTO + LDA GENPTR+1 + ADCIM 0 + STA MOVTO+1 + LDAIM :LSB:TXTNAM + STA MOVFRM + LDAIM :MSB:TXTNAM + STA MOVFRM+1 + LDXIM NAMLNT + JSR MOVE + + LDYIM DRSTAR ;**08/02/87** + LDAIM &FF + CMPIY GENPTR ;parent pointer in first entry? + BNE #90 + INY + CMPIY GENPTR + BNE #90 + LDYIM DRSTAR+DRSIN ;yes, update to current parent + LDA DIRSIN + STAIY GENPTR + INY + LDA DIRSIN+1 + STAIY GENPTR + INY + LDA DIRSIN+2 + STAIY GENPTR + +90 JSR MRKDRT ;MARK IT DIRTY + LDAIM 2 + JSR SETRTN ;N.B. STR ADDR ALREADY ON NEWARG STACK + LDYIM ARGD + LDAIM UNLKIT + STAIY NEWARG ;ENSURE & UNLOCK THE DIR + JMP STRMAN + + +;COPY LOAD ADDR -> SIN, WHICH ARE ON ARGPTR STACK, +;INTO THE DIR ENTRY POINTED TO BY CRNTEN. + +COPYDT LDAIM ARGF + STA OFF1 ;Move from offset + LDAIM DRLOAD + STA OFF2 ;Move to offset + LDXIM ARGPTR ;Move from ptr. + LDYIM CRNTEN ;Move to ptr. + LDAIM &E ;Move 14 bytes + JMP MOVBLK + + +;Copy object name from TXTNAM to dir. entry + +COPYNM LDAIM :LSB:TXTNAM + STA MOVFRM + LDAIM :MSB:TXTNAM + STA MOVFRM+1 + CLC + LDA CRNTEN + ADCIM DRTITL + STA MOVTO + LDA CRNTEN+1 + ADCIM 0 + STA MOVTO+1 + LDXIM NAMLNT + JMP MOVE + + +INCCRN ROUT + CLC ;CRNTEN +:= DRENSZ + LDA CRNTEN + ADCIM DRENSZ + STA CRNTEN + BCC #10 + INC CRNTEN + 1 +10 RTS + + +ARGOBJ LDYIM ARGQ ;OBJSIN:=SIN OF OBJECT TO BE PRESERVED + LDAIY ARGPTR + STA OBJSIN + INY + LDAIY ARGPTR + STA OBJSIN+1 + INY + LDAIY ARGPTR + STA OBJSIN+2 + RTS + + +ENSMAP JSR ARGOBJ ;ENSURE OBJECT'S MAP IS UPTO DATE ON DISC +ENSOMP LDAIM 6 + JSR SETDSA ;PUT DISC NO & OBJSIN ON NEWARG STACK + JMP MAPMAN ;MAPMAN.ENSUREMAP + + +DELOBJ ROUT + PHA ;REMOVE NEWDIR FROM CACHTB + JSR ARGOBJ ;OBJSIN:=SIN OF OBJECT WHICH WAS TO BE PRESERVED + + JSR REMOVE ;remove the cache entry + TAX ;save RC + PLA + BNE #10 + TXA ;substitute RC here +10 CMPIM &C9 ;look for 'write protect' + BEQ #30 + PHA + JSR DELB ;rest of DLETIT + TAX ;save RC + PLA ;get old RC + BNE #30 ;skip if there is previous error + TXA ;else return new error +30 RTS + + +DELB ROUT + LDAIM 2 + JSR SETDSA + JSR JUSING ;** 21/12/84 ** + JSR MAPMAN ;MAPMAN.FREESPACE + BNE #10 + LDAIM 6 + JSR SETDSA + JSR MAPMAN ;MAPMAN.ENSURE MAP + BEQ #20 +10 JSR INTERR +20 RTS + + +REMOVE LDAIM 5 + JSR SETDSA ;REMOVE OBJSIN FROM CACHE + JMP STRMAN ;STRMAN.REMOVE + + +;INCREASE THE SIZE OF A DIR + +;ENTRY: DIRSIN = SIN OF DIR TO HAVE ITS SIZE CHANGED +;EXIT: A = RC + +CHZSZE ROUT + JSR DIROBJ ;OBJSIN := DIRSIN + JSR REMOVE ;REMOVE OBJSIN FROM THE CACHE + JSR SINSZE + BNE #10 + LDYIM ARGB + LDAIY NEWARG + STA CRNTEN + INY + LDAIY NEWARG + STA CRNTEN+1 ;CRNTEN:=EXACT CURRENT SIZE OF DIR + LDYIM ARGE + LDAIY NEWARG + STA BREGA + INY + LDAIY NEWARG + STA BREGA+1 ;BREGA := NUMBER OF BLOCKS + LDAIM 0 + STA BREGA+2 + JSR MULTBS ;BREGA *:= BLKSZE + CLC + LDA BREGA + ADCIM :LSB:BLKSZE + STA DIRTMP + LDA BREGA+1 + ADCIM :MSB:BLKSZE + STA DIRTMP+1 ;DIRTMP:=SIZEOFDIR+BLKSZE(INTEGRAL NB OF BLKS) + +;TEST FOR MAX SIZE OF DIR ALLOWED + + LDAIM :LSB:MAXDIR + CMP DIRTMP + LDAIM :MSB:MAXDIR + SBC DIRTMP+1 + BCS #20 + LDAIM DRERRM +10 RTS + + +20 LDAIM 3 + JSR SETDSA + INY + LDA DIRTMP + STAIY NEWARG ;LS(NEW SIZE) + INY + LDA DIRTMP+1 + STAIY NEWARG ;CS(NEW SIZE) + INY + LDAIM 0 + STAIY NEWARG ;MS(NEW SIZE) + + JSR JUSINF ;** 3/10/84 ** + + JSR MAPMAN ;MAPMAN.CHANGESIZE + BNE #30 + + JSR LDDR ;LOAD CURRENT DIR + BNE #30 + + LDA CRNTEN + BNE #25 + DEC CRNTEN+1 +25 DEC CRNTEN ;CRNTEN-:=1(TO OVERWRITE OLD TRALNG SQ NO) + CLC + LDA DIRSTA + ADC CRNTEN + STA CRNTEN + LDA DIRSTA+1 + ADC CRNTEN+1 + STA CRNTEN+1 ;CRNTEN PTS TO NEXT ENTRY TO BE MADE FREE + + JSR FORMAT ;FORMAT DIR + + JSR ENSRIT ;ENSURE ITS UPTO DATE ON DISC & UNLOCKIT + BNE #30 +;ENSURE THE OBJECT MAP + + JSR ENSOMP ;N.B. OBJSIN MUST = SIN OF DIR + BEQ #30 + JSR INTERR + +30 RTS + + LNK UADE0F diff --git a/Level3/SRC/L3/Uade0F b/Level3/SRC/L3/Uade0F new file mode 100644 index 0000000..52b143e --- /dev/null +++ b/Level3/SRC/L3/Uade0F @@ -0,0 +1,1114 @@ + + OPT UADE0F ;> Uade0F + TTL File server file UADE0F + +;********************** +;* A U T M A N * +;********************** + +;AUTMAN: THE AUTHENTICATION MANAGER +;THE PASSWORD FILE CONTAINS A NUMBER +;OF ENTRIES, EACH OF WHICH HAS THE FOLLOWING FORM:- +;0) USERID (10 BYTES) +;1) PASSWORD (6 BYTES) +;4) Free space (4 bytes) +;3) FLAG (1 BYTE) - INUSE & privileges FLAG + +APWIND * 4 ;window size in blocks + +;***** MAIN ROUTINE ***** + +AUTMAN ROUT + LDXIM 10 ;AUTMAN HAS 10 ENTRY POINTS + LDAIM MODAUT ;A:=NAME OF THIS MODULE + JSR ENTRY + LDAAX ATRTNS + STA ATJUMP+1 + LDAAX ATRTNS+1 + STA ATJUMP+2 + LDAIM 0 + STA ATDRIV ;**23/1/87** altered in ATNWUS + LDAIM 9 + STA ATWORK ;**31/10/83** >0 -> dont keep window with empty slot + JSR SETFS +ATJUMP JMP ATJUMP +ATRTNS + & ATNWUS ;1 => NEW USER + & ATCKPW ;2 => CHECK PASSWORD + & ATSTPW ;3 => SET PASSWORD + & ATDLUS ;4 => DELETE USER + & ATSPRV ;5 => SET PRIVILEGE + & ATREST ;6 => RESTART + & ATSOPT ;7 => SET "USER OPTION" + & ATENS ;8 => Update user disc space in PW file ** 2/10/84 ** + & ATFREE ;9 => Return user disc space + & ATWRIT ;10=> Write user disc space +ATEXIT JMP PREXIT + +PWTITL = "$.PASSWORDS",CR + +;***** ATNWUS ***** + +;ATNWUS: NEW USER - MAKE AN ENTRY IN THE PASSWORD FILE + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO USERID + +;EXIT: ARGA = RC + +;FUNCTION:- +;0) CHECK THAT CALLER HAS SYSTEM PRIV +;1) CHECK THAT USERID DOES NOT EXIST ALREADY +;2) CHECK SYNTAX OF USERID +;3) MAKE AN ENTRY IN PW FILE + +ATNWUE ROUT ;Here to enlarge the file on retry + STA ATWORK ;Nonzero flag + JSR APENRG ;Enlarge the file + BNE ATEXIT + +ATNWUS ROUT + LDAIM 0 + STA DOTFLG + JSR CHKPRV ;CHECK THAT CALLER HAS SYSTEM PRIV + BNE ATEXIT + JSR SETAUT ;AUTPTR:=PTR TO USERID + +;SEE IF USERID EXISTS ALREADY + + LDAIM 0 + STA ATDRIV + JSR FDUSID + BNE #05 + LDAIM ATERRF ;USERID ALREADY IN USE + BNE #27 + +;Find free slot in p/w file + +05 LDAIM 0 + STA ATWORK ;Find free slot + STA ATDRIV ;**23/1/87** First drive to scan in default + JSR ATOPWF ;**22/3/88** Open suitable password file + BEQ #10 + CMPIM ATERRB ;Not found? + BEQ ATNWUE ;Go enlarge file + BNE ATEXIT ;Exit on other error + +;Check syntax of userid + +10 LDYIM 0 + STY DOTFLG +20 LDXIM MAXID + LDAIY AUTPTR ;Check first char is alpha only + JSR ISCHAR + BCS #25 ;Nope -> error + +22 LDAIY AUTPTR + JSR ISDCHA ;Is digit or char + BCS #24 ;Nope + INY + DEX + BNE #22 + + LDAIY AUTPTR ;Check char after user id. is terminator +24 CMPIM CR + BEQ #30 ; => continue + + CMPIM DOT + BNE #25 + + LDA DOTFLG + BNE #25 + INC DOTFLG + + CPYIM MAXID+1 ;should have had a "." before this + BCS #25 + INY + BCC #20 + +25 LDAIM ATERRG ;SYNTAX ERROR IN USERID +27 JMP #65 + +;SEE IF THERE IS ANY ROOM IN PW FILE + +30 TYA ;Check if ptr. zero + BEQ #25 ; => bad user id. + EORIM MAXUNM + STA DOTFLG ;0=> maximum length + + LDYIM PWUSID +35 LDAIY AUTPTR ;Set userid (terminated CR) + CMPIM DOT + BNE #40 + + LDX DOTFLG + BNE #40 + + LDA PWFPTR + BNE #37 + DEC PWFPTR+1 +37 DEC PWFPTR + JMP #45 + +40 STAIY PWFPTR + CMPIM CR + BEQ #50 ;Check for end of userid +45 INY + BNE #35 + +50 LDA DOTFLG + BNE #55 + + INC PWFPTR + BNE #55 + INC PWFPTR+1 + +55 LDYIM PWPASS + LDAIM TERMIN + STAIY PWFPTR ;PASSWORD = "" + + LDYIM PWFREE ;space allocation always maximum + LDAIM 4 + LDXIM UTFRLN-1 +60 STAIY PWFPTR ;** 2/10/84 ** + INY + DEX + BNE #60 + TXA + STAIY PWFPTR + + LDYIM PWFLAG + LDAIM INUSE + STAIY PWFPTR + JSR MARKDT ;MARK PW FILE DIRTY + LDAIM 0 ; success return code +65 JSR APENFL ;**25/12/86** flush from cache + JMP ATEXIT + +ATOPWF ROUT ;**22/5/88** + JSR CHKPRV ;**23/1/87** To get GENPTR:=Userinfo + BNE #10 + LDYIM UTDISC + LDAIY GENPTR + TAX + INY + LDAIY GENPTR + LDYIM ARGC + STAIY NEWARG ;Selected disc number to stack + TXA + DEY + STAIY NEWARG + LDAIM 15 + JSR SETRTN + JSR MAPMAN ;MAPMAN.MPDRNB + BNE #07 ;use default if error + LDYIM ARGB + LDAIY NEWARG ;Else get selected drive number + STA ATDRIV +07 JSR FDUSID +10 RTS + +;***** ATCKPW ***** + +;ATCKPW: CHECK PASSWORD + +;ENTRY: +;ARGB-C SPARE +;ARGD-E PTR TO USERID FOLLOWED BY PW + +;EXIT: ARGA = RC +;ARGB-E LS User disc space **2/10/84** +;ARGF = FLAG BYTE FROM PW FILE +;ARGG = Drive number of PW file **25/12/86** + +ATCKPW ROUT + JSR SETAUT ;AUTPTR:=PTR TO USERID + JSR FDUSID ;SEARCH PW FILE FOR USERID + BNE #30 + + JSR ATFIND ;is user already logged on + BCC #10 ;yes + + LDAIM PWFREE + LDXIM PWFPTR + BNE #20 + +10 JSR ATFPTR ;make pointer + LDAIM UTFREE + LDXIM GENPTR + +20 STA OFF1 + LDYIM ARGPTR + LDAIM ARGB + STA OFF2 + LDAIM 4 + JSR MOVBLK ;general move routine + + LDYIM PWFLAG + LDAIY PWFPTR + LDYIM ARGF + STAIY ARGPTR + INY + LDA ATDRIV + STAIY ARGPTR ;**25/12/86** Set PW file drive + +;NOW SEE IF PASSWORDS MATCH + + JSR CHEKPW + JSR APENFL ;remove the referenced block +30 JMP ATEXIT + +;***** ATSTWP ***** + +;ATSTPW: SET PASSWORD + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO OLD PW FOLLOWED BY NEW PW + +;EXIT: ARGA = RC + +;FUNCTION:- IF OLD PW MATCHES +;EXISTING PW IN PW FILE THEN CHANGE PW. + +ATSTPW ROUT + JSR SETAP1 ;Set AUTPTR to point to user id. + JSR FDUSID ;SEARCH PW FILE FOR USERID + BNE #50 + +;NOW SEE IF OLD PW MATCHES THAT IN PW FILE + + LDYIM ARGD + LDAIY ARGPTR + STA AUTPTR + INY + LDAIY ARGPTR + STA AUTPTR+1 ;AUTPTR USED BY CHEKPW + LDYIM 0 ;Offset for first pw + JSR CHEKP1 + BNE #40 + +;CHECK SYNTAX OF NEW PW + + JSR STEPUR ;Step Y past first PW + STY OFF1 ;OFFSET FOR START OF NEW PW + LDXIM MAXPW +10 LDAIY AUTPTR + CMPIM TERMIN + BEQ #30 + JSR ISDCHA ;Is digit or character ? + BCS #20 ;Nope => error + + INY + DEX + BNE #10 + LDAIY AUTPTR + CMPIM TERMIN + BEQ #30 ;SYNTAX OF PW OK +20 LDAIM ATERRE + BNE #40 + +;NOW COPY NEW PW INTO PW FILE + +30 LDAIM PWPASS ;Copy new PW into PW file + STA OFF2 ;Note OFF1 already set + LDXIM AUTPTR ;"From" ptr. + LDYIM PWFPTR ;"To" ptr. + LDAIM MAXPW + JSR MOVBLK + + JSR MARKDT ;MARK PW FILE STORE BUFFER DIRTY + LDAIM 0 +40 JSR APENFL ;clear out the referenced block +50 JMP ATEXIT + +;***** ATDLUS ***** + +;ATDLUS: DELETE USER FROM PASSWORD FILE + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO USERID + +;EXIT: ARGA = RC + +ATDLUS ROUT + JSR ATOPWF ;**22/3/88** Open suitable password file + BNE #30 ;**22/3/88** br if error including unprivileged + +;NOW CLEAR PASSWORD FILE ENTRY + + LDXIM PWENSZ + LDYIM 0 + TYA +10 STAIY PWFPTR + INY + DEX + BNE #10 + JSR MARKDT ;MARK PW FILE BUFFER DIRTY + LDAIM 0 + JSR APENFL ;Flush PW FILE + +30 JMP ATEXIT + +;***** ATSPRV ***** + +;ATSPRV: SET PRIVILEGE OF A SPECIFIED USER + +;ENTRY: +;ARGB-C PTR TO USERINFO +;ARGD-E PTR TO USERID +;ARGF = PRIV. FLAG (0 => user, 1 => syst priv, 2 => low priv) + +;EXIT: ARGA = RC + +ATSPRT = 0, SYSTPV, LOPRIV, 0 ; table for priv bits *** 25/5/86 *** + +ATSPRV + JSR ATOPWF ;**22/3/88** Open suitable password file + BNE #30 ;**22/3/88** br if error including unprivileged + + LDYIM ARGF + LDAIY ARGPTR ;Load priv. flag + ANDIM 3 ;**25/5/86** mask low value bits + TAY ;**25/5/86** for indexing + LDAAY ATSPRT ;**25/5/86** get priv bit setting + STA ATWORK ;Mask to be OR'd in to PW file + LDYIM PWFLAG + LDAIY PWFPTR + ANDIM NTSYST-LOPRIV ;**25/5/86** Mask off priv bits + JMP ATENPW ;OR in ATWORK, ensure PW file + +;***** ATREST ***** + +;ATREST: AUTMAN.RESTART +;FINDOUT THE DISC NUMBER OF THE DISC +;WHICH CONTAINS THE PASSWORD FILE. +;NOTE IF PW FILE NOT FOUND A <>0 RC IS RETURNED + +;EXIT: ARGA = RC + +ATREST ROUT + LDAIM :LSB:ATUSRI + STA ATUSPT + LDAIM :MSB:ATUSRI + STA ATUSPT+1 ;ATUSPT := PTR TO AUTMAN'S USERINFO AREA + + LDAIM ATERRA ;**25/12/86** Assume the worst + STA ATWORK + + LDYIM UTPRIV + LDAIM SYSTPV+INUSE + STAIY ATUSPT ;AUTMAN HAS SYSTEM PRIV + LDAIM 0 + STA ATDRIV ;DRIVE NUMBER +10 LDA ATDRIV ;A:=DRIVE NUMBER + JSR DRVINF ;MAPMAN.DRIVEINFO + BNE #30 ;**14/06/86** + + JSR RETPWF ;RETRIEVE PW FILE + BEQ #20 + CMPIM DRERRC ;IF RC=CANNOT FIND OBJECT THEN TRY NEXT DRIVE + BEQ #30 + JSR INTERR +20 LDAIM 0 + STA ATWORK ;**25/12/86** PW file found +30 INC ATDRIV ;ATDRIV+:= 1 + LDA ATDRIV ;**14/06/86** + CMP DRIVES ;**14/06/86** + BCC #10 ;**14/06/86** Continue until all checked + LDA ATWORK ;**25/12/86** RC reflects presence of password file + JMP ATEXIT + + +;***** ATSOPT ***** + +;Set user option bits in PW flag (bottom two bits) + +;ENTRY: ARGB/C = ptr. to user info (lo/hi) +; ARGD = new option bits (bottom two bits) + +;EXIT : ARGA = RC + +ATSOPT ROUT + JSR SETAP1 ;Set AUTPTR -> user id. + JSR FDUSID ;Find user id. in pw file + BNE #20 + LDYIM ARGD + LDAIY ARGPTR + ANDIM OPTMSK ;Mask off option bits + STA ATWORK + LDYIM PWFLAG + LDAIY PWFPTR ;Read PW flag byte + ANDIM NTOPT ;Mask off all but option bits + +ATENPW + +;Exit code shared by ATSPRV + + ORA ATWORK ;OR in option bits + CMPIY PWFPTR ;**25/12/86** Has option changed? + BEQ #10 ;**25/12/86** skip marking dirty if not + STAIY PWFPTR + JSR MARKDT ;Mark PW file dirty +10 LDAIM 0 ;Return code (restored over ENSPWF) + JSR APENFL ;Ensure PW file +20 JMP ATEXIT + +;***** ATENS ***** + +;ensure that user disc allocation is up to date +;on disc. + +;ENTRY ARGB,C unset +; ARGD,E pointer to user id +; ARGF,G,H,I value to write + +ATENS ROUT + JSR SETAUT ;point to userid + JSR FDUSID ;lookup the name + BNE #60 + +10 LDAIM ARGF + STA OFF1 + LDAIM PWFREE + STA OFF2 + LDXIM ARGPTR + LDYIM PWFPTR + LDAIM 0 ;**25/12/86** prepare move routine + JSR MOVBLK + LDXIM UTFRLN + JSR COMPAR ;**25/12/86** has field changed? + BEQ #20 ;**25/12/86** no, do not mark dirty + LDXIM UTFRLN ;**25/12/86** yes, copy field + JSR MOVE ;**25/12/86** pointers are preset + JSR MARKDT +20 JSR APENLV ;unlock PW file + LDAIM 0 + BEQ #60 + +;***** ATFREE ***** + +;ENTRY ARGB,C ptr to callers info +; ARGD,E ptr to user name + +;EXIT ARGB,C,D,E user free space + +ATFREE JSR ATFIND ;is user logged on + BNE #60 ;some error here + BCC #30 ;user logged on + + JSR SETAUT + JSR FDUSID + BNE #60 ;not found + + LDAIM PWFREE + STA OFF1 + LDXIM PWFPTR + SEC + BCS #40 + +30 JSR ATFPTR ;grasp pointer from stack + LDAIM UTFREE + STA OFF1 + LDXIM GENPTR + CLC + +40 LDAIM ARGB + STA OFF2 + LDYIM ARGPTR + + PHP + LDAIM 4 + JSR MOVBLK ;copy the info to the appropriate place + PLP + LDAIM 0 + BCC #60 +50 JSR APENFL + +60 JMP ATEXIT ;and return to caller + + + +;***** ATWRIT ***** + +;ENTRY as for ATFREE+ ARGF-I value to write + +ATWRIT ROUT + JSR CHKPRV + BNE #30 ;check for priv + + LDYIM ARGD + LDAIY ARGPTR + TAX + INY + LDAIY ARGPTR + LDYIM ARGC + STAIY NEWARG + DEY + TXA + STAIY NEWARG ;pointer to name + + LDAIM ARGF + STA OFF1 + LDXIM ARGPTR + LDAIM ARGD + STA OFF2 + LDYIM NEWARG + LDAIM 4 + JSR MOVBLK + + LDAIM 9 + JSR SETRTN ;call update user free space + JSR USRMAN + BNE #30 + + JSR SETAUT + JSR FDUSID + BNE #30 ;not found + + LDAIM PWFREE ;area to copy to + STA OFF2 + LDYIM PWFPTR + + LDAIM ARGF + STA OFF1 + LDXIM ARGPTR + + LDAIM 4 + JSR MOVBLK + + JSR MARKDT ;indicate that PW file is dirty + LDAIM 0 + JSR APENFL ;flush the PW file block + +30 JMP ATEXIT + +ATFPTR LDYIM ARGF ;setup Zpage pointer from ARGE + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 + RTS + +ATFIND ROUT + LDXIM 4 ;EXIT Z=1 => ok user: C=1 => not logged on + LDYIM ARGB +10 LDAIY ARGPTR + STAIY NEWARG + INY + DEX + BNE #10 ;copy stack for USRMAN + + LDAIM 6 ;find user + JSR SETRTN + JSR USRMAN + CLC + BEQ #20 ;user found in table + + CMPIM URERRE ;'not logged on' +20 RTS + +SETAUT LDYIM ARGD + LDAIY ARGPTR + STA AUTPTR + INY + LDAIY ARGPTR + STA AUTPTR+1 ;AUTPTR:=ADDRESS OF USERID + RTS + +CHKPRV ROUT + LDYIM ARGB + LDAIY ARGPTR + STA GENPTR + INY + LDAIY ARGPTR + STA GENPTR+1 + LDYIM UTPRIV + LDAIY GENPTR + ANDIM SYSTPV + BNE #10 + LDAIM ATERRD ;INSUFFICIENT PRIV + RTS + +10 LDAIM 0 + RTS + +;RETPWF: RETRIEVE PW FILE FROM DISC (ARGB-C HOLDS DISCNO) + +;FIRST SETUP ARGS FOR DIRMAN.RETRIEVE + +RETPTB = 2 ;DIRMAN.RETRIEVE + & ATUSRI ;userinfo + & PWTITL ;PW file title + & ATINF ;result area + = 0 + +RETPWF ROUT + LDYIM ARGB ;**25/12/86** Copy disc no to UTDISC + LDAIY NEWARG + LDYIM UTDISC + STAIY ATUSPT + LDYIM ARGC + LDAIY NEWARG + LDYIM UTDISC+1 + STAIY ATUSPT + + LDYIM ARGA +10 LDAAY RETPTB-ARGA + STAIY NEWARG + INY + CPYIM ARGI + BNE #10 + + JSR DIRMAN + BNE #30 + LDYIM ARGB + LDAIY NEWARG + ANDIM TYPDIR + CMPIM TYPFIL + BEQ #20 + LDAIM ATERRI ;$.PASSWORDS WRONG TYPE + JSR INTERR +20 LDAIM 0 ;RC:=0 +30 PHP + CMPIM MPERRA ;DISC NOT FOUND + BNE #40 + LDAIM ATERRA +40 PLP + RTS + +; DSCSIA: Put arg, INFDIS & INFSIN on NEWARG stack +; DSCSIN: Put just INFDIS & INFSIN on NEWARG stack +; Exit: Y=ARGF + +DSCSIA ROUT + JSR SETRTN ;**25/12/86** +DSCSIN LDYIM ARGB ;PLACE DISC NO & SIN ONTO NEWARG STACK + LDA ATINF+INFDIS ;disc number (lo) + STAIY NEWARG + INY + LDA ATINF+INFDIS+1 ;disc number (hi) + STAIY NEWARG + INY + LDA ATINF+INFSIN + STAIY NEWARG ;SIN (ls) + INY + LDA ATINF+INFSIN+1 + STAIY NEWARG ;SIN (cs) + INY + LDA ATINF+INFSIN+2 + STAIY NEWARG ;SIN (ms) + RTS + +MARKDT LDA ATSTRA + STA GENPTR + LDA ATSTRA+1 + STA GENPTR+1 + JMP MRKDRT + +;FDUSID: SEARCH THE PW FILE FOR GIVEN USERID + +;ENTRY: AUTPTR = POINTER TO USERID +; ATDRIV = first drive to scan (usually zero) +; ATWORK = +- to search for userid, 0 to find free entry +; if 0, then ATDRIV has a hint for a first drive + +;EXIT: A = RC +;PWFPTR = PTR TO RELEVANT ENTRY IN PW FILE + + +FDUSID ROUT + LDA ATDRIV ;**23/1/87** first drive to scan + LDY ATWORK ;**23/1/87** free entry with hint? + BNE #00 + DEY + STY ATDRIV ;**23/1/87** so drive 0 up next after hint +00 JSR DRVINF + BEQ #04 ;**25/12/86** Br if disc on this drive +02 INC ATDRIV ;**25/12/86** Next drive + LDA ATDRIV + CMP DRIVES + BCC #00 ;**25/12/86** More drives, scan on + LDAIM ATERRB ;**25/12/86** Cannot find user id + RTS + +04 JSR APINIT ;get first block of entries + BEQ #05 + CMPIM DRERRC ;**25/12/86** onto next disc if no pw file + BEQ #02 + +05 LDAIM 0 + STA DOTFLG ;initialise the flag for every lookup + + LDYIM PWFLAG + LDAIY PWFPTR + ANDIM INUSE ;IS THE ENTRY IN USE? + BEQ #45 + + LDA ATWORK + BEQ #60 + LDYIM PWUSID + STY TEMPA ;use registers to hold pointers + STY TEMPB ;pointer into PW file +10 LDY TEMPA + LDAIY AUTPTR + JSR ISCHAR ;C=1 -> not alpha + LDY TEMPB + EORIY PWFPTR ;Compare with PW file + BCS #15 + ANDIM &DF ;Compare with case forcing +15 BNE #60 + + LDAIY PWFPTR ;Here are equal, so check if are terminators + CMPIM TERMIN + BEQ #40 ;Both terminators => found + + CPYIM PWPASS-1 ; *** LH 24/10/85 + BNE #20 ;Not last pair so continue + LDY TEMPA ;Check USERID terminated + INY + LDAIY AUTPTR + CMPIM TERMIN + BEQ #40 ;End and terminated + BNE #60 ;Not terminated so step on + +20 INC TEMPA + INC TEMPB + LDY TEMPA + LDAIY AUTPTR + CMPIM DOT + BNE #30 + INC DOTFLG + + CPYIM MAXID ;only skip if the dot could have been omitted + BNE #30 ;from the PW file + + LDY TEMPB ;just look for "." + EORIY PWFPTR + BNE #25 ;dont adjust if it is there + INC TEMPB +25 INC TEMPA ;step past in AUTPTR, not PWFPTR + +30 LDY TEMPA + CPYIM MAXID+1 ;check that we have had a dot in first 11 chars + BNE #10 ;** LH 24/10/85 check next match ** + + LDA DOTFLG + BEQ #60 ;should have found one by now + BNE #10 ;Dot found so continue + +40 LDAIM 0 ;FOUND IT +42 RTS + +45 LDA ATWORK ;**25/12/86** looking for free slot? + BEQ #42 ;**25/12/86** exit with free slot in PWFPTR + + ;NOW MAKE PWFPTR POINT TO THE NEXT ENTRY + +60 JSR APTEST ;check for end-of-window + BNE #65 + JSR APEND ;check end-of-file + BEQ #90 + JSR APNEXT ;get next window + BNE #42 +65 JMP #05 + +90 LDAIM 0 ;**25/12/86** flush final block + JSR APENFL + BNE #42 + LDA ATWORK ;**25/12/86** stop after first file + BEQ #95 ;**25/12/86** if looking for free slot + JMP #02 ;**25/12/86** userid not found - next drive + +95 LDAIM ATERRB ;**25/12/86** no free slot + RTS + +;CHEKPW: CHECK PASSWORD SUPPLIED BY THE USER WITH +;THAT IN THE PASSWORD FILE. + +;ENTRY: AUTPTR = PTR TO USERID (TERMINATED CR) FOLLOWED BY PW. +;PWFPTR = PTR TO PW FILE ENTRY. + +;EXIT: A = RC + +CHEKPW ROUT + JSR STEPUR ;Step Y past userid. to password +CHEKP1 ;Entry from SETPASSWORD (Y already set) + LDAIM PWPASS ;Set up offsets for PW comparison + STA OFF2 + +10 LDAIY AUTPTR + STY OFF1 + LDY OFF2 ;Offset into PW file + CPYIM PWPASS+MAXPW ;Check if reached end of pw in file + BEQ #20 ;If so, check that pw from AUTPTR is terminated + + EORIY PWFPTR + INC OFF2 ;Increment PW ptr. for next time + LDY OFF1 ;Get offset from AUTPTR + INY ;Increment for next time + ANDIM &DF ;Complete comparison + BNE #30 ;Not the same -> exit with error + + DEY ;Point to char. off AUTPTR + LDAIY AUTPTR ;The same -> check if end of string + INY ;Restore Y in case going back to CHEKWB + SEC + SBCIM TERMIN + BNE #10 + RTS + +20 SEC + SBCIM TERMIN + BEQ #40 ;Both are terminators => exit with zero + +30 LDAIM ATERRC ;=> not found +40 RTS + +STEPUR LDYIM 0 +50 LDAIY AUTPTR + INY + CMPIM TERMIN ;Move Y to point to posn. after userid + BNE #50 ;Not there yet + RTS + +SETAP1 ;Set pointer to callers user id + CLC + LDYIM ARGB + LDAIY ARGPTR + ADCIM UTUSID + STA AUTPTR + INY + LDAIY ARGPTR + ADCIM 0 + STA AUTPTR+1 ;AUTPTR:=PTR TO CALLER'S USERID + RTS + +;**** Start of PW paging routines **** + +;start pointer := 0 +;end pointer := 0 +;current pointer := 0 ;initialisation of variables + +;REPEAT +; load window ( end pointer DIV 256, window size) +; End pointer+:= amount loaded +; Current pointer := Current pointer REM 256 +; REPEAT +; perform operation (current pointer) +; start pointer+:= entry size +; current pointer+:= entry size +; UNTIL end pointer - start pointer < entry size OR ... +; IF end pointer <> start pointer THEN end pointer -:= 256 +;UNTIL end pointer >= file size OR ... + +;**** Initialisation of variables **** + +APINIT ROUT + LDAIM 0 + STA STRPTR + STA STRPTR+1 ;start := 0 + STA PTREND + STA PTREND+1 ;end := 0 + STA PWFPTR + STA PWFPTR+1 ;current := 0 + JSR RETPWF ;read the password file info + BEQ #20 ;first call has no window to release + CMPIM DRERRC ;**25/12/86** file not found? + BNE #20 ;continue if not + TAX + RTS ;**25/12/86** Error exit + +;**** Grab next chunk of PW file **** + +APNEXT LDAIM 0 ;flush previous block + JSR APENFL + BNE #60 ;detect error here +20 LDAIM 1 ;Disc address -> store address + JSR DSCSIA ;put disc number & SIN onto NEWARG stack + INY + LDA STRPTR+1 + STAIY NEWARG ;logical block (lo) + INY + LDAIM 0 + STAIY NEWARG ;logical block (hi) + + INY + SEC + LDA ATINF+INFSZE+1 + SBC STRPTR+1 ;get number of blocks remaining + LDX ATINF+INFSZE ;**1/6/88** round up if part sector + BEQ #30 + CLC + ADCIM 1 + BEQ #35 ;**1/6/88** in case now 256 +30 CMPIM APWIND + BCC #40 ;<= window size left +35 LDAIM APWIND +40 STAIY NEWARG ;no of blocks (lo) + + INY + LDAIM 0 ;no of blocks (hi) + STAIY NEWARG + + JSR STRMAN ;do the call + + PHA ;save RC + CLC + LDYIM ARGB + LDAIY NEWARG ;get store address + STA ATSTRA + ADC STRPTR + STA PWFPTR + INY + LDAIY NEWARG + STA ATSTRA+1 ;two bytes + ADCIM 0 + STA PWFPTR+1 + + INY + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 ;get number of blocks loaded + + LDYIM CEBLKS ;from cache descriptor + LDAIY GENPTR + CLC + ADC STRPTR+1 ;**1/6/88** + STA PTREND+1 ;update PTREND by this value + + PLA + BCC #60 ;**1/6/88** br if password file not too big + JSR APENFL ;**1/6/88** flush unwanted segment + LDAIM ATERRB ;**1/6/88** else say entry not found +60 RTS ;return code from STRMAN + +;**** Update counters, test end condition **** +;**** Z-> end condition met **** + +APTEST ROUT + CLC + LDAIM PWENSZ + ADC STRPTR + STA STRPTR ;strptr+:= entry size + BCC #10 + INC STRPTR+1 + +10 CLC + LDAIM PWENSZ + ADC PWFPTR + STA PWFPTR ;curptr+:= entry size + BCC #20 + INC PWFPTR+1 + +20 SEC + LDA PTREND + SBC STRPTR + TAX ;save result + LDA PTREND+1 + SBC STRPTR+1 + BNE #30 ;not zero condition + TXA + BEQ #30 ;start=end + CMPIM PWENSZ + LDXIM &FF ;unset Z if necessary + BCS #30 + LDAIM 0 +30 RTS + +;**** test for end of PW file **** + +APEND ROUT + LDXIM &FF + LDA PTREND+1 + CMP ATINF+INFSZE+1 + BCC #10 + BNE #00 + LDA PTREND + CMP ATINF+INFSZE + BCC #10 + +00 INX +10 TXA ;set code + RTS ;Z shows condition + + +;**** release old window **** + +APENLV ROUT + PHA + LDAIM 3 ;STRMAN.unlock window + BNE #10 ;but leave it in cache + +APENFL PHA + LDAIM 4 ;STRMAN.flush old window +10 JSR SETRTN + INY + LDA ATSTRA ;store address + STAIY NEWARG + INY + LDA ATSTRA+1 + STAIY NEWARG + INY + LDAIM &FF + STAIY NEWARG ;decrement reference count (2) +20 JSR STRMAN ;make call + TAX ;return the first error code + PLA + BNE #30 + TXA +30 RTS ;return error + +APENRG ROUT ;enlarge the password file + LDA ATINF+INFSZE+2 + BNE #00 + LDA ATINF+INFSZE+1 ;**1/6/88** see if maximal size already + CMPIM &FE ;**1/6/88** won't work if bigger than this + BCC #05 ;**1/6/88** because two byte offsets only used +00 LDAIM ATERRH ;**1/6/88** password file too big + RTS + +05 LDAIM 14 ;MAPMAN.changesize without space check + JSR DSCSIA ;put disc number & SIN onto NEWARG stack + INY + LDAIM 0 + STAIY NEWARG ;new size (lo) + CLC + INY + LDA ATINF+INFSZE+1 + ADCIM 1 + STAIY NEWARG ;new size (mid) + INY + LDA ATINF+INFSZE+2 + ADCIM 0 + STAIY NEWARG ;new size (hi) + + JSR MAPMAN + BNE #10 ;skip if some error + + LDAIM 13 ;Zero area of disc + JSR DSCSIA + INY + LDA ATINF+INFSZE + STAIY NEWARG + INY + LDA ATINF+INFSZE+1 + STAIY NEWARG + INY + LDA ATINF+INFSZE+2 + STAIY NEWARG + + JSR MAPMAN + BNE #10 + + LDAIM 6 ;MAPMAN.ensure + JSR DSCSIA ;discno & sin onto NEWARG stack + JSR MAPMAN +10 RTS ;leave with RC set + + LNK UADE10 diff --git a/Level3/SRC/L3/Uade10 b/Level3/SRC/L3/Uade10 new file mode 100644 index 0000000..fe1bdfd --- /dev/null +++ b/Level3/SRC/L3/Uade10 @@ -0,0 +1,1021 @@ + OPT UADE10 ;> Uade10 + TTL File server file UADE10 + + +;********************************** +;* M A P M A N * +;********************************** + +;THE MAP TABLE (MAPTB) CONTAINS :- +;0) DISC NUMBER (2 BYTES) +;1) NO. OF SECTORS/TRACKS ON DISC (2 BYTES) +;2) SIN OF ROOT DIRECTORY (3 BYTES) +;3) DATE ROOT CREATED (2 BYTES) +;DRIVE NUMBER PROVIDES THE OFFSET IN MAPTB. +;POSSIBLE STATES ARE :- + +MAPMAN ROUT + + LDXIM 16 ;MAPMAN ENTRY POINTS + LDAIM MODMAP ;A := NAME OF THIS MODULE + JSR ENTRY + LDAAX MPRTNS + STA MPJUMP+1 + LDAAX MPRTNS+1 + STA MPJUMP+2 + LDAIM 20 + JSR SETFS +MPJUMP JMP MPJUMP ;JUMP TO CORRECT ROUTINE + +;ADDRESSES OF ENTRY POINTS FOR EACH ROUINE +MPRTNS + & MPCRSP ;1 => CREATE SPACE + & MPFRSP ;2 => FREE SPACE + & MPCHSZ ;3 => CHANGE SIZE + & MPSNRT ;4 => SIN OF ROOT + & MPSZIN ;5 => SIZE OF CHAIN + & MPENSR ;6 => WRITE MAP TO DISC + & MPREST ;7 => START + & MPDSNB ;8 => RETURN DISC NUMBER FOR A GIVEN DRIVE + & MPREDR ;9 => RESTART ONE DRIVE + & MPDNNA ;10 => RETURN NUMBER FOR GIVEN DISC NAME + & MPNADN ;11 => RETURN NAME FOR GIVEN DISC NO. + & MPFREE ;12 => FREE AREA ON DISC + & MPZDSK ;13 => ZERO AREA OF DISC + & MPCHSJ ;14 => changesize without space check + & MPDRNB ;15 => return drive number from disc number + & MPFLSH ;16 => flush bit map and map block caches + +MPENSR LDAIM 0 ;Null routine now +MPEXIT JMP PREXIT + +;MPCRSP: CREATE SPACE + +;ENTRY: +;ARGB-C DISC NUMBER +;ARGD-F NUMBER OF BYTES WANTED +;ARGG-H Ptr to user info + +;EXIT: +;ARGA = RC +;ARGB-C DISC NUMBER +;ARGD-F SIN +;ARGG-H Ptr to user info + +;FUNCTION: MAPTB IS SEARCHED TO FIND THE RELEVANT ENTRY. IF THE SECTOR MAP +;IS NOT IN STORE, IT IS READ IN. THE FREE SPACE COUNT IS CHECKED TO SEE IF +;THE SPACE IS AVAILABLE. A CHAIN IS CREATED, THE FREE COUNT IS DECREMENTED +;AND THE MAP IS MARKED DIRTY. THE SIN OF THE FIRST BLOCK OF THE CHAIN IS +;RETURNED. + +MPBLTX = "paMseJ" ;Mapblocktext + +MPCRSP LDYIM ARGG + JSR MPMKFR ;make pointer + LDAIM ARGD + STA MAPTMP + LDAIM UTFREE + STA MAPTMP+1 + LDXIM :LSB:(1-UTFRLN) + SEC + +10 LDY MAPTMP+1 + LDAIY GENPTR + LDY MAPTMP + SBCIY ARGPTR + STAAX MPNWFR-:LSB:(1-UTFRLN) ;save this result + INC MAPTMP + INC MAPTMP+1 + INX + BNE #10 + + LDY MAPTMP+1 + LDAIY GENPTR + SBCIM 0 ;extra length byte + STA MPNWFR+(UTFRLN-1) + + LDAIM MPERRN ;error code to return with insufficient free space + BCC #20 + + LDAIM 0 + STA ERRTYP ;NO ERRORS YET!!! + STA DNDLTE + JSR FNDMAP ;GET POINTER TO MAPTB + BEQ #25 +20 JMP #90 +25 LDA Mpdrve ;**24/2/88** test for write protect + JSR Testdv + BNE #20 + LDYIM ARGD ;NUMBER OF BYTES REQUIRED + LDAIY ARGPTR + STA DIVPAR + INY + LDAIY ARGPTR + STA DIVPAR+1 + INY + LDAIY ARGPTR + STA DIVPAR+2 + JSR DVDE ;TO FIND MOST LIKELY NUMBER OF BLOCKS + BCC #30 + JMP #85 +30 LDYIM MPCYMP ;READY TO CHECK IF ENOUGH ROOM + LDAIY MAPPTR + STA MPCYPT + INY + LDAIY MAPPTR + STA MPCYPT+1 + SEC + LDYIM 0 + LDAIY MPCYPT + SBC DIVTMP ;FOR NUMBER OF BLOCKS + STAIY MPCYPT + INY + LDAIY MPCYPT + SBC DIVTMP+1 + STAIY MPCYPT + INY + LDAIY MPCYPT + SBC DIVTMP+2 + STAIY MPCYPT + BCS #40 +35 JMP #80 ;BRANCH IF NO ROOM +40 JSR FNDCY ;FIND LARGEST CYCLINDER + JSR RDBTMP ;READ IN THE BIT MAP + BNE #35 ;**25/12/86** Disc fault - say no room + JSR ALBLK ;ALLOCATE ONE BLOCK AS MAP BLOCK + LDA MPTMPA + LDYIM ARGD + STAIY ARGPTR ; SAVE SIN OF NEW FILE + INY + LDA MPTMPA+1 + STAIY ARGPTR + INY + LDA MPTMPA+2 + STAIY ARGPTR + LDA DIVTMP ;ONE LESS BLOCK REQUIRED + BNE #42 + LDA DIVTMP+1 + BNE #41 + DEC DIVTMP+2 +41 DEC DIVTMP+1 +42 DEC DIVTMP + + SEC + JSR RDMPBK ;ALLOCATE SPACE FOR MAP BLOCK + LDA DIVTMP+2 + ORA DIVTMP+1 + ORA DIVTMP ;CHECK IF ONLY ONE BLOCK REQUIRED + BEQ #60 ;BRANCH IF JUST ONE BLOCK + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + LDA MPTMPB ;POINTS TO CYCLINDER MAP + STA MPCYPT + LDA MPTMPB+1 + STA MPCYPT+1 + LDYIM 0 + LDAIY MPCYPT ;CHECK FOR NO FREE SPACR + INY + ORAIY MPCYPT + BEQ #45 ;BRANCH TO GET NEW CYLINDER + JSR ABLKS ; ALLOCATE THE REST OF THE BLOCKS +45 LDA DIVTMP + ORA DIVTMP+1 + ORA DIVTMP+2 ;CHECK IF ALL BLOCKS ALLOCATED + BEQ #60 ;OK IF THEY HAVE + JSR FLBLKS ;OTHERWISE CONTINUE ALLOCATING BLOCKS + BCC #60 ;CARRY CLEAR IF OK +50 LDA ERRTYP + STA DNDLTE + JSR MPDLTE ;CLEAR ALL BLOCKS + JSR ULMB + JSR ENSMB + JSR ENSBM + JMP #80 ;INDICATE NO ROOM + +60 JSR RDmpbd ;**8/5/87** Read block at ARGD + LDA MAPTMP + STA MPSCPT + STA CBSTA + LDA MAPTMP+1 + STA MPSCPT+1 + STA CBSTA+1 + + LDYIM BLKSN + LDXIM 5 ;mapblock identifier text +70 LDAAX MPBLTX + STAIY MPSCPT + INY + DEX + BPL #70 + + LDYIM BILB + LDA DIVPAR ;FILL IN ODD BYTES + STAIY MPSCPT + INY + LDA DIVPAR+1 + STAIY MPSCPT + JSR MMBWT + JSR ENSBM ;ENSURE THE BIT MAPS + JSR ENSMB ;ENSURE THE MAP BLOCKS + LDA ERRTYP + BNE #50 + BEQ #90 ;INDICATES ALL WAS WELL + +80 CLC + LDYIM 0 + LDAIY MPCYPT + ADC DIVTMP + STAIY MPCYPT + INY + LDAIY MPCYPT + ADC DIVTMP+1 + STAIY MPCYPT + INY + LDAIY MPCYPT + ADC DIVTMP+2 + STAIY MPCYPT + LDA ERRTYP + BEQ #85 + SEC + LDYIM 0 + LDAIY MPCYPT + SBCIM 1 + STAIY MPCYPT ;MAP BLOCK LEFT! + INY + LDAIY MPCYPT + SBCIM 0 + STAIY MPCYPT + INY + LDAIY MPCYPT + SBCIM 0 + STAIY MPCYPT + LDAIM MPERRC + BNE #90 + +85 LDAIM MPERRB +90 LDYIM ARGG + JSR MPSETF ;update the user free store if operation ok + JMP MPEXIT + +;MPFLSH; Flush bit map and map block caches. This is done when a disc is to be +; Changed, otherwise we can get confused over who's blocks are cached. + +MPFLSH ROUT ;**26/2/87** + JSR ENSBM ;Ensure all bitmaps + JSR ENSMB ;Ensure all map blocks + JSR SETBM ;Scan all bit map CBs and mark idle + JSR #50 + JSR SETMB ;Scan all map block CBs and mark idle + JSR #50 + JMP MPEXIT + +50 LDX NCBDB +60 LDYIM CAFLG + LDAIM 0 + STAIY GNCBPT ;Zero all flags + JSR ADGNCB + DEX + BNE #60 + TXA + RTS + + + +;MPCHSZ: CHANGE THE SIZE OF A CHAIN ON DISC + +;ENTRY: +;ARGB-C DISC NO +;ARGD-F SIN +;ARGG-I NEW SIZE IN BYTES +;ARGJ-K Ptr to user info + +;EXIT: ARGA = RC + +;FUNCTION: MAPTB IS SCANNED TO FIND THE RELEVANT ENTRY. IF NECESSARY +;THE SECTOR MAP IS READ INTO STORE. THE CURRENT SIZE IS DISCOVERED AND IT +;IS DECIDED WHETHER IT IS AN INCREASE OR A DECREASE IN SIZE. +;THE RELEVANT NUMBER OF BLOCKS ARE THEN ALLOCATED/DEALLOCATED. + + +MPCHSZ ROUT + JSR FNDMAP ;find map entry, set MPDRVE ** 16/1/86 ** + BNE #10 + LDYIM ARGJ + JSR MPFRAD ;get size of chain + BNE #10 ;catch errors + + LDXIM :LSB:-3 + LDYIM ARGG + SEC +05 LDAAX MPNWFR-:LSB:-3 + SBCIY ARGPTR + STAAX MPNWFR-:LSB:-3 + INY + INX + BNE #05 ;calculate new size required + + LDA MPNWFR+3 + SBCIM 0 + STA MPNWFR+3 + + LDAIM MPERRN + BCC #10 ;exit 'cos there's no room + BCS #08 + +MPCHSJ JSR FNDMAP + BNE #10 +08 LDAIM 0 + STA ERRTYP ;NO ERRORS + STA DNDLTE + STA MPTMPB + STA MPTMPB+1 + STA MPTMPB+2 + STA SAVSC ;FIRST BLOCK FLAGGED + JSR MPsetd ;**8/5/87** MPTMPA->ARGD + LDAIY ARGPTR ;GET LENGTH IN BYTES + STA DIVPAR + INY + LDAIY ARGPTR + STA DIVPAR+1 + INY + LDAIY ARGPTR + STA DIVPAR+2 + CLC + JSR RDMPBK ;READ IN RELEVANT MAP BLOCK + LDA ERRTYP + BEQ #13 + LDAIM MPERRC +10 JMP MPCHEN ;REPORT DISC ERROR + +13 JSR DVDE ;DIVIDE BYTES TO GET BLOCKS + BCC #16 + LDAIM MPERRB + BNE #10 + +16 LDA DIVTMP ;DECREMENT SINCE NO MAP BLOCK REQUIRED + BNE #18 + LDA DIVTMP+1 + BNE #17 + DEC DIVTMP+2 +17 DEC DIVTMP+1 +18 DEC DIVTMP + + LDAIM 0 + STA MPTMPB + STA MPTMPB+1 + STA MPTMPB+2 + +19 LDA MAPTMP ;ADDRESS OF MAP BLOCK + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + CLC + LDA MPMBPT ;GET TO POINT AT ENTRIES + ADCIM :LSB:MBENTS + STA MPMBPT + LDA MPMBPT+1 + ADCIM :MSB:MBENTS + STA MPMBPT+1 +20 LDYIM 0 + LDAIY MPMBPT ;CHECK IF NEXT POINTER IS ZERO + INY + ORAIY MPMBPT + INY + ORAIY MPMBPT + BEQ #30 + CLC + LDA MAPTMP + ADCIM :LSB:LSTENT + TAX + LDA MAPTMP+1 + ADCIM :MSB:LSTENT + CPX MPMBPT + BNE #26 + CMP MPMBPT+1 + BNE #26 + LDYIM 0 ;YES, SO THIS POINTER IS SIN OF MAP BLOCK + LDAIY MPMBPT + STA MPTMPA ;PREPARE TO READ NEW MAP BLOCK + INY + LDAIY MPMBPT + STA MPTMPA+1 + INY + LDAIY MPMBPT + STA MPTMPA+2 + CLC + JSR RDMPBK ;READ IN NEW MAP BLOCK + JMP #19 ;**8/5/87** + +26 CLC ; KEEP ADDING UP NUMBER OF BLOCKS + LDYIM 3 + LDAIY MPMBPT + ADC MPTMPB + STA MPTMPB + INY + LDAIY MPMBPT + ADC MPTMPB+1 + STA MPTMPB+1 + BCC #28 + INC MPTMPB+2 +28 LDA MPTMPB + CMP DIVTMP ;CHECK IF ENOUGH BLOCKS FOUND + LDA MPTMPB+1 + SBC DIVTMP+1 + LDA MPTMPB+2 + SBC DIVTMP+2 + BCS #30 ;BRANCH IF ENOUGH FOUND + CLC ;HERE IF JUST LOOK AT NEXT ENTRY + LDA MPMBPT + ADCIM :LSB:ENSZ + STA MPMBPT ; LOOK AT NEXT ENTRY + LDA MPMBPT+1 + ADCIM :MSB:ENSZ + STA MPMBPT+1 + JMP #20 + +30 LDA MPTMPB ;NOW SEE ABOUT THE SIZE + CMP DIVTMP + LDA MPTMPB+1 + SBC DIVTMP+1 + LDA MPTMPB+2 + SBC DIVTMP+2 + BCS #33 ;BRANCH IF MORE SPACE REQUIRED + JMP NEEDMR +33 LDA MPTMPB + CMP DIVTMP + BNE #36 ;IF THESE ARE NOT THE SAME, ODD BLOCKS MUST BE DISCARDED + LDA MPTMPB+1 + CMP DIVTMP+1 + BNE #36 + LDA MPTMPB+2 + CMP DIVPAR+2 + BNE #36 ;THEY ARE EQUAL SO NO PART GROUPS TO DEALLOCATE + JMP #80 +36 SEC ;FIND ODD NUMBER FOR DEALLOCATION + LDA MPTMPB + SBC DIVTMP + STA MPTMPB + LDA MPTMPB+1 + SBC DIVTMP+1 + STA MPTMPB+1 + LDA MPTMPB+2 + SBC DIVTMP+2 + STA MPTMPB+2 + LDYIM 3 + SEC ;GET NUMBER OF THIS GROUP TO DEALLOCATE + LDAIY MPMBPT + SBC MPTMPB + STA MPTMPD + STAIY MPMBPT + INY + LDAIY MPMBPT + SBC MPTMPB+1 + STA MPTMPD+1 + STAIY MPMBPT + LDAIM 0 + SEC + SBC MPTMPB+2 + STA MPTMPD+2 + LDA MAPTMP + STA CBSTA + LDA MAPTMP+1 + STA CBSTA+1 + JSR MMBWT + LDYIM 0 + CLC ; FIND DISC ADDRESS FOR DEALLOCATION + LDAIY MPMBPT + ADC MPTMPD + STA MPTMPE + INY + LDAIY MPMBPT + ADC MPTMPD+1 + STA MPTMPE+1 + INY + LDAIY MPMBPT + ADC MPTMPD+2 + STA MPTMPE+2 + INY + LDAIY MPMBPT + INY + ORAIY MPMBPT + BNE #40 + LDYIM 0 + TYA + STAIY MPMBPT + INY + STAIY MPMBPT + INY + STAIY MPMBPT +40 ;FIND CYLINDER NUMBER + LDAIM 0 + STA MPTMPC ;ZERO CYLINDER COUNT + STA MPTMPC+1 +43 SEC + LDYIM MPSPCY + LDA MPTMPE + SBCIY MAPPTR + STA MPTMPE + INY + LDA MPTMPE+1 + SBCIY MAPPTR + STA MPTMPE+1 + LDA MPTMPE+2 + SBCIM 0 + STA MPTMPE+2 + BCC #46 ; FOUND IF GONE NEGATIVE + INC MPTMPC + BNE #43 + INC MPTMPC+1 + JMP #43 + +46 JSR RDBTMP ;READ THE RELEVANT BIT MAP + BEQ #47 + JMP MPCHEN ;**23/2/87** failed, attempt recovery + +47 JSR MBMLKD + LDYIM MPSPCY + CLC + LDA MPTMPE + ADCIY MAPPTR + STA MPTMPD + INY + LDA MPTMPE+1 + ADCIY MAPPTR + STA MPTMPD+1 + LDYIM 0 +50 LDA MPTMPD+1 + BNE #53 ; CANNOT OF GOT TO THE RIGHT PLACE IF THIS NON-ZERO + LDA MPTMPD + CMPIM 8 ;CHECK FOR LESS THAN EIGHT + BCC #56 ;IF LESS GO AND FIND ACTUAL BIT +53 INY + SEC + LDA MPTMPD ; KEEP DECREMENTING + SBCIM 8 + STA MPTMPD + BCS #50 + DEC MPTMPD+1 + JMP #50 + +56 LDA MPTMPB + PHA ; SAVE THIS COUNT + LDA MPTMPB+1 + PHA + LDXIM 9 ; X TRACKS POSITION IN CURRENT BYTE + LDAIY MPSCPT ; GET THE BYTE +60 RORA ; KEEP ROTATING FOR POSITION + DEX + DEC MPTMPD + BPL #60 +63 SEC ;MARK BLOCK FREE + RORA + PHP ; SAVE THESE VALUES + PHA + DEX + BEQ #70 ; CHECK FOR END OF THIS BYTE +66 LDA MPTMPB ;CHECK IF ALL BLOCKS HAVE BEEN FREED + BNE #67 + DEC MPTMPB+1 +67 SEC + SBCIM 1 + STA MPTMPB + ORA MPTMPB+1 + BEQ #73 ; ZERO WHEN ALL DEALLOCATED + PLA + PLP ;GET VALUES BACK + JMP #63 ;JUMP BACK TO FREE NEXT + +70 STAIY MPSCPT ;SAVE THIS VALUE + LDXIM 8 ;SET UP FOR WHOLE BYTE + INY ;POINT TO NEXT ENTRY IN BIT MAP + PLA + PLP ;JUST TO GET RID OF THEM + LDAIY MPSCPT ; GET NEW BYTE + RORA ;SET UP FOR FREEING BLOCKS + PHP + PHA + JMP #66 + +73 PLA + PLP ;CLEAR VALUES ON STACK +76 RORA + DEX + BNE #76 + STAIY MPSCPT ; AND SAVE HIS VALUE + PLA ; RETRIEVE BLOCK COUNT + STA MPTMPB+1 + PLA + STA MPTMPB + JSR ADDFR ; ADD FREED BLOCKS TO BLOCK COUNT + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JSR MBMWT +80 LDYIM ENSZ ; NOW REST OF ENTRIES CAN BE DEALLOCATED + LDAIY MPMBPT ;CHECK FOR LAST ENTRY + INY + ORAIY MPMBPT + INY + ORAIY MPMBPT + BEQ #90 ;IF NONE LEFT WE'VE FINSHED + SEC + LDA MPMBPT ; RETRIEVE ADDRESS OF MAP BLOCK + SBC MAPTMP ; AND GET OFFSET + STA MPSCPT + LDA MPMBPT+1 + SBC MAPTMP+1 + STA MPSCPT+1 + CLC ;NOW POINT AT NEXT ENTRY + LDA MPSCPT + ADCIM :LSB:ENSZ + STA MPSCPT + LDA MPSCPT+1 + ADCIM :MSB:ENSZ + STA MPSCPT+1 + LDAIM 0 + STA MPTMPE ;don't delete this map block + JSR CLRBLK +90 JSR ULBM + JSR ENSMB + JSR ENSBM + LDA ERRTYP + BEQ #95 + LDAIM MPERRC + JMP MPCHEN + +95 JMP CSEND ;FINISH REDUCTION +; +; SIZE TO BE INCREASED +; +NEEDMR ROUT + SEC ;GET THE POINTER + LDA MPMBPT + SBC MAPTMP + STA SAVPTA ;SAVE THE OFFSET IN THE MAP BLOCK IN CASE IT NEEDS TO BE RESTORED + LDA MPMBPT+1 + SBC MAPTMP+1 + STA SAVPTA+1 + LDA MPTMPA ;SAVE THE SIN OF THE MAP BLOCK + STA SAVPTB + LDA MPTMPA+1 + STA SAVPTB+1 + LDA MPTMPA+2 + STA SAVPTB+2 + SEC ;DISCOVER HOW MUCH NEEDS TO BE ALLOCATED + LDA DIVTMP + SBC MPTMPB + STA DIVTMP + LDA DIVTMP+1 + SBC MPTMPB+1 + STA DIVTMP+1 + LDA DIVTMP+2 + SBC MPTMPB+2 + STA DIVTMP+2 + LDYIM MPCYMP ;GET ADDRESS OF CYLINDER MAP + LDAIY MAPPTR + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 + SEC + LDYIM 0 ; CHECK IF THERE IS ENOUGH SPACE + LDAIY MAPGEN + SBC DIVTMP + STAIY MAPGEN + INY + LDAIY MAPGEN + SBC DIVTMP+1 + STAIY MAPGEN + INY + LDAIY MAPGEN + SBC DIVTMP+2 + STAIY MAPGEN + BCS #10 + JMP #50 ; BRANCH IF THERE IS NO ROOM +10 LDA SAVPTA + CMPIM MBENTS + BNE #20 + LDA SAVPTA+1 + BEQ #30 ; EMPTY MAP BLOCK SO ALLOCATE FROM SIN +20 SEC + LDA MPMBPT + PHA + SBCIM :LSB:ENSZ + STA MPMBPT + LDA MPMBPT+1 + PHA + SBCIM :MSB:ENSZ + STA MPMBPT+1 + LDYIM 0 ; GET A CURRENT DISC ADDRESS + LDAIY MPMBPT + STA MPTMPA + INY + LDAIY MPMBPT + STA MPTMPA+1 + INY + LDAIY MPMBPT + STA MPTMPA+2 + PLA + STA MPMBPT+1 ;**1/7/88** restore pointer + PLA + STA MPMBPT +30 JSR DIVSEC ; FIND CYLINDER FROM SIN + LDA MPTMPB ;GET CYLINDER TO SOMEWHERE USEFUL + STA MPTMPC + LDA MPTMPB+1 + STA MPTMPC+1 + JSR GTCYPS ; FIND A CLOSE CYLINDER WITH FREE BLOCKS + LDA MPTMPE + STA MPTMPC + LDA MPTMPE+1 + STA MPTMPC+1 + JSR RDBTMP + BNE #55 ;**23/2/87** Failed, attempt to report error + LDA MAPGEN + STA MPCYPT ; READY TO ALLOCATE BLOCKS + LDA MAPGEN+1 + STA MPCYPT+1 + JSR ABLKS ; ALLOCATE ONE LOT OF BLOCKS + BCS #40 ; BRANCH IF FAILED + LDA DIVTMP + ORA DIVTMP+1 + ORA DIVTMP+2 + BEQ CSEND ; CHECK IF FINISHED + JSR FLBLKS ; FILL IN THE REST OF THE BLOCKS + BCS #40 ; BRANCH IF ALL WENT WELL + JSR ENSBM + JMP CSEND + +40 LDA SAVPTB ; IT FAILED SO DEALLOCATE ANY BLOCKS STILL ALLOCATED + STA MPTMPA ; GET SIN BACK + LDA SAVPTB+1 + STA MPTMPA+1 + LDA SAVPTB+2 + STA MPTMPA+2 + LDA SAVPTA ; GET OFFSET BACK + STA MPSCPT + LDA SAVPTA+1 + STA MPSCPT+1 + LDAIM 0 + STA MPTMPE ; LEAVE CURRENT MAP BLOCK ALONE + JSR CLRBLK ; TIDY UP +50 CLC + LDYIM 0 + LDAIY MAPGEN + ADC DIVTMP + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC DIVTMP+1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC DIVTMP+2 + STAIY MAPGEN + LDA ERRTYP + BEQ #60 + LDAIM MPERRC +55 BNE MPCHEN + +60 LDAIM MPERRB ; FLAG NO ROOM + BNE MPCHEN + +CSEND JSR RDmpbd ;**8/5/87** Read block at ARGD + LDA MAPTMP + STA MPMBPT + STA CBSTA + LDA MAPTMP+1 + STA MPMBPT+1 + STA CBSTA+1 + LDYIM BILB ; POSITION OF ODD BYTES + LDA DIVPAR ; BYTES FROM DIVISION + STAIY MPMBPT + INY + LDA DIVPAR+1 + STAIY MPMBPT + JSR MMBWT + JSR ENSMB + JSR ENSBM + LDAIM 0 ; INDICATE SUCCESS + +MPCHEN BNE #80 + LDYIM ARGA + LDAIY ARGPTR + EORIM 14 ;detect special case + BEQ #80 + LDYIM ARGJ + LDAIM 0 + JSR MPSETF +80 JMP MPEXIT + +;MPREST: +;FUNCTION: LOADS THE MAP TABLE FROM DISC. +;CHECKS THAT ALL MAPS ARE O.K. ALSO +;SETS UP TABLE FOR FREE STORE MANAGEMENT + +MPREST ROUT ;CLEAR ALL VARS. + LDAIM 0 + STA ERRTYP + STA MAPTMP + STA MAPTMP+1 + STA MPTMPA + STA MPTMPA+1 + STA MPTMPB + LDX DRIVES ;FOR LOOP + LDYIM MPTBSZ + JSR SETTAB ;SET MAP TABLE AND CLEAR STORE + STY MAPTB + STY MAPPTR + STX MAPTB+1 + STX MAPPTR+1 + + LDXIM NTSIZE + LDYIM NTENSZ + JSR SETTAB ;SET NAME TABLE + STY NAMETB + STX NAMETB+1 + + STY DNMPTR + STX DNMPTR+1 + LDXIM NTSIZE + LDAIM UNUSED + LDYIM NTUSED + +;MARK ALL NAME TABLE ENTRIES UNUSED + +10 STAIY DNMPTR + PHA + JSR INAMPT + PLA + DEX + BNE #10 + + LDXIM 1 + STX NXTDNO + DEX + STX NXTDNO+1 ;SET DISC ALLOCATION NO. + JSR INBKMN + + LDAIM 0 + STA MPDRVE + STA LDRNB +20 LDA FREPTR + STA MPSCPT ;GENERAL PTR. TO SEC. ZERO DATA + LDA FREPTR+1 + STA MPSCPT+1 + LDA MPDRVE + STA DRIVNO + + JSR RDDATA ;GET INFO FROM DISC + BNE #50 ;Ignore if disc error ** 14/06/86 ** + JSR CHKDSC ;CHECK IS FS DISC + BNE #50 ;NOPE, ISN'T + +;NOW SET MAP TABLE ENTRY FOR THIS DRIVE + + JSR SMAPEN + + JSR CHDNAM ;PUT IN NAME TABLE + BEQ #30 +25 LDAIM 0 ;Couldn't (duplicate disc name??) + LDYIM Mpnocy + STAIY Mapptr ;... so mark map entry unused + INY + STAIY Mapptr ;by saying it has no cylinders + BNE #50 ; ** 14/10/86 ** + +;NOW CREATE CYLINDER MAP FOR THIS DISC'S MAP +30 JSR MPRESZ ;**5/3/88** get number of cylinders + CLC ;NOW INCREASE SIZE TO HOLD FREE SPACE COUNT + LDA MPTMPB + ADCIM 3 + TAY + LDA MPTMPB+1 + ADCIM 0 + TAX + JSR GETVEC ;get space for cylinder map + TYA ; SAVE ADDRESS OF CY.MAP + LDYIM MPCYMP + STAIY MAPPTR + INY + TXA + STAIY MAPPTR + JSR MPSTCY + LDYIM MPADFT + CLC +50 INC MPDRVE ; ** 14/06/86 ** drives contiguously numbered + JSR MPADMP + INC LDRNB + LDA LDRNB + CMP DRIVES + BNE #20 + LDAIM 0 ;RC + JMP MPEXIT + +MPRESZ ROUT ;**5/3/88*** calculate number of cylinders + JSR MPMPSZ ;total number of sectors + LDAIM 0 + STA MPTMPB + STA MPTMPB+1 + LDYIM MPDSCS + LDAIY MAPPTR + TAX +10 LDYIM MPNOCY + CLC + LDAIY MAPPTR + ADC MPTMPB + STA MPTMPB + INY + LDAIY MAPPTR + ADC MPTMPB+1 + STA MPTMPB+1 + DEX + BNE #10 + STAIY MAPPTR ;restore total count + DEY + LDA MPTMPB + STAIY MAPPTR + CLC + ROL MPTMPB ;multiply cyls by two + ROL MPTMPB+1 + RTS + +;MPSZIN: RETURNS THE LENGTH OF A CHAIN IN BYTES AND BLOCKS + +;ENTRY: +;ARGB-C DISC NO +;ARGD-F SIN + +;EXIT: +;ARGA = RC +;ARGB-D SIZE IN BYTES +;ARGE-F SIZE IN BLOCKS + +;FUNCTION: GETS THE RELEVANT ENTRY IN MAPTB. CHECKS THAT +;THE SIN POINTS TO THE START OF A CHAIN. RETURNS THE LENGTH OF THE CHAIN. + +MPSZIN ROUT + JSR FNDMAP ;GET MAP TO MAPPTR + BNE #20 + JSR RDmpbd ;**8/5/87** Read block at ARGD + BEQ #10 + LDAIM MPERRC ;ERROR RETURN OF NOT START + BNE #20 ;AND RETURN + +10 LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + JSR MPGTSZ ;GET SIZE OF MAP + LDYIM ARGB + LDA MPTMPA ;SIZE IS IN MPTMPA + STAIY ARGPTR + INY + LDA MPTMPA+1 + STAIY ARGPTR + INY + LDA MPTMPA+2 + STAIY ARGPTR + LDYIM ARGE + LDA MPTMPD + STAIY ARGPTR ;SAVE NUMBER OF BLOCKS + INY + LDA MPTMPD+1 + STAIY ARGPTR + LDAIM 0 ;RC +20 JMP MPEXIT + +;MPSNRT: RETURNS THE SIN OF THE ROOT DIRECTORY +;ENTRY: +;ARGB-C DISC NO + +;EXIT: +;ARGA = RC +;ARGB-D SIN OF ROOT DIRECTORY +;ARGE-F DATE ROOT CREATED + + +MPSNRT ROUT + JSR FNDMAP + BNE #30 + LDYIM MPRTSN +10 LDAIY MAPPTR + PHA + INY + CPYIM MPRTSN+5 + BNE #10 + + LDYIM ARGF +20 PLA + STAIY ARGPTR + DEY + CPYIM ARGA + BNE #20 + + LDAIM 0 +30 JMP MPEXIT + + LNK UADE11 diff --git a/Level3/SRC/L3/Uade11 b/Level3/SRC/L3/Uade11 new file mode 100644 index 0000000..ebe5b81 --- /dev/null +++ b/Level3/SRC/L3/Uade11 @@ -0,0 +1,1174 @@ + OPT UADE11 ;> Uade11 + TTL File server file UADE11 + +;************************ +;* Restart one drive * +;* Disc number -> name * +;* Disc name -> number * +;* * +;* U T I L I T I E S * +;************************ + + +;MPFRSP: FREE SPACE + +;ENTRY: +;ARGB-C DISC NUMBER +;ARGD-F SIN +;ARGG-H Ptr to user info + +;EXIT: ARGA = RC + +;FUNCTION: MAPTB IS SEARCHED TO FIND THE RELEVANT ENTRY. IF THE SECTOR +;MAP IS NOT IN STORE IT IS READ IN. THE SIN IS CHECKED TO ENSURE THAT IT +;POINTS TO THE FIRST BLOCK OF THE CHAIN. ALL THE SECTORS ON THE CHAIN ARE +;THEN ADDED TO THE FREE CHAIN. THE FREE SECTOR COUNT IS THEN ADJUSTED. THE +;DIRTY FLAG FOR THE SECTOR MAP IS SET. + +MPFRSP ROUT + JSR FNDMAP ;GET CURRENT MAP TABLE POSITION + BNE #10 + + LDAIM 0 + STA ERRTYP + STA DNDLTE + + LDYIM ARGG + JSR MPFRAD + BNE #10 + + JSR MPDLTE + BNE #10 + JSR ENSMB + JSR ENSBM + LDAIM 0 ; REPLY ZERO +10 LDYIM ARGG + JSR MPSETF + JMP MPEXIT + + +;MPREDR: *** RESTART ONE DRIVE ** + +;ENTRY: ARGB = DRIVE NO. + +;EXIT: ARGA = RC + +MPREDR ROUT + LDAIM 0 + STA ERRTYP + LDA BBUF + STA DSCCB+TRADD ;SET UP AREA TO READ IN SECTOR TWO + STA MPSCPT + LDA BBUF+1 + STA DSCCB+TRADD+1 + STA MPSCPT+1 + + LDYIM ARGB + LDAIY ARGPTR + STA CURDRV ;SET CURRENT DRIVE + STA MPDRVE + + JSR RDSTWO ;GET SECTOR ZERO TO BIG BUFFER + BNE #20 ;**6/7/88** + + JSR CHKDSC ;CHECK DISC IS FS DISC + BNE #20 + JSR SMPPTR ;SET POINTER TO RELEVANT MAPTAB ENTRY + +;Store old MAPTB entry, so that if an error +;occurs, MAPTB can be replaced. +; Having stored old MAPTB entry, replace with stuff +;from sector zero. + + LDYIM MPDCNO +10 LDAIY MAPPTR + STAAY MAPTBF-MPDCNO + INY + CPYIM MPTBSZ + BNE #10 + + JSR SMAPEN ;Move sector zero info. from BBUF + + JSR MPRESZ ;**5/3/88** Get size of disc + JSR CHMPSZ ;CHECK MAP WILL FIT IN AVAILABLE SPACE + BNE #30 + + JSR MPSTCY ;SET CORRECT MAP (MOST RECENT) + + JSR AGENTB ;AGE NAME TABLE + + LDA BBUF + STA MPSCPT + LDA BBUF+1 + STA MPSCPT+1 ;CHMAPS destroys MPSCPT + + LDA MAPTBF + STA CURDSC ;Set disc no. for FNDDNO + LDA MAPTBF+1 + STA CURDSC+1 + JSR FNDDNO ;Find name table entry of old disc + LDAIM UNUSED + LDYIM NTUSED + STAIY DNMPTR ;Mark old disc unused + + JSR CHDNAM ;CHECK DISC NAME AND PUT IN NAME TABLE + BNE #30 ;POSSIBLY NOT UNIQUE DISC + + LDAIM 0 ;=> Success +20 JMP MPEXIT ;*** EXIT ** + +30 PHA ;Error exit !! + LDYIM MPTBSZ-1 +40 LDAAY MAPTBF + STAIY MAPPTR ;Restore MAPTB information, + DEY ;so that state is as before + BPL #40 + PLA + JMP #20 + +;MPDRNB: + +;ENTRY: ARGB-C DISC NUMBER + +;EXIT: ARGA = RC +;ARGB DRIVE NUMBER + +;FUNCTION: finds the relevant entry +;in MAPTB and returns the drive number currently +;containing that disc (if any) + +MPDRNB ROUT + JSR FNDMAP ;to find disc number + PHA + LDYIM ARGB ;save possible answer + LDA MPDRVE + STAIY ARGPTR + PLA + JMP MPEXIT + +;MPDSNB: + +;ENTRY: ARGB = DRIVE NUMBER + +;EXIT: ARGA = RC +;ARGB-C DISC NUMBER + +;FUNCTION: FINDS THE RELEVANT ENTRY +;IN MAPTB AND RETURNS THE DISC NUMBER CURRENTLY +;ON THAT DRIVE. + +MPDSNB ROUT + LDYIM ARGB ;TO FIND DRIVE NUMBER + LDAIY ARGPTR + CMP DRIVES + BCS #10 ;BRANCH IF LEG PULL + STA CURDRV + JSR SMPPTR + LDYIM MPNOCY ; ** 14/06/86 ** Unless disc has cyls ... + LDAIY MAPPTR + INY + ORAIY MAPPTR + BEQ #10 ; ** 14/06/86 ** It is a gap between drives + +;ENTRY FOUND SO LOOK AT IT + LDYIM MPDCNO ;FOR DISC NUMBER + LDAIY MAPPTR + LDYIM ARGB ;TO SAVE IT FOR RETURN + STAIY ARGPTR + LDYIM MPDCNO+1 + LDAIY MAPPTR + LDYIM ARGC + STAIY ARGPTR + LDAIM 0 ;RC + BEQ #20 + +10 LDAIM MPERRF +20 JMP MPEXIT + +;MPDNNA + +;ENTRY: ARGB-C PTR TO DISC NAME + +;EXIT : ARGB-C DISC NO. + +MPDNNA ROUT + LDYIM ARGB + LDAIY ARGPTR + STA GENPTR + INY + LDAIY ARGPTR + STA GENPTR+1 + LDYIM 0 + + LDAIY GENPTR + CMPIM CR + BNE #10 + LDAIM MPERRK + BNE #50 ;null disc name + +10 LDAIY GENPTR + CMPIM CR + BEQ #20 ;ARG. IS TERMINATED CR, SO NEEDS PADDING + STAAY DNMBUF + INY + JMP #10 + +20 LDAIM SPACE +30 CPYIM DNAMLN ;CONTINUE PADDING ? + BCS #40 ;NOPE, Y>=DNAMLN + STAAY DNMBUF ;YEP, CONTINUE + INY + BNE #30 + +40 JSR FNDNAM ;LOOK UP NAME IN NAME TABLE + BNE #50 ;NOT FOUND ... + + LDYIM NTDNO + LDAIY DNMPTR + PHA + INY + LDAIY DNMPTR + LDYIM ARGC + + STAIY ARGPTR + PLA + DEY + STAIY ARGPTR + LDAIM 0 + +50 JMP MPEXIT + + +;MPNADN + +;** DISC NO. -> DISC NAME ** + +;ENTRY: ARGB-C DISC NO. + +;EXIT: ARGB-C PTR. TO NAME + +MPNADN ROUT + LDYIM ARGB + LDAIY ARGPTR + STA CURDSC + INY + LDAIY ARGPTR + STA CURDSC+1 + + JSR FNDDNO + BEQ #10 + + LDAIM MPERRA ;DISC NO. NOT FOUND + BNE #20 + +10 LDYIM ARGB + CLC + LDA DNMPTR + ADCIM NTNAME + STAIY ARGPTR + INY + LDA DNMPTR+1 + ADCIM 0 + STAIY ARGPTR + LDAIM 0 ;OK EXIT ... + +20 JMP MPEXIT + +;MPFREE +; RETURN SIZE OF FREE CHAIN +; +; Entry: +; ARGB-C DISC NO +; +; Exit: +; ARGB-D SIZE +; ARGE-G TOTAL SPACE + +MPFREE ROUT + JSR FNDMAP ;GET MAP TO STORE + BNE #10 + LDYIM MPCYMP + LDAIY MAPPTR + STA MPCYPT + INY + LDAIY MAPPTR + STA MPCYPT+1 + LDYIM 0 + LDAIY MPCYPT ;GET FREE SPACE + STA MPTMPA + INY + LDAIY MPCYPT + STA MPTMPA+1 + INY + LDAIY MPCYPT + STA MPTMPA+2 + LDYIM ARGB + LDA MPTMPA + STAIY ARGPTR + INY + LDA MPTMPA+1 + STAIY ARGPTR + INY + LDA MPTMPA+2 + STAIY ARGPTR + LDYIM MPSCTT + LDAIY MAPPTR + STA MPTMPA + INY + LDAIY MAPPTR + STA MPTMPA+1 + INY + LDAIY MAPPTR + LDYIM ARGG + STAIY ARGPTR + DEY + LDA MPTMPA+1 + STAIY ARGPTR + DEY + LDA MPTMPA + STAIY ARGPTR + LDAIM 0 +10 JMP MPEXIT + +;MPZDSK: ZERO AREA OF DISC +; +;ENTRY: +;ARGB-C DISC NUMBER +;ARGD-F SIN +;ARGG-I OLD SIZE +; +;EXIT: ARGA = RC + +MPZDSK ROUT + JSR MPsetd ;**8/5/87** MPTMPA = ARGD + LDAIY ARGPTR + STA OLDSZE + INY + LDAIY ARGPTR + STA OLDSZE+1 + INY + LDAIY ARGPTR + STA OLDSZE+2 + LDAIM 0 + STA OLDSZE+3 + JSR ZERDSK + JMP MPEXIT + +;********************************** +;* M A P M A N * +;* U T I L I T I E S * +;********************************** + + + +; READS THE SPECIFIED BIT MAP INTO STORE +; +; ON ENTRY +; MAPPTR points to map table entry +; MPTMPC IS CYLINDER NUMBER OF BIT MAP +; +; ON EXIT +; MPSCPT points to first byte of bit map +; MPSCOR points to first byte of bit map sector + +RDBTMP ROUT ;READ BIT MAP + LDAIM 0 + STA CBSIN ;ZERO OUT SIN + STA CBSIN+1 + STA CBSIN+2 + STA MPSCPT + STA MPSCPT+1 + LDYIM MP1BIT + LDAIY MAPPTR ;**23/1/87** See if packed bitmap + BNE #60 + LDA MPTMPC ;GET CYLINDER NUMBER + STA CBTPPT ;SAVE FOR DECREMENTING + LDA MPTMPC+1 + STA CBTPPT+1 + JSR #90 ;**23/1/87** Calculate SIN of bit map +20 JSR SETBM ;**23/1/87** FOUND SO SET SIZE OF BIT MAP CHAIN + JSR GTBTS ;READ IN BLOCK IF NECESSARY + BNE #50 ;NON-ZERO IF FAILED + CLC + LDA CBSTA ;GET STORE ADDRESS + STA MPSCOR ;**23/1/87** AND SAVE FOR RETURN + ADC MPSCPT + STA MPSCPT ;**23/1/87** calculate offset start + LDA CBSTA+1 + STA MPSCOR+1 + ADC MPSCPT+1 + STA MPSCPT+1 + LDA ERRTYP + BEQ #40 + LDA RSTFLG + BNE #30 + LDAIM IERRAJ + JSR INTERR +30 LDA CBSTA + STA CLRPTR + LDA CBSTA+1 + STA CLRPTR+1 + LDYIM 0 + LDXIM 1 + JSR CLRSTR +40 LDAIM 0 +50 RTS + +60 LDYIM MPSCYL ;**23/1/87** packed bit map code + LDAIY MAPPTR ;calculate SIN of packed map + STA CBTPPT + INY + LDAIY MAPPTR + STA CBTPPT+1 + JSR #90 + LDA MPTMPC ;get cylinder number + STA CBTPPT + LDA MPTMPC+1 + STA CBTPPT+1 +70 LDA CBTPPT ;see if sector/offset found + ORA CBTPPT+1 + BEQ #20 ;yes, go read bit map sector + LDA CBTPPT + BNE #75 + DEC CBTPPT+1 +75 DEC CBTPPT ;count through cylinders + LDYIM MP1BIT + CLC + LDA MPSCPT ;calculate offset + ADCIY MAPPTR + BEQ #80 + STA MPSCPT + ADCIY MAPPTR ;entry must not cross sector bdry + BCC #70 + BEQ #70 ;exact fit allowed ok +80 LDAIM 0 + STA MPSCPT ;flows or new sector + INC CBSIN + BNE #70 + INC CBSIN+1 + BNE #70 + INC CBSIN+2 + JMP #70 + +90 LDA CBTPPT ;CHECK IF CYLINDER FOUND + ORA CBTPPT+1 + BEQ #50 ; FOUND SO GO AND READ IN + LDYIM MPSPCY + CLC + LDA CBSIN + ADCIY MAPPTR + STA CBSIN + INY + LDA CBSIN+1 ;GET TO NEXT BIT MAP + ADCIY MAPPTR + STA CBSIN+1 + BCC #95 + INC CBSIN+2 +95 LDA CBTPPT ; DECREMENT CYLINDER COUNTER + BNE #96 + DEC CBTPPT+1 +96 DEC CBTPPT + JMP #90 + +; +; READ THE BLOCK SPECIFIED AT ARGD INTO STORE +; +RDmpbd ROUT + JSR MPsetd ;**8/5/87** MPTMPA = ARGD + CLC ;**8/5/87** fall into RDMPBK + +; +; READ THE SPECIFIED MAP BLOCK INTO STORE +; +; ON ENTRY +; MPTMPA HOLDS SIN +; CARRY SET IF BLOCK NOT TO BE READ IN +; +; ON EXIT +; MAPTMP HOLDS POINTER +; +RDMPBK ROUT ;READ IN MAP BLOCK + PHP ;SAVE STATE OF CARRY FLAG + LDA MPTMPA ;GET SIN TO RIGHT PLACE + STA CBSIN + LDA MPTMPA+1 + STA CBSIN+1 + LDA MPTMPA+2 + STA CBSIN+2 + JSR SETMB ;**1/7/88** + PLP ;GET CARRY FLAG BACK + BCS #30 ;BRANCH IF NOT TO BE READ IN + JSR GTBTS ; GET THE MAP BLOCK TO STORE + BNE #20 ; NON-ZERO IF FAILED + LDA CBSTA ;SAVE ADDRESS IN CORRECT PLACE + STA MAPTMP + STA GNCBPT + LDA CBSTA+1 + STA MAPTMP+1 + STA GNCBPT+1 + LDYIM MBSQNO ;POINT TO FIRST SEQUNCE NUMBER + LDAIY GNCBPT + TAX + CLC + LDA GNCBPT + ADCIM :LSB:LSTSQ + STA GNCBPT + LDA GNCBPT+1 + ADCIM :MSB:LSTSQ + STA GNCBPT+1 + LDYIM 0 + TXA + CMPIY GNCBPT ;COMPARE WITH LAST NUMBER + BEQ #10 + LDAIM MPERRC + RTS + +10 LDAIM 0 +20 RTS + +30 JSR FNDMB + BCC #40 + LDYIM CBSA + JMP #50 + +40 JSR GETFR ;JUST FIND A FREE SPACE + BNE #20 + LDYIM CBDR + LDA MPDRVE + STAIY GNCBPT + LDYIM CAFLG + LDAIY GNCBPT + ORAIM 1 ;FLAG ALLOCATED + STAIY GNCBPT + INY + LDA MPTMPA + STAIY GNCBPT + INY + LDA MPTMPA+1 + STAIY GNCBPT + INY + LDA MPTMPA+2 + STAIY GNCBPT + INY +50 LDAIY GNCBPT ;GET ADDRESS OF FREE STORE + STA MAPTMP + STA CLRPTR + INY + LDAIY GNCBPT + STA MAPTMP+1 + STA CLRPTR+1 + LDYIM :LSB:BTINBK + LDXIM :MSB:BTINBK + JSR CLRSTR ;CLEAR MAP BLOCK TO ZEROES SINCE NOT READ IN + JMP #10 + +; CALCULATE THE NUMBER OF SECTORS REQUIRED FROM +; THE NUMBER OF BYTES REQUIRED. +; +; ON ENTRY +; DIVPAR HOLDS THE NUMBER OF BYTES +; +; ON EXIT +; DIVPAR HOLDS ODD BYTES +; DIVTMP HOLDS THE NUMBER OF BLOCKS +; Carry Set if Overflow +; +DVDE ROUT + LDAIM 0 + STA DIVTMP + STA DIVTMP+1 + STA DIVTMP+2 + LDA DIVPAR + ORA DIVPAR+1 + ORA DIVPAR+2 + BEQ #40 +10 SEC ;NOW LOOP DO DIVIDE BY BLOCK SIZE + LDA DIVPAR + SBCIM :LSB:BTINBK + STA DIVPAR + LDA DIVPAR+1 + SBCIM :MSB:BTINBK + STA DIVPAR+1 + LDA DIVPAR+2 + SBCIM 0 + STA DIVPAR+2 + BCC #20 ;CARRY CLEAR AT END OF DIVISION + LDA DIVPAR + ORA DIVPAR+1 + ORA DIVPAR+2 + BEQ #30 + INC DIVTMP + BNE #10 + INC DIVTMP+1 + JMP #10 + +20 LDA DIVPAR ;REPLACE LOWER BYTE + ADCIM :LSB:BTINBK + STA DIVPAR + LDA DIVPAR+1 + ADCIM :MSB:BTINBK + STA DIVPAR+1 + BCC #30 + INC DIVPAR+2 +30 CLC + LDA DIVTMP + ADCIM 2 ;AT LEAST TWO BLOCKS LONG + STA DIVTMP + BCC #45 + INC DIVTMP+1 + BNE #45 + INC DIVTMP+2 + BNE #45 + SEC + RTS + +40 INC DIVTMP +45 CLC + RTS + + + +;GETPOS +; FINDS NEXT FREE POSITION IN MAP BLOCK +; SETS CARRY FLAG IF MAP BLOCK FULL +; +; ON ENTRY +; MAPGEN POINTS TO START OF MAP BLOCK +; +; ON EXIT +; MAPGEN POINTS TO NEXT FREE POSITION +; +; USES +; MPTMPE +; +GETPOS ROUT + CLC + LDA MAPGEN + ADCIM :LSB:MBENTS ;GET MAPGEN TO START OF ENTRIES + STA MAPGEN + LDA MAPGEN+1 + ADCIM :MSB:MBENTS + STA MAPGEN+1 + LDAIM 0 + STA MPTMPE + STA MPTMPE+1 ;CLEAR VARIABLES +10 LDA MPTMPE + CMPIM :LSB:(MXENTS-1) ;CHECK FOR END OF LIST + LDA MPTMPE+1 + SBCIM :MSB:(MXENTS-1) + BCS #50 ;RETURNS WITH CARRY SET IF END OF LIST + LDYIM 0 ;Y POINTS AT SIN + LDAIY MAPGEN + BNE #30 ;ZERO IS END OF LIST + INY + LDAIY MAPGEN + BNE #30 + INY + LDAIY MAPGEN + BEQ #40 +30 CLC ;LOOK AT NEXT ENTRY + LDA MAPGEN + ADCIM ENSZ + STA MAPGEN + BCC #35 + INC MAPGEN+1 +35 INC MPTMPE ;MPTMPE HOLDS NUMBER OF ENTRIES WE'VE LOOKED AT + BNE #10 + INC MPTMPE+1 + JMP #10 + +40 CLC +50 RTS ;RETURNS HERE WITH CARRY CLEAR, ALL OK, SET IF NOT. + +; GET CYLINDER MAP POSITION +; +; STARTS A SEARCH FROM MPTMPC FOR THE NEXT +; CYLINDER WITH A FREE SECTOR +; +; ON ENTRY +; MPTMPC HOLDS THE CURRENT CYLINDER +; MAPGEN POINTS TO START OF CYLINDER MAP +; MAPPTR POINTS TO MABTB ENTRY +; +; ON EXIT +; MAPGEN POINTS TO CYLINDER WITH FREE ENTRY +; +; USES MPTMPE + +GTCYPS ROUT + LDA MPTMPC + ASLA + STA MPTMPE ;**1/7/88** current position*2 + LDA MPTMPC+1 + ROLA + STA MPTMPE+1 + CLC + LDA MAPGEN ;POINT TO START OF MAP + ADCIM 3 + STA MAPGEN + BCC #10 + INC MAPGEN+1 +10 CLC + LDA MAPGEN ;**1/7/88** add offset to cylinder + ADC MPTMPE + STA MAPGEN + LDA MAPGEN+1 + ADC MPTMPE+1 + STA MAPGEN+1 + LSR MPTMPE+1 + ROR MPTMPE + +30 LDYIM 0 ;NOW LOOK FOR POSITION WITH FREE BLOCK + LDAIY MAPGEN + INY + ORAIY MAPGEN + BNE #50 ;FOUND IF NON ZERO + INC MPTMPE + BNE #32 + INC MPTMPE+1 +32 LDA MPTMPE + LDYIM MPNOCY ;CHECK FOR END OF CYCLINDER MAP + CMPIY MAPPTR + INY + LDA MPTMPE+1 + SBCIY MAPPTR + BCS #40 + LDAIM 2 ;NOT END SO LOOK AT NEXT ENTRY +35 CLC + ADC MAPGEN + STA MAPGEN + BCC #30 + INC MAPGEN+1 + JMP #30 + +40 LDAIM 0 + STA MPTMPE ;END SO BACK TO BEGINNING + STA MPTMPE+1 + LDYIM MPCYMP + LDAIY MAPPTR ;GET START OF CYLINDER MAP + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 + LDAIM 3 ;GET POINTER TO START OF ENTRIES + BNE #35 + +50 RTS + +; FIND CYLINDER +; +; FINDS THE CYCLINDER WITH THE LARGEST AMOUNT +; OF FREE SPACE +; +; ON ENTRY +; MPCYPT POINTS TO START OF CYLINDER MAP +; +; ON EXIT +; MPCYPT POINTS TO CYLINDER FOUND +; +; USES MAPTMP MPTMPA MPTMPB + +FNDCY ROUT + LDAIM 0 + STA MAPTMP ;ZERO VALUES + STA MAPTMP+1 + STA MPTMPA + STA MPTMPA+1 + STA MPTMPC + STA MPTMPC+1 + CLC + LDA MPCYPT ;GET TO START OF ENTRIES + ADCIM 3 + STA MPCYPT + STA MPTMPB + LDA MPCYPT+1 + ADCIM 0 + STA MPCYPT+1 + STA MPTMPB+1 +10 LDYIM 0 ;NOW SCAN ENTRIES FOR LARGEST + LDA MAPTMP + CMPIY MPCYPT + INY + LDA MAPTMP+1 + SBCIY MPCYPT ; MAPTMP HOLDS LARGEST SO FAR + BCS #20 ;BRANCH IF NOT LARGER + LDAIY MPCYPT + STA MAPTMP+1 + DEY + LDAIY MPCYPT + STA MAPTMP + LDA MPCYPT ;SAVE POSITION + STA MPTMPB + LDA MPCYPT+1 + STA MPTMPB+1 + LDA MPTMPA + STA MPTMPC ;SAVE CYLINDER NUMBER + LDA MPTMPA+1 + STA MPTMPC+1 +20 CLC + LDA MPCYPT ;MOVE TO NEXT ENTRY + ADCIM 2 + STA MPCYPT + BCC #25 + INC MPCYPT+1 +25 INC MPTMPA + BNE #30 + INC MPTMPA+1 +30 LDYIM MPNOCY ;CHECK FOR END OF MAP + LDAIY MAPPTR + CMP MPTMPA + BNE #10 + INY + LDAIY MAPPTR + CMP MPTMPA+1 + BNE #10 + LDA MPTMPB ;END SO RETURN POINTER + STA MPCYPT + LDA MPTMPB+1 + STA MPCYPT+1 + RTS + +; RETURNS THE SIZE OF A BLOCK OF STORE +; +; ON ENTRY +; MPSCPT POINTS TO BIT MAP +; +; ON EXIT +; MPTMPD HOLDS THE SIZE +; +; USES MPTMPE +; +SIZE ROUT + LDYIM MPSPCY + LDAIY MAPPTR + STA TMPSPC + INY + LDAIY MAPPTR + STA TMPSPC+1 + LDAIM 0 + STA MPTMPD ;CLEAR VARIABLES + STA MPTMPD+1 + STA MPTMPE + STA MPTMPE+1 + LDYIM 0 +10 LDAIY MPSCPT + BEQ #80 ;NO FREE BITS IN THIS PART + LDXIM 8 ;LOOK AT ALL EIGHT BITS +20 RORA ;GET BIT INTO CARRY + PHA + BCC #70 ;CLEAR SO CHECK FOR END + INC MPTMPD + BNE #30 ;KEEP A COUNT OF SECTORS + INC MPTMPD+1 +30 INC MPTMPE + BNE #40 + INC MPTMPE+1 ;AND CHECK HOW MANY BITS WE'VE LOOKED AT +40 JSR TESTME ;**23/1/87** check for end of map + BCC #60 + LDA MPTMPD + ORA MPTMPD+1 + BNE #50 +48 LDAIM &F6 + JSR INTERR +50 PLA ;GET BIT MAP VALUE BACK +55 RTS + +60 PLA + DEX + BNE #20 +65 INY + JMP #10 + +70 LDA MPTMPD + ORA MPTMPD+1 + BNE #50 ;END IF ALREADY SOME COUNT + BEQ #30 + +80 LDA MPTMPD + ORA MPTMPD+1 + BNE #55 + CLC + LDA MPTMPE + ADCIM 8 ;LOOK AT NEXT BYTE OF MAP + STA MPTMPE + BCC #85 + INC MPTMPE+1 +85 JSR TESTME ;**23/1/87** test for end of map + BCC #65 + BCS #48 + +; FILL BLOCKS +; ALLOCATES REST OF BLOCKS THAT ARE REQUIRED +; +; ON ENTRY +; DIVTMP HOLDS SIZE +; MPSCPT POINTS TO CURRENT BIT MAP +; MPTMPC HOLDS CYLINDER NUMBER +; MAPTMP POINTS TO MAP BLOCK +; MAPPTR POINTS TO MAP TABLE +; MPCYPT POINTS TO POSITION IN CYLINDER MAP +; +; ON EXIT +; C SET IF FAILED +; + +FLBLKS ROUT + LDA DIVTMP ;CHECK IF ALL BLOCKS ALLOCATED + ORA DIVTMP+1 + ORA DIVTMP+2 + BEQ #40 + JSR GETBIT ;FIND FIRST FREE BLOCK + BCS #10 ;NONE LEFT SO GET NEXT TRACK + JSR ABLKS ;ALLOCATE THESE BLOCKS + BCC FLBLKS ;KEEP ALLOCATING BLOCKS UNTIL NONE LEFT + LDA ERRTYP + BEQ #10 +00 SEC + RTS + +10 INC MPTMPC + BNE #20 + INC MPTMPC+1 +20 LDA MPTMPC ;GET NEXT BIT MAP + LDYIM MPNOCY ; CHECK FOR END + CMPIY MAPPTR + INY + LDA MPTMPC+1 + SBCIY MAPPTR + BCS #30 + CLC + LDA MPCYPT ;KEEP CYLINDER MAP POINTER UP TO DATE + ADCIM 2 + STA MPCYPT + BCC #25 + INC MPCYPT+1 +25 LDYIM 0 + LDAIY MPCYPT + INY + ORAIY MPCYPT + BEQ #10 + JSR RDBTMP ; GET THE BIT MAP + BNE #00 ;**23/2/87** Failed + BEQ FLBLKS ; KEEP TRYING TO ALLOCATE + +30 LDAIM 0 + STA MPTMPC ;GO BACK TO THE BEGINNING + STA MPTMPC+1 + LDYIM MPCYMP ;RETURN CYLINDER MAP TO BEGINNING + CLC + LDAIY MAPPTR + ADCIM 1 + STA MPCYPT + INY + LDAIY MAPPTR + ADCIM 0 + STA MPCYPT+1 + JMP #20 + +40 CLC ;INDICATE OK + RTS + +; +; GET BIT +; FINDS THE FIRST FREE BIT IN THE BIT MAP +; +; ON ENTRY +; MPSCPT POINTS TO BIT MAP +; +; ON EXIT +; MPTMPE HOLDS BIT NUMBER +; C SET IF NOT BITS FOUND +; +GETBIT ROUT + LDYIM MPSPCY + LDAIY MAPPTR + STA TMPSPC + INY + LDAIY MAPPTR + STA TMPSPC+1 + LDYIM 0 + STY MPTMPE + STY MPTMPE+1 +10 LDAIY MPSCPT ; GET BYTE OF BIT MAP + BEQ #40 ; IF NONE FREE GET NEXT BYTE +20 RORA ; ROTATE UNTIL BIT FOUND + BCS #50 ; BRANCH WHEN FOUND + INC MPTMPE ;KEEP TRACK OF WHERE WE ARE + BNE #30 + INC MPTMPE+1 +30 PHA + JSR TESTME ;CHECK FOR END OF ENTRY + PLA + BCC #20 +40 CLC + LDA MPTMPE ;ADD 8 FOR THIS BYTE + ADCIM 8 + STA MPTMPE + BCC #45 + INC MPTMPE+1 +45 INY + JSR TESTME ; CHECK FOR END OF BIT MAP + BCC #10 + SEC ;WHEN NONE FOUND + RTS + +50 CLC + RTS + +; +; CHECK FOR END OF BIT MAP +; +TESTME LDA MPTMPE + CMP TMPSPC + LDA MPTMPE+1 + SBC TMPSPC+1 + RTS +; +; CORRECT THE CURRENT FREE BLOCK COUNT +; +; ON ENTRY +; MPTMPB HOLDS NUMBER OF BLOCKS +; MPTMPC HOLDS CYLINDER NUMBER +; MAPPTR POINTS TO MAP TABLE ENTRY +; +; USES MAPGEN +; +ADDFR ROUT + LDYIM MPCYMP + LDAIY MAPPTR + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 ;GET POINTER TO CYLINDER MAP + LDYIM 0 + CLC + LDAIY MAPGEN ;ADD TO FREE COUNT AT START + ADC MPTMPB + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC MPTMPB+1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC MPTMPB+2 + STAIY MAPGEN + CLC ; NOW FOUND CYLINDER POSITION + LDA MAPGEN + ADCIM 3 ;START OF ENTRIES + STA MAPGEN + BCC #05 + INC MAPGEN+1 +05 LDA MPTMPC + ORA MPTMPC+1 + BEQ #40 + LDX MPTMPC + LDY MPTMPC+1 + JMP #20 + +10 CLC + LDA MAPGEN + ADCIM 2 + STA MAPGEN + BCC #20 + INC MAPGEN+1 +20 CPXIM 0 + BEQ #30 + DEX + JMP #10 + +30 CPYIM 0 + BEQ #40 + DEX + DEY + JMP #10 + +40 LDYIM 0 + CLC ;NOW ADD THE NEW VALUES + LDAIY MAPGEN + ADC MPTMPB + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC MPTMPB+1 + STAIY MAPGEN + RTS + +MPMKFR ROUT + LDAIY ARGPTR ;form zero page pointer from supplied info + STA GENPTR + INY + LDAIY ARGPTR + STA GENPTR+1 +10 RTS + +MPSETF TAX + BNE #10 ;non-zero => dont update the free store + JSR MPMKFR + CLC + TAX + LDA GENPTR + ADCIM UTUSID + LDYIM ARGB + STAIY NEWARG + INY + BCC #20 + INX +20 TXA + STAIY NEWARG + + LDXIM :LSB:-4 +30 INY + LDAAX MPNWFR-:LSB:-4 ;write calculated new free space + STAIY NEWARG + INX + BNE #30 + LDAIM 9 + JSR SETRTN + JMP USRMAN + +MPsetd ROUT ;**8/5/87** Copy ARGD into MPTMPA + LDYIM ARGD + LDAIY ARGPTR + STA MPTMPA + INY + LDAIY ARGPTR + STA MPTMPA+1 + INY + LDAIY ARGPTR + STA MPTMPA+2 + INY ;exit with Y=ARGG + RTS + +MPFRAD ROUT + JSR MPMKFR ;setup pointer + JSR RDmpbd ;**8/5/87** Read block at ARGD + BNE #30 ;exit + + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + JSR MPGTSZ + + LDXIM :LSB:-3 + LDYIM UTFREE + CLC + +20 LDAIY GENPTR + ADCAX MPTMPA-:LSB:-3 + STAAX MPNWFR-:LSB:-3 ;save it away + INY + INX + BNE #20 + +;deal with extra length byte + + LDAIY GENPTR + ADCIM 0 ;'cos size only three bytes + STAAX MPNWFR+3 + + TXA ;return ok +30 RTS + + LNK UADE12 diff --git a/Level3/SRC/L3/Uade12 b/Level3/SRC/L3/Uade12 new file mode 100644 index 0000000..9cf72e1 --- /dev/null +++ b/Level3/SRC/L3/Uade12 @@ -0,0 +1,1149 @@ + OPT UADE12 ;> Uade12 + TTL File server file UADE12 + +;** MAPMAP UTILS II(2) ** + +;SET POINTER TO ENTRY IN MAP TABLE +;CORRESPONDING TO DRIVE IN CURDRV. +;POINTER IN BOTH MAPPTR AND MAPENT. + +SMPPTR ROUT + LDX CURDRV + LDA MAPTB + STA MAPPTR + LDA MAPTB+1 + STA MAPPTR+1 +10 DEX + BMI #20 + JSR MPADMP + JMP #10 + +20 LDA MAPPTR + STA MAPENT + LDA MAPPTR+1 + STA MAPENT+1 + RTS + +;RDDATA: READ DISC INFO FROM SECTOR 0 INTO +;STORE STARTING AT ADDRESS IN FREPTR. + +;ENTRY: A = DRIVE NO. + +;EXIT: A = RC + +;FUNCTION: - +;0) SET FDRIVE, OLDFDR & SELECT & START DRIVE +;1) SEEK TRACK ZERO +;2) READ SECTOR 0 + +;RDSTWO ENTRY POINT FOR USE WHEN +;DDRSTA POINTER ALREADY SET UP. + +RDDATA ROUT + LDY FREPTR + STY DSCCB+TRADD + LDY FREPTR+1 + STY DSCCB+TRADD+1 ;DDRSTA:=STORE ADDR FOR SECTOR + LDYIM 0 + STY DSCCB + STY DSCCB+TRADD+2 + STY DSCCB+TRADD+3 + + + [ WINCH=0 +RDSTWO STA Drivno + LDXIM Length+3-Cmd + LDAIM 0 +00 STAAX Dsccb+Cmd ;Zero part of disc CB ** 27/9/86 ** + DEX + BPL #00 + LDA Drivno + LSRA + RORA + RORA + RORA + STA DSCCB+CMD+1 + LDAIM &08 + STA DSCCB+CMD + LDA DSCCB+TRADD + STA MPCYPT + LDA DSCCB+TRADD+1 + STA MPCYPT+1 + LDAIM 0 + STA RBDA ;Sector zero + INC DSCCB+LENGTH+1 ;All was zero +10 JSR DSCCMD + BNE #20 + LDYIM SZOFF + LDAIY MPCYPT + STA DSCCB+CMD+3 + INY + LDAIY MPCYPT + STA DSCCB+CMD+2 + INY + LDA DRIVNO + LSRA + RORA + RORA + RORA + ORAIY MPCYPT + STA DSCCB+CMD+1 + JSR DSCCMD + BEQ #30 +20 LDY Dsccb ;Bad drive? **27/9/86 ** + CPYIM &65 + BEQ #30 ;Don't bother with alternate + LDY RBDA + BNE #30 + INC RBDA + INC DSCCB+CMD+3 + BNE #10 + +30 TAX ;Set CC + RTS + | +RDSTWO STA DSCCB ;SET DRIVE NUMBER + + STA DSCCB+PARAMS ;TRACK ZERO + LDAIM 2 ;SECTOR TWO + STA DSCCB+PARAMS+ 1 ;SECTOR TWO + LDAIM 3 ;NUMBER OF PARAMETERS + STA DSCCB+NOPRMS + LDAIM &21 ; ONE SECTOR + STA DSCCB+PARAMS+ 2 + LDAIM &53 ;FOR READ + STA DSCCB+CMD + + JSR DSCCMD + + RTS + ] + +; +; MAKE AN ENTRY IN THE MAP BLOCK +; +; ON ENTRY +; MKENVA HOLD THE NUMBER OF BLOCKS TO ALLOCATE +; MAPTMP POINT TO THE MAP BLOCK +; MPTMPC points to allocation cylinder number +; +; ON EXIT +; C SET IF FAILED +; +; USES : MAPGEN, MPTMPA, MPTMPB, MPTMPC, MPTMPE +; +MKEN ROUT + LDYIM MPSPCY + LDAIY MAPPTR + STA TMPSPC + INY + LDAIY MAPPTR + STA TMPSPC+1 + LDA MAPGEN + PHA + LDA MAPGEN+1 + PHA + LDA MAPTMP ;GET POINTER TO MAP BLOCK + STA MAPGEN + LDA MAPTMP+1 + STA MAPGEN+1 + JSR GETPOS ;GET NEXT FREE POSITION IN MAP BLOCK + BCS #10 ;BRANCH IF ROOM + JMP #30 +10 LDYIM MPCYMP ;GET ADDRESS OF CYLINDER MAP + LDAIY MAPPTR + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 + SEC + LDYIM 0 ;CHECK IF ROOM FOR ANOTHER BLOCK + LDAIY MAPGEN + SBCIM 1 + STAIY MAPGEN + INY + LDAIY MAPGEN + SBCIM 0 + STAIY MAPGEN + INY + LDAIY MAPGEN + SBCIM 0 + STAIY MAPGEN + BCC #15 + LDA MAPTMP + STA MPMBPT + STA CBSTA + LDA MAPTMP+1 + STA MPMBPT+1 + STA CBSTA+1 + JSR MMBLKD + JSR GTCYPS ;get closest cylinder block + LDA MAPGEN + STA MPTMPB + LDA MAPGEN+1 + STA MPTMPB+1 + LDA MPTMPE + STA MPTMPC ;NEW CYLINDER COUNT + LDA MPTMPE+1 + STA MPTMPC+1 + JSR RDBTMP + BNE #12 ;**23/2/87** Failed + JSR ALBLK ;GET NEW MAP BLOCK + SEC + JSR RDMPBK ;GET AREA OF STORE FOR IT + LDA ERRTYP + BEQ #20 +12 JSR ULMB +15 JMP #90 + +20 CLC + LDA MPMBPT ;GET POINTER TO OLD MAP BLOCK + STA CBSTA + ADCIM :LSB:LSTENT ;POINT TO LAST ENTRY + STA MPMBPT + LDA MPMBPT+1 + STA CBSTA+1 + ADCIM :MSB:LSTENT + STA MPMBPT+1 + LDYIM 0 ;SAVE SIN OF NEW MAP BLOCK + LDA MPTMPA + STAIY MPMBPT + INY + LDA MPTMPA+1 + STAIY MPMBPT + INY + LDA MPTMPA+2 + STAIY MPMBPT + INY ;NOW SAVE LENGTH + LDAIM 1 + STAIY MPMBPT + INY + LDAIM 0 + STAIY MPMBPT + JSR MMBWT + JSR ULMB + CLC + LDYIM MPCYMP ;GET ADDRESS OF CYLINDER MAP + LDAIY MAPPTR + STA MAPGEN + ADCIM 3 ;POINT TO START OF ENTRIES + STA MPTMPB + INY + LDAIY MAPPTR + STA MAPGEN+1 + ADCIM 0 + STA MPTMPB+1 + JSR GTCYPS + LDA MAPGEN + STA MPCYPT + LDA MAPGEN+1 + STA MPCYPT+1 + LDA MPTMPE + STA MPTMPC + LDA MPTMPE+1 + STA MPTMPC+1 + JSR RDBTMP + BNE #12 ;**23/12/87** Failed + LDA MAPTMP + STA MAPGEN ;SAVE ADDRESS OF NEW MAP BLOCK + LDA MAPTMP+1 + STA MAPGEN+1 + JSR SIZE + LDA MPTMPD ;number of contiguous blocks + CMP MKENVA + LDA MPTMPD+1 + SBC MKENVA+1 + BCS #25 + LDA MPTMPD + STA MKENVA + LDA MPTMPD+1 + STA MKENVA+1 +25 JSR GETPOS ;GET FREE POSITION IN MAP BLOCK +30 LDAIM 0 + STA MPTMPE + STA MPTMPE+1 ;ZERO VARIABLES + STA MPTMPE+2 + TAY +35 LDAIY MPSCPT ;LOOK FOR BLOCKS TO ALLOCATE + BEQ #45 ;NOT FOUND + LDXIM 8 +40 RORA + BCS #50 + DEX + INC MPTMPE ;STILL NOT FOUND + BNE #40 + INC MPTMPE+1 + JMP #40 ;CHECK NEXT ONE + +45 CLC ;NEXT BYTE SO ADD 8 + LDA MPTMPE + ADCIM 8 + STA MPTMPE + INY + BCC #35 + INC MPTMPE+1 + CLC ;**1/7/88** + BCC #35 + +50 PHA + LDA MPTMPE + ORA MPTMPE+1 + STA MPTMPB+2 ;**23/1/87** Flag for start of cylinder + LDA MKENVA + STA MPTMPB + LDA MKENVA+1 + STA MPTMPB+1 + PLA +55 CLC + RORA + PHP + PHA + LDA MPTMPB + BNE #57 + DEC MPTMPB+1 +57 DEC MPTMPB + LDA MPTMPB+1 + ORA MPTMPB + BEQ #60 + PLA + PLP + DEX + BNE #55 + STAIY MPSCPT + INY + LDAIY MPSCPT + LDXIM 8 + RORA + JMP #55 + +60 PLA + PLP + DEX +65 RORA + DEX + BNE #65 + STAIY MPSCPT + LDA MPTMPC + PHA + LDA MPTMPC+1 + PHA ;SAVE POSITION +70 LDA MPTMPC ;NOW GET DISC ADDRESS + ORA MPTMPC+1 ;IF ZERO THS IS IT! + BEQ #80 + CLC + LDA MPTMPE + ADC TMPSPC + STA MPTMPE + LDA MPTMPE+1 + ADC TMPSPC+1 + STA MPTMPE+1 + BCC #75 + INC MPTMPE+2 +75 LDA MPTMPC + BNE #77 + DEC MPTMPC+1 +77 DEC MPTMPC + JMP #70 + +80 PLA + STA MPTMPC+1 + PLA + STA MPTMPC + + [ 1=1 ;Attempt map entry merge *** 27/05/86 *** + LDA MPTMPB+2 ;**23/1/87** do not merge if start of cylinder + BEQ #83 + SEC + LDA MAPGEN ;if (MAPGEN-MAPTMP)=MBENTS ; unless first entry + SBC MAPTMP + TAY + LDA MAPGEN+1 + SBC MAPTMP+1 + BNE #81 + CPYIM MBENTS + BEQ #83 +81 SEC + LDA MAPGEN ;then $( MAPGEN-:=ENSZ ; previous entry + PHA + SBCIM :LSB:ENSZ + STA MAPGEN + LDA MAPGEN+1 + PHA + SBCIM :MSB:ENSZ + STA MAPGEN+1 + SEC + LDYIM 0 ; CBSTA:=MPTMPE-SIN(MAPGEN) ; separation of extents + LDA MPTMPE + SBCIY MAPGEN + STA CBSTA + INY + LDA MPTMPE+1 + SBCIY MAPGEN + STA CBSTA+1 + INY + LDA MPTMPE+2 + SBCIY MAPGEN + BNE #82 ; ; (not too long) + INY + LDA CBSTA ; if (CBSTA=LEN(MAPGEN)) ; do extents abut + CMPIY MAPGEN + BNE #82 + INY + LDA CBSTA+1 + CMPIY MAPGEN + BNE #82 + DEY + CLC + LDA MKENVA ; then $( LEN(MAPGEN)+:=MKENVA ; yes, extend previous + ADCIY MAPGEN + STAIY MAPGEN + INY + LDA MKENVA+1 + ADCIY MAPGEN + STAIY MAPGEN + PLA + PLA + JMP #84 ; goto #84 $) + +82 PLA ; MAPGEN+:=ENSZ ; else separate extents so make new entry + STA MAPGEN+1 + PLA + STA MAPGEN + ] + +83 LDYIM 0 ;SAVE THE DISC ADDRESS + LDA MPTMPE + STAIY MAPGEN + INY + LDA MPTMPE+1 + STAIY MAPGEN + INY + LDA MPTMPE+2 + STAIY MAPGEN + INY + LDA MKENVA ;SAVE SIZE + STAIY MAPGEN + LDA MKENVA+1 + INY + STAIY MAPGEN +84 LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JSR MBMWT ;MARK BIT MAP WRITTEN TO + LDA MAPTMP + STA CBSTA + LDA MAPTMP+1 + STA CBSTA+1 + JSR MMBWT ;MARK MAP BLOCK WRITTEN + SEC + LDA DIVTMP + SBC MKENVA + STA DIVTMP + LDA DIVTMP+1 + SBC MKENVA+1 + STA DIVTMP+1 + CLC ;FLAG EVERYTHING OK +85 PLA + STA MAPGEN+1 + PLA + STA MAPGEN + RTS + +90 CLC + LDYIM 0 + LDAIY MAPGEN + ADCIM 1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADCIM 0 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADCIM 0 + STAIY MAPGEN + SEC ;NO GOOD + BCS #85 + +;ALLOCATE ONE BLOCK +; +; LOOKS IN CURRENT BIT MAP AND RETURNS THE SIN +; OF THE FIRST FREE BLOCK +; +; ON ENTRY +; MPTMPC HOLDS THE CYLINDER NUMBER +; MPSCPT POINTS TO THE CURRENT BIT MAP +; +; ON EXIT +; MPTMPA HOLDS THE SIN OF THE ALLOCATED BLOCK +; +; USES : MPCYPT +; +ALBLK ROUT ;ZERO VARIABLES + LDAIM 0 + STA MPTMPA + STA MPTMPA+1 + STA MPTMPA+2 + LDA MPSCPT ;COPY POINTER TO USE + STA MPCYPT + LDA MPSCPT+1 + STA MPCYPT+1 +10 LDYIM 0 + LDAIY MPCYPT ;FIND FREE BLOCK + BEQ #30 +20 RORA ;NOW FIND THE SECTOR + BCS #50 ;FOUND WHEN C SET + INC MPTMPA ;KEEP LOOKING + BNE #20 + INC MPTMPA+1 + JMP #20 + +30 CLC + LDA MPTMPA ;MOVE TO NEXT BYTE + ADCIM 8 + STA MPTMPA + BCC #35 + INC MPTMPA+1 +35 INC MPCYPT + BNE #10 + INC MPCYPT+1 + JMP #10 + +50 PHA ;SAVE TO MARK AS ALLOCATED + LDA MPTMPA + ANDIM 7 + TAX + INX + PLA + CLC +60 ROLA + DEX + BNE #60 + STAIY MPCYPT ;BLOCK MARKED ALLOCATED + LDA MPTMPC + STA MAPTMP + LDA MPTMPC+1 + STA MAPTMP+1 +70 LDA MAPTMP + ORA MAPTMP+1 + BEQ #80 ;GET DISC ADDRESS + LDYIM MPSPCY + CLC + LDA MPTMPA + ADCIY MAPPTR + STA MPTMPA + INY + LDA MPTMPA+1 + ADCIY MAPPTR + STA MPTMPA+1 + BCC #75 + INC MPTMPA+2 +75 LDA MAPTMP ;DECREMENT CYLINDER COUNT + BNE #77 + DEC MAPTMP+1 +77 DEC MAPTMP + JMP #70 + +80 LDA MPTMPB ;GET POINTER TO CYLINDER MAP + STA MPCYPT + LDA MPTMPB+1 + STA MPCYPT+1 + LDYIM 0 ;DECREMENT FREE COUNT + SEC + LDAIY MPCYPT + SBCIM 1 + STAIY MPCYPT + INY + LDAIY MPCYPT + SBCIM 0 + STAIY MPCYPT + LDYIM MPCYMP + LDAIY MAPPTR + STA MPCYPT + INY + LDAIY MAPPTR + STA MPCYPT+1 + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JSR MBMWT ;MARK BIT MAP WRITTEN + LDA MPTMPA + ORA MPTMPA+1 + ORA MPTMPA+2 + BNE #90 + LDAIM &FC + JSR INTERR +90 RTS + +; ALLOCATE A SERIES OF BLOCKS +; +; ON ENTRY +; MPCYPT POINTS TO POSITION IN CYLINDER MAP +; DIVTMP HOLDS NUMBER OF SECTORS REQUIRED +; MPSCPT POINTS TO BIT MAP +; MAPPTR POINTS TO MAP TABLE +; MAPTMP POINTS TO MAP BLOCK +; MPTMPC HOLDS CYLINDER NUMBER +; +; ON EXIT +; DIVTMP HOLDS NUMBER OF BLOCKS LEFT +; C SET IF FAILED +; +; USES : MAPGEN +; +ABLKS ROUT + LDYIM MPCYMP + LDAIY MAPPTR ;GET POINTER TO START OF CYLINDER MAP + STA MAPGEN + INY + LDAIY MAPPTR + STA MAPGEN+1 + JSR SIZE ;GET SIZE OF THIS BLOCK + LDA MPTMPD ;MPTMPD HAS SIZE + TAX ;**1/7/88** + CMP DIVTMP ;SEE IF WE NEED THEM ALL + LDA MPTMPD+1 + TAY + SBC DIVTMP+1 + BCC #10 + LDA DIVTMP+2 + BNE #10 ;ABSALL ALLOCATES ALL BLOCKS + LDX DIVTMP + LDY DIVTMP+1 +10 STX MKENVA ;MAKE ENTRY IN MAP BLOCK + STY MKENVA+1 + JSR MKEN + BCS #30 ;ALL DONE SO FINISH + LDA ERRTYP + BNE #30 + LDYIM 0 + SEC + LDAIY MPCYPT + SBC MKENVA + STAIY MPCYPT + INY + LDAIY MPCYPT + SBC MKENVA+1 + STAIY MPCYPT + CMPIM &FF + BNE #20 + DEY + LDAIY MPCYPT + CMPIM &FF + BNE #20 + LDAIM &FA + JSR INTERR +20 CLC + RTS + +30 JSR DAGRP ;NOT ABLE TO MAKE ENTRY + LDYIM 0 + CLC + LDAIY MAPGEN ;INCREASE FREE COUNT + ADC MKENVA + STAIY MAPGEN + INY + LDAIY MAPGEN + ADC MKENVA+1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADCIM 0 + STAIY MAPGEN + SEC ;TO INDICATE FAILURE + RTS + + +; DEALLOCATE MAP BLOCK +; +; DEALLOCATES THE SPECIFIED MAP BLOCK. OVERWRITES THE SEQUENCE NUBERS +; SO THAT IT WILL NO LONGER APPEAR AS A MAP BLOCK +; +; ON ENTRY +; MPTMPA HOLDS THE SIN OF THE MAP BLOCK +; MPCYPT POINTS TO THE CYLINDER MAP +; +; USES : MPTMPA,MPTMPD,MPTMPC,MPSCPT +; +DAMPBK ROUT + LDYIM MPSPCY + LDAIY MAPPTR + STA TMPSPC + INY + LDAIY MAPPTR + STA TMPSPC+1 + LDA MPTMPA ;DEALLOCATE MAP BLOCK + STA CBSIN + LDA MPTMPA+1 + STA CBSIN+1 + LDA MPTMPA+2 + STA CBSIN+2 + JSR FNDMB ; GNCBPT POINTS TO CURRENT ENTRY + LDYIM CBSA + LDAIY GNCBPT + STA MPSCPT ;SAVE POINTER TO MAP BLOCK + STA CBSTA + INY + LDAIY GNCBPT + STA MPSCPT+1 + STA CBSTA+1 + LDYIM MBSQNO + LDAIM &FF + STAIY MPSCPT ;SAVE INVALID SQ.NO. + CLC + LDA MPSCPT + ADCIM :LSB:LSTSQ + STA MPSCPT + LDA MPSCPT+1 + ADCIM :MSB:LSTSQ + STA MPSCPT+1 + LDAIM 0 + TAY + STAIY MPSCPT + JSR MMBWT + LDAIM 0 + STA MPTMPC ; ZERO VARIABLES + STA MPTMPC+1 +10 SEC + LDA MPTMPA + SBC TMPSPC ; FIND CYLINDER NUMBER + STA MPTMPA + LDA MPTMPA+1 + SBC TMPSPC+1 + STA MPTMPA+1 + LDA MPTMPA+2 + SBCIM 0 + STA MPTMPA+2 + BCC #20 ; CYLINDER FOUND + INC MPTMPC ;INCREMENT CYLINDER COUNT + BNE #10 + INC MPTMPC+1 + JMP #10 + +20 JSR RDBTMP ; GET THE RELEVANT BIT MAP TO STORE + CLC + LDA MPTMPA ; GET WHICH BLOCK OF THIS CYLINDER + ADC TMPSPC + STA MPTMPA + LDA MPTMPA+1 + ADC TMPSPC+1 + STA MPTMPA+1 + BCC #25 + INC MPTMPA+2 +25 LDYIM 0 +30 SEC ;GET POSITION IN BIT MAP + LDA MPTMPA + SBCIM 8 + STA MPTMPA + LDA MPTMPA+1 + SBCIM 0 + STA MPTMPA+1 + BCC #40 ; POSITION FOUND IF BRANCH + INY + JMP #30 + +40 CLC + LDA MPTMPA ; GET OLD POSITION BACK + ADCIM 8 + STA MPTMPA + BCC #45 + INC MPTMPA+1 +45 LDX MPTMPA + INX + LDAIY MPSCPT ; X HOLDS POSITION IN BYTE A HOLDS THE BYTE +50 RORA ;MOVE TO CORRECT POSITION + DEX + BNE #50 + SEC + LDX MPTMPA ;BLOCK IS FLAGGED FREE AND X HOLDS NUMBER OF SHIFTS + INX +60 ROLA ; UNTIL BACK TO CORRECT POSITION + DEX + BNE #60 + STAIY MPSCPT ; SAVE FLAGS + CLC + LDA MPCYPT ;NOW MAKE COUNTS CORRECT + ADCIM 3 + STA MAPGEN + LDA MPCYPT+1 + ADCIM 0 + STA MAPGEN+1 + LDA MPTMPC + STA MPTMPE + LDA MPTMPC+1 + STA MPTMPE+1 +70 LDA MPTMPE + ORA MPTMPE+1 + BEQ #80 + CLC + LDA MAPGEN + ADCIM 2 + STA MAPGEN + BCC #75 + INC MAPGEN+1 +75 LDA MPTMPE + BNE #77 + DEC MPTMPE+1 +77 DEC MPTMPE + JMP #70 + +80 LDYIM 0 + CLC + LDAIY MAPGEN ;INCREMENT FREE BLOCK COUNT + ADCIM 1 + STAIY MAPGEN + INY + LDAIY MAPGEN + ADCIM 0 + STAIY MAPGEN + LDYIM 0 + CLC + LDAIY MPCYPT + ADCIM 1 + STAIY MPCYPT + INY + LDAIY MPCYPT + ADCIM 0 + STAIY MPCYPT + INY + LDAIY MPCYPT + ADCIM 0 + STAIY MPCYPT + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JMP MBMWT ; NOW FINISHED +; +; DALLOCATE A GROUP OF BLOCKS +; MARKS THE ENTRIES IN THE SPECIFIED BIT MAP FREE AND INCREASES THE FREE BLOCK COUNT +; +; ON ENTRY +; MPSCPT POINTS TO RELEVANT ENTRY IN MAP BLOCK +; MPCYPT POINTS TO CYLINDER MAP +; MAPTMP POINTS TO MAP BLOCK +; +; USES MPTMPC,MAPGEN,MPTMPD,MAPTMP +; +DAGRP ROUT + LDA MAPTMP + PHA + LDA MAPTMP+1 + PHA + LDAIM 0 + STA MPTMPC ; ZERO VALUES + STA MPTMPC+1 + LDYIM 0 + LDAIY MPSCPT ; GET SIN + STA MPTMPD + INY + LDAIY MPSCPT + STA MPTMPD+1 + INY + LDAIY MPSCPT + STA MPTMPD+2 + LDA MPSCPT ; SAVE MAP BLOCK POINTER + STA MAPGEN + LDA MPSCPT+1 + STA MAPGEN+1 + +05 LDYIM MPSPCY + SEC ; NOW FIND CYLINDER + LDA MPTMPD + SBCIY MAPPTR + STA MPTMPD + INY + LDA MPTMPD+1 + SBCIY MAPPTR + STA MPTMPD+1 + LDA MPTMPD+2 + SBCIM 0 + STA MPTMPD+2 + BCC #10 ; END FOUND + INC MPTMPC ; COUNT TO NEXT CYLINDER + BNE #05 + INC MPTMPC+1 + JMP #05 + +10 LDYIM MPSPCY + CLC + LDA MPTMPD ; RESTORE BLOCK COUNT + ADCIY MAPPTR + STA MPTMPD + INY + LDA MPTMPD+1 + ADCIY MAPPTR + STA MPTMPD+1 + BCC #12 + INC MPTMPD+2 +12 LDA MPTMPC ; SAVE CYLINDER NUMBER + STA MAPTMP + LDA MPTMPC+1 + STA MAPTMP+1 + JSR RDBTMP + LDYIM 0 +15 SEC ; GET POSITION IN BIT MAP + LDA MPTMPD + SBCIM 8 + STA MPTMPD + LDA MPTMPD+1 + SBCIM 0 + STA MPTMPD+1 + LDA MPTMPD+2 + SBCIM 0 + STA MPTMPD+2 + BCC #20 ; WHEN POSITION FOUND + INY + JMP #15 + +20 CLC ; GET BIT POSITION BACK + LDA MPTMPD + ADCIM 8 + STA MPTMPD + BCC #22 + INC MPTMPD+1 + BNE #22 + INC MPTMPD+2 +22 LDA MPTMPD + STA MPTMPC ; SAVE BIT COUNT + INC MPTMPC + LDAIY MPSCPT ; GET CORRECT BYTE + LDXIM 9 +25 RORA ; ROTATE TO GET CORRECT POSITION + DEX + DEC MPTMPC + BNE #25 + PHA ;SAVE VALUE + TYA + PHA ;SAVE POSITION + LDYIM 3 + LDAIY MAPGEN ; GET NUMBER OF BLOCKS TO BE DEALLOCATED + STA MPTMPC + INY + LDAIY MAPGEN + STA MPTMPC+1 + PLA ; GET POSITION BACK + TAY + PLA +30 SEC ;MARK BLOCK FREE + RORA + DEX + BEQ #40 + PHP + PHA ; SAVE VALUE +35 LDA MPTMPC ; DECREMENT COUNT + BNE #37 + DEC MPTMPC+1 +37 DEC MPTMPC + LDA MPTMPC+1 + ORA MPTMPC ; CHECK FOR END + BEQ #45 + PLA ; GET VALUE BACK + PLP + JMP #30 ; DEALLOCATE NEXT BLOCK + +40 STAIY MPSCPT ; SAVE NEW VALUE + INY + LDAIY MPSCPT ; GET NEXT VALUE + RORA ; POSITION CORRECTLY + PHP + PHA + LDXIM 8 ;GIVE X CORRECT VALUE + BNE #35 + +45 CPXIM 0 + BEQ #55 ; BRANCH IF POSITION CORRECT + PLA ;BLOCKS HAVE BEEN DEALLOCATED SO CORRECT POSITION + PLP +50 RORA + DEX + BNE #50 ; KEEP GOING UNTIL BACK RIGHT + BEQ #60 + +55 PLA + PLP +60 STAIY MPSCPT ;SAVE VALUE + LDA MPscor ;**23/1/87** + STA CBSTA + LDA MPscor+1 + STA CBSTA+1 + JSR MBMWT + LDYIM 3 ; NOW CORRECT FREE BLOCK COUNT + LDAIY MAPGEN + STA MPTMPC + INY + LDAIY MAPGEN + STA MPTMPC+1 + LDYIM 0 + CLC ; NOW ADD TO FREE BLOCK COUNT + LDA MPTMPC + ADCIY MPCYPT + STAIY MPCYPT + INY + LDA MPTMPC+1 + ADCIY MPCYPT + STAIY MPCYPT + INY + LDAIM 0 + ADCIY MPCYPT + STAIY MPCYPT + CLC ;NOW GET POSITION IN CYLINDER MAP + LDAIM 3 + ADC MPCYPT + STA MPSCPT + LDAIM 0 + ADC MPCYPT+1 + STA MPSCPT+1 +65 LDA MAPTMP + ORA MAPTMP+1 ; HAVE WE GOT THERE ? + BEQ #70 + CLC ; MOVE TO NEXT ENTRY + LDA MPSCPT + ADCIM 2 + STA MPSCPT + BCC #67 + INC MPSCPT+1 +67 LDA MAPTMP ; DECREMENT CYLINDER COUNT + BNE #68 + DEC MAPTMP+1 +68 DEC MAPTMP + JMP #65 + +70 CLC ; NOW DO THE ADD + LDYIM 0 + LDAIY MPSCPT + ADC MPTMPC + STAIY MPSCPT + INY + LDAIY MPSCPT + ADC MPTMPC+1 + STAIY MPSCPT + LDA MAPGEN ; RESTORE SOME VALUES + STA MPSCPT + LDA MAPGEN+1 + STA MPSCPT+1 + LDYIM 0 + TYA + LDXIM 5 +75 STAIY MPSCPT + INY + DEX + BNE #75 + PLA + STA MAPTMP+1 + STA CBSTA+1 + PLA + STA MAPTMP + STA CBSTA + JMP MMBWT + +;CLRBLK +; DEALLOCATES ALL BLOCKS FROM A GIVEN ENTRY. +; THE ORIGINAL MAP BLOCK WILL BE DELETED IF A FLAG IS SET. +; +; ON ENTRY +; MPTMPA HOLDS THE SIN OF THE MAP BLOCK +; MPSCPT HOLDS THE OFFSET IN THE MAP BLOCK +; MPTMPE IF NON-ZERO IMPLIES MAP BLOCK TO BE DELETED +; + +CLRBLK ROUT + LDYIM MPCYMP + LDAIY MAPPTR + STA MPCYPT + INY + LDAIY MAPPTR + STA MPCYPT+1 + CLC + JSR RDMPBK ; MAKE SURE MAP BLOCK IS IN STORE + BNE #20 + CLC + LDA MAPTMP ; GET POINTER TO MAP BLOCK + STA MPMBPT + ADC MPSCPT ; GET CURRENT POSITION + STA MPSCPT + LDA MAPTMP+1 + STA MPMBPT+1 + ADC MPSCPT+1 + STA MPSCPT+1 +10 LDYIM 0 ; CHECK IF END OF BLOCK + LDAIY MPSCPT + INY + ORAIY MPSCPT + INY + ORAIY MPSCPT + BNE #30 ; END OF MAP BLOCK REACHED +15 LDA MPTMPE + BEQ #20 + LDA DNDLTE + BNE #20 + JSR DAMPBK +20 RTS + +30 CLC + LDA MPMBPT + ADCIM :LSB:LSTENT + TAX + LDA MPMBPT+1 + ADCIM :MSB:LSTENT + CPX MPSCPT ; CHECK FOR LAST ENTRY + BNE #60 + CMP MPSCPT+1 + BNE #60 + LDYIM 0 ; GET NEW SIN + LDAIY MPSCPT + STA MPTMPB + INY + LDAIY MPSCPT + STA MPTMPB+1 + INY + LDAIY MPSCPT + STA MPTMPB+2 + + LDYIM 4 + LDAIM 0 +40 STAIY MPSCPT ;clear out this pointer + DEY + BPL #40 ;**14/9/84** + JSR MMBWT ;**8/5/87** mark block written to + + JSR #15 ; CHECK IF THIS BLOCK TO BE DELETED + LDAIM 0 + STA DNDLTE + LDAIM 1 + STA MPTMPE + LDA MPTMPB + STA MPTMPA + LDA MPTMPB+1 + STA MPTMPA+1 + LDA MPTMPB+2 + STA MPTMPA+2 + CLC + JSR RDMPBK ; READ IN NEW MAP BLOCK + CLC + LDA MAPTMP ;TRANSFER POINTER + STA MPMBPT + ADCIM :LSB:MBENTS ; GET TO POINT TO START OF ENTRIES + STA MPSCPT + LDA MAPTMP+1 + STA MPMBPT+1 + ADCIM :MSB:MBENTS + STA MPSCPT+1 +60 JSR DAGRP + LDA SAVSC + BNE #70 + INC SAVSC + JSR ENSMB + JSR ULBM +70 CLC ; MOVE TO NEXT ENTRY + LDA MPSCPT + ADCIM :LSB:ENSZ + STA MPSCPT + LDA MPSCPT+1 + ADCIM :MSB:ENSZ + STA MPSCPT+1 + JMP #10 + + LNK UADE13 diff --git a/Level3/SRC/L3/Uade13 b/Level3/SRC/L3/Uade13 new file mode 100644 index 0000000..9c6b8b5 --- /dev/null +++ b/Level3/SRC/L3/Uade13 @@ -0,0 +1,1029 @@ + OPT UADE13 ;> Uade13 + TTL File server file UADE13 + +;FNDMAP: +;SEARCHES MAPTB LOOKING FOR DISC NUMBER +;WHICH IS IN ARGB AND ARGC. WHEN +;FOUND LEAVES A POINTER TO THE CORRECT ENTRY IN MAPPTR & MAPENT. +;NOTE THAT MAPENT IS USED BY DSCMAN & SHOULD +;NOT BE ALTERED BY MAPMAN. + +FNDMAP ROUT + LDAIM 0 + STA MPDRVE + STA DRIVNO + LDA MAPTB ;START OF MAP TABLE + STA MAPPTR ;LOOK AT FIRST ENTRY + LDA MAPTB+1 + STA MAPPTR+1 + LDXIM 0 ;X HOLDS DRIVE NUMBER +10 LDYIM MPDCNO ;OFFSET TO DISC NUMBER + LDAIY MAPPTR + LDYIM ARGB + CMPIY ARGPTR ;SEE IF ITS CORRECT DISC NUMBER + BNE #20 + LDYIM MPDCNO+1 + LDAIY MAPPTR + LDYIM ARGC + CMPIY ARGPTR + BEQ #30 ;BRANCH IF DISC NUMBER MATCHES +20 INC MPDRVE ; ** 14/06/86 ** drive numbers contiguous + JSR MPADMP ;GET NEXT ENTRY + INC DRIVNO + LDA DRIVNO + CMP DRIVES ;CHECK FOR END + BNE #10 ;BRANCH IF NOT AT END +;IF WE REACH HERE THE DISC WAS NOT FOUND + LDAIM MPERRA + RTS + +30 LDYIM MPNOCY ;Check no leg pull ** 14/06/86 ** + LDAIY MAPPTR + INY + ORAIY MAPPTR ;by non-zero cyl count ** 14/06/86 ** + BEQ #20 + LDA MAPPTR + STA MAPENT + LDA MAPPTR+1 + STA MAPENT+1 ;MAPENT := PTR TO MAPTB ENTRY + LDAIM 0 ;SUCESSFUL SO ZERO RC + RTS + +;CHECK MAP SIZE +; +;CHECKS THAT NEW CYLINDER MAP SIZE IS NOT GREATER THAN OLD +; +;SECTOR TWO INFO POINTED TO BY MPSCPT, +;MAP TABLE ENTRY BY MAPPTR +; +CHMPSZ ROUT + LDYIM MPNOCY+1 + LDAAY MAPTBF + PHA + DEY + LDAAY MAPTBF + PHA ;GET OLD NUMBER OF CYLINDERS + LDYIM MPNOCY ;SECTOR TWO NO. CYLINDERS + PLA + CMPIY MAPPTR + PLA + INY + SBCIY MAPPTR + LDAIM 0 + BCS #10 ;OLD MAP >= NEW MAP + LDAIM MPERRI +10 RTS + + +; +; +;FIND SIZE OF NEW MAP AND SAVE IT +; +; +MPMPSZ ROUT + LDYIM MPSECS ;NO. OF SECTORS ON DISC + LDAIY MAPPTR + STA MPTMPC ;SAVE IT + INY + LDAIY MAPPTR + STA MPTMPC+1 + INY + LDAIY MAPPTR + STA MPTMPC+2 + LDAIM 0 + STA MPTMPA + STA MPTMPA+1 + STA MPTMPA+2 + LDYIM MPDSCS + LDAIY MAPPTR + TAX +10 CLC + LDA MPTMPA + ADC MPTMPC + STA MPTMPA + LDA MPTMPA+1 + ADC MPTMPC+1 + STA MPTMPA+1 + LDA MPTMPA+2 + ADC MPTMPC+2 + STA MPTMPA+2 + DEX + BNE #10 + LDYIM MPSCTT + LDA MPTMPA + STAIY MAPPTR + INY + LDA MPTMPA+1 + STAIY MAPPTR + INY + LDA MPTMPA+2 + STAIY MAPPTR + RTS +; +;DELETE THE RELEVANT OBJECT +; +MPDLTE LDYIM ARGD ;GET SIN + LDAIY ARGPTR + STA MPTMPA + INY + LDAIY ARGPTR + STA MPTMPA+1 + INY + LDAIY ARGPTR + STA MPTMPA+2 + LDAIM :LSB:MBENTS ;GET OFFSET TO START + STA MPSCPT + LDAIM :MSB:MBENTS + STA MPSCPT+1 + LDAIM 1 ;FLAG CURRENT MAP BLOCK TO BE DELETED + STA MPTMPE + STA SAVSC ;STOP EXTRA WORK + JMP CLRBLK ;REMOVE ALL ENTRIES +; +;INCREMENT MAPPTR TO NEXT MAPTB ENTRY +; + +MPADMP ROUT + CLC + LDAIM MPTBSZ + ADC MAPPTR + STA MAPPTR + BCC #10 + INC MAPPTR+1 +10 RTS + +DIVIDE ROUT + JSR DVDE ;CONVERT TO OLD DIVIDE + SEC + LDA DIVTMP + SBCIM 1 + STA DIVPAR + LDA DIVTMP+1 + SBCIM 0 + STA DIVPAR+1 + LDA DIVTMP+2 + SBCIM 0 + STA DIVPAR+2 + RTS + +;ADD NAME TABLE ENTRY LENGTH TO +;DNMPTR. + +INAMPT ROUT + CLC + LDAIM NTENSZ + ADC DNMPTR + STA DNMPTR + BCC #00 + INC DNMPTR+1 +00 RTS + + +;DIVIDE SECTORS +; +; CALCULATES A CYLINDER NUMBER FROM A SIN +; +;ON ENTRY +; MPTMPA HOLDS THE SIN +; +;ON EXIT +; MPTMPB HOLDS THE CYLINDER +; +;USES MPTMPA +; +DIVSEC LDAIM 0 + STA MPTMPB + STA MPTMPB+1 ;CLEAR VARIABLE +10 LDYIM MPSPCY + SEC + LDA MPTMPA + SBCIY MAPPTR ;DIVIDE BY SECTORS PER CYLINDER + STA MPTMPA + INY + LDA MPTMPA+1 + SBCIY MAPPTR + STA MPTMPA+1 + LDA MPTMPA+2 + SBCIM 0 + STA MPTMPA+2 + BCC #00 + INC MPTMPB + BNE #10 + INC MPTMPB+1 + JMP #10 + + +;TAKE TEXT DISC NAME FROM DNMBUF +;AND PUT IN NAME TABLE ENTRY AT +;DNMPTR. ALSO PUT IN NEW DISC NUMBER +;FROM NXTDNO, AND MARK ENTRY IN USE. +;DISC NO. ALSO PLACED IN MAP TABLE ENTRY +;POINTED TO BY MAPPTR. + +;ALSO INCREMENT NXTDNO !! + +SDSCNM ROUT + LDYIM NTNAME + LDXIM 0 + +10 LDAAX DNMBUF + STAIY DNMPTR + INY + INX + CPXIM DNAMLN + BNE #10 + + LDYIM NTDNO + LDA NXTDNO + PHA + STAIY DNMPTR ;SET DISC NO. LO + INY + LDA NXTDNO+1 + STAIY DNMPTR + + LDYIM MPDCNO+1 + STAIY MAPPTR ;DISC NO. IN MAP TABLE + DEY + PLA + STAIY MAPPTR + + LDYIM NTUSED + LDAIM USED + STAIY DNMPTR + + INC NXTDNO + BNE #20 + INC NXTDNO+1 +20 LDAIM 0 + RTS + +; +;SET UP CYLINDER MAP FOR CURRENT DISC +; +MPSTCY ROUT + LDAIM 1 + STA RSTFLG + LDYIM MPCYMP + CLC + LDAIY MAPPTR + ADCIM 3 ;TO POINT AT ACTUAL ENTRIES + STA MPCYPT + INY + LDAIY MAPPTR + ADCIM 0 + STA MPCYPT+1 + LDAIM 0 + STA DDRSZE+2 + STA MPTMPC + STA MPTMPC+1 + STA MPTMPA+2 ;** 21/11/84 ** +10 LDYIM MPSCYL + LDA MPTMPC + CMPIY MAPPTR + INY + LDA MPTMPC+1 + SBCIY MAPPTR + BCS #20 + LDAIM 0 + TAY + STAIY MPCYPT + INY + STAIY MPCYPT + CLC + LDA MPCYPT + ADCIM 2 + STA MPCYPT + BCC #15 + INC MPCYPT+1 +15 INC MPTMPC + BNE #10 + INC MPTMPC+1 + JMP #10 + +20 STA MPTMPB + STA MPTMPB+1 + STA MPTMPB+2 +25 LDAIM 0 + STA MPTMPA ;LOOP TO READ IN BIT MAPS + STA MPTMPA+1 + + LDA MPTMPA+2 ;check not skipping + BEQ #30 + DEC MPTMPA+2 ;counter for maps to skip + JMP #60 + +30 JSR RDBTMP + + LDYIM MP1BIT + LDAIY MAPPTR ;**23/1/87** no valid flag if packed map + BNE #32 + LDYIM MPVAL ;check that subsequent maps are valid + LDAIY MPSCPT ;** 21/11/84 ** + STA MPTMPA+2 ;save this flag [n<>0 => skip n maps] + +32 LDYIM MPSPCY + LDAIY MAPPTR + STA MAPTMP + INY + LDAIY MAPPTR + STA MAPTMP+1 ;SECTORS PER CYCLINDER +35 LDXIM 8 ;EIGHT BITS PER BYTE + LDYIM 0 + LDAIY MPSCPT +40 RORA ;CHECK IF SECTOR FREE + BCC #45 ;CLEAR IF ALLOCATED + INC MPTMPA ;COUNT OF FREE SECTORS + BNE #45 + INC MPTMPA+1 +45 PHA + LDA MAPTMP ;TO CHECK FOR END OF MAP + BNE #47 + DEC MAPTMP+1 +47 DEC MAPTMP + LDA MAPTMP+1 + ORA MAPTMP + BEQ #50 ;BRANCH IF END OF MAP + PLA + DEX ;FOR END OF BYTE + BNE #40 + INC MPSCPT ;INCREMENT POINTER TO BIT MAP + BNE #35 + INC MPSCPT+1 + JMP #35 ;TO LOOK AT NEXT BIT + +50 PLA ;REMOVE SAVED REG. +60 LDA MPTMPA + STAIY MPCYPT ;SAVE COUNT OF FREE SECTORS + CLC + ADC MPTMPB ;SAVE TOTAL + STA MPTMPB + INY + LDA MPTMPA+1 + STAIY MPCYPT + ADC MPTMPB+1 + STA MPTMPB+1 + BCC #63 + INC MPTMPB+2 +63 CLC ;MOVE POINTER TO NEXT ENTRY + LDA MPCYPT + ADCIM 2 + STA MPCYPT + BCC #66 + INC MPCYPT+1 +66 INC MPTMPC + BNE #70 + INC MPTMPC+1 +70 LDYIM MPNOCY ;CHECK FOR END OF DISC + LDA MPTMPC + CMPIY MAPPTR + INY + LDA MPTMPC+1 + SBCIY MAPPTR + BCS #80 + JMP #25 + +80 LDYIM MPCYMP ;END OF MAPS SO SAVE TOTAL COUNT + LDAIY MAPPTR + STA MPSCPT + INY + LDAIY MAPPTR + STA MPSCPT+1 + LDYIM 0 + LDA MPTMPB + STAIY MPSCPT + INY + LDA MPTMPB+1 + STAIY MPSCPT + INY + LDA MPTMPB+2 + STAIY MPSCPT + LDAIM 0 + STA RSTFLG + RTS + +;FIND SIZE OF OBJECT +; +;ON ENTRY +; MPMBPT POINTS TO MAP BLOCK +; ARGD holds SIN of MAP root +; +;ON EXIT +; MPTMPA HOLDS NUMBER OF BYTES +; MPTMPD HOLDS NUMBER OF BLOCKS +; +; +MPGTSZ ROUT + LDAIM 0 + STA MPTMPD + STA MPTMPD+1 + STA MPTMPD+2 ;ZERO BLOCK COUNT +10 LDAIM :LSB:MBENTS + STA MPTMPB + LDAIM :MSB:MBENTS + STA MPTMPB+1 ;OFFSET +20 ;ADD UP NEXT ENTRY + CLC + LDA MPMBPT + ADC MPTMPB + STA MPSCPT + LDA MPMBPT+1 + ADC MPTMPB+1 + STA MPSCPT+1 + LDYIM 0 + LDAIY MPSCPT + INY + ORAIY MPSCPT + INY + ORAIY MPSCPT + BEQ #50 + LDA MPTMPB + CMPIM :LSB:LSTENT + LDA MPTMPB+1 + SBCIM :MSB:LSTENT + BCS #30 + LDYIM 3 + CLC + LDA MPTMPD + ADCIY MPSCPT + STA MPTMPD + INY + LDA MPTMPD+1 + ADCIY MPSCPT + STA MPTMPD+1 + BCC #25 + INC MPTMPD+2 +25 CLC + LDA MPTMPB + ADCIM ENSZ + STA MPTMPB + BCC #20 + INC MPTMPB+1 + JMP #20 + +30 ;GET NEXT MAP BLOCK + LDYIM 0 + LDAIY MPSCPT + STA MPTMPA + INY + LDAIY MPSCPT + STA MPTMPA+1 + INY + LDAIY MPSCPT + STA MPTMPA+2 + CLC + JSR RDMPBK + BEQ #40 +35 LDAIM MPERRC + RTS + +40 LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + JMP #10 + +50 JSR RDmpbd ;**8/5/87** Read block at ARGD + BNE #35 + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + + ;CALCULATE BYTES FROM BLOCKS + LDA MPTMPD ;NUMBER OF BLOCKS + STA MPTMPB + LDA MPTMPD+1 + STA MPTMPB+1 + LDA MPTMPD+2 + STA MPTMPB+2 + LDAIM 0 + STA MPTMPA ;ZERO BYTE COUNT + STA MPTMPA+1 + STA MPTMPA+2 + LDA MPTMPD + ORA MPTMPD+1 + ORA MPTMPD+2 + BEQ #90 +60 LDA MPTMPB + BNE #62 + LDA MPTMPB+1 + BNE #61 + DEC MPTMPB+2 +61 DEC MPTMPB+1 +62 DEC MPTMPB + LDA MPTMPB+2 + ORA MPTMPB+1 + ORA MPTMPB + BEQ #70 + JSR #95 ; MPTMPA := MPTMPA+BTINBK + JMP #60 + +70 ;GET BYTES IN LAST BLOCK + LDYIM BILB + LDAIY MPMBPT + INY + ORAIY MPMBPT + BNE #80 + JSR #95 ;MPTMPA := MPTMPA+BTINBK + JMP #90 + +80 LDYIM BILB + CLC + LDA MPTMPA + ADCIY MPMBPT + STA MPTMPA + INY + LDA MPTMPA+1 + ADCIY MPMBPT + STA MPTMPA+1 + BCC #90 + INC MPTMPA+2 +90 LDAIM 0 + RTS + +95 CLC ; MPTMPA := MPTMPA+BTINBK + LDA MPTMPA + ADCIM :LSB:BTINBK + STA MPTMPA + LDA MPTMPA+1 + ADCIM :MSB:BTINBK + STA MPTMPA+1 + BCC #99 + INC MPTMPA+2 +99 RTS + +;CHDNAM + +;LOOK UP DISC NAME IN SECTOR ZERO INFO +;POINTED TO BY MPSCPT. +;IF FOUND, AND ENTRY IN USE -> ERROR +;IF FOUND, ENTRY NOT IN USE, MARK IN USE +;AND SET MAP TABLE ENTRY DISC NO. FROM TABLE +;IF NOT FOUND, CHUCK OUT LRU DISC NO. NOT +;CURRENTLY IN USE, INSERT NEW NAME AND GIVE IT +;A NEW DISC NUMBER (FROM NXTDNO). MARK ENTRY IN USE. +;SET DISC NO. IN MAP TABLE + +;ON ENTRY MAPPTR -> MAP TABLE ENTRY + + +CHDNAM ROUT + JSR FNDDSC ;EXIT WITH DNMPTR POINTING TO ENTRY + BNE #20 ;NOT FOUND, THROW AN ENTRY OUT + +;IF HERE, DISC FOUND. IF IN USE, THEN ERROR +;COZ => TWO DISCS OF SAME NAME IN USE +;ON SAME SYSTEM. IF NOT IN USE, RETURN +;DISC NUMBER. + + LDYIM NTUSED + LDAIY DNMPTR + BNE #10 ;NOT IN USE, OK + + LDAIM MPERRJ + RTS ;ERROR + +10 LDYIM NTDNO + LDAIY DNMPTR + PHA + INY + LDAIY DNMPTR + +;NOW SET MAP TABLE ENTRY + + LDYIM MPDCNO+1 + STAIY MAPPTR + DEY + PLA + STAIY MAPPTR + +;MARK NAME TABLE ENTRY IN USE + + LDYIM NTUSED + LDAIM USED + STAIY DNMPTR + + JMP #30 ;FOUND FINISH + + +20 JSR LRUDSC + +;NOW DNMPTR => LRU NAME ENTRY + + JSR SDSCNM + +30 LDAIM 0 + RTS ;EXIT + + +;MOVE DISC NAME FROM SEC. ZERO +;TO DNMBUF. + +MOVDNM ROUT + LDXIM 0 + LDYIM MPSZNM +10 LDAIY MPSCPT + STAAX DNMBUF + INY + INX + CPXIM DNAMLN + BNE #10 + RTS + + +;FNDDSC + +;ENTRY: MPSCPT -> SECTOR ZERO INFO, INCLUDING DISC NAME + +;EXIT: DNMPTR -> NAME TABLE ENTRY IF FOUND +;Z FLAG SET IF FOUND + +;SIDE EFFECT: DISC NAME MOVED TO DNMBUF + +FNDDSC ROUT + JSR MOVDNM ;MOVE DISC NAME TO DNMBUF + +FNDNAM LDA NAMETB + STA DNMPTR + LDA NAMETB+1 + STA DNMPTR+1 ;SET P.0 POINTER + LDAIM NTSIZE ;NO. OF ENTRIES IN NAMTAB + STA TEMPA + +10 LDYIM NTNAME ;NAMTAB OFFSET + LDXIM 0 +20 LDAIY DNMPTR + EORAX DNMBUF ;Compare + ANDIM &DF ;Force cases + BNE #30 + INX + INY + CPXIM DNAMLN + BNE #20 + RTS + +;IF HERE, NAME FOUND, Z SET. + +30 DEC TEMPA + BEQ #40 ;SEARCH FINISHED, NOT FOUND + JSR INAMPT ;SET DNMPTR TO POINT TO NEXT ENTRY + JMP #10 ;DO NEXT ENTRY + +40 LDAIM MPERRK ;UNSET Z FLAG + RTS + + + +;LRUDSC + +;SEARCH NAME TABLE FOR LRU ENTRY + +;ON EXIT DNMPTR -> LRU ENTRY + +LRUDSC ROUT + LDA NAMETB + STA GENPTR + LDA NAMETB+1 + STA GENPTR+1 + + LDAIM &FF + STA TEMPA ;USED TO KEEP PARTIAL RESULT + LDXIM NTSIZE ;NO. OF ENTRIES + +10 LDYIM NTUSED ;OFFSET OF USE FLAG + LDAIY GENPTR + BEQ #20 ;IN USE -> NO GOOD + + CMP TEMPA + BCS #20 ;TABLE ENTRY>=TEMPA, CONTINUE + + STA TEMPA ;NEW PARTIAL RESULT + LDA GENPTR + STA DNMPTR ;SET POINTER TO PARTIAL RESULT ENTRY + LDA GENPTR+1 + STA DNMPTR+1 + +20 DEX + BEQ #30 ;ALL ENTRIES DONE, FINISH + + CLC + LDAIM NTENSZ + ADC GENPTR + STA GENPTR + BCC #10 + INC GENPTR+1 + JMP #10 + +30 RTS + + + +;DDNAME + [ 1=0 +;DELETE DISC NAME POINTED TO BY +;DNMPTR. +;PUT $80 IN FIRST CHAR. OF NAME SO +;IT WON'T BE RECOGNISED AND SET +;USED FLAG TO UNUSED. + +DDNAME ROUT + LDYIM NTNAME + LDAIM &80 + STAIY DNMPTR + LDYIM NTUSED + LDAIM UNUSED + STAIY DNMPTR + RTS + ] + +;FNDDNO +;LOOK UP CURDNO IN NAMETABLE. +;EXIT: NAMTAB -> ENTRY, Z SET IF FOUND + +FNDDNO ROUT + JSR SDNMPT + LDXIM NTSIZE-1 + +10 LDYIM NTDNO + LDA CURDSC + CMPIY DNMPTR + BNE #20 + INY + LDA CURDSC+1 + CMPIY DNMPTR + BEQ #30 ;FOUND, FINISH + +20 JSR INAMPT ;MOVE DNMPTR + DEX + BPL #10 + +30 RTS + + + +;AGENTB +;AGE ALL ENTRIES NOT IN USED IN THE +;DISC NAME TABLE + +AGENTB ROUT + JSR SDNMPT + LDXIM NTSIZE + LDYIM NTUSED +10 LDAIY DNMPTR + BEQ #20 ;IN USE, DON'T AGE + SEC + SBCIM 1 ;AGE + STAIY DNMPTR +20 JSR INAMPT + DEX + BNE #10 + RTS + + +SDNMPT LDA NAMETB + STA DNMPTR + LDA NAMETB+1 + STA DNMPTR+1 + RTS + + +;CHECK SECTOR ZERO INFO (POINTED TO BY MPSCPT) IS FOR A VALID FS DISC +;If a Winchester, check for suitable company copyright. + +TAGTAB = "AFS0" + +CHKDSC ROUT + [ 1=0 + LDA MPdrve ;**23/1/87** Check if Winnie + CMPIM 4 + BCS #00 ;br if floppy + LDAIM &25 ;check user page A + LDXIM :LSB:CAcorn + LDYIM :MSB:CAcorn + JSR #50 + BNE #30 + LDAIM &26 ;check user page B + LDXIM :LSB:(CAcorn+4) + LDYIM :MSB:(CAcorn+4) + JSR #50 + BNE #30 + ] + +00 LDYIM MPDRNM+3 ;POINTER TO NAME + LDXIM 4 +10 LDAAX TAGTAB-1 + CMPIY MPSCPT + BNE #30 + DEY + DEX + BNE #10 ;IF EQ, DROP THROUGH AND EXIT, Z SET +20 RTS + +30 LDAIM MPERRD + RTS + + [ 1=0 +50 STX Movto ;Save pointer into copyright + STY Movto+1 + PHA + LDAIM 0 + LDXIM Cmd+5 ;Zero disc control block +60 STAAX Dsccb + DEX + BPL #60 + PLA + STA Dsccb+Cmd+2 ;Set page number + LDAIM &1A ;Mode sense command + STA Dsccb+Cmd + CLC + LDAIM :LSB:Datara ;Where to read user pages + STA Dsccb+Tradd + ADCIM 6 + STA Movfrm + LDAIM :MSB:Datara + STA Dsccb+Tradd+1 + ADCIM 0 + STA Movfrm+1 + LDAIM 16 ;Max length of data area + STA Dsccb+Cmd+4 + JSR Dsccmd + BNE #20 ;exit on any error, Z clear + LDXIM 4 + JMP Compar ;go compare text and return + ] + + +;SMAPEN +;MOVE SECTOR ZERO INFO. POINTED TO +;BY MPSCPT INTO MAP TABLE ENTRY +;POINTED TO BY MAPPTR + +SMAPEN ROUT + CLC ;COPY AREA OF STORE + LDA MAPPTR + ADCIM MPNOCY ;MAKE MAPPTR POINT TO START OF AREA + STA MOVTO + LDA MAPPTR+1 + ADCIM 0 + STA MOVTO+1 ;STORE IN POINTER TO COPY + CLC + LDA MPSCPT + ADCIM MPSZNC ;TO POINT TO DISC INFO + STA MOVFRM + LDA MPSCPT+1 + ADCIM 0 + STA MOVFRM+1 ;POINTER FOR MOVING TO + LDXIM MPSZLN + JMP MOVE ;MOVE AND EXIT + +;Zeroes an area of disc. Is a psuedo +;map management routine. +; +;On entry +; OLDSZE = Old size in bytes +; MPTMPA = SIN of object +; +;On exit Z set if sucessful + +ZERDSK ROUT + JSR FNDMAP + BEQ #10 +05 RTS + +10 CLC + JSR RDMPBK ;Requires SIN in MPTMPA + BNE #05 + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + LDA OLDSZE + STA DIVPAR + LDA OLDSZE+1 + STA DIVPAR+1 + LDA OLDSZE+2 + STA DIVPAR+2 + JSR DVDE + BCC #15 + LDAIM &F9 + JSR INTERR +15 LDAIM 2 + LDY OLDSZE + BNE #20 + LDAIM 1 +20 STA DIVPAR + SEC + LDA DIVTMP + SBC DIVPAR ;START FROM BLOCK ZERO + STA BREGA + LDA DIVTMP+1 + SBCIM 0 + STA BREGA+1 + LDAIM &FF + STA NBLKS + STA NBLKS+1 + JSR DCENT2 + BEQ #30 + JMP #90 + +;MAPTMP holds SIN of current disc block +;MPTMPD holds count of number in this entry +;Now zero out rest of current block +30 LDA MAPTMP + STA MPTMPA + LDA MAPTMP+1 + STA MPTMPA+1 + LDA MAPTMP+2 + STA MPTMPA+2 + LDA OLDSZE + ORA OLDSZE+1 + ORA OLDSZE+2 + BEQ #40 + LDA OLDSZE + BEQ #60 ;If all of this block used continue +40 CLC + JSR RDMPBK ;Pretend its map block + LDA MAPTMP ;Ignore possible error + STA MPCYPT + LDA MAPTMP+1 + STA MPCYPT+1 + LDY OLDSZE + LDAIM 0 +50 STAIY MPCYPT ;Zero rest of block + INY + BNE #50 + JSR SETMB + JSR CASTWB ;Mark block written + JSR ENSMB ;Write it to disc + JSR SETMB + JSR FNDBLK ;FIND BLOCK TO FLUSH + LDAIM 0 + LDYIM CAFLG + STAIY GNCBPT + LDA MPTMPD + BNE #55 + DEC MPTMPD+1 +55 DEC MPTMPD + INC MPTMPA + BNE #60 + INC MPTMPA+1 + BNE #60 + INC MPTMPA+2 +;Next bit writes 0's to MPTMPD entries until +;none left. +60 JSR SETBM ;Use bit maps + JSR GETFR + LDYIM CBSA + LDAIY GNCBPT + STA MPCYPT + INY + LDAIY GNCBPT + STA MPCYPT+1 + LDYIM 0 + TYA +70 STAIY MPCYPT + INY + BNE #70 ;Area of store zeroed + LDA MPCYPT + STA DCSTAD + LDA MPCYPT+1 + STA DCSTAD+1 + LDA MPDRVE + STA DRIVNO +75 LDA MPTMPD + ORA MPTMPD+1 + BEQ #80 + LDA MPTMPA + STA RBDA + LDA MPTMPA+1 + STA RBDA+1 + LDA MPTMPA+2 + STA RBDA+2 + LDAIM &A + STA SAVCOM + JSR XFER + LDA MPTMPD + BNE #77 + DEC MPTMPD+1 +77 DEC MPTMPD + INC MPTMPA + BNE #75 + INC MPTMPA+1 + BNE #75 + INC MPTMPA+2 + JMP #75 + +80 JSR NXTEN + BNE #90 + LDA MAPTMP + STA MPTMPA + LDA MAPTMP+1 + STA MPTMPA+1 + LDA MAPTMP+2 + STA MPTMPA+2 + JMP #75 + +90 LDAIM 0 + RTS + + LNK MBBMCM diff --git a/Level3/SRC/L3/Uade14 b/Level3/SRC/L3/Uade14 new file mode 100644 index 0000000..a4128a8 --- /dev/null +++ b/Level3/SRC/L3/Uade14 @@ -0,0 +1,845 @@ + OPT UADE14 ; > Uade14 + TTL File server file UADE14 + +DSCTOP + ORG DSCTOP + + +;********************************* +;* D S C M A N * +;********************************* + +;DSCMAN: THE DISC MANAGER +;THIS MODULE READS & WRITES OBJECTS FROM +;AND TO THE DISC. +;NOTE THAT IT USES MANY OF THE POINTERS,VARIABLES, +;AND ROUTINES PROVIDED BY MAPMAN. + + +;ENTRY: +;ARGA = (1=>READ,2=>WRITE) +;ARGB-C DISC NO +;ARGD-F SIN +;ARGG-H START BLOCK NO +;ARGI-J NUMBER OF BLOCKS +;ARGK-L STORE ADDRESS + +;EXIT: ARGA = RC + + + +;********************************* +;* D S C M A N * +;********************************* + + + +;********** MAIN ROUTINE ********** + +DSCMAN LDXIM 4 + LDAIM MODDSC + JSR ENTRY + LDAAX DCRTNS + STA DCJUMP+1 + LDAAX DCRTNS+1 + STA DCJUMP+2 +DCJUMP JMP DCJUMP ;N.B. NO NEED FOR SETFS-NOT CALLING ANY MODULE +DCRTNS + & DCREAD ;1 => READ + & DCWRIT ;2 => WRITE + & DCIORD ;3 => READ (I/O processor) + & DCIOWR ;4 => WRITE (I/O processor) +DCEXIT BEQ DCEXEX + LDXIM &FF + STX ODSCMN ;invalidate cache on disc error + STX ODSCMN+1 +DCEXEX JMP PREXIT + + + + + +;************ DCREAD ************ + + +;DCREAD: READ AN OBJECT FROM THE DISC. +;NOTE IF A SECTOR HAS NOT BEEN WRITTEN THEN +;THE APPROPRIATE AREA OF STORE IS CLEARED TO ZERO. + + +DCIORD ROUT + JSR DCCACH ;check call against last caller + BEQ #40 ;all done !!!!! + + LDXIM &FF ;for I/O side operation + BNE #10 +DCREAD LDXIM 0 +10 STX DSCCB+TRADD+2 + STX DSCCB+TRADD+3 + + JSR DCINIT ;INITIALISE FOR DSCMAN VARIABLES + BNE #30 + + [ WINCH=0 + LDAIM 8 + | + LDAIM &53 ;DOS READ COMMAND + ] + STA SAVCOM ;SAVCOM := DOS DISC READ COMMAND + +20 JSR SETDSE ;DCSECT := SECTOR NUMBER + + + JSR SETDES ;SETUP DOS DISC DRIVE DESCRIPTOR + + [ DEBUG <> 0 + LDAIM "r" + JSR TRACE + ] + + LDA DCRASH + BNE #40 ;If a disc error occured in NMI +;task...error. + + JSR XFERIN ;TRANSFER MPTMPD SECTORS + JSR MOVEON ;FIND NEXT SECTORS FROM DISC MAP + BEQ #20 + CMPIM 1 + BNE #30 ;NO MORE SECTORS TO READ + LDAIM 0 +30 TAX + LDA DCRASH + BNE #40 ;Check no crash on last BG job + TXA +40 JMP DCEXIT + + + +;************ DCWRIT ************ + + +;DCWRIT: WRITE AN OBJECT TO DISC +;NOTE THAT IF A SECTOR IS WRITTEN FOR THE FIRST TIME +;IT IS MARKED DIRTY IN THE MAP (IN WHICH CASE +;THE MAP IS MARKED DIRTY). + + +DCIOWR ROUT + JSR DCCACF ;copy new stack into variables + LDXIM &FF ;for I/O side operation + BNE #10 +DCWRIT JSR DCSIN ;check invalidation of cache + LDXIM 0 +10 STX DSCCB+TRADD+2 + STX DSCCB+TRADD+3 + JSR DCINIT + BNE #30 + + [ WINCH=0 + LDAIM &0A + | + LDAIM &4B ;DOS DISC WRITE COMMAND + ] + STA SAVCOM ;SAVCOM:=COMMAND TO WRITE +20 JSR SETDSE ;DCSECT:=SECTOR NUMBER + JSR SETDES ;SETUP DRIVE DESCRIPTOR FOR DOS + + [ DEBUG <> 0 + LDAIM "w" + JSR TRACE + ] + + LDA DCRASH + BNE #30 + + JSR XFERIN ;START TRANSFR OF ONE SECTOR + + JSR MOVEON + BEQ #20 + + TAX + LDA DCRASH + BNE #30 + TXA + CMPIM 1 + BNE #30 ;NO MORE SECTORS TO READ + LDAIM 0 +30 JMP DCEXIT + + + + +;DCINIT: INITIALISE DSCMAN VARIABLES FOR TRANSFER +;0) GET APPROPRIATE DISC MAP LOADED +;1) LDRNB := LOGICAL DRIVE NUMBER (GOT FROM MAPTB ENTRY) +;2) NBLKS := NUMBER OF DISC BLOCKS TO TX +;3) DCSTAD := STORE ADDRESS OF SECTOR +;4) CHECK SIN IS FOR START OF OBJECT +;5) MAPTMP := SIN, MPSCPT:=PTR TO RELEVENT MAP ENTRY +;6) DSCTMP := PTR TO MAP'S DIRTY FLAG + + + +DCINIT ROUT + LDAIM 0 + STA DCRASH ;Initialise disc error flag + JSR FNDMAP ;MAPPTR & MAPENT PT MAPTB ENTRY + BNE #25 + LDA MPDRVE + STA LDRNB ;LDRNB:= LOGICAL DRIVE NUMBER + +;FIRST CHECK THAT THE SPECIFIED SIN IS SENSIBLE + + LDYIM ARGD + LDAIY ARGPTR + STA MPTMPA + INY + LDAIY ARGPTR + STA MPTMPA+1 ;MPTMPA:=SIN + INY + LDAIY ARGPTR + STA MPTMPA+2 + CLC + JSR RDMPBK + BNE #25 + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + LDAIM 0 + STA NBLKS+1 + LDYIM ARGI + LDAIY ARGPTR + STA NBLKS ;NBLKS:=NUMBER OF SECTORS TO BE TX + BNE #30 +20 LDAIM DCERRA ;INVALID NUMBER OF BLOCKS +25 RTS + +30 INY + LDAIY ARGPTR + BNE #20 + + LDYIM ARGK + LDAIY ARGPTR + STA DCSTAD + INY + LDAIY ARGPTR + STA DCSTAD+1 ;DCSTAD:=STORE ADDRESS + + +;NOW GET TO THE CORRECT STARTING POINT IN THE OBJECT + + LDYIM ARGG + LDAIY ARGPTR + STA BREGA + INY + LDAIY ARGPTR + STA BREGA+1 ;BREGA:=START BLOCK NUMBER + +DCENT2 LDAIM :LSB:MBENTS + STA MPTMPB + LDAIM :MSB:MBENTS + STA MPTMPB+1 + CLC + LDA MPMBPT + ADC MPTMPB + STA MPSCPT + LDA MPMBPT+1 + ADC MPTMPB+1 + STA MPSCPT+1 +50 SEC + LDYIM 3 + LDA BREGA + SBCIY MPSCPT + STA BREGA + LDA BREGA+1 + INY + SBCIY MPSCPT + STA BREGA+1 + BCC #60 + JSR NXTEN + BEQ #50 + RTS + +60 CLC + LDYIM 3 + LDAIY MPSCPT + ADC BREGA + STA BREGA + INY + LDAIY MPSCPT + ADC BREGA+1 + STA BREGA+1 + LDYIM 0 + CLC + LDAIY MPSCPT + ADC BREGA + STA MAPTMP + INY + LDAIY MPSCPT + ADC BREGA+1 + STA MAPTMP+1 + INY + LDAIY MPSCPT + ADCIM 0 + STA MAPTMP+2 + SEC + INY + LDAIY MPSCPT + SBC BREGA + STA MPTMPD + INY + LDAIY MPSCPT + SBC BREGA+1 + STA MPTMPD+1 + JSR SETSZE + LDAIM 0 + RTS + +SETSZE ROUT + LDA NBLKS + CMP MPTMPD + LDA NBLKS+1 + SBC MPTMPD+1 + BCS #10 + LDA NBLKS + STA MPTMPD + LDA NBLKS+1 + STA MPTMPD+1 +10 RTS + +NXTEN ROUT + CLC + LDA MPTMPB + ADCIM :LSB:ENSZ + STA MPTMPB + LDA MPTMPB+1 + ADCIM :MSB:ENSZ + STA MPTMPB+1 +10 CLC + LDA MPMBPT + ADC MPTMPB + STA MPSCPT + LDA MPTMPB+1 + ADC MPMBPT+1 + STA MPSCPT+1 + LDYIM 0 + LDAIY MPSCPT + INY + ORAIY MPSCPT + INY + ORAIY MPSCPT + BEQ #30 + LDA MPTMPB + CMPIM :LSB:LSTENT + LDA MPTMPB+1 + SBCIM :MSB:LSTENT + BCC #40 + LDYIM 0 + LDAIY MPSCPT + STA MPTMPA + INY + LDAIY MPSCPT + STA MPTMPA+1 + INY + LDAIY MPSCPT + STA MPTMPA+2 + LDA DSCCB+TRADD+2 + PHA + LDA DCSTAD + PHA + LDA DCSTAD+1 + PHA + LDA SAVCOM + PHA + CLC + JSR RDMPBK + BNE #20 + PLA + STA SAVCOM + PLA + STA DCSTAD+1 + PLA + STA DCSTAD + PLA + STA DSCCB+TRADD+2 + STA DSCCB+TRADD+3 + LDA MAPTMP + STA MPMBPT + LDA MAPTMP+1 + STA MPMBPT+1 + LDAIM :LSB:MBENTS + STA MPTMPB + LDAIM :MSB:MBENTS + STA MPTMPB+1 + JMP #10 + +20 TAX + PLA + PLA + PLA + PLA + TXA + RTS + +30 LDAIM DCERRC + RTS + +40 LDYIM 0 + LDAIY MPSCPT + STA MAPTMP + INY + LDAIY MPSCPT + STA MAPTMP+1 + INY + LDAIY MPSCPT + STA MAPTMP+2 + INY + LDAIY MPSCPT + STA MPTMPD + INY + LDAIY MPSCPT + STA MPTMPD+1 + LDAIM 0 + RTS + + +SETDSE LDA MAPTMP ;DCSECT := MAPTMP (I.E SECTOR NUMBER) + STA DCSECT + LDA MAPTMP+1 + STA DCSECT+1 + LDA MAPTMP+2 + STA DCSECT+2 + RTS + + +;SETDES: SETUP DOS'S DISC DRIVE DESCRIPTOR. +;SETUP CORRECT SECTOR NUMBER IN DOS DESCRIPTOR +;AND SELECT APPROPRIATE DRIVE, WHEN ACTUAL DRIVES +;CHANGE. +;A DRIVE MUST BE "DRVSEL" SELECTED & STARTED +;BEFORE TRANSFERS CAN BE INITIATED. +;HOWEVER WE WANT TO AVOID CALLING"DRVSEL" BETWEEN +;THE SECTORS OF A MULTI-SECTOR TRANSFER. + +;ENTRY: OLDFDR = LAST ACTUAL DRIVE NUMBER USED(SETBY SETDES) +;LDRNB = LOGICAL DRIVE NO(I.E. DISC UNIT) +;DCSECT = LOGICAL SECTOR NUMBER +;MAPENT = PTR TO RELEVENT MAPTB ENTRY(MAPMAN/FNDMAP) + +;FUNCTION:- +;SECTSD := NO OF SECTORS ON A SIDE OF THIS DISC; +;IF DCSECT >= SECTSD #NO OF SECTORS ON A SIDE# +;THEN SECTOR NO=SECTDC-SECTSD +;DRIVNO = LDRNB + 2 +;ELSE SECTOR NO=DCSECT; +;DRIVNO := LDRNB +;FI; +;IF DRIVNO <> OLDFDR +;THEN FDRIVE = DRIVE NUMBER +;JSR DRVSEL; +;IF DRIVNO <> othersideof OLDFDR THEN JSR ZTRKSL +;FI; + + +SETDES ROUT + LDA LDRNB + STA DRIVNO + + LDYIM MPSECS + LDAIY MAPENT + STA SECTSD + INY + LDAIY MAPENT + STA SECTSD+1 ;SECTSD:=NUMBER OF SECTORS ON A SIDE + INY + LDAIY MAPENT + STA SECTSD+2 + +10 LDA DCSECT + CMP SECTSD + LDA DCSECT+1 + SBC SECTSD+1 + LDA DCSECT+2 + SBC SECTSD+2 + BCC #20 + +;DCSECT >= SECTSD + + CLC + LDYIM MPDRNC + LDA DRIVNO + ADCIY MAPPTR + STA DRIVNO + SEC + LDA DCSECT + SBC SECTSD + STA DCSECT + STA RBDA + LDA DCSECT+1 + SBC SECTSD+1 ;SUBT NO. OF SECTORS ON A SIDE + STA DCSECT+1 + STA RBDA+1 + LDA DCSECT+2 + SBC SECTSD+2 + STA DCSECT+2 + STA RBDA+2 + JMP #10 + +;DCSECT < SECTSD + +20 + [ WINCH=0 + LDA DCSECT + STA RBDA + LDA DCSECT+1 + STA RBDA+1 + LDA DCSECT+2 + STA RBDA+2 + RTS + | + LDA DCSECT + STA DDRSCT+1 + LDA DCSECT+1 + ANDIM &F + STA DDRSCT ;SECTOR NUMBER + +;WORK OUT TRACK & SECTOR NUMBER + + + LDAIM 0 + STA CTRACK ;START FROM TRACK ZERO +30 LDYIM MPSPCY + SEC ;KEEP SUBTRACTING UNTIL CORRECT TRACK FOUND + LDA DCSECT + SBCIY MAPPTR + STA DCSECT + INY + LDA DCSECT+1 + SBCIY MAPPTR + STA DCSECT+1 + LDA DCSECT+2 + SBCIM 0 + STA DCSECT+2 + BCC #40 + INC CTRACK + JMP #30 + +40 LDYIM MPSPCY + CLC ;GET SECTOR NUMBER BACK + LDA DCSECT + ADCIY MAPPTR + STA DCSECT + STA CSECTR + INY + LDA DCSECT+1 + ADCIY MAPPTR + STA DCSECT+1 + LDA DCSECT+2 + ADCIM 0 + STA DCSECT+2 + RTS + + ] + + +;MOVEON: SET NXT SECTOR +;FUNCTION:- NBLKS -:=1 +;DCSTAD +:= BLKSZE +;MAPTMP := NXT SECTOR NUMBER +;MPSCPT := PTR TO NXT MAP ENTRY + +;EXIT: A = 0 => CARRY ON +;A = 1 => NO MORE BLOCKS TO TX +;A > 1 => ERROR + +MOVEON ROUT + SEC + LDA NBLKS + SBC MPTMPD + STA NBLKS + LDA NBLKS+1 + SBC MPTMPD+1 + STA NBLKS+1 + ORA NBLKS + BNE #10 + LDAIM 1 ;RC:=1 if no more blocks + RTS + +10 CLC ;INCREMENT STORE ADDRESS + LDA DCSTAD+1 + ADC MPTMPD + STA DCSTAD+1 + BCC #20 + LDAIM DCERRB ;STORE ADDR GONE ILLEGAL + JSR INTERR +20 JSR NXTEN ;UPDATE MAPTMP & MPSCPT + JMP SETSZE + + +XFER ROUT + LDAIM 1 + STA DDRSZE+1 + LDAIM 0 + JMP #10 + +XFERIN LDA MPTMPD + STA DDRSZE+1 + LDA MPTMPD+1 +10 STA DDRSZE + LDA DCSTAD + STA DDRSTA + LDA DCSTAD+1 + STA DDRSTA+1 + LDA SAVCOM ;A:=TYPE OF TRANSFER (READ/WRITE) + JSR TRANS + BEQ #40 ;is ok, end NMI + STA DCRASH ;record fault +40 RTS + + +;Block read and write +; On entry:: +; DRIVNO holds the drive number +; DDRSTA holds the start address +; CSECTR holds the start sector number +; CTRACK holds the start track number +; DDRSZE holds the number of sectors to transfer + + [ WINCH=0 +BLKRD ROUT + LDAIM &08 ;COMMAND FOR READ +TRANS STA DSCCB+CMD + LDA DRIVNO + CLC + RORA + RORA + RORA + RORA + ORA RBDA+2 + STA DSCCB+CMD+1 + LDA RBDA+1 + STA DSCCB+CMD+2 + LDA RBDA + STA DSCCB+CMD+3 + +;test for writing to sector zero + + LDA RBDA + ORA RBDA+1 + ORA RBDA+2 + BNE #10 + + LDAIM IERRAK ;writing to sector zero + JMP INTERR ;*** + +10 LDA DDRSTA + STA DSCCB+TRADD ; SAVE THE ADDRESS + LDA DDRSTA+1 + STA DSCCB+TRADD+1 + LDA DDRSZE+1 ;CHECK FOR END OF TRANSFER + STA DSCCB+LENGTH+1 + LDA DDRSZE + STA DSCCB+LENGTH+2 + LDAIM 0 + STA DSCCB + STA DSCCB+LENGTH + STA DSCCB+LENGTH+3 + STA DSCCB+CMD+4 + STA DSCCB+CMD+5 + JMP DSCCMD ;DO THE TRANSFER + + | + +BLKRD ROUT + LDAIM &53 ;COMMAND FOR READ +TRANS STA DSCCB+CMD + LDA DRIVNO + STA DSCCB ;SAVE THE DRIVE NUMBER + LDA DDRSTA + STA DSCCB+TRADD ; SAVE THE ADDRESS + LDA DDRSTA+1 + STA DSCCB+TRADD+1 + LDAIM 3 ;NUMBER OF PARAMETERS + STA DSCCB+NOPRMS +10 LDA DDRSZE ;CHECK FOR END OF TRANSFER + ORA DDRSZE+1 + BNE #20 +15 RTS + +20 SEC + LDAIM &A ;MAX NUMBER OF SECTORS + SBC CSECTR ;MAX WE CAN TRANSFER + STA DSCCB+PARAMS+2 + LDA DDRSZE ;IF THIS IS NON-ZERO TRANS CANNOT HAVE FINISHED + BNE #30 + LDA DSCCB+PARAMS+2 ;DO WE NEED THIS MANY + CMP DDRSZE+1 + BMI #30 ;SKIP IF NOT + LDA DDRSZE+1 + STA DSCCB+PARAMS+2 ;ONLY TRANSFER AMOUNT REQUIRED +30 LDA CSECTR + STA DSCCB+PARAMS+1 ;SAVE SECTOR NUMBER + LDA CTRACK + STA DSCCB+PARAMS ;SAVE TRACK NUMBER + LDAIM &20 ;256 BYTES PER SECTOR + ORA DSCCB+PARAMS+2 + STA DSCCB+PARAMS+2 + JSR DSCCMD ;DO THE TRANSFER + BNE #15 ;OOPS! FAILED + LDAIM &00 ;FROM NOW ON START AT SECTOR ZERO + STA CSECTR + INC CTRACK ;NEXT TRACK + LDA DSCCB+PARAMS+2 + ANDIM &F ;GET NUMBER OF SECTORS + STA CNTA + SEC + LDA DDRSZE+1 + SBC CNTA ;SUBTRACT FROM TOTAL + STA DDRSZE+1 + LDA DDRSZE + SBCIM 0 + STA DDRSZE + CLC + LDA DSCCB+PARAMS+2 + ANDIM &F + ADC DSCCB+TRADD+1 + STA DSCCB+TRADD+1 +; LDA DSCCB+TRADD+2 ;** 15/2/85 ** dangerous ! +; ADCIM &00 +; STA DSCCB+TRADD+2 + JMP #10 ;GET THE REST + ] + + [ WINCH=0 +DSCCMD ROUT + [ 0=1 + LDYIM 16 +00 LDAAY DSCCB + JSR WHEX + DEY + BPL #00 + LDAIM "r" + JSR OSWRCH + JSR OSCRLF + + ] + LDAIM 0 + STA DSCCB + + LDXIM :LSB:DSCCB + LDYIM :MSB:DSCCB + LDAIM &72 + JSR OSWORD + LDA DSCCB + BEQ #05 ; REPORT DISC ERRORS TO SCREEN 5/6/86 LH + JSR #10 +05 RTS + +10 PHA + LDAIM &73 + LDXIM DSCCB + LDYIM /(DSCCB ) + JSR OSWORD + JSR VSTRIN + = "Disc Error No. " + NOP + LDA DSCCB+3 + JSR WHEX + JSR VSTRIN + = " At Disc Address " + NOP + LDA DSCCB+2 + JSR WHEX + LDA DSCCB+1 + JSR WHEX + LDA DSCCB + JSR WHEX + PLA + RTS + + | +;DSCCMD +; SEND A COMMAND TO THE DISC CONTROLLER +; DSCCB IS THE CONTROL BLOCK AND MUST BE SET UP +; TRIES ANY ERROR 10 TIMES +; RETURNS WITH Z SET IF OK +; IF FAILED RETURNS WITH ERROR NUMBER +DSCCMD ROUT + LDAIM &A ;COUNT + STA CNTA +10 LDXIM :LSB:DSCCB + LDYIM :MSB:DSCCB + LDAIM &7F + JSR OSWORD + LDA DSCCB+PARAMS+3 ;LOOK AT REPLY + BEQ #20 + DEC CNTA + BNE #10 ;TRY AGAIN IF ERROR + LDA DSCCB+PARAMS+3 +20 RTS ;RETURN WITH CORRECT ERROR NUMBER + ] + +DCCACH ROUT + LDYIM ARGJ ;get MS number of blocks to load + LDAIY ARGPTR + BNE #40 ;exit 'cos its too big + DEY ;get LS number of blocks + LDAIY ARGPTR + CMP IOBSIZ+1 + BEQ #10 + BCS #40 ;overflow here + +DCCACF +10 LDYIM ARGL + LDXIM 10 + LDAIM 0 + STA GENPTR ;spare space + +20 LDAIY ARGPTR + CMPAX ODSCMN ;look against old stack + BEQ #30 + INC GENPTR ;unzero flag +30 STAAX ODSCMN ;save stack + DEY + DEX + BPL #20 ;loop until done + + LDA GENPTR ;load flag +40 RTS + +DCSIN ROUT + LDYIM ARGB + LDXIM 0 +10 LDAIY ARGPTR + CMPAX ODSCMN ;compare against old cache + BNE #20 + INY + INX + CPXIM 5 ;test disc number & SIN + BNE #10 + LDXIM &FF + STX ODSCMN ;invalidate cache + STX ODSCMN+1 +20 RTS ;return to main routine + +; Routine to perform 'test drive' function, +; user mainly to check for write protect +; A on entry is the required drive number + +Testdv ROUT ;**24/2/88** + PHA + LDXIM Length+3 + LDAIM 0 +10 STAAX Dsccb + DEX + BPL #10 + PLA + LSRA + RORA + RORA + RORA + STA Dsccb+Cmd+1 + JMP Dsccmd + + LNK UADE15 diff --git a/Level3/SRC/L3/Uade15 b/Level3/SRC/L3/Uade15 new file mode 100644 index 0000000..0012e69 --- /dev/null +++ b/Level3/SRC/L3/Uade15 @@ -0,0 +1,908 @@ + OPT UADE15 ; > Uade15 + TTL File server file UADE15 + + +;* C O M M A N D P R O C E S S O R* + +CMND JSR GETBB ;Get big buffer ! + + JSR VSTRIN + = CR,"Starting - " + NOP + + +CLPA LDXIM MONON + STX MONFLG ;Monitor ON to start with + STX OTIME + STX OTIME+1 ;timer timeout + +;SET UP RXCB + + INX + STX EVCHAR ;initialise event flag + STX RIPPLE ;Rxcb counter + + JSR OPENRX ;open CB1 + + LDA &220 + STA OLDEV + LDA &220+1 + STA OLDEV+1 + + LDAIM :LSB:EVENT + STA &220 + LDAIM :MSB:EVENT + STA &220+1 + + LDAIM 14 + LDXIM 2 + JSR OSBYTE ;enable KB event + LDAIM 229 ;disable escape + LDXIM 1 + JSR OSBYTE + + JSR VSTRIN + = "Ready",CR,CR,15 + NOP + + + LDAIM 53 + JSR OSBYTE ;** 13/2/84 ** + ; sever any REMOTE connection now + + LDXIM :LSB:PROT + LDYIM :MSB:PROT + LDAIM &13 ; Net OSWORD + JSR OSWORD ; Set protection mask + +CLPD ;CLPD + +; Poll KB and Rxcb's in the I/O processor + +CPOLL0 + + LDA EVCHAR ;look for event + BEQ COMRTS + LDXIM 0 + STX EVCHAR ;reset the flag + CMPIM ESC + BEQ DOCHDI + ANDIM &DF ;force upper case + CMPIM "M" + BEQ DOMONT ;switch monitor status + CMPIM "Q" + BEQ DOQUIT ;call HALT + +;else fall through .. +;Now poll the control blocks using the MOS + +COMRTS ;come here for new command + + LDX RXTAB ;get number of CB to poll + STX RXCBN ;save this for later use + LDAIM 51 ;poll Rx number (X) + JSR OSBYTE ;result returned in X + TXA + BMI DOCMND ;leap off to deal with the Rx'd packet + JSR PRTIM ;** only call dongle every 30 or so seconds ** + JMP CPOLL0 + +DOCHDI ;DOCHDI + LDAIM &7E + JSR OSBYTE ;acknowledge escape condition here + JSR NOEVNT ;disable events + LDAIM 8 + JSR SETRTN ;ensure free space table + JSR USRMAN + JSR CHDISC ;*** CHANGE DISC ** + JMP CLPA ;back to the start + +DOQUIT ;DOQUIT + JSR NOEVNT ;disable events + LDAIM 8 ;ensure all users free space ** 3/10/84 ** + JSR SETRTN + JSR USRMAN ;no RC from this + JSR FLUSYS + LDXIM :LSB:DOBYE + LDYIM :MSB:DOBYE + JSR OSCLI ;*bye the discs + JMP INITCO ;Back to COMMAND prompt + +DOBYE = "Bye",CR + + +;Switch monitor and go back to loop start. + +DOMONT ROUT + JSR VSTRIN + = CR,"Monitor " + NOP + + LDX MONFLG + CPXIM MONOFF + BEQ #10 + JSR VSTRIN + = "OFF" + NOP + LDAIM MONOFF + JMP #20 + +10 JSR VSTRIN + = "ON" + NOP + LDAIM MONON +20 STA MONFLG + +DBNCEX JSR OSCRLF + JMP CLPD ;Go back to main RX loop + + +;Reception has happened, so check +;the function code in the RXbuffer +;and jump to the operation. + +DOCMND ROUT + LDA RXCBN ;save CB number + PHA ;altered in OPENRX + JSR OPENRX ;open a new Rxcb + PLA ;RXTAB updated to new CB here + STA RXCBN ;reset CB number + + LDXIM :LSB:RXCBN + LDYIM :MSB:RXCBN + LDAIM &11 ;MOS interface + JSR OSWORD ;read the control block + +; the structure set up in RXCBV is of the form +; CB number (1) ;in RXCBN +; CB data (12) + +; Thus QPTR is always zero as only one CB is +; read at any time + + LDAIM &00 + STA QPTR ;standard offset + SEC + LDA RXCBV+4 ;get low byte of address + SBCIM RXBUF ;calulate buffer offset + STA BPTR ;point at the buffer + TAX + + LDAAX RXBUF ;Reply port at top of buffer + STA RPLYPT ;Store reply port + + LDA CBBUF + STA OLDRXB ;STORE OLD BUFFER PTR. + LDA CBBUF+1 + STA OLDRXB+1 + + +;Provide p.0 pointer to control block (used +;in XMIT/REPLY etc.) + + CLC + LDA QPTR + ADCIM :LSB:RXCBV + STA NETCB + LDAIM :MSB:RXCBV + ADCIM 0 + STA NETCB+1 + + LDAAX RXBUF+1 ;Get fn. code + BEQ #50 ;Don't monitor commands immediately + + PHA + JSR MONITR ;*** Do monitor ** + PLA + + CMPIM FCMAX ;Is < biggest fn. code? + BCC #50 ;Yes => ok + + LDAIM COERRA + +;Send error return to machine + + JSR EXTERR + +;Finish command (don't matter if error +;didn't get through). + + JMP COMRTS + +;FN. code is ok, so get routine entry address + +50 ASLA + TAX + + LDY BPTR + LDAAY CPUFD ;**20/5/87** set all handles for use + STA UMHUFD ;**20/5/87** by pseudo-directory references + LDAAY CPLIB + STA UMHLIB + LDAAY CPCSD + STA UMHCSD + + LDAAX FNTAB + STA GENPTR + LDAAX FNTAB+1 + STA GENPTR+1 + +;ENTER ROUTINE .. + + JMI GENPTR + + + +;T A B L E S + +CTABA ROUT + +;Initial receive control block +;First 12 bytes - addresses may change + + = RXFLAG + = COPORT ;Command port + = 0 + = 0 ;Set to RX on any station + & RXBUF + = 0,0 + & RXBUF+RXBUFL + = 0,0 + +FNTAB ROUT + +;Addresses of functions + + & CLINE ;Decode command line + & SAVE ;1 + & LOAD ;2 + & EXAMIN ;3 + & CATHDR ;4 + & LOAD ;Load command for execution + & FIND ;6 + & CPSHUT ;7 + & GETBYT ;8 + & PUTBYT ;9 + & GBYTES ;10 + & PBYTES ;11 + & CPRDAR ;=> GETARGS + & CPSTAR ;=> SETARGS + & DISCS ;14 + & CPUSRS ;15 + & CPDATE ;16 + & CPEOF ;17 + & CPINFO ;18 + & CPSTAT ;Set object attributes + & CPDEL ;Delete from fn. code + & USRENV ;21 + & CPSOPT ;Set user option bits + & FCBYE ;Logoff by function code + & CPUINF ;Single user info. + & CPVERN ;25 + & CPSPAC ;26 - returns disc free space + & CDIRFN ;27 - cdir from function code, specify size + & CPSETD ;28 - Set date and time from program + & SAVE ; 29 - Do a 'create', like 'save' but no data + & RDFREE ;30 - read callers free space + & WRFREE ;31 - write users free space + & CPWHO ;32 - return client user name +FNusr2 & CPUSRS ;33 - user list with job/task numbers +FNuin2 & CPUINF ;34 - single user info with job/task number +FCMAX * (.-FNTAB)/2 + +;COMMAND LINE DECODER .... + + +COMTAB + + [ Lang = English + = "DELETE",&A0 + & DELETE + = "INFO",&A0 + & INFO + = "DIR",&A0 + & SELDIR + = "SDISC",&A0 + & SELDSC + = "CDIR",&A0 + & CDIR + = "ACCESS",&A0 + & SETACC + = "PASS",&A0 + & SETPW + = "I AM",&B0 + & LOGON + = "BYE",&A0 + & USROFF + = "NEWUSER",&A0 + & NEWUSE + = "PRIV",&A0 + & STPRIV + = "LIB",&A0 + & SLIB + = "REMUSER",&A0 + & REMUSE + = "RENAME",&A0 + & RENAME + = 0 ;Indicates table end + ] + + [ Lang = Italian + = "CANCELLA",&A0 + & DELETE + = "INFO",&A0 + & INFO + = "DIR",&A0 + & SELDIR + = "SDISC",&A0 + & SELDSC + = "CDIR",&A0 + & CDIR + = "ACCESSO",&A0 + & SETACC + = "PASSA",&A0 + & SETPW + = "I SONO",&B0 + & LOGON + = "CIAO",&A0 + & USROFF + = "NUTENTE",&A0 + & NEWUSE + = "PRIV",&A0 + & STPRIV + = "BIBL",&A0 + & SLIB + = "RIMUT",&A0 + & REMUSE + = "RINOME",&A0 + & RENAME + = 0 ;Indicates table end + ] + +CLINE ROUT + LDXIM &FF + CLD +10 LDY BPTR + JSR SPACES + DEY +20 INY + INX + LDAAX COMTAB + BEQ BADCOM ;Last delimiter is zero + BMI #50 ;Check next char after command is non-alpha + EORAY MIDRX ;Compare + ANDIM &DF ;Force cases + BEQ #20 + DEX +30 INX + LDAAX COMTAB + BPL #30 + LDAAY MIDRX + CMPIM "." + BNE #55 + INY + JMP #60 + +50 LDAAY MIDRX ;Otherwise check char. after cmnd. is non-alpha + JSR ISCHAR + BCS #60 ;Is non-alpha => end of command +55 INX + INX ;Inc. past terminator and address + JMP #10 + +60 LDAAX COMTAB+1 ;Get command processor address + STA Cozero + LDAAX COMTAB+2 + STA Cozero+1 + JMI Cozero ;Enter command processor + + +;UNRECOGNISED COMMAND + +BADCOM ROUT + JSR BUFTXT + BNE #30 ;Quotes error + LDXIM 0 ;Now move from TXTBUF to TXBUF +10 LDAAX TXTBUF + STAAX MIDTX + INX + CMPIM CR + BNE #10 + + CPXIM 1 + BNE #20 + LDAIM WOTERR + JSR EXTERR ;Do WHAT? error immediately + JMP #30 + +20 TXA + CLC + ADCIM TXHDR ;Message length + LDYIM CCCMND + STY CCODE + JSR REPLYC +30 JMP COMRTS + + [ Lang = English +40 = "Bad command in ",0 + ] + [ Lang = Italian +40 = "Comando errato nel ",0 + ] + + +MONITR ROUT + BIT MONFLG + BPL #15 ;bit7=0 -> no monitor + + LDXIM MONTL ;length of the 'monitored' function codes table + +10 CMPAX MONT1 ;look for function match + BEQ #20 ;found one + DEX + BPL #10 ;if fall thru' then exit +15 RTS + +20 STX COTEMP+1 ;save this for later use + JSR PRTMC ;print the machine number + + JSR VSTRIN + = ": " + NOP + + LDYIM 0 + LDX COTEMP+1 + BEQ #65 ;CLI here + +30 LDAAY MONT3 ;read though the text + BEQ #40 ;count the number so far + INY + BNE #30 +40 INY + DEX + BNE #30 + LDX COTEMP+1 + +50 LDAAY MONT3 ;now at the correct operation + BEQ #60 + JSR WRCH ;print ascii chars only + INY ;step thru' + BNE #50 ;stop on zero + +60 JSR MONOUT ;print a space +65 LDAAX MONT2 ;determine objectname offset (if any) + BMI #90 ;none here + + CLC + ADC BPTR + TAY ;Y has offset within the buffer + +70 LDAAY MIDRX ;get chars from Rx buffer + CMPIM CR ;end of name + BEQ #80 + JSR WRCH ;print the name + INY + BNE #70 + +80 JSR MONOUT ;print another space + +90 LDAAX MONT4 ;determine size offset (if any) + BMI #95 + CLC + ADC BPTR + TAY ;Y has offset within the buffer + + LDAAY MIDRX+2 + JSR WHEX + LDAAY MIDRX+1 + JSR WHEX + LDAAY MIDRX + JSR WHEX + +95 JMP OSCRLF + + +WRCH CMPIM &7F + BCS #15 + CMPIM &20 + BCC #15 + JMP OSASCI ;print ascii characters + +MONT1 = 0,1,2,5,20,23,27,29 ;function codes +MONT2 = 0,11,0,0,0,-1,1,11 ;name offsets +MONT3 + = 0 ;CLI here + = "Save",0 + = "Load",0 + = "Run",0 + = "Delete",0 + = "Bye",0 + = "Cdir",0 + = "Create",0 +MONT4 = -1,8,-1,-1,-1,-1,-1,8 ;length offsets +MONTL * MONT2-MONT1-1 + + + + [ 1=0 + +;Print machine number. + +PTRMC ROUT + LDA CBSTID+1 + BEQ #10 ;Net. no. = 0 + JSR WRTDEC + JMP #20 +10 JSR VSTRIN + = " " + NOP +20 LDAIM SPACE + JSR OSWRCH + LDA CBSTID + +WRTDEC ROUT + STA TEMPA + LDAIM 0 + STA TEMPB + TXA + PHA + TYA + PHA + LDXIM "/" ;Hundreds + LDA TEMPA + SEC +10 SBCIM &64 + INX + BCS #10 + ADCIM &64 + PHA + TXA + JSR WRTDIG + LDXIM "/" ;Tens + PLA + SEC +20 SBCIM &A + INX + BCS #20 + ADCIM &A + PHA + TXA + JSR WRTDIG + DEC TEMPB + PLA + CLC + ADCIM "0" + JSR WRTDIG + PLA + TAY + PLA + TAX + RTS + +WRTDIG ROUT + CMPIM "0" + BNE #10 + BIT TEMPB + BMI #20 + LDAIM SPACE + BNE #20 +10 DEC TEMPB ;Only works for 15 leading spaces +20 JMP OSWRCH + + | + +PRTMC ROUT + LDA CBSTID+1 + BEQ #05 + + JSR MKDEC ;make decimal + JSR #30 ;print the network number + LDAIM "." + JSR OSWRCH + JMP #15 + +05 LDXIM 4 +10 LDAIM SPACE + JSR OSWRCH + DEX + BNE #10 ;print spaces + +15 LDA CBSTID + JSR MKDEC ;convert to decimal + JSR #30 + LDXIM 4 + LDA CBFLG + ANDIM MCtask ;**12/6/87** isolate job/task number + BEQ #20 + LSRA + LSRA + LSRA + LSRA + PHA + LDAIM "[" + JSR OSWRCH + PLA + JSR WHEXD + LDAIM "]" + JSR OSWRCH + LDXIM 1 +20 LDAIM SPACE + JSR OSWRCH + DEX + BNE #20 + RTS + +30 LDA COWORK ;msig digit + JSR OSWRCH + LDA COWORK+1 + JSR OSWRCH + LDA COWORK+2 + JMP OSWRCH ;print all three characters in COWORK + + +;Convert to decimal + +MKDEC ROUT + TAY + LDAIM &FF + STA TEMPA ;leading zero flag + + LDAIM 100 + JSR #10 + STA COWORK + LDAIM 10 + JSR #10 + STA COWORK+1 + LDAIM 1 + +10 STA COWORK+3 + TYA + LDXIM "0"-1 + SEC + +20 INX + SBC COWORK+3 + BCS #20 + ADC COWORK+3 + + CPXIM "0" + BNE #30 + BIT TEMPA + BPL #30 + LDXIM SPACE + BNE #40 + +30 INC TEMPA ;print zeros +40 TAY ;restore original parameter + TXA + STA COWORK+2 ;save this for now + RTS + ] + +;CHDISC +;1) READ DRIVE NUMBER (IF DRIVES>1) +;2) GET DISC NUMBER FOR DRIVE +;3) FLUSH ALL OBJECTS FROM STORE +;4) ENSURE DISC MAP +;5) RESTART (MAPMAN) +;6) RESTART (AUTMAN) + +CHDISC ROUT + LDA DRIVES + SEC + SBCIM 1 + BEQ #10 ;ONE DRIVE, CONTINUE + + JSR RDDRIV + BNE #50 ;IF QUIT TYPED, QUIT ** 13/9/84 + +10 PHA ;STORE DRIVE NO. + JSR CHMSG ;"CHANGING DRIVE - ??" + PLA + STA CURDRV + JSR DRVINF ;GET DISC NO. + + BNE #40 ;ABORT IF ERROR + + LDAIM 8 + JSR SETRTN + JSR STRMAN ;*** FLUSH STORE ** + BNE #40 + + LDAIM 6 + JSR SETRTN + JSR MAPMAN ;*** ENSURE DISC ** + BNE #40 + +20 JSR CHMSGA ;"LOAD NEW DISC" + BNE #50 ;IF ABORT, ABORT ** 13/9/84 ** + + LDA CURDRV + LDYIM ARGB + STAIY NEWARG + LDAIM 9 + JSR SETRTN + JSR MAPMAN ;*** RESTART DRIVE ** + BEQ #30 ;ALL WELL, FINISH + + JSR USRERR ;ERROR, PRINT MESSAGE + JMP #20 + +30 JSR GETPWF ;Restart AUTMAN + JSR VSTRIN + = CR,"Restarting - " + NOP + + RTS + +40 JSR INTERR +50 JSR FLUSYS ;clear out the system + JMP INITCO ;** 13/9/84 ** return to command prompt after abort + + +;READ DRIVE NUMBER FROM CMND. LINE + +RDDRIV ROUT + JSR VSTRIN + = CR,"Drive: " + NOP + + JSR RDLINE + + LDYIM 0 + LDAIY COMPTR + ANDIM &DF ;force upper case + CMPIM ABTCH ;ABORT ?? "Q" + BNE #10 ;** 13/9/84 ** + + LDAIM &FF + BNE #20 ;ABORT ... + +10 JSR GETINT ;GET DRIVE NO. + BNE RDDRIV ;DO AGAIN IF NESC. + + LDA INTEGR+1 + BNE RDDRIV + + LDA INTEGR + CMP DRIVES + BCS RDDRIV ;INTEGR>=DRIVES -> ERROR + + LDXIM 0 ;GIVE Z SET EXIT +20 RTS + + + +CHMSG ROUT + PHA + JSR VSTRIN + = CR,"Changing drive - " + NOP + + PLA + JSR WHEX + JMP OSCRLF + + + +CHMSGA ROUT + JSR VSTRIN + = CR,"Load new disc",CR + NOP + +10 JSR OSECHO ;fudge around ESCAPE problem ** 28/9/84 ** + CMPIM SPACE + BEQ #20 + ANDIM &DF ;force upper case ** 13/9/84 ** + CMPIM ABTCH + BNE #10 + + LDAIM &FF ;GIVE ABORT EXIT +20 RTS + + + +;Call AUTMAN restart and write message +;if PW file not found. + +GETPWF ROUT + LDAIM 6 + LDYIM ARGA + STAIY NEWARG + JSR AUTMAN + BEQ #10 + + JSR VSTRIN + = CR,"WARNING - PW File not found" + NOP + +10 RTS + +EVENT ROUT + PHP ;save status over routine + PHA + CMPIM 2 + BNE #10 + STY EVCHAR + PLA + PLP + RTS + +10 PLA + PLP + JMI OLDEV ;unknown event + +NOEVNT ROUT + LDAIM 15 + LDXIM 0 + JSR OSBYTE ;flush buffer + + LDAIM 13 + LDXIM 2 + JSR OSBYTE ;disable event + LDAIM 229 + LDXIM 0 + JSR OSBYTE ;re-enable escape + + LDA OLDEV + STA &220 + LDA OLDEV+1 + STA &220+1 + + LDX RXCBN ;get CB number + LDAIM 52 + JMP OSBYTE ;delete open CB + +; Routine to open RECEIVE CB + +OPENRX ROUT + LDXIM 11 ;Table offset +10 LDAAX CTABA + STAAX RXCBV ;Set flag, port and stid and bfr addresses. + DEX + BPL #10 + + LDAIM 0 + STA RXCBN ;ready for OSWORD call + +;Now correct buffer pointers if second buffer. +;The one byte gap between the buffers +;is to prevent corruption when a zero is placed +;at the end of received data to prevent +;catastrophe when a bad file name is being +;decoded. + + LDA RIPPLE + INC RIPPLE + LSRA ;flag in carry + + BCC #20 + + LDAIM :LSB:(RXBUF+RXBUFL+1) + STA RXCBV+4 + LDAIM :MSB:(RXBUF+RXBUFL+1) + STA RXCBV+5 + + LDAIM :LSB:(RXBUF+RXBUFL+RXBUFL+1) + STA RXCBV+8 + LDAIM :MSB:(RXBUF+RXBUFL+RXBUFL+1) + STA RXCBV+9 + +;At this point, previous CB is set to receive. + +20 LDXIM :LSB:RXCBN + LDYIM :MSB:RXCBN + LDAIM &11 + JSR OSWORD ;do OPENRX + + LDA RXCBN + STA RXTAB ;save CB number + BNE #30 + + LDAIM IERRAI ;unable to open Rxcb + JMP INTERR + +30 RTS + + + LNK UADE16 diff --git a/Level3/SRC/L3/Uade16 b/Level3/SRC/L3/Uade16 new file mode 100644 index 0000000..9a713fa --- /dev/null +++ b/Level3/SRC/L3/Uade16 @@ -0,0 +1,884 @@ + OPT UADE16 ; > Uade16 + TTL File server file UADE16 + +;SAVE/LOAD/ ETC. + +;************* +;* S A V E * +;************* + +;1) Do FINDMC, get disc number from +;DIRMAN file title -> disc number + +;2) Call CREATESPACE in MAPMAN using above args +;and size given in operation request +;for create goto 7 +;3) Send first reply +;4) Receive blocks one at a time into big buffer +;5) Write to disc (DSCMAN) +;6) If disc error, continue to receive, +;but set error flag +;7) All received OK => call PRESERVE in DIRMAN +;8) Send final return code +;9) Possibly DELETE previous file from map, +;flush from store and ensure map. + +;**8/2/88** Command level code deleted + +SAVE ROUT ; Also entered here for a CREATE 11/6/84 BC + JSR STKUSE ;Set m/c no. and call FINDMC + BNE #22 ;Fail, return + + LDAIM 13 ;**23/3/88** DIRMAN.CHECKPRES + JSR #95 ;**23/3/88** see if file will preserve + BNE #23 + + LDAIM &A ;File title -> disc number + JSR SETRTN + + JSR STKUSA + LDAIM SAVFTO + JSR SETFTP + INY + LDAIM &80 ;no wild cards in last name + STAIY NEWARG + + JSR DIRMAN ;Disc number on stack + BNE #23 ;**9/6/87** + + LDX BPTR + LDYIM ARGD + +;Move size from message buffer to +;arg. stack for create space call + +10 LDAAX MIDRX+8 + STAIY NEWARG + INX + INY + CPYIM ARGD+3 + BNE #10 + DEY ;pass info @ ARGG,H + JSR SETUSE ;put userinfo on stack + + LDAIM 1 + JSR SETRTN + + JSR MAPMAN ;** CREATE SPACE ** + BNE #23 + + LDXIM 4 + LDYIM ARGF +20 LDAIY NEWARG + STAAX DANDS ;Save disc. no. and SIN + DEY + DEX + BPL #20 + + ; New stuff for create 11/6/84 BC + LDX BPTR + LDAAX FCODE + EORIM FCCRET ; The function code for create + BNE #25 + LDAIM 0 + STA CCODE ; Blat the command return code + JMP #70 + +22 JMP COMRTS ;Finish + +23 JMP ERROR + +25 LDAIM PSAVD + STA MIDTX ;Save data port + + LDAIM :LSB:BUFSZ ;** 6/2/84 ** + STA MIDTX+1 ;Size of save buffer + LDAIM :MSB:BUFSZ ;** 6/2/84 ** + STA MIDTX+2 ;Size of save buffer hi + + LDAIM 0 + STA RTCODE + LDAIM 3 ;offset in buffer of name + STA CCODE + + JSR SAVNAM ;get filename + TYA ;Y=length of filename + CLC + ADCIM TXHDR+7 + + JSR REPLY ;Send message with 0 RC and C.code + BNE #42 ;No contact => abort + +;If we get here, ready to receive +;data, so set up for receive loop. + + LDAIM 0 + STA DATAIN + STA DATAIN+1 + STA DATAIN+2 ;DATAIN -> no. of bytes received + STA DSCERR ;Error flag + LDX BPTR + LDAAX MIDRX+8 ;Check if zero length file + ORAAX MIDRX+9 + ORAAX MIDRX+&A + BNE #35 ;Nope -> carry on + JMP #65 ;Yep -> send final reply + +35 LDAIM 0 + LDYIM ARGG + STAIY NEWARG ;Current disc block start + INY + STAIY NEWARG ;Current disc block start (hi) + +;Set buffer pointers in control block + +40 LDY QPTR + LDA IOBUF + STAAY CBBUF + LDA IOBUF+1 ;Buffer (hi) + STAAY CBBUF+1 + + LDA IOEND + STAAY CBBUFE ;Buffer end (lo) + LDA IOEND+1 + STAAY CBBUFE+1 ;Buffer end (hi) + + LDAIM &FF + STAAY CBBUF+2 + STAAY CBBUF+3 + STAAY CBBUFE+2 + STAAY CBBUFE+3 ;high order addresses + + LDAIM PSAVD ;Set data port + STAAY CBPORT + + JSR WAIT ;Station set + BEQ #45 ;Ok, continue +42 JMP #90 ;No contact => abort + +;Now subtract buffer received limits to +;get how much data was received. + +45 LDY QPTR ;** Y corrupted in WAIT ** + SEC + LDAAY CBBUFE + SBCAY CBBUF + STA DIVPAR + + LDAAY CBBUFE+1 + SBCAY CBBUF+1 + STA DIVPAR+1 + LDAIM 0 + STA DIVPAR+2 ;Top byte always 0 + +;Add no. received to total no. of +;bytes received. + + CLC + LDA DIVPAR + ADC DATAIN + STA DATAIN + LDA DIVPAR+1 + ADC DATAIN+1 + STA DATAIN+1 + LDA DIVPAR+2 ;For superstitions sake + ADC DATAIN+2 + STA DATAIN+2 + + LDA DSCERR + +;If error code set, ignore received +;data and jump past disc write. + + BNE #50 + + JSR DIVIDE ;Get no. of disc blocks to write (in BREGA) + + LDYIM ARGI + LDA DIVPAR + STAIY NEWARG + INY + LDA DIVPAR+1 + STAIY NEWARG ;No. of blocks to write + INY + LDA IOBUF + STAIY NEWARG ;Address of data to write + INY + LDA IOBUF+1 + STAIY NEWARG ;As above (hi) + + LDYIM ARGB + JSR SINDSC ;Set SIN and disc number + + LDAIM 4 ;write from IO side + JSR SETRTN + JSR DSCMAN + BEQ #50 + STA DSCERR + + +;Now compare amount received (in DATAIN) +;with file size (in receive message buffer). + +50 LDY BPTR + SEC + LDAAY MIDRX+8 + SBC DATAIN + STA BREGA + LDAAY MIDRX+9 + SBC DATAIN+1 + STA BREGA+1 + LDAAY MIDRX+&A + SBC DATAIN+2 + + ORA BREGA + ORA BREGA+1 + BEQ #65 ;If equal, SAVE finished... + BCS #55 ;If rx'd < size, carry on + +;Otherwise, client has sent too +;much data, so send error code and +;abort. + + LDAIM SAVERA ;Error code + JMP #85 + +;Add no. of blocks saved to block +;start to get block start for next +;reception of data. + +55 LDYIM ARGI + LDAIY NEWARG + DEY + DEY + CLC + ADCIY NEWARG + STAIY NEWARG + INY + LDAIY NEWARG + INY + INY + ADCIY NEWARG + DEY + DEY + STAIY NEWARG + +;Now send ack. on ack. port sent from client + + LDY BPTR + LDXAY CPUFD ;Ack. port + LDAIM 1 ;Message length + JSR REPLYB + BNE #90 ;Not ok, abort + JMP #40 ;Go off round loop again. + +;At this point, have received the +;correct amount of data, so check +;error flag to see if all data was +;written, and if not, send the +;error off as a return code. + +65 LDA DSCERR + BNE #85 + +;Now prepare to do PRESERVE to +;keep the data on disc. + +70 LDAIM DRPRS ;DIRMAN.PRESERVE + JSR #95 + BNE #85 + + LDYIM ARGG ;** 4/8/83 ** + LDAIY NEWARG ;access status + STA MIDTX + LDAIM TXHDR+3 ;Otherwise reply with access + date + JSR REPLYC + + JSR OBJCLR ;Delete object if neccessary (see PRESERVE) + BNE #85 ;**** 17/3/83 **** + +80 JMP COMRTS ;Finished ... exit + +85 JSR EXTERR ;Send error to client + +;Abort exit ... clear entry from +;map of created space using FREESTORE, +;and exit. + +90 LDYIM ARGB + JSR SINDSC ;Get disc/sin to stack + LDAIM 2 + JSR SETRTN + + LDYIM ARGF ;pass pointer to user info (ARGG,H) + JSR SETUSE ;** 3/10/84 ** + + JSR MAPMAN ;** Free space ** + BEQ #80 + JSR INTERR + +;Routine to call DIRMAR.DRPRS or DIRMAN.CHECKPRES +;DIRMAN function code in A on entry + +95 JSR SETRTN + LDYIM ARGO ;SIN GOES IN ARGQ->ARGS (!) + JSR SINDSC ;Get SIN/DISC to stack + LDAIM &80 + STAIY NEWARG ;ARGT = wild card flag + + JSR STKUSA + LDAIM SAVFTO + JSR SETFTP + + [ Pseudods = Yes + LDYIM UTHUFD ;**1/7/87** fix up user root handle + LDAIY USTPTR + STA UMHUFD + ] + +;Move load/exec addresses from +;receive message buffer to stack + + LDX BPTR + LDYIM ARGF +97 LDAAX MIDRX + STAIY NEWARG + INX + INY + CPYIM ARGF+8 + BNE #97 + + LDAIM ACCDEF ;Access default + STA MIDTX ;Store for final reply + STAIY NEWARG + + [ 1=0 + JSR SETDAT ;Read time chip if present + ] + LDYIM ARGO + LDA DATE + STA MIDTX+1 ;Store for final reply + STAIY NEWARG + INY + LDA DATE+1 + STA MIDTX+2 ;Store for final reply + STAIY NEWARG + + JMP DIRMAN ;*** DO PRESERVE ** + + +;************* +;* L O A D * +;************* + +;1) RETRIEVE object info. (DIR. MAN) +;check access and type. + +;2) Get handle of file, and open for +;reading, just in case. + +;3) REPLY +;4) Loop round DSCMAN doing getdata from disc +;into Big Buffer, and sending to client. +;If disc error, set error flag but continue +;to pad out data until loop end. +;5) Return code reply. + +;**8/2/88** Command level code deleted + +LOAD ROUT + JSR GETUSE ;Get user info. using FINDMC + BNE #17 ;Fail, exit + + [ Pseudods = Yes + LDYIM UTHUFD ;**1/7/87** fix up user root directory + LDAIY USTPTR + STA UMHUFD + ] + + JSR LDRETR ;Do retrieve + BEQ #20 ;OK, continue + + LDX BPTR + LDYAX FCODE + CPYIM FCCMND ;Do a command ?? + BNE #15 ;Nope, send not found error. + + LDAAX CPLIB ;Get lib. handle + LDYIM UTHSLD + STAIY USTPTR ;Note, assumes USTPTR still OK from STKUSE. + + JSR LDRETR ;Do another retrieve. + BEQ #20 ;OK, continue + CMPIM DRERRC + BEQ #10 ;Is, "not found". + CMPIM DRERRA ;Is bad file title ? + BNE #15 ;Nope, carry on +10 LDAIM WOTERR +15 JMP ERROR + +17 JMP COMRTS ;Finish !!! + +20 LDYIM ARGB + LDAIM TYPDIR ;Directory type + ANDIY NEWARG ;0 => is file + BEQ #25 ;OK, carry on + LDAIM LODERA ;Not ok, external error + BNE #15 + +25 LDAIM READAC + ANDIY NEWARG + BNE #30 ;Read access => OK + LDAIM LODERB ;Not ok, external error + BNE #15 + +30 LDA DETDIS + STA DANDS ;Store Disc. no. + LDA DETDIS+1 + STA DANDS+1 + + LDXIM 2 +35 LDAAX DETSIN ;Store SIN + STAAX DANDS+2 + DEX + BPL #35 + + LDAIM 2 ;arg to RNDMAN.INFO + JSR SETRTN + INY + JSR SINDSC ;put disc number & SIN on stack + JSR RNDMAN + BNE #40 ;opject not open at all + LDYIM ARGB ;test mode of access to object + LDAIY NEWARG + ANDIM &02 ;test bit 1 (write bit) + BEQ #40 + LDAIM DRERRI ;object in use + BNE #15 + +;Move load/exec info. from COWORK to transmit buffer +;Note CPYLXS copies date and access as well + +40 LDXIM 0 ;Offset from MIDTX + JSR CPYLXS ;Note corrupts COTEMP + + LDXIM 10 +45 LDAAX COWORK + STAAX MIDTX+14 + DEX + BPL #45 + + LDAIM &20 + STA MIDTX+24 + STA MIDTX+25 + STX MIDTX+26 ;negative byte here + + LDXIM 2 +50 LDAAX DETSZ ;Move file size to TOSEND variable + STAAX TOSEND + DEX + BPL #50 + + LDAIM 0 + STA RTCODE + LDAIM 14 ;offset of name string in buffer + STA CCODE + + LDAIM TXHDR+28 ;Message length (load/exec/size/acc/date) + JSR REPLY ;Send reply + BEQ #55 + JMP #95 ;Reply failed + +55 LDAIM 0 + STA DSCERR ;Set disc error flag + STA FINFLG ;Set finish flag + STA CURBLK + STA CURBLK+1 + +;Loop round sending data to client +;in blocks of size BBSIZE. TOSEND +;is the amount left to send, decremented +;by BBSIZE each loop. +;If a disc error occurs, the disc +;error number is put in DSCERR and +;the loop continues, padding out the +;data until the right amount has +;been sent. The disc error number +;is then sent as a return code. + +;First, subtract BBSIZE from TOSEND + +60 SEC + LDA TOSEND + SBC IOBSIZ + STA COWORK + LDA TOSEND+1 + SBC IOBSIZ+1 + STA COWORK+1 + LDA TOSEND+2 + +;Note BBSIZE is TWO bytes !! + + SBCIM 0 + STA COWORK+2 + + ORA COWORK + ORA COWORK+1 + +;If result +ve TOSEND > BBSIZE, so send +;a block of size BBSIZE. + + BEQ #65 + BCS #70 + +;If BBSIZE >= TOSEND, send remaining +;data (in TOSEND) and set flag. + +65 LDA TOSEND + STA OUTBSZ + LDA TOSEND+1 + STA OUTBSZ+1 + DEC FINFLG ;Set loop finish flag=#FF + ORA TOSEND + BEQ #90 ;Zero length file => send final reply only + BNE #75 + +70 LDA IOBSIZ + STA OUTBSZ + LDA IOBSIZ+1 + STA OUTBSZ+1 + +;The size of the block to send (in +;bytes) is now in OUTBSZ. So divide +;by disc block size to get number +;of disc blocks to transfer. + +75 LDA OUTBSZ + STA DIVPAR + LDA OUTBSZ+1 + STA DIVPAR+1 + LDAIM 0 + STA DIVPAR+2 ;3 byte arg. + JSR DIVIDE + LDYIM ARGB + JSR SINDSC ;Set disc/SIN on stack + JSR IBLOCK ;Set disc block parms on stack + LDAIM 3 ;Read disc function + JSR SETRTN + JSR DSCMAN ;*** DO DISC XFER TO BIG BUFFER ** + BEQ #80 ;OK => continue + STA DSCERR ;Otherwise set disc error + +80 LDY BPTR + LDAAY CPUFD ;Get data port sent from client + + JSR SENDIO ;Send big block + BNE #95 ;Otherwise, contact lost with client, so give up. + +;At end of loop, test finish flag, +;and set CURBLK to be start disc +;block for next iteration. +;Also set TOSEND from COWORK as decremented counter + +85 BIT FINFLG + BMI #90 ;#FF => exit + + CLC + LDA CURBLK + ADC DIVPAR ;Add no. of blocks xfered + STA CURBLK + LDA CURBLK+1 + ADC DIVPAR+1 + STA CURBLK+1 + + LDA COWORK + STA TOSEND + LDA COWORK+1 + STA TOSEND+1 + LDA COWORK+2 + STA TOSEND+2 + + JMP #60 ;*** LOOP RETURN ** + +90 LDA DSCERR + JSR RCODE ;Send return code + +;No cleaning up to do, so exit + +95 JMP COMRTS + + + +;*************** +;* D E L E T E * +;*************** + + +;1) CALL DELETE IN DIRMAN, WHICH SUPPLIES +;SIN AND DISC NO. OF OBJECT TO BE DELETED +;AFTER REMOVING IT FROM THE APPROPRIATE +;DIRECTORY. + +;2) CALL UTILITY OBJCLR TO REMOVE OBJECT FROM +;STORE, FROM THE MAP, AND ENSURE THE MAP. + + +DELETE ROUT + STY COTEMP ;Store command line pointer + JSR STKUSE + BNE #10 + + LDY COTEMP + JSR RDTITL + BNE #10 + + LDYIM ARGC + JSR SBUFPT + LDAIM 3 + JSR SETRTN + + LDYIM ARGG + LDAIM &80 + STAIY NEWARG ;specify full last name + + JSR DIRMAN ;*** DIRECTORY DELETE ** + BNE #05 ;**23/1/87** if error, reply now + JSR OBJCLR ;OTHERWISE CLEAR OLD OBJECT +05 JSR RCODE ;**** 17/3/83 **** + +10 JMP COMRTS + + + +;********************** +;* C A T H E A D E R * +;********************** + +;1) DIRMAN CALL RETRIEVE TO GET DIR. NAME +;AND DISC. NO. +;2) MAPMAN CALL TO GET DISC NAME FOR GIVEN NO. +;3) FORMAT ABOVE WITH INDICATION OF WHETHER +;OWNER OR PUBLIC ACCESS TO DIR. (ALSO +;GOT FROM EXAMINE CALL) + +CATHDR ROUT + JSR GETUSE + BNE #30 + + LDAIM 0 ;Offset from MIDTX to put dir. title + JSR DIRIND ;Get dir. title/access/disc no. + BNE #40 + + LDAIM SPACE + STA MIDTX+NAMLNT + LDYIM ARGD + LDAIY NEWARG + ANDIM OWNER + BEQ #10 + LDAIM "O" + BNE #20 + +10 LDAIM "P" ;PUBLIC OR OWNER ACCESS +20 STA MIDTX+&B + LDAIM SPACE + STA MIDTX+&C + STA MIDTX+&D + STA MIDTX+&E + + LDAIM &F ;Offset from MIDTX to put disc name + JSR CPDNAM ;Read disc name of current disc + BNE #40 + + LDAIM CR + STAAX MIDTX ;Note assumes X is offset remaining from CPDNAM + LDAIM EXTERM ;BLOCK DELIM. + STAAX MIDTX+1 + + TXA + CLC + ADCIM TXHDR+2 ;GET MESSAGE LENGTH + JSR REPLYC +30 JMP COMRTS + +40 JMP ERROR + + + +;***************** +;* E X A M I N E * +;***************** + +;Mainly concerned with getting args +;from RXBUF to NEWARG, calling DIRMAN, +;and getting args back again. + +EXAMIN + JSR STKUSE ;CALL FINDMC AND SET USTPTR ON STACK + BNE #30 + + LDAIM EXAFTO + JSR SETFTP ;SET FILE TITLE POINTER ON STACK + + INY + CLC + LDA BBUF + ADCIM TXHDR+2 + STAIY NEWARG ;SET POINTER TO RESULT AREA + +;RESULT OF CALL OF DIRMAN IS PLACED IN THE BIG +;BUFFER, OFFSET BY TWO BYTES FOR THE MESSGE HEADER +;TO BE INSERTED + + INY + LDA BBUF+1 + ADCIM 0 + STAIY NEWARG + +;NOW COPY 3 ARGS FROM RXBUF TO STACK + + LDX BPTR ;OFFSET IN RXBUF FOR THIS RX BUFFER + INY + LDAAX MIDRX + STAIY NEWARG ;ARG + INY + LDAAX MIDRX+1 + STAIY NEWARG ;entry point + INY + LDAAX MIDRX+2 + STAIY NEWARG ;number of entries + + LDAIM 7 ;FUNCTION NUMBER IN DIRMAN + JSR SETRTN + + LDYIM ARGK + LDAIM &C1 ;specify directory here + STAIY NEWARG ;pass parameter + + JSR DIRMAN ;*** DIRECTORY MANAGER CALL ** + BNE #40 + LDA BBUF + STA GENPTR + LDA BBUF+1 + STA GENPTR+1 + LDYIM 0 + TYA + STAIY GENPTR ;STORE 0 RETURN CODE IN MESSAGE + INY + STAIY GENPTR ;STORE 0 COMMAND CODE + + LDYIM ARGD + LDAIY NEWARG ;GET NUMBER OF ENTRIES RETURNED + PHA ;Store for later + INY + LDAIY NEWARG + LDYIM TXHDR+1 ;Store cycle no. of directory + STAIY GENPTR + PLA ;Restore no. of entries returned + DEY + STAIY GENPTR ;Set in message to client + + +;NOW SET UP CONTROL BLOCK + + LDA RPLYPT ;REPLY PORT + LDX QPTR ;C.B POINTER + STAAX CBPORT + + LDA BBUF ;POINTER TO MESSAGE START + STAAX CBBUF + LDA BBUF+1 + STAAX CBBUF+1 + + LDYIM ARGB + LDAIY NEWARG ;POINTER TO END OF MESSAGE, + ;RETURNED BY DIR. MAN. + + STAAX CBBUFE + INY + LDAIY NEWARG + STAAX CBBUFE+1 + + LDY QPTR ;SET ARG FOR SEND + JSR SEND ;*** SEND INFO ** + + JMP COMRTS + + + +;*********** +;* I N F O * +;*********** + + +;GET INFO ON A FILE IN A CHAR STRING +;FROM DIRMAN INTO BIG BUFFER AND SEND + +INFO ROUT + JSR RDTITL + BNE #20 + JSR STKUSE + BNE #20 + + JSR SBUFPT + INY + CLC + LDA BBUF + ADCIM TXHDR + STAIY NEWARG + +;RESULT POINTER PASSED TO DIRMAN IS BBUF +A BIT +;TO ALLOW ROOM FOR THE MESSAGE HEADER +;IN THE FINAL MESSAGE BACK TO THE CLIENT. + + INY + LDA BBUF+1 + ADCIM 0 ;RESULT AREA TOP BYTE + STAIY NEWARG + + LDAIM 8 + JSR SETRTN + + LDYIM ARGH + LDAIM &C0 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;*** GET THE INFO ** + BEQ #10 ;OK, CONTINUE + JMP ERROR + +10 LDA BBUF + STA GENPTR + LDA BBUF+1 + STA GENPTR+1 + + LDYIM 0 + LDAIM CCINF + STAIY GENPTR ;Command code + INY + LDAIM 0 ;Zero r.code + STAIY GENPTR + +;FROM HERE, SET UP TRANSMIT CONTROL BLOCK + + LDX QPTR + LDA RPLYPT + STAAX CBPORT + + LDA BBUF + STAAX CBBUF ;MESSAGE BUFFER + LDA BBUF+1 + STAAX CBBUF+1 + + LDYIM ARGB ;GET MESSAGE BUFFER END FROM STACK + LDAIY NEWARG + STAAX CBBUFE + INY + LDAIY NEWARG + STAAX CBBUFE+1 + + LDY QPTR + JSR SEND ;OFF WE GO .... + +20 JMP COMRTS + + LNK UADE17 diff --git a/Level3/SRC/L3/Uade17 b/Level3/SRC/L3/Uade17 new file mode 100644 index 0000000..e112e7f --- /dev/null +++ b/Level3/SRC/L3/Uade17 @@ -0,0 +1,1070 @@ + OPT UADE17 ;FILE > Uade17 + TTL File server file UADE17 + +;INFO/LOGON/PRIV. OPERATIONS ETC. + + +;Get info in m/c readable format, depending on +;argument. + +;1 = creation date +;2 = load/execution addresses +;3 = size +;4 = type/access +;5 = all above 4 in order load/execute/size/access/date +; +;6 = get access, cycle (sequence) number, and last +; component of dir. title for dir. name. NOTE +; does not use retrieve, and does not trap "NOT +; FOUND" error. + +CPINFO ROUT + JSR GETUSE + BNE #50 + + LDX BPTR + LDAAX MIDRX + BEQ #05 ;Zero arg => error + CMPIM 6 + BEQ #70 ;=> do directory information + BCC #10 ;Otherwise, is valid arg. + +05 LDAIM INFERA + BNE #60 ;Abort with err. msg. + +10 LDAIM 0 + STA MIDTX ;Set existence flag to "does not exist" + LDAIM INFFTO + JSR CPRETR ;Retrieve details + BEQ #15 ;Ok, continue + CMPIM DRERRC ;If not found, alter existence flag + BNE #60 ;Not "not found" => error + LDXIM 1 ;Length of reply + BNE #45 ;Exit, sending reply + +15 INC MIDTX ;Set flag to "is a file" + LDX BPTR + LDAAX MIDRX ;Check arg. + LDXIM 1 ;Offset for COCOPY + CMPIM 5 ;Is "all args" ? + BNE #20 ;Nope, continue + + JSR CPYLXS ;Yep, copy all args + BEQ #30 ;Always jump + +20 JSR COCOPY ;Copy relevant amount of stuff COWORK->MIDTX + +30 LDYIM ARGB ;check for OWNER/PUBLIC + LDAIY NEWARG + ANDIM OWNER + BEQ #35 + LDAIM &FF +35 EORIM &FF ;invert byte [Owner => 0] + STAAX MIDTX ;put this at the end of the information + INX + +40 LDYIM INFACC + LDAAY COWORK + ANDIM TYPDIR ;Check if is a directory + BEQ #45 ;Is not -> continue + INC MIDTX ;Is => set flag to 2 => directory +45 TXA ;Length of information transfered + JMP Datous ;Go send msg + +50 JMP COMRTS + +60 JMP ERROR + +70 JSR STKUSA ;Set user info. on stack + LDAIM 3 + STA COZERO ;Offset for dir. name result + LDAIM HDRLEN+1 ;Offset of dir. name arg. + LDXIM &C1 ;force directory here + JSR DIRIN2 ;Get dir. infomation + BNE #60 + + LDYIM ARGD ;Now set access & sequence number + LDAIM 0 + STA MIDTX+NAMLNT+3 ;Zero => owner, $FF => public + STA MIDTX+1 + LDAIM OWNER + ANDIY NEWARG ;Check access to dir. + BNE #80 ;Is owner, continue + DEC MIDTX+NAMLNT+3 ;Otherwise, give $FF +80 INY + LDAIY NEWARG + STA MIDTX+NAMLNT+4 ;Set sequence number of dir. + LDAIM NAMLNT + STA MIDTX+2 ;Set length of dir. name + LDXIM NAMLNT+5 ;Length of message - TXHDR + BNE #40 ;Exit with reply (Note MIDTX undefined) + +CPIXTB = 2 ;Table of length of data + = 8 + = 3 + = 1 + +CPIATB = INFDTE ;Offset of data in COWORK + = INFLOA + = INFSZE + = INFACC + + +;Copy load/exec/size/access/date into MIDTX + +CPYLXS ROUT + LDAIM 2 + JSR COCOPY ;Load/exec + LDAIM 3 + JSR COCOPY ;Size + LDAIM 4 + JSR COCOPY ;access + LDAIM 1 ;creation date + +;Fall through into last call of COCOPY + +COCOPY + +;Copy some object attribute from COWORK into MIDTX +;offset by X. Attribute length and value is determined +;by A on entry which indexes into two tables + + TAY + LDAAY CPIXTB-1 + STA COTEMP ;Set length to copy + LDAAY CPIATB-1 + TAY ;Get offset in COWORK +10 LDAAY COWORK + STAAX MIDTX + INY + INX + DEC COTEMP + BNE #10 + RTS ;Note assumed elsewhere always exit EQ + + + + +;Set object attributes according to arg. + +;1 => set load/execute/access +;2 => set load address +;3 => set execute address +;4 => set access byte +;5 => set date bytes ** 5/9/84 ** + +;Basically just a call to DIRMAN.SETATTRIBS + +CPSTAT ROUT + JSR STKUSE + BNE #50 + + LDX BPTR + LDAAX MIDRX + BEQ #10 + CMPIM 6 ;** 5/9/84 ** + BCC #20 ;Arg ok, continue + +10 LDAIM INFERA ;Error in arg. + JMP ERROR + +20 TAY + LDAAY DRSAT2-1 ;Note uses table in DIRMAN to get data length + BEQ #40 ;If setting zero number of bytes, exit + + CLC + ADCIM HDRLEN+1 ;Get offset of file title in RX buffer + LDYIM ARGC + JSR SETFTP ;Set pointer to file title + + INY ;ARGF here + LDAIM &C0 + STAIY NEWARG ;wild card flag + + LDX BPTR +30 INY + LDAAX MIDRX ;Load arg. to DIRMAN.SETATTRIBS + STAIY NEWARG + INX + CPYIM ARGH+9 + BNE #30 + +;Stack now all set, call DIRMAN.SETATTRIBS + + LDAIM 4 + JSR SETRTN + JSR DIRMAN +40 JSR RCODE +50 JMP COMRTS + + +;Non-command line call to delete object, and return +;object information after deletion. + +CPDEL ROUT + JSR STKUSE + BNE #20 + LDAIM HDRLEN ;Offset of file title + JSR CPRETR ;Retrieve details of object to delete + BNE #10 ;No good, error + + JSR STKUSA ;Reset user pointer on stack + LDAIM HDRLEN ;File title offset + JSR SETFTP ;Set file title pointer + LDAIM 3 + JSR SETRTN + + LDYIM ARGG + LDAIM &80 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;** Call DIRMAN.DELETE ** + BNE #10 ;Error + + LDXIM 0 ;Set offset from MIDTX for file details + JSR CPYLXS ;Copy the whole lot over + CLC + TXA + ADCIM TXHDR ;Length of message + STA Cozero ;**1/7/87** save length + JSR OBJCLR ;Clear object out of map + BEQ #25 ;error returned here +10 JSR RCODE ;Send error return +20 JMP COMRTS ;And finish + +25 LDA Cozero ;**1/7/87** load reply length + BNE #30 + + +;Return user environment information. +; 1) Call DIRMAN.EXAMINE to get dir. name, and disc +; number of CSD. +; 3) Call MAPMAN.DISCNAME to get name of disc with +; given disc number. +; 4) Call DIRMAN.EXAMINE to get title of LIB. + +USRENV + JSR GETUSE + BNE #20 + + LDX BPTR + LDAIM TERMIN + STAAX MIDRX ;Fool DIRINF into getting CSD info. + + LDAIM 17 ;Offset from MIDTX for dir. title + JSR DIRINF ;Read dir. information + BNE #40 ;Error -> bomb out + + LDAIM 1 ;Offset from MIDTX for disc name + JSR CPDNAM ;Read disc name (note assumes disc no. on stack) + BNE #40 + + LDX BPTR + LDAAX CPLIB ;Read library handle + LDYIM UTHSLD + STAIY USTPTR ;Set as CSD of user + + LDAIM 27 ;Offset from MIDTX of LIB name + JSR DIRINF ;Entry point not changing CSD handle + BNE #40 + + LDAIM DNAMLN ;Disc name length + STA MIDTX + LDAIM 0 + STA CCODE + LDAIM TXHDR+37 ;Message length +30 JSR REPLYC + JMP COMRTS + +40 JMP ERROR + + + +;************* +;* L O G O N * +;************* + + +LOGON ROUT + + JSR SPACES +10 LDAAY MIDRX ;Step past station if present + CMPIM "." ;Network number terminator - special case + BEQ #20 + CMPIM "0" + BCC #30 ;On if <0 + CMPIM ":" ;On if >9 + BCS #30 +20 INY + BNE #10 + +30 JSR BUFTXT ;Read User + BNE #50 + INX ;Step past CR between userid & pw + JSR BTXTA + BNE #50 + JSR COMEND ;Check to end of C.line + BNE #50 + + LDYIM ARGB + LDX QPTR + LDAAX CBSTID + STAIY NEWARG + STA MCNUMB ;** 31/08/86 ** + INY + LDAAX CBSTID+1 + STAIY NEWARG + STA MCNUMB+1 ;** 31/08/86 ** + INY + LDAAX CBflg ;**25/12/86** Get control byte + ANDIM MCtask ;**25/12/86** Isolate task no + STAIY NEWARG ;pass station id + STA MCnumb+2 + + JSR SBUFPT ;pointer to TXTBUF + + LDAIM 1 + JSR SETRTN + JSR USRMAN ;attempt logon + BNE #60 ;failed + + LDYIM ARGH ;test for priv'd logon + LDAIY NEWARG + BNE #32 ;no monitor for priv'd users + + BIT MONFLG + BPL #32 ;skip if monitor off anyway + + LDY QPTR + JSR PRTMC ;output mc number + JSR VSTRIN + = ": I am " + NOP + + LDXIM 0 +31 LDAAX TXTBUF + INX + JSR OSASCI ;print the user name + CMPIM CR + BNE #31 + +32 LDYIM ARGG + LDXIM 3 +40 LDAIY NEWARG ;Get UFD/CSD/LIB handles + option byte + STAAX MIDTX + DEY + DEX + BPL #40 + +45 LDAIM CCLGON + STA CCODE + LDAIM TXHDR+4 ;Message length + JSR REPLYC ;Send handles etc. back + +50 JMP COMRTS ;FINISH + +60 JMP ERROR + + +;*************** +;* L O G O F F * +;*************** + + +USROFF ROUT + +;(LABEL USROFF TO AVOID NAME CLASH +;WITH USRMAN ROUTINE) + +;SET UP ARGS FOR LOGOFF (DELETE USER) +;IN USERMAN, CALL, AND SEND APPROPRIATE +;MESSAGE BACK TO CLIENT. + + JSR COMEND + BNE #30 + +FCBYE + +;nice if this returns no error if not logged on ** 5/9/84 ** + + JSR GETUSR ;23/1/76** + BEQ #10 ;check for logged on user here + + LDAIM 0 + BEQ #20 ;exit ok + +10 JSR STKUSE ;Entry by function code + BNE #30 + + LDAIM 2 ;LOGOFF ROUTINE NUMBER + JSR SETRTN + JSR USRMAN +20 JSR RCODE +30 JMP COMRTS + + + +CPSOPT ROUT + +;Set USER OPTION in pw file +;Just call appropriate AUTMAN routine + + JSR STKUSE + BNE #20 + LDAAX MIDRX ;Note assumes X is BPTR here + CMPIM &10 ;Check option <16 + BCS #30 + INY + STAIY NEWARG + LDYIM UTPRIV ; check not low-priv user *** 25/5/86 *** + LDAIY USTPTR ; *** 25/5/86 *** + ANDIM LOPRIV ; *** 25/5/86 *** + BNE #40 ; error if so *** 25/5/86 *** + LDAIM 7 + JSR SETRTN + JSR AUTMAN ;Call AUTMAN.USEROPTION +10 JSR RCODE +20 JMP COMRTS + +30 LDAIM INFERA ;Bad arg + BNE #10 + +40 LDAIM ATERRD ; Insufficient privilege *** 25/5/86 *** + BNE #10 + + +;************************ +;* S E L E C T D I S C * +;************************ + + +SELDSC ROUT ;SELDSC + +;ALL WORK DONE IN USRMAN. + + JSR RDTITL ;GET DISC NAME ON STACK + BNE #20 + + LDAIM &A + JSR SETRTN + JSR SBUFPT + JSR MAPMAN ;*** GET DISC NO FOR NAME ** + BNE #30 + + LDYIM ARGB + LDAIY NEWARG + PHA + INY + LDAIY NEWARG + INY + INY + STAIY NEWARG ;MOVE DISC. NO. UP TO MAKE WAY FOR USRPTR + DEY + PLA + STAIY NEWARG + JSR STKUSE ;SET USER POINTER + BNE #20 + LDYIM ARGF + JSR STKHND ;PUT 3 HANDLES ON STACK + + LDAIM 3 + JSR SETRTN + JSR USRMAN ;*** SELECT DISC ** + BNE #30 + + LDYIM ARGD + LDXIM 2 +10 LDAIY NEWARG + STAAX MIDTX + DEY + DEX + BPL #10 + + LDAIM CCSDIS + STA CCODE + LDAIM TXHDR+3 ;MESSAGE LENGTH + JSR REPLYC +20 JMP COMRTS + +30 JMP ERROR + + +;********************** +;* S E L E C T D I R * +;********************** + +SELDIR ROUT ;SELDIR + +;ALL WORK DONE BY USERMAN AGAIN. + + JSR RDTITL + BNE #10 + JSR STKUSE + BNE #10 + + JSR SBUFPT ;** 5/9/84 ** + LDYIM ARGF + JSR STKHND ;Handles -> stack + JSR SELHAN + BNE #20 ;error in allocation + + LDAIM CCSDIR +00 STA CCODE + LDAIM TXHDR+1 ;Message length + JSR REPLYC +10 JMP COMRTS + +20 JMP ERROR + + +SELHAN LDAIM 5 ;ROUTINE NUMBER + JSR SETRTN + JSR USRMAN ;*** SELECT DIR. ** + BNE #30 ;exit if fail + + LDYIM ARGB + LDAIY NEWARG + STA MIDTX ;New s.dir + LDAIM 0 +30 RTS + +;****************************** +;* S E L E C T L I B R A R Y * +;****************************** + +;as for DIR but null filename is illegal +;if RETRIEVE ok then call USRMAN with LIB as CSD + +SLIB JSR RDTITL + BNE #10 + JSR STKUSE + BNE #10 + JSR SBUFPT + JSR SCOWPT ;Set pointer to COWORK on stack + LDAIM 2 ;Dirman retrieve + JSR SETRTN + + LDYIM ARGH + LDAIM &C0 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;*** RETRIEVE ** + BNE #20 + + JSR STKUSE + BNE #10 + JSR SBUFPT + JSR SCOWPT ;Set pointer to COWORK on stack + + LDYIM ARGF + JSR STKHND ;handles -> stack + + LDYIM ARGH + LDAIY NEWARG + DEY + STAIY NEWARG ;LIB->CSD + + JSR SELHAN ;** 5/9/84 ** + BNE #20 ;error in allocation + + LDAIM CCSLIB + BNE #00 + + +;********************* +;* S E T A C C E S S * +;********************* + + +SETACC ROUT + +;1) PUT USER INFO. POINTER AND FILE TITLE +;POINTER ON STACK. +;2) INTERPRET STRING SENT FROM CLIENT INTO +;AN ACCESS BYTE AND STICK ON STACK. +;3) CALL SETATTRIBS IN DIRMAN +;4) REPLY TO CLIENT + + + JSR BUFTXT ;Get file name + BNE #40 + STY COWORK ;Store cmnd. line ptr. + JSR STKUSE + BNE #40 + + JSR SBUFPT + + LDY COWORK ;Restore cmnd. line ptr. + JSR SPACES + + LDAIM 0 + STA COZERO ;Partial result + DEY +10 INY + LDXIM 2 ;Offset into access tables + JSR CMPACC ;Compare letter at Y with access tables + BEQ #10 ;Access letter found + CMPIM "/" ;Owner access delimiter + BEQ #20 + JSR SPACER ;skip trailing spaces ** 25/5/83 ** + CMPIM CR + BNE #50 ;Invalid character => error + DEY ;Point to CR so will exit after rotating COZERO + +20 ASL COZERO ;Rotate access bits to owner position + ASL COZERO + +30 INY ;Increment past '/' delimiter + LDXIM 1 + JSR CMPACC + BEQ #30 + JSR SPACER ;skip trailing spaces ** 25/5/83 ** + CMPIM CR + BNE #50 ;If here, CR has terminated string => set access + + LDYIM ARGF + LDAIM &C0 + STAIY NEWARG ;wild cards flag + LDAIM 4 + INY ;Set arg to SETATTRIBS => SETACCESS + STAIY NEWARG + INY + LDA COZERO ;Restore access byte + STAIY NEWARG ;SET ACCESS BITS + LDAIM 4 ;SETACC ROUTINE NO. + JSR SETRTN + JSR DIRMAN ;*** SET ACCESS ** + JSR RCODE ;SEND REPLY +40 JMP COMRTS ;FINISH + +50 LDAIM SAERRA + JMP ERROR + + +OWNTAB + = "R" + = "W" + = "L" + +POWNTB = 1 ;OWNER READ + = 2 ;OWNER WRITE + = 4 + +CMPACC ROUT + LDAAY MIDRX + EORAX OWNTAB + ANDIM &DF ;Compare with cases forced + BEQ #10 + DEX + BPL CMPACC + LDAAY MIDRX ;Exit, A = char, Z unset + RTS + +10 LDAAX POWNTB + ORA COZERO + STA COZERO ;Update partial result + LDXIM 0 ;Set Z flag; note A corrupted + RTS + + + +;****************** +;* N E W U S E R * +;****************** + + +NEWUSE ROUT + +;ALL WORK DONE IN AUTMAN, ROUTINE NO. 1 + + JSR RDTITL ;Get user name + BNE #10 + JSR STKUSE ;Stack caller's user info + BNE #10 + JSR SBUFPT ;Stack new user ptr. + + LDAIM 1 +DOUSE JSR SETRTN ;SET ROUTINE NUMBER + JSR AUTMAN ;DO NEW USER + JSR RCODE ;SEND RETURN CODE +RUEXIT ;Shared with REMUSE +SPWEXT ;Shared with SETPW +10 JMP COMRTS ;FINISH + + + +;************************ +;* R E M O V E U S E R * +;************************ + +REMUSE ROUT + +;REMARKABLY SIMILAR TO NEWUSER + + JSR RDTITL + BNE RUEXIT + JSR STKUSE + BNE RUEXIT + JSR SBUFPT + + LDAIM 4 + BNE DOUSE ;Always jump + + +;************************** +;* S E T P A S S W O R D * +;************************** + + +SETPW ROUT + +;GET USER INFO AND CALL ROUTINE IN AUTMAN +;TO DO WORK. + + JSR BUFTXT ;Buffer old pw + BNE SPWEXT + INX ;Ptr. to next free spot in TXTBUF + JSR BTXTA ;Buffer new pw + BNE SPWEXT + JSR COMEND + BNE SPWEXT + + BIT MONFLG ;Do monitor message specially to avoid PW + BPL #00 ;No monitor -> carry on + LDY QPTR ;Point to RX control block + JSR PRTMC ;Print machine number + JSR VSTRIN + = ": Pass",CR + NOP + +00 JSR STKUSE + BNE SPWEXT + JSR SBUFPT + + LDYIM UTPRIV ; check low-privilege *** 25/5/86 *** + LDAIY USTPTR ; *** 25/5/86 *** + ANDIM LOPRIV ; *** 25/5/86 *** + BNE #10 ; br if password not allowed *** 25/5/86 *** + + LDAIM 3 ;ROUTINE NUMBER + BNE DOUSE ;Always jump + +10 LDAIM ATERRD ; Insufficient privilege *** 25/5/86 *** + JMP ERROR ; *** 25/5/86 *** + + +;********************** +;* C R E A T E D I R * +;********************** + + +CDIRFN ROUT + JSR Stkuse ; Check logged-on first + BNE #20 ; *** 31/10/86 *** + LDY BPTR + INY + JSR RDTITL + BNE #20 + LDY BPTR + LDAAY MIDRX + BEQ #30 ;zero is a silly number + CMPIM (:MSB:MAXDIR)+1 + BCS #30 + BCC #10 ;check for overflow + +CDIR ;CDIR + +;PASS USER INFO AND DIRECTORY NAME +;TO DIRMAN. THEN CLEAN UP IF NECCESSARY. + + JSR RDTITL + BNE #20 + LDAIM 2 ;size of directory + +10 CMP CACHSZ+1 ;** 31/1/85 + BCS #30 + LDYIM ARGF + STAIY NEWARG + INY + LDAIM &80 ;** 11/10/84 ** + STAIY NEWARG ;wild card flag + JSR STKUSE + BNE #20 + + JSR SBUFPT + LDAIM 5 ;CREATE DIR. FUNCTION CODE + JSR SETRTN + JSR DIRMAN ;*** DO DIR. CREATE ** + BNE #15 + JSR OBJCLR ;CLEAR OLD OBJECT +15 JSR RCODE ;store RC + +SPEXIT ;Shared with SETPRIV +20 JMP COMRTS + +30 LDAIM DRERRP + JMP ERROR + + +;****************** +;* S E T P R I V * +;****************** + + +STPRIV ROUT + +;MOST WORK DONE BY AUTMAN + + JSR BUFTXT ;MOVE USER ID. + BNE SPEXIT + STY COWORK + JSR STKUSE + BNE SPEXIT + JSR SBUFPT + + LDY COWORK + JSR SPACES + ANDIM &DF ;Force upper case + CMPIM "S" ;SYSTEM USER ??? + BEQ #10 + CMPIM "L" ;ow-privilege user? *** 25/5/86 *** + BEQ #50 ; *** 25/5/86 *** + CMPIM CR ;NON-SYSTEM USER ?? + BNE #30 + LDAIM 0 ;NON-SYST. USER + BEQ #20 + +10 INY + JSR COMEND + BNE SPEXIT + LDAIM 1 ;SYSTEM USER ! +20 LDYIM ARGF + STAIY NEWARG ;Set user's priv. flag + LDAIM 5 ;SET PRIV. + JMP DOUSE + +30 LDAIM SPERRA +40 JMP ERROR + +50 INY ; *** 25/5/86 *** + JSR COMEND ; *** 25/5/86 *** + BNE SPEXIT ; *** 25/5/86 *** + LDAIM 2 ;Low-privilege user *** 25/5/86 *** + BNE #20 ; *** 25/5/86 *** + +;************* +;* D I S C S * +;************* + +DISCS ROUT + +;Provide list of discs currently on system. + +;User supplies entry (drive) number, and +;number of drives. For each drive he is interested in, +;call MAPMAN once to get disc number +;and again to get disc name. + + LDAIM 0 + STA COZERO ;No. of drives found + LDA BBUF + CLC + ADCIM TXHDR+1 ;Result buffer + STA COZERO+1 + LDA BBUF+1 + ADCIM 0 + STA COZERO+2 +10 LDX BPTR + LDAAX MIDRX + CMP DRIVES + BCS #30 ;User drive >= drives + + LDYIM 0 + STAIY COZERO+1 ;Store probable drive number + LDYIM ARGB + STAIY NEWARG + LDAIM 8 ;Drive -> disc no. + JSR SETRTN + JSR MAPMAN + BNE #28 ;Abort + LDAIM &B ;Disc no. -> name + JSR SETRTN + JSR MAPMAN + BNE #40 + INC COZERO+1 + BNE #20 + INC COZERO+2 +20 LDA COZERO+1 + STA MOVTO + LDA COZERO+2 + STA MOVTO+1 + + LDYIM ARGB + LDAIY NEWARG ;Ptr. to name + STA MOVFRM + INY + LDAIY NEWARG + STA MOVFRM+1 + LDXIM DNAMLN + JSR MOVE ;Move name to result + CLC + LDA COZERO+1 + ADCIM DNAMLN + STA COZERO+1 + BCC #25 + INC COZERO+2 +25 INC COZERO ;No. of drives dealt with +28 LDX BPTR ;**14/06/86** + INCAX MIDRX ;Next drive to do + LDA Cozero ;**1/5/87** loop until requested drives done + CMPAX Midrx+1 ;**1/5/87** + BCC #10 ;**1/5/87** + +30 LDYIM ARGB + LDA COZERO ;Set args to LSTPRY + STAIY NEWARG + INY + LDA COZERO+1 + STAIY NEWARG + INY + LDA COZERO+2 + STAIY NEWARG + LDAIM CCDSCS + JSR LSTRPY ;Reply to client +35 JMP COMRTS + +40 JSR EXTERR + JMP #35 + +;************* +;* U S E R S * +;************* + +CPUSRS ROUT + + JSR STKLST + + JSR GETUSR ;Get current user (16/1/86) + BNE #15 ;***31/10/86*** + LDYIM UTPRIV + LDAIY USTPTR + ANDIM SYSTPV ;Stack privilege for USRMAN +05 LDYIM ARGF + STAIY NEWARG + LDX BPTR + LDAAX RXBUF+1 ;**20/5/87** check function code + EORIM (FNusr2-FNtab)/2 ;**20/5/87** zero if job/task nos + INY + STAIY NEWARG + + LDAIM 7 + JSR SETRTN + JSR USRMAN + BNE #10 + LDAIM CCUSRS + JSR LSTRPY + JMP COMRTS + +10 JMP ERROR + +15 LDAIM 0 ;not logged on, hide priv users + BEQ #05 + +;*********** +;* D A T E * +;*********** + + +CPSETD ROUT ;Set the date ** 20/9/83 ** + JSR Getuse ;***Check caller logged on*** + BNE #20 + LDYIM Utpriv ;***and system priv*** + LDAIY Ustptr + ANDIM Systpv + BEQ #30 ;***31/10/86*** + LDA DATE + PHA + LDA DATE+1 + PHA ;SAVE DATE IN CASE WE NEED IT! + LDY BPTR ;check flag + LDAAY MIDRX + STA DATE + LDAAY MIDRX+1 + STA DATE+1 + JSR CHKDTE + BNE #10 + LDY BPTR + LDAAY MIDRX+2 + CMPIM 24 + BCS #10 + STA HRS + LDAAY MIDRX+3 + CMPIM 60 + BCS #10 + STA MINS + LDAAY MIDRX+4 + CMPIM 60 + BCS #10 + STA SECS + JSR SETTME + JSR PRDTE ;Display new date + PLA + PLA ;REMOVE SAVED DATE + LDAIM TXHDR ;Rx header only + BNE DATOUT + +10 PLA + STA DATE+1 + PLA + STA DATE + LDAIM DTERR + JSR RCODE +20 JMP COMRTS + +30 LDAIM ATerrd ;Insufficient privilege *** 31/10/86 *** + JMP Error ;*** 31/10/86 *** + +CPDATE ROUT + +;No user check since doesn't involve +;files. + + JSR PRTIM + LDA DATE ;read date + STA MIDTX + LDA DATE+1 + STA MIDTX+1 + LDA HRS + STA MIDTX+2 + LDA MINS + STA MIDTX+3 + LDA SECS + STA MIDTX+4 ;Time = zero if clock not present + LDAIM TXHDR+5 ;Message length + BNE Datout + + +;***************** +;* V E R S I O N * +;***************** + +CPVERN ROUT + LDYIM 0 +10 LDAAY VERSN + STAAY MIDTX + INY + CMPIM 6 ;end of version number character + BNE #10 + + TYA +Datous ;Entry with text length in A + CLC + ADCIM TXHDR +Datout ;Entry with msg length in A + LDXIM 0 + STX CCODE ;0 command code + JSR REPLYC ;Message length in A here +Datoux ;Here to just exit + JMP COMRTS + + LNK UADE18 diff --git a/Level3/SRC/L3/Uade18 b/Level3/SRC/L3/Uade18 new file mode 100644 index 0000000..f9d677d --- /dev/null +++ b/Level3/SRC/L3/Uade18 @@ -0,0 +1,877 @@ + OPT UADE18 ;FILE > Uade18 + TTL File server file UADE18 + +;Random access and RENAME & User Info + + +;*************** +;* R E N A M E * +;*************** + +;Rename file <A> as <B> +; +;1) Buffer both file names, call DIRMAN.CHECKDISCNOS +;2) Retrieve A. Check owner access, is a file, is unlocked +;3) Preserve name B with details of A +;4) If old SINofB = SINofA, renaming same file -> return +;5) Else, clear oldB from map, and delete A from dir (not map!) + +RENAME ROUT + STY COTEMP + JSR GETUSE + BNE Datoux + + LDY COTEMP ;pointer into MIDRX + JSR BUFTXT ;Buffer name A + BNE #10 ;Exit via extra jump + INX + STX COTEMP ;Store offset of B in TXTBUF + JSR BTXTA ;Buffer name B + BNE #10 ;Exit via extra jump + JSR COMEND ;Check to end of command line + BNE #10 ;Exit via extra jump + +;** 24/9/84 ** + +;Substantial rewrite to allow renaming of directories +;The actual mechanics are identical to renaming files +;but lots of checking for loops in directories needs to be +;done, which means that full pathname expansion is called for + + LDA BBUF + STA PTR + LDA BBUF+1 + STA PTR+1 + + LDAIM 0 + STA REXIST ;full wild card lookup + JSR RNAMLK ;do the checking for existence etc. + BNE #10 ;fail + + STX RTYPE ;type of object that we've found + CLC + LDA PTR + STA PTR1 + ADCIM :LSB:INFNXT + STA PTR + + LDA PTR+1 + STA PTR1+1 + ADCIM :msb:INFNXT + STA PTR+1 ;new result area + +;PTR =lastname and info <B> +;PTR1=lastname and info <A> + + LDA COTEMP ;offset of name <B> + JSR RNAMLK ;similar checking as for <A> + BEQ #15 ;all succeeded [but may not be ok !] + + LDXIM 0 ;no object returned so no type either + CMPIM DRERRC ;'not found' in final part of name +10 BNE #45 ;failed for some serious reason + ROR REXIST ;object <B> done NOT exist (=>&80) + [ 1=0 ; removed, INFDIS set if B does not exist ** 14/10/86 ** + BMI #20 ;if so then skip disc number check + ] + +;now look for rename across discs + +15 LDYIM INFDIS + LDAIY PTR + CMPIY PTR1 + BNE #40 ;failed here + INY + LDAIY PTR + CMPIY PTR1 + BNE #40 ;failed here too + +20 LDA RTYPE ;look for file/dir + ANDIM TYPDIR + BEQ #55 ;file so ok + +;now look for loops in directories + + LDYIM 0 ;from the beginning + STY LAST + STY NAME + LDX COTEMP ;starts with "$" ? + LDAAY TXTBUF + JSR RNAMPD ;**20/5/87** check root or pseudo directory + BNE #25 + STA NAME ;**20/5/87** store root or pseudo directory name + LDAAY TXTBUF+1 + JSR RNAMPT ;**20/5/87** check separator/terminator + BNE #25 + INC LAST +25 LDAAX TXTBUF + JSR RNAMPD ;**20/5/87** check root or pseudo directory + BNE #28 + EOR NAME ;**20/5/87** zero if same root or pseudo directory as A? + STA NAME + LDAAX TXTBUF+1 + JSR RNAMPT ;**20/5/87** check separator/terminator + BNE #28 + DEC LAST +28 ;X=0 or fail here + LDA LAST ;test for mismatch + BNE #40 ;bad rename + LDA NAME ;**20/5/87** A & B must be in same or no pseudo directory + BNE #40 + +30 LDAAY TXTBUF + JSR ISCHAR + BCS #32 + ANDIM &DF ;force upper case +32 CMPIM TERMIN + BEQ #50 ;bad, LEFT$<B>=$<A> unless $<A>=$<B> + STA NAME + LDAAX TXTBUF ;mismatch in names is essential + JSR ISCHAR ;force case on both chars + BCS #35 + ANDIM &DF +35 CMP NAME ;match against other name + BNE #37 + INX + INY + BNE #30 + +37 BIT REXIST ;different names so <B> must NOT exist + BMI #55 + +40 LDAIM RNAMQQ ;bad rename error string +45 JMP ERROR + +50 LDAAX TXTBUF ;check for subdirectory here + CMPIM SEPART ;** 27/3/85 ** + BEQ #40 +55 JSR STKUSE ;Set up PRESERVE call for A details, named B + LDA COTEMP + JSR SETTXP ;put name to stack + + INY + STY NAME + LDAIM INFLOA + STA ONAME ;counters + LDXIM 17 + +60 LDY ONAME + LDAIY PTR1 + LDY NAME + STAIY NEWARG + INC ONAME + INC NAME + DEX + BNE #60 + + LDAIM 12 + JSR SETRTN ;Do DIRMAN.PRESERVE (without DELCHK) + + LDYIM ARGT + LDAIM &80 ;enable wildcards + STAIY NEWARG ;wild card flag + + JSR DIRMAN + BNE #45 + + BIT REXIST ;did <B> exist + BMI #80 ; .. no .. + + LDXIM 3 + LDYIM INFSIN+2 +65 LDAIY PTR + CMPIY PTR1 + BNE #70 + DEY + DEX + BNE #65 + +70 TXA + BEQ #85 ;if identical then NOP + +75 JSR OBJCLR ;Clear old B from map (if SIN <> zero) + BNE #45 ;Error exit + +;Then finally delete name A from directory + +80 JSR STKUSE + JSR SBUFPT ;Set pointer to TXTBUF + LDAIM 11 ;** 24/9/84 ** + JSR SETRTN + + LDYIM ARGG + LDAIM &C0 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;Delete A +85 JSR RCODE ;Return success/failure and exit + +90 JMP COMRTS + + +RNAMLK ROUT ;A=offset in TXTBUF of pathname for object +;PTR=results area + +;retrieves object in TXTBUF, expanding pathname into !PTR +;checks object existence, pathname completeness, +;object owned, unlocked, not open + + PHA + JSR STKUSE ;prepare for retrieve call + PLA + JSR SETTXP ;point to the name + + LDYIM ARGF + LDA PTR + STAIY NEWARG + INY + LDA PTR+1 + STAIY NEWARG ;pointer to results area + INY + LDAIM 0 ;no wildcards + STAIY NEWARG + + LDAIM 2 + JSR SETRTN + JSR DIRMAN ;call retrieve + BNE #40 ;DIRMAN call failed + + LDYIM ARGB + LDAIY NEWARG + TAY + + ANDIM OWNER + BNE #10 + LDAIM DRERRE ;'insufficient priv' + RTS + +10 TYA + ANDIM LOCKED + BEQ #20 + LDAIM DRERRG ;'entry locked' + RTS + +20 STY LAST ;preserve Type & access + +;now check that it isn't open + + LDAIM ARGB + STA NAME + LDYIM INFDIS + STY ONAME + LDXIM 2 + JSR #50 ;copy disc no. + + LDAIM INFSIN + STA ONAME + LDXIM 3 + JSR #50 ;copy SIN + + LDAIM 2 + JSR SETRTN + JSR RNDMAN ;ask for info + PHA + LDX LAST + PLA + BNE #30 ;RC=0 if open + LDAIM RDERRH ;'already open' + RTS + +30 LDAIM 0 +40 RTS ;*** the end ** + + +50 LDY ONAME + LDAIY PTR + LDY NAME + STAIY NEWARG + INC NAME + INC ONAME + DEX + BNE #50 + RTS + +RNAMPD ROUT ;**20/5/87** check name for root or pseudo directory + CMPIM ROOT + BEQ #10 + JMP Testpd + +RNAMPT ;**20/5/87** check separator or terminator + CMPIM SEPART + BEQ #10 + CMPIM TERMIN +10 RTS + + +;************** +;* USER INFO * +;************** + + +CPUINF ROUT + + JSR STKUSE + BNE #30 ;Who are you + + LDAIM HDRLEN ;Offset of user name + JSR SETFTP ;Set ptr. to user name + + LDAIM 6 ;USRMAN.USERINFO + JSR SETRTN + + JSR USRMAN + BNE #40 + + LDYIM ARGB + LDAIY NEWARG + [ 1=0 + LDXIM 0 ;calculate privilege value ; *** 25/5/86 *** + BITIM SYSTPV + BEQ #10 + LDXIM 1 +10 BITIM LOPRIV + BEQ #20 + LDXIM 2 +20 STX MIDTX + | + ANDIM SYSTPV ;calculate privilege value ;**31/10/86** + STA MIDTX + ] + INY ;copy station address + LDAIY NEWARG + STA MIDTX+1 + INY + LDAIY NEWARG + STA MIDTX+2 + INY + LDAIY NEWARG ;**20/5/87** return job (task) number + LSRA ;**20/5/87** position job (task) number + LSRA + LSRA + STA MIDTX+3 ;**20/5/87** assume extended format + + LDX BPTR + LDAAX RXBUF+1 ;**20/5/87** check function code + CMPIM (FNuin2-FNtab)/2 ;**20/5/87** C set if extended function + LDAIM TXHDR+3 ;Message length + BCC #20 + LDAIM TXHDR+4 +20 JSR REPLYC ;Return message +Cpuinx +30 JMP COMRTS + +40 JSR RCODE ;Send error + JMP #30 + + + +;************* +;* C L O S E * +;************* + +CPSHUT JSR STKUSE + BNE #30 + LDX BPTR + LDAAX MIDRX ;Get old handle + BEQ #50 ;Handle=0 => close all files for machine + + INY + STAIY NEWARG + LDAIM 3 ;"Close handle" + BNE #60 + +50 LDAIM &D ;"Close all files" +60 JSR SETRTN + JSR RNDMAN + JMP #40 + +;******** +;* FIND * +;******** + +;Open a file for reading or update, +;or open a directory + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +FIND ROUT + LDAIM 0 + STA COTEMP ;** 15/11/84 ** used to build access byte + + JSR GETUSE ;Set mc no. and call FINDMC + BNE Cpuinx ;Fail, exit + +;USTPTR now points to user info. +;Check if need to create a new file +;or if existing one will do. Then either create or retrieve +;new or existing file. + + LDX BPTR + LDAAX MIDRX+1 + BNE #30 ;Not opening for update + LDAAX MIDRX + BNE #30 ;File must exist => don't create + + JSR FICRFL ;Otherwise, create file and forge retrieve info. + BNE #45 ;Error + + LDAIM FILEJC ;Set "just created" flag in mode + ORA COTEMP + STA COTEMP + BNE #40 ;Skip round retrieve since we have all info. already + +30 JSR FIRETR ;Retrieve details of existing file + BNE #45 + +40 LDYIM ARGB + LDAIY NEWARG ;Get access allowed and type + TAX + ANDIM RDWRAC+TYPE + BNE #50 ;File, no read or write access + + LDAIM DRERRE +45 JMP Error ;insufficient access + +50 LDYIM ARGE + TXA + STAIY NEWARG ;Set up for RNDMAN call + PHA ;save access byte + + LDAIM 1 ;RNDMAN.OPEN + JSR SETUSA ;Copy USTPTR onto stack + +;Mode so far is in COTEMP - may need write +;access bit setting. + + PLA ;restore access byte + LDX BPTR + LDYAX MIDRX+1 ;Get read flag from client + BNE #60 ;Jump if set + + ANDIM 3 ;supply just the public access bits + JMP #65 ;fall thru' IS ok here + +; ORAIM RDWRAC ;Set Read/Write access + +60 LDAIM READAC +65 ORA COTEMP + LDYIM ARGD + STAIY NEWARG ;Put mode on stack + + INY ;Y := ARGE + JSR SCOWPT ;Put COWORK ptr on stack + + JSR RNDMAN ;*** Call RNDMAN.OPEN ** + BNE #90 ;Open failed + +;Open worked - return handle + + LDYIM ARGB + LDAIY NEWARG + STA MIDTX ;Store handle in TX buffer + + LDA COTEMP + ANDIM FILEJC ;DATE ALREADY SET IF JUST CREATED + BNE #70 + LDY BPTR + LDAAY MIDRX+1 ;updating file ? + BNE #70 + LDA DATE ;Check date and skip update if unchanged + CMP COTEMP+INFDTE + BNE #67 + LDA DATE+1 + CMP COTEMP+INFDTE+1 + BEQ #70 +67 LDAIM 4 ;DIRMAN.SET ATTRIBUTES + JSR SETUSA ;USER INFO + LDAIM FNDFTO ;POINTER TI FILE TITLE + JSR SETFTP ;FILE TITLE POINTER TO STACK + INY + LDAIM &C0 ;** 19/11/84 ** only updates one entry + STAIY NEWARG ;SET WILD CARD FLAG + INY + LDAIM 5 ;SET DATE FUNCTION + STAIY NEWARG + INY + LDA DATE + STAIY NEWARG ;PUT IN CURRENT DATE + INY + LDA DATE+1 + STAIY NEWARG + JSR DIRMAN ;SET TODAYS DATE ON OBJECT + BNE #90 ;SHOULDN'T FAIL!!! + +70 LDAIM TXHDR+1 ;Message length + JSR REPLYC ;Send handle back + +80 JMP COMRTS ;Return + +90 JSR EXTERR ;Send error code + JMP #80 ;exit + + +;*** FIRETR *** + +;Called from FIND to retrieve file details. +;Calls DIRMAN.RETRIEVE + +;Entry: USTPTR points to USERTB entry +;File title stil in RX buffer + +;Exit: A: return code +;COWORK buffer: file details +;ARGB on NEWARG: max access allowed + +FIRETR ROUT + LDAIM DRRTR ;DIRMAN.RETRIEVE + JSR SETUSA ;Put user info on NEWARG stack + + LDAIM FNDFTO ;File title offset + JSR SETFTP ;Set file title pointer + + JSR SCOWPT + + LDYIM ARGH + LDAIM &C0 + STAIY NEWARG ;wild card flag + + JMP DIRMAN ;*** Call DIRMAN.RETRIEVE and return ** + + +;*** FICRFL *** + +;Called to create new file in FIND. +;File is created with standard size of FIFLSZ bytes. + +;Entry: USTPTR points to user info +;File title in request buffer + +;Exit: A = return code +;COWORK buffer: file details as if from +;DIRMAN.RETRIEVE + +FICRFL ROUT + LDAIM 10 ;=> get disc number for this file + JSR SETUSA + LDAIM FNDFTO + JSR SETFTP ;Set pointer to file title + + LDYIM ARGK + LDAIM &80 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;DIRMAN.FILETITLETODISCNUMBER + BNE #10 + +;Correct disc number now on stack + + LDYIM ARGD ;Set file size to manifest FIFLSZ + LDAIM :LSB:FIFLSZ + STAIY NEWARG ;LS byte + INY + LDAIM :MSB:FIFLSZ + STAIY NEWARG ;CS byte + INY + LDAIM 0 ;MS byte zero + STAIY NEWARG + + JSR SETUSE ;pass userinfo @ ARGG,H ** 3/10/84 ** + + LDAIM MAPCS ;MAPMAN.CREATESPACE + JSR SETRTN + + JSR MAPMAN ;*** MAPMAN.CREATSPACE ** + BEQ #20 +10 RTS ;Exit if failed + +;Disc number and SIN on stack. +;Save them in COWORK (=DETRAM) buffer in +;DIRMAN.RETRIEVE format. + +20 LDYIM ARGB + LDAIY NEWARG ;Disc no. (LS) + STA DETDIS + INY + LDAIY NEWARG ;Disc no. (MS) + STA DETDIS+1 + + LDYIM ARGD + LDAIY NEWARG ;SIN (LS) + STA DETSIN + INY + LDAIY NEWARG ;SIN (CS) + STA DETSIN+1 + INY + LDAIY NEWARG ;SIN (MS) + STA DETSIN+2 + +;zero the new space + + LDYIM ARGG + LDAIM 0 ;old size + STAIY NEWARG + INY + STAIY NEWARG + INY + STAIY NEWARG + + LDAIM 13 + JSR SETRTN + JSR MAPMAN + BNE #10 ;exit if error + +;Preserve the newly created file + + LDAIM DRPRS ;DIRMAN.PRESERVE + JSR SETUSA ;Set user info on NEWARG stack + + LDAIM FNDFTO ;Offset of file title + JSR SETFTP ;Set pointer to title + + LDAIM &FF ;Clear load & exec addresses to $FF + +30 INY + STAIY NEWARG + CPYIM ARGM ;ARGM is end of exec address + BNE #30 ;Loop + + LDAIM ACCDEF+TYPFIL ;Default access; Type = file + INY + STAIY NEWARG ;Set type & access + + INY ;Set creation date + LDA DATE + STAIY NEWARG + INY + LDA DATE+1 + STAIY NEWARG + +;Copy SIN from COWORK (=DETRAM) to NEWARG stack + + LDA DETSIN ;SIN (LS) + INY + STAIY NEWARG + LDA DETSIN+1 ;SIN (CS) + INY + STAIY NEWARG + LDA DETSIN+2 ;SIN (MS) + INY + STAIY NEWARG + + LDYIM ARGT + LDAIM &80 + STAIY NEWARG ;wild card flag + + JSR DIRMAN ;*** Call DIRMAN.PRESERVE ** + BNE #40 ;Failed + JSR OBJCLR ;Clear old object out of map & cache if nesc. + BNE #40 ;**** 17/3/83 **** + +;Have created file: fabricate DIRMAN.RETRIEVE info +;in DETRAM buffer (disc no. and SIN already there) +;and on NEWARG stack. Need to include only access +;info and size. + + LDAIM ACCDEF ;Default access + STA DETACC + + LDAIM :LSB:FIFLSZ ;Size (LS) + STA DETSZ + LDAIM :msb:FIFLSZ ;Size (CS) + STA DETSZ+1 + LDAIM 0 + STA DETSZ+2 ;Size (MS) + +;Need to put type of object & max access +;allowed on NEWARG stack at ARGB (because +;DIRMAN.RETRIEVE does). + + LDAIM RDWRAC+TYPFIL ;Read/write access; Type = file + LDYIM ARGB + STAIY NEWARG + + LDAIM 0 ;return code + RTS + +;Failed to do preserve - must free space + +40 STA COTEMP+1 ;Save RC + + JSR FIDSIN ;Disc no. & SIN to stack + + LDYIM ARGF + JSR SETUSE ;pass pointer to user info ** 3/10/84 ** + + LDAIM MAPFS ;MAPMAN.FREESPACE + JSR SETRTN + + JSR MAPMAN ;*** MAPMAN.FREESPACE ** + BEQ #50 ;OK + JSR INTERR ;Never happens? + +50 LDA COTEMP+1 ;Get back RC from Preserve + RTS + + +;*** FIDSIN *** + +;Copy disc no. and SIN from DETRAM (=COWORK) buffer +;to NEWARG stack + +FIDSIN ROUT + LDYIM ARGB + LDA DETDIS ;Disc no (LS) + STAIY NEWARG + LDA DETDIS+1 ;Disc no (MS) + INY + STAIY NEWARG + + LDA DETSIN ;SIN (LS) + INY + STAIY NEWARG + LDA DETSIN+1 ;SIN (CS) + INY + STAIY NEWARG + LDA DETSIN+2 ;SIN (MS) + INY + STAIY NEWARG + RTS + + + +;*********** +;* E O F * +;*********** + +CPEOF ROUT + +;Calls RDEOF and returns $FF if HWM<=SFP, zero +;otherwise. + + JSR STKUSE + BNE #05 ;User not valid + + LDX BPTR + LDAAX MIDRX + INY + STAIY NEWARG ;Set handle of file + LDAIM &F + JSR SETRTN + JSR RNDMAN ;Do End of File call + BNE #06 ;Error -> pass on + LDYIM ARGB + LDAIY NEWARG ;Get result from randman + STA MIDTX + LDAIM TXHDR+1 + JSR REPLYC +05 JMP COMRTS + +06 JSR RCODE ;Return error + JMP COMRTS + +;***************************** +;* Return free space on disc * +;***************************** + +CPSPAC + JSR RDTITL + BNE #05 ;syntax error ? + + LDAIM 10 + JSR SETRTN + JSR SBUFPT ;put pointer on stack + + JSR MAPMAN ;name -> number + BNE #20 ;skip on error + +;returns: +;ARGB = LS disc number +;ARGC = MS disc number + + LDAIM 12 ;new entry point 21/3/83 + JSR SETRTN + + JSR MAPMAN + BNE #20 ;skip on error + + LDXIM 5 + LDYIM ARGG ;ready to copy data back +10 LDAIY NEWARG + STAAX MIDTX + DEY + DEX + BPL #10 ;return three bytes + + LDAIM TXHDR+6 ;message length + JMP Datout ;send back result + +20 JMP Error + + +;return callers free space + +RDFREE ROUT + JSR STKUSE + BNE #70 + + LDYIM ARGC + LDX BPTR + LDAAX MIDRX + CMPIM CR + BNE #20 ;no argument + + LDA USTPTR + CLC + ADCIM UTUSID + STA USTPTR + BCC #10 + INC USTPTR+1 +10 JSR SETUSE ;set the user pointer on stack + JMP #30 + +20 LDAIM HDRLEN+0 + JSR SETFTP ;point to user name + +30 LDAIM 9 + JSR SETRTN + JSR AUTMAN + BNE #50 + + LDXIM 3 + LDYIM ARGB+3 +40 LDAIY NEWARG + STAAX MIDTX + DEY + DEX + BPL #40 + LDAIM HDRLEN+4 + JMP Datout + +50 JMP ERROR + +;set user free space + +WRFREE JSR STKUSE + BNE #70 + + LDYIM ARGC + LDAIM HDRLEN+4 ;offset of name + JSR SETFTP ;pointer to name + + LDX BPTR + LDYIM ARGF +60 LDAAX MIDRX + STAIY NEWARG + INX + INY + CPYIM ARGF+4 + BNE #60 + + LDAIM 10 + JSR SETRTN + JSR AUTMAN + JSR RCODE ;reply with zero RC +70 JMP COMRTS ;else all ok + + LNK UADE19 diff --git a/Level3/SRC/L3/Uade19 b/Level3/SRC/L3/Uade19 new file mode 100644 index 0000000..0cf0778 --- /dev/null +++ b/Level3/SRC/L3/Uade19 @@ -0,0 +1,745 @@ + OPT UADE19 ;File > Uade19 + TTL File server file UADE19 + + +;********** +;* GETBYT * +;********** + +;Read single byte from file. +;All work done by RNDMAN. + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +GETBYT ROUT + JSR STKUSE ;Put user info ptr on stack + BNE #10 + + JSR #30 + + LDAIM 7 ;RNDMAN.RDCH + JSR SETRTN + JSR RNDMAN ;*** Call RNDMAN.RDCH ** + BNE #20 ;Failed + + LDYIM ARGB + LDAIY NEWARG ;Get byte read + STA MIDTX ;Put in TX buffer + + INY + LDAIY NEWARG ;Get EOF flag + STA MIDTX+1 ;Put in TX buffer + LDAIM TXHDR+2 ;Message length + +;Note that sequence no. is still in control block + + JSR REPLYC ;Send reply + +10 JMP COMRTS ;exit + +20 JMP ERROR + +30 LDX BPTR + LDAAX RXBUF+2 ;Get file handle + LDYIM ARGD + STAIY NEWARG + + LDX QPTR ;Get seq no. from control block + LDAAX RXCBV + ANDIM 1 ;Mask out reception flag + INY + STAIY NEWARG + RTS + + +;********** +;* PUTBYT * +;********** + +;Write single byte to file. +;All work done by RNDMAN. + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +PUTBYT + JSR STKUSE ;Put user info ptr on stack + BNE #10 + + JSR #30 + + LDX BPTR + LDAAX RXBUF+3 ;Get byte to be written + INY + STAIY NEWARG ;Put on call stack + + LDAIM 8 ;RNDMAN.WRCH + JSR SETRTN + JSR RNDMAN ;*** Call RNDMAN.WRCH ** + +;Note that sequence no. is still in control block + + JSR RCODE ;Send return code + + JMP COMRTS ;exit + + + +;* CPRDAR * + +;Read specified part of file info + +;Most work done in RNDMAN. + +CPRDAR ROUT + JSR GETUSE ;USTPTR := USERTB entry + BNE #60 + JSR SETUSR ;Copy user info to NEWARG stack + LDX BPTR ;Offset of request buffer + LDAAX MIDRX ;Get handle + LDYIM ARGD + STAIY NEWARG ;Put handle on NEWARG stack + + LDAIM &B ;RNDMAN.RDAR + JSR SETRTN + JSR RNDMAN ;*** Call RNDMAN.RDAR ** + BNE #40 ;Not OK, send error code and exit + +;Have now got sequential file ptr, file hwm, +;and file size on NEWARG stack. +;The one to be sent back is determined by +;arg in request block. +;Arg is 0,1,2 resp. to get the above. + +;Set Y to appropriate offset on NEWARG stack + + LDX BPTR ;Offset of request buffer + LDAAX MIDRX+1 ;Arg from request + BNE #10 ;Not 0 + + LDYIM ARGB ;Offset of file ptr + BNE #50 + +10 CMPIM 1 ;Test arg + BNE #20 ;Not 0 or 1 + + LDYIM ARGE ;Offset of file HWM + BNE #50 + +20 CMPIM 2 ;Test arg + BNE #30 ;Not 0, 2, or 1 + + LDYIM ARGH ;Offset of file size + BNE #50 + +;Invalid arg in request + +30 LDAIM ARGERR ;"Bad arg to RDAR" +40 JMP ERROR ;Send error and exit + +;Y now contains the offset on NEWARG +;of the required 3 bytes. + +50 LDAIY NEWARG ;LS byte + STA MIDTX ;Put in TX buffer + INY + LDAIY NEWARG ;CS byte + STA MIDTX+1 + INY + LDAIY NEWARG ;MS byte + STA MIDTX+2 + LDAIM TXHDR+3 ;Mesage length + JSR REPLYC ;Send reply + +60 JMP COMRTS ;Exit + + + +;* CPSTAR * + +;Set sequential file pointer + +CPSTAR ROUT + JSR GETUSE ;USTPTR := ptr to user info + BNE #10 ;error + JSR SETUSR ;Copy user info to stack + LDX BPTR ;Offset of request buffer + LDAAX MIDRX ;Get handle + LDYIM ARGD + STAIY NEWARG ;Put handle on stack + +;Put arg saying what to set on stack + + LDAAX MIDRX+1 + INY + STAIY NEWARG + +;Put value to be set on stack + + LDAAX MIDRX+2 ;value (LS) + INY + STAIY NEWARG + LDAAX MIDRX+3 ;value (CS) + INY + STAIY NEWARG + LDAAX MIDRX+4 ;value (MS) + INY + STAIY NEWARG + LDAAX MIDRX+5 ;Some vals have 4 bytes + INY + STAIY NEWARG + + LDAIM &C ;RNDMAN.STAR + JSR SETRTN + JSR RNDMAN ;*** Call RNDMAN.STAR ** + JSR RCODE ;Transmit reply + +10 JMP COMRTS ;Exit + + + +;************ +;* PUTBYTES * +;************ + +;Write several bytes to specified file offset. + +;1) Set up pointer to user info +;2) (abolished) +;3) Send first reply, giving data port +;and max. blocksize. +;4) LOOP: receive block into big buffer +;5) LOOP: write to disc (RNDMAN.PUTBYTES) +;unless disc error flag set +;6) LOOP: If disc error, then set flag but +;continue to receive. +;7) LOOP: If more to receive, adjust OFFSET +;and loop to 4). +;8) Send final RC (disc error flag) + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +PBYTES ROUT + JSR GETUSE ;USTPTR := ptr to user info + BNE #10 ;not logged on ** 6/9/84 ** + + JSR RMSUBO ;Prepare for some PUTBYTES calls + BEQ #15 + +05 JSR EXTERR ;Not OK, send RC +10 JMP COMRTS ;Exit + +;Send first reply, giving data port and max blocksize + +15 LDAIM PSAVD ;Use same data port as SAVE + STA MIDTX + + LDAIM :LSB:BUFSZ ;Big buffer size (2 bytes) + STA MIDTX+1 + LDAIM :MSB:BUFSZ + STA MIDTX+2 + + LDAIM 0 + STA RTCODE ;RTCODE := CCODE := 0 + STA CCODE + + LDAIM TXHDR+3 ;Message length + + JSR REPLY ;Send message + BNE #10 ;Lost contact - abort + +;Ready to receive data, so set up for +;reception loop. + + LDAIM 0 + STA DATAIN ;DATAIN := 0 (3 bytes) + STA DATAIN+1 + STA DATAIN+2 + STA DSCERR ;Clear disc err flag + STA FINFLG ;Clear end-of-transfer flag + +;Test specially for transfer of zero bytes, +;to prevent 64K net control block being +;set up! Jump straight to final reply. + + LDX BPTR + LDAAX MIDRX+2 ;Ls byte of size + ORAAX MIDRX+3 ;CS + ORAAX MIDRX+4 ;MS + BNE #20 ;Not zero bytes + JMP #70 ;Jump straight to final reply + +;Loop which receives data and writes it to disc +;Set buffer pointers in RX control block + +20 LDY QPTR ;Buffer start = BBUF + LDA BBUF + STAAY CBBUF + LDA BBUF+1 + STAAY CBBUF+1 + + LDA BBEND ;Buffer end = BBEND + STAAY CBBUFE + LDA BBEND+1 + STAAY CBBUFE+1 + + LDAIM PSAVD ;Set data port + STAAY CBPORT + +;Station already set from first reception + + JSR WAIT ;Wait for reception + BNE #10 ;No contact => abort + +;Now subtract buffer limits to see how +;much data was received. + + LDY QPTR + SEC ;COWORK := CBBUFE-CBBUF + LDAAY CBBUFE + SBCAY CBBUF + STA COWORK ;LS byte + LDAAY CBBUFE+1 + SBCAY CBBUF+1 + STA COWORK+1 ;MS byte + +;Add amount received to total number of bytes +;received. + + CLC ;DATAIN +:= COWORK + LDA COWORK ;LS byte + ADC DATAIN + STA DATAIN + LDA COWORK+1 ;CS byte + ADC DATAIN+1 + STA DATAIN+1 + BCC #25 ;MS byte of received length always 0 + INC DATAIN+2 +25 + +;Compare total amount received (in DATAIN) +;with total number of bytes to be written. +;(in original message buffer). +;Set FINFLG if exactly the right amount +;has been received. +;If too much has been received, then send +;a return code. + + LDX BPTR + SEC + LDAAX MIDRX+2 ;LS byte of size + SBC DATAIN + STA BREGA ;Use BREGA as workspace + LDAAX MIDRX+3 ;CS byte of size + SBC DATAIN+1 + STA BREGA+1 + LDAAX MIDRX+4 ;MS byte + SBC DATAIN+2 + +;Carry set if received <= size + + ORA BREGA ;OR 3 bytes of result + ORA BREGA+1 ;for zero test + BEQ #30 ;Equal => last block + BCS #40 ;Recd < size => carry on + +;Client sent too much data. +;Send error code and stop. + + LDAIM PBERRA ;Error code + JMP #05 ;Send RC and exit + +30 LDAIM &FF ;Last block; set FINFLG + STA FINFLG + +;If disc error flag set, ignore received data, +;and jump round disc write. + +40 LDA DSCERR ;Disc error flag + BNE #50 ;Jump if error + +;Set up for call of RNDMAN + + + LDX BPTR + LDAAX MIDRX ;Get file handle + LDYIM ARGD + STAIY NEWARG ;Put on call stack + + LDA BBUF ;Buffer addr (Big Buffer) + INY + STAIY NEWARG + LDA BBUF+1 + INY + STAIY NEWARG + + LDA COWORK ;No. of bytes (calculated above) + INY + STAIY NEWARG ;LS byte + LDA COWORK+1 + INY + STAIY NEWARG ;MS byte + + LDAIM &A ;RNDMAN.PUTBYTES + JSR SETUSA ;Stack user info + + JSR RNDMAN ;*** RNDMAN.PUTBYTES ** + BEQ #50 ;OK, continue + STA DSCERR ;Store error code + +;If FINFLG is set, then we have just written +;the last block. +;Otherwise, adjust the file offset and carry on. + +50 LDA FINFLG ;Finished? + BNE #70 ;Exit from loop if yes + +;Send ack to client's ack port + + LDY BPTR + LDXAY CPUFD ;Ack port + LDAIM 1 ;Message length + JSR REPLYB ;Send byte (random contents) + BNE #80 ;Contact lost => abort + +60 JMP #20 ;Round loop again + +;Have received all the data. +;Final RC is in DSCERR. +;If RC is zero, send back amount xferred (always amount requested +;if no error). If non-zero, send error. + +70 LDA DSCERR + STA RTCODE + BNE #90 ;RC <> 0 => error + STA CCODE ;Set command code = 0 + STA MIDTX+4 ;send 32 bit number + LDX BPTR + LDAAX MIDRX+2 + STA MIDTX+1 + LDAAX MIDRX+3 + STA MIDTX+2 + LDAAX MIDRX+4 ;Move length of data to MIDTX + STA MIDTX+3 + LDAIM TXHDR+5 + JSR REPLYC ;Send reply (note MIDTX undefined) + +80 JMP COMRTS ;Exit from command + +90 JSR RCODE ;Send error reply + JMP #80 + + + +;************ +;* GETBYTES * +;************ + +;Read several bytes from specified file offset. + +;1) Set up pointer to user info +;2) Save size of transfer. +;SEND first RC to client +;3) LOOP: read chunk into big buffer (RNDMAN.GETBYTES) +;unless disc error flag set +;4) LOOP: If disc error, then set flag but +;continue to send data. +;5) LOOP: send to client +;6) LOOP: If more to send, adjust OFFSET +;and loop to 3). +;7) Send final RC (disc error flag) + +;Entry: BPTR is offset of buffer in RXBUF +;QPTR is offset of control block in RXCBV + +GBYTES ROUT + LDAIM 0 + STA GBBXFD ;GBBXFD := 0 + STA GBBXFD+1 + STA GBBXFD+2 + STA GBEFLG ;GBEFLG := 0 + + JSR GETUSE ;USTPTR := ptr to user info + BNE #10 ;OK, continue ** 6/9/84 ** + + JSR RMSUBO ;Set up RNDMAN for GETBYTES calls + BEQ #15 + +05 JSR EXTERR ;Not OK, send RC +10 JMP COMRTS ;Exit + +15 LDYIM ARGB ;**23/3/88** check mode of access for file + LDAIY NEWARG + ANDIM READAC + BNE #16 + LDAIM RDERRO + BNE #05 + +16 + [ 1=0 + LDX BPTR ;**23/3/88** check if GETBYTES or GETPUTBYTES + LDAAX RXBUF+1 + EORIM 35 + BNE #17 + LDAIM &E ;**23/3/88** GETPUTBYTES, prepare put also + JSR SETUSA + LDAAX MIDRX+1 + JSR RMSUBP + BNE #05 + BEQ #20 + +17 + ] + LDAIM 0 + JSR RCODE ;Send "OK" rc + BNE #10 ;lost contect so ABORT + +;TOSEND := size of transfer + +20 LDX BPTR + LDAAX MIDRX+2 ;Size (LS) + STA TOSEND + LDAAX MIDRX+3 ;Size (CS) + STA TOSEND+1 + LDAAX MIDRX+4 ;Size (MS) + STA TOSEND+2 + +;Use the big buffer. +;Read from disc chunks of size BUFSZ, and transmit +;them to the client. +;Note that, in general, each chunk will be badly +;aligned with respect to disc blocks. RNDMAN tries +;to be efficient about this for each chunk. +;It may be worth adding extra optimization here if +;very large (> BUFSZ) transfers are common. + + LDAIM 0 + STA DSCERR ;No disc error yet + STA FINFLG ;Not finished yet + +;Test specially for transfer of zero +;bytes to prevent 64K net control +;block being set up! + + LDA TOSEND ;Size (LS) + ORA TOSEND+1 ;CS + ORA TOSEND+2 ;MS + BNE #25 ;OK - not zero bytes + JMP #70 ;Jump straight to final reply + + +;Loop, sending data to client in blocks of +;size BUFSZ. TOSEND is the amount left to +;send, OFFSET the current file position. +;If an error occurs, the error code is put +;in DSCERR and the loop continues, padding +;out the transmission until the right +;amount of data has been sent. +;FINFLG gets set on the last time round +;the loop. + +25 SEC ;COWORK := TOSEND - BUFSZ + LDA TOSEND + SBCIM :LSB:BUFSZ + STA COWORK + LDA TOSEND+1 + SBCIM :MSB:BUFSZ + STA COWORK+1 + LDA TOSEND+2 + SBCIM 0 + STA COWORK+2 + + ORA COWORK ;OR 3 bytes for zero test + ORA COWORK+1 + BEQ #30 ;TOSEND = BUFSZ + BCS #35 ;TOSEND < BUFSZ + +;BUFSZ >= TOSEND: send remaining data +;and set finish flag. + +30 LDA TOSEND ;OUTBSZ := TOSEND + STA OUTBSZ + LDA TOSEND+1 + STA OUTBSZ+1 + DEC FINFLG ;Set loop finish flag to $FF + BNE #40 + +35 LDAIM :LSB:BUFSZ ;OUTBSZ := BUFSZ + STA OUTBSZ + LDAIM :MSB:BUFSZ + STA OUTBSZ+1 + +;The size of the block to send is in OUTBSZ. +;Call RNDMAN.GETBYTES to get the data into +;the big buffer. + +40 LDX BPTR + LDAAX MIDRX ;Get file handle + LDXIM 9 ;**23/3/88** RNDMAN.GETBYTES + JSR RMSUBR + +;Add number of bytes actually read to +;GBBXFD, and OR end-of-file flag +;into GBEFLG. + + CLC + LDYIM ARGB + LDAIY NEWARG ;Bytes xferred (LS) + ADC GBBXFD + STA GBBXFD ;LS total + INY + LDAIY NEWARG + ADC GBBXFD+1 + STA GBBXFD+1 ;CS total + BCC #60 ;Only 2 bytes from RNDMAN + INC GBBXFD+2 ;MS total +60 INY + LDAIY NEWARG ;EOF flag + ORA GBEFLG ;OR with flag so far + STA GBEFLG + + LDY BPTR + [ 1=0 + LDAAY RXBUF+1 ;**23/3/88** GETBYTES or GETPUTBYTES + EORIM 35 + BNE #65 + LDA DSCERR + BNE #67 + LDAAY MIDRX+1 + LDXIM &A ;**23/3/88** RNDMAN.PUTBYTES + JSR RMSUBR + JMP #67 + +65 + ] + LDAAY CPUFD ;Get client's data port + JSR SENDBB ;Send big block (size in OUTBSZ) + BNE #90 ;Contact lost with client; give up + +;End of loop. Test finish flag, and set +;TOSEND from COWORK. + +67 BIT FINFLG ;Test finish flag + BMI #70 ;Exit from loop if finished + + LDA COWORK ;TOSEND := COWORK + STA TOSEND + LDA COWORK+1 + STA TOSEND+1 + LDA COWORK+2 + STA TOSEND+2 + + JMP #25 ;Loop return + +;Exit from GBLOOP: RC in DSCERR + +70 LDA DSCERR + BNE #80 ;Jump if error + +;Send back end-of-file flag and +;count of bytes actually read. + + LDA GBEFLG ;EOF flag + STA MIDTX ;Put in TX buffer + LDA GBBXFD ;Bytes xferred (LS) + STA MIDTX+1 + LDA GBBXFD+1 + STA MIDTX+2 ;CS + LDA GBBXFD+2 + STA MIDTX+3 ;MS + LDAIM 0 + STA MIDTX+4 ;send 32 bit number ** 26/2/85 ** + LDAIM TXHDR+5 ;Message length + JMP Datout ;Send reply + +80 JSR RCODE ;Send return code + +90 JMP COMRTS ;Exit from command + + + +;*** Call RNDMAN to set up bytes operation + +RMSUBO ROUT + LDAIM &E ;**** RNDMAN.SUBO *** + JSR SETUSA + LDX BPTR + LDAAX MIDRX+0 ;Get file handle +RMSUBP INY + STAIY NEWARG + + LDX QPTR ;Get seq no from control block + LDAAX RXCBV + ANDIM 1 ;Get just seq bit + INY + STAIY NEWARG + +;The flag, no of bytes, and offset +;are in the correct order in rx block + + LDX BPTR +10 LDAAX MIDRX+1 + INY + STAIY NEWARG + INX + CPYIM ARGL + BNE #10 ;More to copy + + JMP RNDMAN ;**** Call RNDMAN.SUBO & return *** + +;Routine to call RNDMAN.GETBYTES or .PUTBYTES. +;Entry: A=handle X=RNDMAN code + +RMSUBR ROUT + LDYIM ARGD + STAIY NEWARG ;Put handle on stack + + LDA BBUF ;Put buffer address on stack + INY + STAIY NEWARG + LDA BBUF+1 + INY + STAIY NEWARG + + LDA OUTBSZ ;Put no. of bytes on stack + INY + STAIY NEWARG + LDA OUTBSZ+1 + INY + STAIY NEWARG + + TXA ;RNDMAN function code + JSR SETUSA + + JSR RNDMAN ;*** Call RNDMAN ** + BEQ #50 ;OK, continue + STA DSCERR ;Otherwise set error code +50 RTS + + +;Yet another interface - this one allows an application +;to determine the userid under which it is logged-on + +;This is probably most useful for MAILing type progs + +CPWHO ROUT ;** 19/3/85 ** + JSR GETUSE + BNE #20 ;nb this will deal with the error + + LDXIM 0 + LDYIM UTUSID +10 LDAIY USTPTR ;copy the user name + STAAX MIDTX + INY + INX + CMPIM CR ;copy only upto CR (pw follows - dont want that) + BNE #10 + + TXA + JMP Datous ;return the answer with zero RC + +20 JMP COMRTS + + LNK UADE20 diff --git a/Level3/SRC/L3/Uade20 b/Level3/SRC/L3/Uade20 new file mode 100644 index 0000000..bca0068 --- /dev/null +++ b/Level3/SRC/L3/Uade20 @@ -0,0 +1,1118 @@ + OPT UADE20 ;FILE > Uade20 + TTL File server file UADE20 + + +;C O M M A N D P R O C E S S O R + +;U T I L I T I E S + + +RCODE ROUT + +;Check return code in A. If 0, send +;3 byte message. If not, go to error +;routine +;Command code always set 0. + + LDXIM 0 + STX CCODE + TAY + BEQ REPLYA + JMP EXTERR + + +;Sends a zero return code to client. +;Sets RC into TXBUF and drops through into +;REPLY, passing a the header length as message length + +REPLYA LDAIM TXHDR +REPLYC LDXIM 0 + STX RTCODE ;Set R.code + +;Sends a message of length A to client +;on the reply port (in var RPLYPT). + +REPLY LDX RPLYPT + +;Sends a message of length A on port X +;to client. + +REPLYB LDY QPTR ;Get CB pointer + CLC + ADCIM :LSB:TXBUF + STAAY CBBUFE ;Buffer end ptr. (lo) + LDAIM 0 ;Assumed msg. length < 255 + + STAAY CBBUF+2 + STAAY CBBUF+3 ;hi order addresses + STAAY CBBUFE+2 + STAAY CBBUFE+3 ;from 2nd processor + + ADCIM :MSB:TXBUF + STAAY CBBUFE+1 ;Buffer end ptr (hi) + + LDAIM :LSB:TXBUF + STAAY CBBUF ;Buffer ptr lo + LDAIM :MSB:TXBUF + STAAY CBBUF+1 ;Buffer ptr hi + TXA ;Set port + STAAY CBPORT + + +;Entry point used when CB set up elsewhere +;(e.g. LOAD/EXAMINE). Assumed all is +;set but TX flag. + +SEND ROUT + LDAIM TXFLAG + ORAAY CBFLG + STAAY CBFLG + +SENDX LDAIM TXRPT + LDYIM TXDLY ;Delay between tries + +;A = no. of times to try transmit +;Y = delay between tries +;NETCB = page zero pointer to control block + + STA TXJ + STY TXD + LDYIM 0 + LDAIY NETCB + STA TXF ;flag byte +10 LDX NETCB ;Pointers to CBlock + LDY NETCB+1 + LDAIM &10 + JSR OSWORD ;call Tx + + LDYIM 0 + LDAIY NETCB ;check for Tx on Tx + BNE #20 + LDA TXF + STAIY NETCB + BNE #10 ;restore flag byte and try again + +20 LDAIM 50 + JSR OSBYTE + TXA + BMI #20 ;poll 'til done + BEQ #40 ;Yes => success => exit + DEC TXJ ;No. of times decrement + BEQ #30 ;All done => failure + LDY TXD ;Delay time + JSR MSDELY ;Do delay + JMP #10 ;Do again + +30 TXA ;Return flag in A +40 RTS + + +;Wait to receive from client. +;Control block pointed by QPTR, wait +;is a constant (WAITCL) no. of msecs. + +WAIT ROUT + LDAIM RXFLAG + STA CBFLG ;CB is ammended for Rx, so open it + + LDXIM 0 + STX RXCBN + LDAIM &11 + LDXIM :LSB:RXCBN + LDYIM :MSB:RXCBN + JSR OSWORD + + LDXIM 50 +WaitX STX TIMER2 + LDXIM WAITCL + STX TIMER1 +10 LDAIM ONEMS ;One msec loop + STA TIMER ;(2cycles) +20 LDX RXCBN ;(4usecs) + LDAIM 51 + JSR OSBYTE ;poll Rx + TXA + BMI #30 ;(2) + DEC TIMER ;(5) timer not p.0 + BNE #20 ;(3) + DEC TIMER1 ;(2) + BNE #10 ;(3) + DEC TIMER2 + BNE #10 + +;Total inner loop time = 14 cycles +;So ONEMS = 71 (decimal) + +30 LDXIM :LSB:RXCBN + LDYIM :MSB:RXCBN + LDAIM &11 + JSR OSWORD ;read the control block + + LDAIM 0 + BIT RXCBN+1 ;read flag byte + BMI #40 + LDAIM WAITER ;timeout + +40 RTS + + +ERROR ROUT + JSR EXTERR + JMP COMRTS + + +;Puts error code in A into TXBUF +02. +;Looks A up in ERRTAB and if found, puts text into +;message. +;If not found, uses text F.S. ERROR xx (xx is A +;in hex). +;Message then send to client using REPLY. +;CCODE always set to zero in LOOKER + +EXTERR ROUT + PHA + JSR LOOKER ;Find error in table etc. + PLA ;** 17/9/84 ** + CMPIM RDERRH + BNE #30 + LDA MCopat+1 ;Details of where object open + BEQ #10 ;net number + + JSR #40 ;write into the buffer + LDAIM "." + STAAX MIDTX ;add separator + INX + +10 LDA MCopat ;station number + JSR #40 ;append to end of message + LDAIM "(" + STAAX MIDTX ;lest job (task) number present + LDA MCopat+2 + BEQ #20 + INX + JSR #40 ;write into the buffer + LDAIM ")" + STAAX MIDTX + INX + +20 LDAIM CR + STAAX MIDTX + +30 TXA ;Message length for REPLY + SEC ;Set carry to add 1 for CR + ADCIM TXHDR ;Add header length to message length + JMP REPLY ;Send and return + +40 STX COTEMP + JSR MKDEC ;convert to decimal + LDYIM :LSB:-3 + LDX COTEMP ;restore X value +50 LDAAY COWORK-:LSB:-3 ;get results from MKDEC + CMPIM SPACE + BEQ #60 + STAAX MIDTX ;put text in buffer + INX +60 INY + BNE #50 + RTS + + +;Look error in A up and put relevant message +;at MIDTX. + +LOOKER ROUT + STA RTCODE + PHA + + LDAIM :LSB:ERRTAB + STA GENPTR + LDAIM :MSB:ERRTAB + STA GENPTR+1 + LDYIM 0 + STY CCODE ;Set command code to zero +10 PLA + CMPIY GENPTR ;Check error number + BEQ #60 ;Found + + PHA + LDAIM CR +20 INY + BNE #30 + INC GENPTR+1 +30 CMPIY GENPTR ;Move to end of this text + BNE #20 + INY + BNE #40 + INC GENPTR+1 +40 LDAIY GENPTR + BNE #10 ;Non-zero => not end of table + +;If here, number not found, so construct +;default error message. + + LDXIM 0 +45 LDAAX ERRMSG ;Load error text + BMI #50 ;Terminated by NOP + STAAX MIDTX ;Store in transmit buffer + INX + BNE #45 + +50 PLA ;Get error number back + JSR WRTERR ;Put A in hex in message at X + LDAIM CR + STAAX MIDTX ;Terminate message + RTS + +60 LDXIM &FF ;Error found, move text to message +65 INX + INY + BNE #70 + INC GENPTR+1 +70 LDAIY GENPTR + STAAX MIDTX + CMPIM CR + BNE #65 + RTS ;Complete, exit X - length-1 + + +WRTERR ROUT + PHA + LSRA + LSRA + LSRA + LSRA + JSR #10 ;TOP NIBBLE + PLA +10 ANDIM &F + CMPIM &A + BCC #20 + ADCIM 6 +20 ADCIM &30 + STAAX MIDTX + INX + RTS + + + [ Lang = English +ERRMSG = "F.S. Error " + ] + [ Lang = Italian +ERRMSG = "Errore mefile " + ] + NOP + + +;Send big block on port in A. +;Size of message is in OUTBSZ, +;assumes station already set. + +SENDBB ROUT +SENDBC LDY QPTR + STAAY CBPORT + CLC + LDA BBUF ;Buffer address + STAAY CBBUF + ADC OUTBSZ + STAAY CBBUFE + LDA BBUF+1 + STAAY CBBUF+1 + ADC OUTBSZ+1 + STAAY CBBUFE+1 + JMP SEND ;Send message ... + + +SENDIO ROUT + LDY QPTR ;routine to send the IO side buffer + STAAY CBPORT ;in byte-size chunks ** 19/1/84 ** + + CLC + LDA IOBUF + STA COTEMP + ADC OUTBSZ + STA OUTBSZ + LDA IOBUF+1 + STA COTEMP+1 + ADC OUTBSZ+1 + STA OUTBSZ+1 ;COTEMP is low end of buffer + + LDAIM &FF + STAAY CBBUF+2 + STAAY CBBUF+3 + STAAY CBBUFE+2 + STAAY CBBUFE+3 ;initialise top bytes + +10 LDY QPTR + CLC + + LDA COTEMP + STAAY CBBUF + ADCIM BUFSZ + STAAY CBBUFE + STA COTEMP + + LDA COTEMP+1 + STAAY CBBUF+1 + ADCIM :MSB:BUFSZ + STAAY CBBUFE+1 + STA COTEMP+1 ;buffer pointers set, new COTEMP set + + LDAAY CBBUFE + CMP OUTBSZ + LDAAY CBBUFE+1 + SBC OUTBSZ+1 + BCC #20 ;C=1 if cbbufe>= outbsz + + LDA OUTBSZ + STAAY CBBUFE + LDA OUTBSZ+1 + STAAY CBBUFE+1 ;setup last transmission + +20 PHP + JSR SEND ;do transmit + PLP ;restore carry + TAX + BNE #30 ;bad transmit + BCC #10 +30 RTS + +MSDELY ROUT + CPYIM 0 + BEQ #30 ;If no delay, Exit + PHA ;Keep Acc. + TXA + PHA ;Keep X + TYA + PHA + LDXIM 0 +10 DEX + BNE #10 ;1msec loop + DEY + BNE #10 ;Outer loop + PLA + TAY ;Reset delay time + PLA + TAX ;Reset X + PLA ;Reset A +30 RTS + + +;*** NON - NET UTILITIES *** + + +CPDNAM ROUT + +;Read disc name of disc number at ARGF on stack +;into MIDTX offset by A. + + PHA ;Push MIDTX offset + + LDYIM ARGF + LDAIY NEWARG ;GET DISC NO. + PHA + INY + LDAIY NEWARG ;SET ON STACK AT ARGB + LDYIM ARGC + STAIY NEWARG + DEY + PLA + STAIY NEWARG + LDAIM &B ;MAPMAN ENTRY PT. + JSR SETRTN + JSR MAPMAN + BNE #20 + + LDYIM ARGB + LDAIY NEWARG + STA GENPTR + INY + LDAIY NEWARG + STA GENPTR+1 ;SET PTR. TO DISC NAME + + PLA + TAX ; Offset from MIDTX + LDYIM 0 +10 LDAIY GENPTR + STAAX MIDTX + INX + INY + CPYIM DNAMLN + BNE #10 +20 RTS + + +DIRIND ROUT + STA COZERO + JSR STKUSA ;Stack user info at ARGA + LDXIM &C1 + BNE #10 + +;Call DIRMAN.EXAMINE to get last component of +;file title (may be CR) and disc number and cycle +;number of directory. +;On entry, A is offset from MIDTX to put dir. name +;Dir. name arg. is assumed at MIDRX + +DIRINF STA COZERO + JSR STKUSA ;Stack user info at ARGA + LDXIM &C0 +10 LDAIM HDRLEN +DIRIN2 ;Entry point from CPINFO + STX COZERO+1 ;save parameter for DIRMAN + JSR SETFTP ;MOVE FILE TITLE PTR. TO STACK + INY + LDA COZERO ;Load offset + CLC + ADCIM :LSB:MIDTX + STAIY NEWARG ;SET RESULT AREA FOR EXAMINE + LDAIM :MSB:MIDTX + ADCIM 0 + INY + STAIY NEWARG + INY + LDAIM 4 + STAIY NEWARG ;ARG. FOR EXAMINE => GET TITLE + LDAIM 7 + JSR SETRTN + + LDYIM ARGK + LDA COZERO+1 ;passed parameter + STAIY NEWARG ;wild card flag + + JMP DIRMAN ;GET INFO. and return + + +;Copy SIN/Disc no. from DANDS to +;stack. Y already set as stack ptr. + +SINDSC ROUT + LDXIM 0 +10 LDAAX DANDS + STAIY NEWARG + INY + INX + CPXIM 5 + BNE #10 + RTS + + +;Copy disc block information to stack, starting +;at Y. + +;Info is: +;1) Current disc block start (CURBLK) +;2) No. of blocks to read/write (DIVPAR) +;3) Address to read/write to/from (BBUF) + +IBLOCK ROUT + LDA CURBLK + STAIY NEWARG + INY + LDA CURBLK+1 + STAIY NEWARG + + INY + LDA DIVPAR + STAIY NEWARG + INY + LDA DIVPAR+1 + STAIY NEWARG + + INY + LDA IOBUF + STAIY NEWARG + INY + LDA IOBUF+1 + STAIY NEWARG + + RTS + + + +;Set pointer on stack pointing to +;text buffer. +;Also set 0 in byte after receive buffer +;Offset in A on entry to SETTXP + +SBUFPT ROUT + LDAIM 0 + +SETTXP INY + CLC + ADCIM :LSB:TXTBUF + STAIY NEWARG + LDAIM :MSB:TXTBUF +10 INY + ADCIM 0 + STAIY NEWARG + TXA + PHA + LDX BPTR + LDAIM 0 + STAAX RXBUF+RXBUFL ;**22/3/88** + PLA + TAX + RTS + +;Sets file title pointer to stack +;at Y. +;On entry, A is offset of file title +;in RX buffer. + +;This routine also puts 0 in the byte +;after the receive buffer so that +;analysis of the file title doesn't +;get carried away. + +SETFTP INY + CLC + ADC BPTR ;Add file title offset to buffer offset + ADCIM :LSB:RXBUF + STAIY NEWARG + LDAIM :MSB:RXBUF + BNE #10 + +;Returns the last component of the pathname handed to save +;in MIDTX [3:13] + +SAVNAM ROUT + LDX BPTR +10 INX + LDAAX MIDRX+11 + CMPIM CR + BNE #10 ;look for CR +20 DEX + LDAAX MIDRX+11 + CMPIM "." + BEQ #30 + CPX BPTR ;maybe just one component here + BNE #20 + DEX +30 INX + LDYIM 0 +40 LDAAX MIDRX+11 + CMPIM CR + BEQ #50 + STAAY MIDTX+3 + INX + INY + BNE #40 +50 LDAIM &20 +60 CPYIM 12 + BCS #70 + STAAY MIDTX+3 + INY + BNE #60 + +70 LDAIM &80 + STAAY MIDTX+3 + RTS ;terminate with CR + + +;Call FINDMC using machine number +;in net control block. + +;Then set CSD handle from RX block into +;user table. + +GETUSE ROUT ;Entry generating EXTERR if error + JSR GETUSR + BEQ #10 + JSR EXTERR + LDAIM &FF ;Indicate unsuccessful exit + RTS + +GETUSR LDY QPTR ;Entry not generating error + LDAAY CBSTID + STA MCNUMB + LDAAY CBSTID+1 + STA MCNUMB+1 + LDAAY CBflg ;**25/12/86** + ANDIM MCtask + STA MCnumb+2 + + JSR FINDMC + BNE #10 + + LDX BPTR + LDAAX CPCSD ;GET CSD SENT FROM CLIENT + LDYIM UTHSLD + STAIY USTPTR ;SET CSD + LDAIM 0 ;Indicate successful exit +10 RTS + + + +;Move user info. pointer in USTPTR +;to stack. + +SETUSE ROUT + INY + LDA USTPTR + STAIY NEWARG + LDA USTPTR+1 + INY + STAIY NEWARG + RTS + + +;GET USER INFO AND PUT ON STACK AT ARGB + +STKUSE ROUT + JSR GETUSE + BNE #10 +STKUSA LDYIM ARGA + JSR SETUSE ;NOTE SETUSE DOES INY FIRST, SO ARGA CORRECT + LDAIM 0 +10 RTS + + +;PUT THREE HANDLES FROM RX BUFFER +;ON STACK AT Y. + +STKHND ROUT + LDX BPTR + LDAAX CPUFD + STAIY NEWARG + INY + LDAAX CPCSD + STAIY NEWARG + INY + LDAAX CPLIB + STAIY NEWARG + RTS + + +SETRTN ROUT + LDYIM ARGA + STAIY NEWARG + RTS + + +;Set pointer to COWORK on stack + +SCOWPT ROUT + INY + LDAIM :LSB:COWORK + STAIY NEWARG + INY + LDAIM :MSB:COWORK + STAIY NEWARG + RTS + + + +;SIN/disc no. of object are on +;stack (usually just after a call +;of PRESERVE). + +;assumes that GETUSE result is valid ** 3/10/84 ** + +;If SIN <> 0 ... + +;1) Clear object from store. +;2) Delete object from map +;3) Ensure map. + +OBJCLR ROUT + JSR SINZED ;Check SIN is zero (also used in RENAME) + BEQ #30 ;If zero, exit + + LDAIM 5 ;STRALL function + JSR SETRTN + JSR STRMAN ;Flush from store + BNE SETRTN ;put it on the stack if error + + LDYIM ARGF + JSR SETUSE ;pass pointer to user info ** 3/10/84 ** + + LDAIM MAPFS ;Map free store + JSR SETRTN + JSR MAPMAN ;Delete from map + BNE #20 ;No good => abort + + LDAIM MAPENS ;Map ensure fn. + JSR SETRTN + JSR MAPMAN ;Ensure map + BEQ #30 ;OK => exit + +20 JSR INTERR ;Not ok => stop + +30 RTS + + +SINZED LDYIM ARGD + LDAIY NEWARG + INY + ORAIY NEWARG + INY + ORAIY NEWARG + RTS + + +;Gets entry point, no. of entries and a pointer +;to BIGBFR +1 onto stack. Used by DISCS and USERS + +STKLST ROUT + TYA + TAX ;pointer into MIDRX + LDYIM ARGB + LDAAX MIDRX + STAIY NEWARG ;Start point in list + INY + LDAAX MIDRX+1 + STAIY NEWARG ;Number of entries + INY + LDA BBUF + CLC + ADCIM TXHDR+1 ;Result area + STAIY NEWARG + INY + LDA BBUF+1 + ADCIM 0 + STAIY NEWARG + RTS + + + +;Given no. of entries found and ptr. to +;end of result area on stack, sends off the +;result of DISC/USERS in big buffer. +;On entry A = continue code. + +LSTRPY ROUT + STA TEMPA + LDYIM ARGB + LDAIY NEWARG + PHA ;Number of entries found + LDA BBUF + STA GENPTR + LDA BBUF+1 + STA GENPTR+1 + LDYIM 0 + LDA TEMPA ;Continue code + STAIY GENPTR + TYA ;Return code (0) + INY + STAIY GENPTR + PLA + INY + STAIY GENPTR ;Number of entries found + +;Set control block for reply + + LDA RPLYPT + LDX QPTR + STAAX CBPORT + LDA BBUF + STAAX CBBUF ;Ptr. to message + LDA BBUF+1 + STAAX CBBUF+1 + LDYIM ARGC + LDAIY NEWARG ;End of result buffer + STAAX CBBUFE + INY + LDAIY NEWARG + STAAX CBBUFE+1 + LDY QPTR ;Arg to SEND + JMP SEND ;Send reply and exit + + + +;Set stack and call DIRMAN retrieve +;to put details into COWORK buffer. +;On entry A = offset in RXCB of file name + +LDRETR ROUT + LDAIM LODFTO + +CPRETR PHA + LDAIM DRRTR ;Dirman retreive + JSR SETUSA ;PLACE ADDR OF USERINFO ONTO NEWARG STACK + PLA ;Pull f.t. offset + JSR SETFTP ;Set file title pointer + JSR SCOWPT + LDAIM &C0 ;allow wild cards in LOAD + LDYIM ARGH + STAIY NEWARG ;wild card flag + + JMP DIRMAN ;Get info. to COWORK and return + + + + [ 1=0 +RNAMDQ ROUT + TAY + LDAIM &C0 ;wild card flag + PHA + TYA + BNE #10 + +RNAMDM + +;Call DIRMAN with function code in A, file title offset +;from TXTBUF in X. Used from RENAME. + + TAY + LDAIM 0 + PHA + TYA +10 JSR SETUSA + TXA ;Get offset of file name in TXTBUF + JSR SETTXP + PLA + JMP CPRET1 ;Set pointer to COWORK, and call DIRMAN + + + +;Check access/type byte for RENAME +;Must be an unlocked file with OWNER access + +CHEKTB = DRERRG ;Is locked + = LODERA ;Is a directory + = DRERRE ;Insufficient access + +CHEKRN ROUT + LDXIM 3 + LDYIM ARGB + LDAIY NEWARG + EORIM OWNER ;Flip the OWNER bit + ASLA +10 ASLA + BCS #20 + DEX + BNE #10 + + TXA ;Zero RC + RTS + +20 LDAAX CHEKTB-1 + RTS + + ] + + +;COMMAND LINE UTILS + + +;Get string (possibly quoted) from +;CLI string (at MIDRX) and transfer +;to TXTBUF offset by X (normally zero) +;NOTE - ACKS and NACKS ignored here !! + +BUFTXT ROUT + LDXIM 0 +BTXTA LDAIM 0 + STA QUOTED ;Quoted flag + + JSR SPACES + CMPIM """" + BNE #30 + DEC QUOTED ;Quoted flag on + DEX + +20 INX +25 INY +30 LDAAY MIDRX +35 STAAX TXTBUF + + CMPIM ACK + BEQ #25 ;Inc. string ptr., but not buffer + CMPIM NACK + BEQ #25 + + CMPIM CR + BEQ #60 + CMPIM SPACE + BNE #50 + BIT QUOTED + BMI #20 ;Spaces OK in quoted string + +40 LDAIM CR ;Finish with CR as terminator in destn. + BNE #35 + +50 CMPIM """" + BNE #20 + INY ;Step C.line ptr. past final delimiter + INC QUOTED ;Switch off quoted flag + BEQ #40 ;Exit, with CR terminator + +60 LDA QUOTED ;Error in quoted string + BEQ #70 ;Otherwise exit, Z set + +BUFERR LDAIM NAMERR + PHP + JSR EXTERR ;Send error message + PLP +70 RTS ;Give Z unset exit + + [ 1=0 ;**8/2/88 +;Read hex number (up to 4 bytes) +;into 4-byte p.0 area at X. NOTE +;uses 1 extra byte at X. + +RDNUM ROUT + LDAIM 0 + STAAX 0 + STAAX 1 + STAAX 2 + STAAX 3 + STAAX 4 + JSR SPACES +10 LDAAY MIDRX + CMPIM "0" + BCC #40 + CMPIM &3A + BCC #20 + SBCIM 7 + BCC #40 + CMPIM &40 + BCS #40 + +20 ASLA + ASLA + ASLA + ASLA + STYZX 4 + LDYIM 4 +30 ASLA + ROLZX 0 + ROLZX 1 + ROLZX 2 + ROLZX 3 + DEY + BNE #30 + LDYZX 4 + INY + BNE #10 + +40 LDAZX 4 + RTS + ] + +SPACER DEY +50 INY +SPACES LDAAY MIDRX + CMPIM SPACE + BEQ #50 + RTS + + +;Move file title into TXTBUF and +;check to end of line for syntax. + +RDTITL ROUT + JSR BUFTXT + BNE #10 ;**20/5/87** fall into COMEND + +COMEND JSR SPACES + CMPIM CR + BEQ #10 + LDAIM SYNERR + JSR EXTERR + LDAIM SYNERR ;Give non-zero exit +10 RTS + +;** E R R O R T A B L E ** + +ERRTAB + + [ Lang = English + = URERRA,"Who are you?",CR + = WOTERR,"Bad Command",CR + = SYNERR,"Syntax",CR + = NAMERR,"Bad string",CR + = NUMERR,"Bad number",CR + = DRERRA,"Bad file name",CR + = DRERRB,"Broken dir",CR + = DRERRC,"Not found",CR + = DRERRD,"Not a directory",CR + = DRERRE,"Insufficient access",CR + = DRERRG,"Entry locked",CR + = ATERRB,"User not known",CR + = ATERRC,"Wrong password",CR + = ATERRE,"Bad password",CR + = MPERRB,"Disc full",CR + = MPERRA,"Disc changed",CR + = SAERRA,"Bad attribute",CR + = ATERRA,"PW file not found",CR + = &54,"Insert a Fileserver disc",CR + = RDERRB,"Channel",CR + = RDERRJ,"EOF",CR + = RDERRL,"Outside file",CR + = RDERRH,"Already open at station ",CR + = RDERRN,"File read only",CR + = DCERRE,"Disc read only",CR + = DCERRF,"Disc fault",CR + = MPERRL,"Map fault",CR + = RDERRC,"Too many open files",CR + = URERRB,"Too many users",CR + = LODERA,"Is a directory",CR + = &BA,"Insufficient privilege",CR ;** 13/4/83 ** + = DRERRJ,"Dir. not empty",CR + = DRERRM,"Dir. full",CR + = ATERRF,"Already a user",CR + = RNAMQQ,"Bad Rename",CR + = DRERRK,"Types don't match",CR + = URERRE,"Not logged on",CR + = ATERRG,"Bad user name",CR + = RDERRO,"Write only",CR ;** 16/11/84 + = MPERRN,"Insufficient space",CR + = SPERRA,"Bad privilege letter",CR ;** 6/11/86 ** + = 0 ;Table terminator + ] + + [ Lang = Italian + = URERRA,"Chi sei?",CR + = WOTERR,"Comando Errato",CR + = SYNERR,"Syntax",CR ; *********************************** + = NAMERR,"Sequenza errata",CR + = NUMERR,"Numero errata",CR ; *********************************** + = DRERRA,"Nome file errato",CR + = DRERRB,"Dir rotto",CR + = DRERRC,"Non trovato",CR + = DRERRD,"Non e' un directory",CR + = DRERRE,"Accesso insufficiente",CR + = DRERRG,"Entrata bloccata",CR + = ATERRB,"Utente Sconosciuto",CR + = ATERRC,"P.o. Errata",CR + = ATERRE,"P.o. incorretta",CR + = MPERRB,"Disco pieno",CR + = MPERRA,"Disco changed",CR ; ********************************** + = SAERRA,"Attributo Errato",CR + = ATERRA,"P.o. file non trovato",CR + = &54,"Inserire un disco FileStore",CR + = RDERRB,"Canale",CR + = RDERRJ,"FDF",CR + = RDERRL,"Fuori file",CR + = RDERRH,"Gia' aperto alla stazione ",CR + = RDERRN,"File solo lettura",CR + = DCERRE,"Disco solo lettura",CR + = DCERRF,"Disco difettoso",CR + = MPERRL,"Mappa difettoso",CR + = RDERRC,"Troppi file aperti",CR + = URERRB,"Troppi utenti",CR + = LODERA,"E' gia' un directory",CR + = &BA,"Privilegio insufficiente",CR ;** 13/4/83 ** + = DRERRJ,"Dir non vuoto",CR + = DRERRM,"Dir pieno",CR + = ATERRF,"Gia' in uso",CR + = RNAMQQ,"Rinome errata",CR + = DRERRK,"Tipi non coincidono",CR + = URERRE,"Non acceso",CR + = ATERRG,"Nome utente errato",CR + = RDERRO,"Solo scrittura",CR ;** 16/11/84 + = MPERRN,"Spazio insufficiente",CR + = SPERRA,"Privilegio lettera errato",CR ;** 6/11/86 ** + = 0 ;Table terminator + ] + +FNSH +LEFT * FRESTR-. ;get free store + [ LEFT > 0 ;must not overflow workspace + | + ! 0,"FRESTR incorrect" + ] + +;** T H E E N D *** + END + diff --git a/Level3/SRC/README b/Level3/SRC/README new file mode 100644 index 0000000..819b0a4 --- /dev/null +++ b/Level3/SRC/README @@ -0,0 +1,302 @@ +Level 3 File Server v1.31 +========================= + +This disc contains the original source code for the Acorn Level 3 file server. + +Assembling the File Server Source Code +====================================== + +The source code will assemble on either a BBC with an Acorn Turbo (256K) +6502 Co-Processor and ADFS or on Arthur/RISC OS using the 6502 Turbo +Co-Processor emulator which is included here. +To assemble on a BBC, use SHIFT-BREAK or *EXEC !BOOT. On RISC OS, double +clicking the file GO will start the process. The assembled file "FS" will be +placed in the root directory. The assembly process is significantly faster +when a hard drive is used instead of a floppy. + +Files +===== + +\ $ + !BOOT - BBC Routine to set library and call L3ASM + GO - RISC OS Routine to set library, load emulator and call L3ASM + README - This file + L3ASM - Loads TurboMasm and starts the assembly process + LOADER - BASIC program to put together the assembled parts and create the + Level3 binary "FS" + +\ LIBRARY + 65ARTHURT - The Turbo Co-processor emulator for RISC OS + CB - BASIC for the Turbo Co-processor + TURMASM - Turbo version of MASM assembler + +\ L3 + The source code files + +\ L3\X + Location for the assembled parts. Do not delete or the assembler will fail. + + +Version 1.31 +============ + +Date - estimated July 1988. Dates in change comments since v1.24 include +4/29 April 1988, 22 May 1988, 1 Jun 1988 and 1/7/20 July 1988. + +Comments +======== +This is the original and unchanged source code. Since just before v1.20 the +FileStore had become an ACORN product which used the same code base as the Level3 file server. The original disk had 3 directories + - L3 containing the Level3 file server code + - FileStore with the File Store file server code for the new E01 Filestore + - FileServer which appears to be an unfinished or incomplete set of code that + merges the Level3 file server and FileStore file server code base. + +Many thanks to Jon Thackray for discovering these long-lost sources and making +them available to the Acorn community. + +Changes (from v1.24) (L3 source files) +==================== + +HEADER FILE 1 + Uade01 Line 0064 VERLA, version changed from 2 to 3 +20/07/88 Uade01 Line 0065 VERLB, version changed from 4 to 1 + Uade01 Line 0194 SYNERR changed from &FE to &DC + +UTILITIES + Uade03 Line 0012 (C) date changed from 1987 to 1988 + +24/02/88 Uade04 Line 0243 changes made to date evaluation code + Uade04 Line 0244 ensuring day is not >31 + Uade04 Line 0256 + Uade04 Line 0274 + Uade04 Line 0275 + +FILE SERVER INITIALISATION + +24/03/88 Uade04 Line 0685 include the century in the date calculation +[typo 24/02/88?] to 0687 +24/02/88 Uade04 Line 0692 + Uade04 Line 0699 + to 0701 + Uade04 Line 0703 + Uade04 Line 0705 + Uade04 Line 0708 +24/02/88 Uade04 Line 0759 +24/02/88 to 0761 + Uade04 Line 0763 + Uade04 Line 0805 + Uade04 Line 0811 + to 0814 +24/02/88 Uade04 Line 0838 + to 0840 + Uade04 Line 0845 + Uade04 Line 0882 + Uade04 Line 0889 Leap year check + to 0891 + Uade04 Line 0926 Use carry flag to display leading 0 for hours + 0931 Use carry flag to display leading 0 for minutes +24/02/88 Uade04 Line 1012 + to 1015 + +24/02/88 Uade04 Line 0287 changes made to printing decimal numbers + Uade04 Line 0294 ensuring flag to print leading zeros is not lost + Uade04 Line 0297 + Uade04 Line 0304 + +USRMAN + Uade06 Line 0979 close down routine "LOGOFF" +01/06/88 to 0983 + Uade06 Line 0987 + Uade06 Line 0989 + Uade06 Line 0990 + Uade06 Line 0992 + Uade06 Line 0993 +01/06/88 Uade06 Line 0999 + + Uade06 Line 1073 routine GETUFD. change made to the how the root + Uade06 Line 1076 dir is created +07/07/88 to 1077 + Uade06 Line 1091 routine RTROOT + Uade06 Line 1093 + Uade06 Line 1114 store the users disc number in a variable instead + Uade06 Line 1116 of on the stack + Uade06 Line 1120 and use UMHLIB instead of USTEMP + to 1122 + Uade06 Line 1138 + Uade06 Line 1140 + Uade06 Line 1143 comment change to retrieve root again without + to 1144 checking if it already has been + Uade06 Line 1146 Clean up before doing the retrieve + Uade06 Line 1157 retrieve the previous user disc number + Uade06 Line 1159 +RNDMAN +29/04/88 Rman02 Line 0160 Change file size. code moved to a subroutine + Rman02 Line 0161 RDEXSZ in Rman04 to extend the file +29/04/88 Rman02 Line 0163 + Rman02 Line 0164 + +01/06/88 Rman02 Line 0383 bugfix: High water mark not increased when setting + the sequential file pointer, if it exceeded + the high existing high water mark + +23/03/88 Rman03 Line 0250 bugfix for the access mode for Putbytes/Getbytes + to 0254 operations + +29/04/88 Rman04 Line 0183 Set new file size and call the new subroutine + Rman04 Line 0184 RDEXSZ to extend the file +29/04/88 Rman04 Line 0215 Subroutine RDEXSZ + Rman04 Line 0253 + +DIRMAN +23/03/88 Uade0C Line 0021 New function 13 added. Check if object will preserve + Uade0C Line 0023 Increase the number of functions + Uade0C Line 0046 add routine to table +04/04/88 Uade0C Line 0127 call as a subroutine + Uade0C Line 0128 and use the DIRMAN exit function +04/04/88 Uade0C Line 0154 Routine DRRET2 set up the name, root character and 9 + to 0158 spaces + Uade0C Line 0171 add check for directory type and the locked bit + Uade0C Line 0172 + Uade0C Line 0174 + Uade0C Line 0175 + Uade0C Line 0177 + Uade0C Line 0178 + Uade0C Line 0181 +04/04/88 Uade0C Line 0256 Change to RTS as a subroutine exit + +04/04/88 Uade0C Line 0890 DRINFO most of the routine changed + to 0930 + + Uade0D Line 0153 check for : character removed as it was there twice +01/06/88 Uade0D Line 0580 compatibility for "^" ? + Uade0D Line 0581 + Uade0D Line 0584 + + Uade0D Line 0858 Code for RETPAR changed around in order of + Uade0D Line 0861 execution. + Uade0D Line 0865 + to 0912 + + Uade0E Line 0380 OUTZRO routine removed +24/02/88 Uade0E Line 0472 ensure only the day of the month is output + Uade0E Line 0473 + Uade0E Line 0479 + Uade0E Line 0480 set the value for the year + to 0483 + Uade0E Line 0494 +24/02/88 Uade0E Line 0501 ensure year 20xx compatable + to 0504 + Uade0E Line 0524 code optimised for character conversion + +01/06/88 Uade0E Line 0723 bugfix when outputting the access byte + Uade0E Line 0747 + to 0763 + +AUTMAN +22/03/88 Uade10 Line 0092 code moved to subroutine ATOPWF + Uade10 Line 0094 + to 0096 comments added +22/05/88 Uade10 Line 0189 new subroutine ATOPWF + to 0210 +22/03/88 Uade10 Line 0337 changed to use new open password file routine +22/03/88 Uade10 Line 0369 changed to use new open password file routine + + Uade10 Line 0814 check for alternative return code &FF instead of end + of file removed +01/06/88 Uade10 Line 0943 round up if part sector and skip check for page + to 0947 boundary at which was at 0978 (removed) + Uade10 Line 0979 remove unnecessary branch label +01/06/88 Uade10 Line 0982 check if password file is too big +01/06/88 Uade10 Line 0986 + to 0988 flush the now unwanted segment + + Uade10 Line 1027 code optimised to check for end of PW file + to 1036 + +01/06/88 Uade10 Line 1068 check if the password file will be too big before + to 1074 trying to enlarge it + +MAPMAN +24/02/88 Uade10 Line 0106 check added for write protect + to 0108 + + Uade10 Line 0705 code optimisation. keep a copy of the map block + 0709 pointer on the stack. +01/07/88 Uade10 Line 0721 and use it instead of making the calculation again + to 0724 + + Uade10 Line 0864 Code optimised to save having to get the drive + Uade10 Line 0869 number twice + Uade10 Line 0879 + Uade10 Line 0873 Comments reinstated + Uade10 Line 0875 + Uade10 Line 0877 + +05/03/88 Uade10 Line 0882 some checks and then.. + to 0891 code moved to a new subroutine MPRESZ +05/03/88 Uade10 Line 0918 new subroutine MPRESZ from previous code + to 0944 + +MAPMAN UTILITIES +06/07/88 Uade11 Line 0072 exit if Sector zero not retrieved +05/03/88 Uade11 Line 0092 code optimised to use the new routine MPRESZ +01/07/88 Uade11 Line 0498 code replaced by subroutine SETMB +01/07/88 Uade11 Line 0700 ?? + Uade11 Line 0703 + Uade11 Line 0711 + Uade11 Line 0719 branch labels changed + to 0756 + +MAPMAN UTILITIES II +01/07/88 Uade12 Line 0285 code optimised + to 0286 + Uade12 Line 0605 code optimised + to 0617 + +DSCMAN +24/02/88 Uade14 Line 0826 routine Testdv, mainly to check for write protect + to 0843 + +COMMAND PROCESSOR +23/03/88 Uade16 Line 0032 implement check for DIRMAN CHECKPRES (function 13) + Uade16 Line 0287 DRPRES routine moved and now shared with CHECKPRES + Uade16 Line 0288 + Uade16 Line 0320 Routine for CHECKPRES and DRPRES + to 0367 + + Uade16 Line 0039 ?? + to 0042 + + Uade16 Line 0061 code optimised + 0062 + + Uade19 Line 0019 code optimised + Uade19 Line 0043 + Uade19 Line 0053 + to 0070 + Uade19 Line 0085 label removed. no longer required + +23/03/88 Uade19 Line 0473 Check mode of access for file + Uade19 Line 0495 Ensure 0 returned if ok + +23/03/88 Uade19 Line 0580 Code optimised. Moved to new subroutine RMSUBR shared + Uade19 Line 0581 by Putbytes and Getbytes + Uade19 Line 0587 label removed. no longer required + Uade19 Line 0692 code moved to new subroutine RMSUBR + to 0719 + Uade20 Line 0088 Bugfix. Y not initialised to 0 when checking for a tx + on tx + +22/03/88 Uade20 Line 0544 code optimised. + Uade20 Line 0547 because of code reuse ensure X is preserved + Uade20 Line 0551 + to 0553 + Uade20 Line 0548 + Uade20 Line 0571 + Uade20 Line 0572 + + Uade20 Line 1022 New errors. SYNERR "Syntax" + Uade20 Line 1024 NUMERR "Bad Number" + Uade20 Line 1067 repeated for Italian language + Uade20 Line 1069 ������������� \ No newline at end of file diff --git a/Level3/SRC/README.INF b/Level3/SRC/README.INF index 32ed433..ab97424 100644 --- a/Level3/SRC/README.INF +++ b/Level3/SRC/README.INF @@ -1 +1 @@ -README 00000000 00000000 000009FE WR +README FFFFFF59 18948126 00002AD2 LR diff --git a/Level3/adfs/Level3-131bin.adl b/Level3/adfs/Level3-131bin.adl new file mode 100644 index 0000000..65a3414 Binary files /dev/null and b/Level3/adfs/Level3-131bin.adl differ diff --git a/Level3/adfs/Level3-131src.adl b/Level3/adfs/Level3-131src.adl new file mode 100644 index 0000000..f9e88aa Binary files /dev/null and b/Level3/adfs/Level3-131src.adl differ