File: RTFLOP.PA of Tape: Various/Decus/decus-5
(Source file text)
/OS/8-RT-11 FLOPPY INTERCHANGE PROGRAM / This program allows an OS/8 user to manipulate / RT-11 floppies. Functions are available for: / / 1. Writing RT-11 floppies / 2. Reading RT-11 files / 3. Deleting RT-11 files / 4. ZEROing floppies / 5. Listing directories / / This program will run under BATCH. / /Assembly instructions: / / .PAL RTFLOP/L / .SAVE dev RTFLOP=2401 / / Storage allocation: / Field zero / 0000 - 4577 code and pointers / 4600 - 6577 directory buffer / 6600 - 7030 tables (end of these defines below) / 7030 - 7177 keyboard input buffer / 7200 - 7577 OS/8 handler / Field one / 0000 - 1777 USR / 2000 - 2577 messages / 2600 - 5577 data buffer / / Written, produced, and directed by: / Dick Murphy / Western Region Software Operations Group / Digital Equipment Corporation / 2525 Augustine Drive / Santa Clara, CA 95051 / / / ****** note ***** /Image patch: to copy files from RT-11 to OS/8 in IMAGE mode /(that is, without changing the contents, such as binary or /save files) patch this location to NOP (7000) *0 IMAGE /This patch is not necessary or recommended for ASCII files. With /this patch in, the end of the ASCII file is not flagged. /OS/8-RT-11 FLOPPY INTERCHANGE PROGRAM /First define some floppy (RX8E) instructions LCD=6751 /Load command XDR=6752 /transfer data register to/from AC STR=6753 /SKIP on TRANSFER REQUEST flag. SER=6754 /SKIP on ERROR flag SDN=6755 /SKIP on DONE flag INTR=6756 /set/clear interrupt enable INIT=6757 /initialize floppy interface /Now define mnemonics for the functions BYTE=100 /8 Bit mode command bit FILL=0^2+BYTE /Fill sector buffer EMPTY=1^2+BYTE /Empty sector buffer WRITE=2^2+BYTE /Write sector READ=3^2+BYTE /Read sector RDERR=7^2 /Read error code. /OS/8 USR Functions FETCH=1 LOOKUP=2 ENTER=3 CLOSE=4 /BATCH program locations BATIN=5400 /Place to jms to to get a char. BATOUT=7400 /Place to jms to print on BATCH log. /OPTFLG bit assignment mnemonics INOS=1 /Input file is os/8 OUTOS=2 /Output file is OS/8 INRT=4 /Input is RT-11 OUTRT=10 /Output is RT-11 NOIO=20 /No files DIRIO=40 /Directory (used for default out dev) /Page zero locations and constants. *10 AX0, .-. /Miscellaneous autoindex AX1, .-. AX2, .-. RTPTR, .-. /RT-11 buffer pointer DIRECT, .-. /Directory scan pointer DIRPTR, .-. /Character output buffer pointer TTPTR, .-. /Output buffer pointer for OS/8 *20 WS0, .-. /Working storage WS1, .-. /Ditto WS2, .-. /Double ditto. ACH, .-. /Double precision AC high order ACL, .-. /Double precision AC low order. OPLO, .-. /Double precision secondary operand OPHI, .-. /used in addition routine. TRACK, .-. /Physical floppy track# SECTOR, .-. /and sector # UNIT, .-. /Floppy unit number (RT-11) ERRCNT, .-. /Error retry counter. NSECS, .-. /Counter for the four sectors /comprising one RT-11 block. RTBLOK, .-. /Logical RT-11 block number. NBLOK, .-. /Number of RT-11 Blocks to read. BUFPTR, .-. /Pointer to start of present sector's /buffer. Used for retries. ENTRY, .-. /Starting block of file HIGHSG, .-. /Last segment of directory INCNT, .-. /Number of characters in input buffer. ESCAPE, .-. /Set to one if input terminated with escape. OPTFLG, .-. /Input/output flag. 1=out, 2=in (RT) OPTION, .-. /Command decoder option DEVNO, .-. /OS/8 Handler device number. OSLEN, .-. /Length of OS/8 output file. MAXLEN, .-. /Maximum length of the output file. DIRSG, .-. /Segment number of directory segment in core. RTLEN, .-. /Length of the RT-11 file. SCANPTR,.-. /Pointer for directory scans. BIGMT, .-. /Size of biggest empty file on floppy. BIGSEG, .-. /Segment # of biggest empty. BIGPTR, .-. BIGBLK, .-. /Block # of biggest empty. RTCTR, .-. /RT-11 Block counter OSCTR, .-. /OS/8 Block counter. RTSIZE, .-. /Size of RT-11 file generated. BYTCTR, .-. /Counter for filling sector buffer. BATINP, BATIN /BATCH input pointer. EXTRA, .-. /Number of extra bytes in a directory entry PAGE /Initialization; set up BATCH or SCOPE mode. TLS /Set printer flag START, CLA CLL TAD (JMP CALLDEC DCA 200 /Don't do init again. CDF 10 /Check OS/8 scope word TAD I (7726 /Which is at 17726 CDF 00 AND [0200 /Bit 4 is the scope bit. SNA CLA JMP NOSCOPE /Not a scope if bit 4 not set. JMS MOVE /Move SCOPE overlay over rubout INBUF /code RUBOUT -RUBLEN NOSCOPE,TAD I (7777 /Get BATCH running flag- CLL RAL SMA CLA JMP CALLDEC /Batch not running. JMS MOVE /Move BATCH overlay. TTPAT TTOUT+2 -3 JMS MOVE INPAT INLOOP -3 TAD I (7777 /Get BATCH field AND (0070 TAD (CIF /Make CIF BATCH DCA WS0 TAD WS0 DCA I (TTOUT+1 TAD WS0 DCA I (INLOOP TAD (LFPAT /Patch line feeds to be ignored. DCA I (LINPAT /Call the command decoder (not OS/8's) ; Decode /the desired function and execute it. CALLDEC,JMS I (DECODE /Get and decode a command line. JMP I OPTION /Go to desired routine. DIR, JMS I (SIXBIT /Directory listing - get output file. JMS I (OSFETCH /Fetch output handler JMS I (OSENTER /Enter the output file JMS I (LISTDR /List the directory JMS I (OSCLOSE /Close the output file JMP ESCHK WRTRT, JMS I (SIXBIT /Writing RT-11 floppy. JMS I (OSFETCH /Get OS/8 handler JMS I (OSLOOK /Look up input file JMS I (RTENTER /Enter output file JMS I (OSREAD /Write output JMS I (RTCLOSE /Close output JMP ESCHK /More function drivers RDRT, JMS I (SIXBIT JMS I (OSFETCH JMS I (RTLOOK /Look up the RT-11 file JMP FILER /File does not exist JMS I (OSENTER /Enter the output file. JMS I (RTREAD /Read and repack. JMS I (OSCLOSE /Close the file. JMP ESCHK /Loop for more commands. RTZERO, JMS I (RTZER JMP ESCHK DELETE, JMS I (RTDEL JMP NOFILE JMP ESCHK NOFILE, JMS I [PRTZRO NOTFND JMP CALLDEC FILER, JMS I [PRTZRO NOTFND /"File not found" JMP NOSCOPE ESCHK, TAD ESCAPE /Check escape flag SZA CLA JMP I [7605 /If command ended with $, quit. JMP CALLDEC /Loop for more. WRTERR, INIT FLOPERR,JMS I [PRTZRO RXERR JMP CALLDEC /Patch mover MOVE, 0 STA TAD I MOVE /From DCA AX1 ISZ MOVE STA TAD I MOVE /To DCA AX2 ISZ MOVE TAD I MOVE /Count DCA WS0 ISZ MOVE MOVER, TAD I AX1 DCA I AX2 ISZ WS0 JMP MOVER JMP I MOVE PAGE /Routine to read a block from the RT-11 floppy /into the specified buffer. Before calling, set up / / BUFPTR to the start of the desired buffer / NBLOK to the number of blocks to transfer / RTBLOK to the starting block number. / / The data field should be set to the buffer field. / READBLK,HLT RDF /Get the field to transfer to TAD (CDF DCA STRCDF CDF 0 TAD RTBLOK /Get block number CLL RTL /Multiply block # by four to get /RT-11 logical sector number DCA RTBLOK /Save first sector number. TAD NBLOK /Convert block count to negative CLL RTL /sector count. (multiply by four) CIA DCA NSECS /One RT-11 block takes four sectors. TAD (-10 /Setup error counter DCA ERRCNT TAD RTBLOK /Convert logical block to physical JMS I (CONVERT/Track and sector # RDLOOP, STA /Initialize buffer autoindex pointer TAD BUFPTR DCA RTPTR RDRTY, JMS I [FLOPPY /Do the read. READ STRCDF, HLT TAD (EMPTY /After the read is complete, empty the LCD /sector buffer. TAD [-200 /No. of bytes in a sector DCA BYTCTR RDWAIT, STR JMP .-1 /Wait for STR XDR /get byte DCA I RTPTR /Stash in buffer. ISZ BYTCTR /Done yet? JMP RDWAIT /No. JMS CHKCC /Check for control c. SER /Any errors? JMP NXTBLK /Nope. INIT /Do an initialize on any errors. JMS SDNCC /Wait for initialize to complete. JMP .-1 TAD RTPTR /Reset buffer pointer. TAD [-200 DCA RTPTR ISZ ERRCNT /Eight retries yet? JMP RDRTY /No - try again. JMP I [FLOPERR /Solid error. Oh well. NXTBLK, CDF 0 TAD BUFPTR /Update buffer pointer TAD [200 DCA BUFPTR ISZ NSECS /All four read yet? JMP RDLOOP /Read next sector JMP I READBLK /All done. /Floppy skip iot routines. Also check for /control C from the keyboard. STRCC, HLT /STR iot. STR JMP NOSTR ISZ STRCC /Skip and return. JMP I STRCC NOSTR, DCA STRSAV JMS CHKCC /Check control C. TAD STRSAV JMP I STRCC /And return. SDNCC, HLT /SDN iot. SDN JMP NOSDN ISZ SDNCC /Skip and return JMP I SDNCC NOSDN, JMS CHKCC JMP I SDNCC /Return. CHKCC, HLT /Check for control c. TAD [200 /Ignore parity. KRS TAD (-203 /Is it ^C? SZA CLA JMP I CHKCC /Nope. KSF /Is the flag set? JMP I CHKCC /Nope. JMP I [7600 /Return to OS/8. STRSAV, 0 /Move name to the tentative entry in the directory buffer. MOVNAM, HLT TAD (-6 /Number of bytes in name. DCA WS0 TAD (RTNAM-1 DCA AX0 /From the RT name buffer, MVNAM, TAD I AX0 CIA /Remove CIA done by lookup. DCA I DIRECT /Into directory buffer. ISZ WS0 JMP MVNAM CLA CLL JMP I MOVNAM /GETIN Character table /First the character looking for, then /a pointer to the routine to execute CHRLST, "C-100; 7605 /^C - Return to OS/8 "U-100; CLRIN /^U - Delete line 215; RETURN /C/R 212; REPEAT /L/F 377; RUBOUT 233; ESC 375; ESC 376; ESC /All brands of escape "$; ESC /Including "$" "*; INLOOP /Ignore "*" "?; INLOOP /And "?" 0 PAGE /Floppy I/O routine. Performs actual READ or WRITE /operations. / / call: / JMS FLOPPY / command / Where "command" is a read or write command, as needed. /Sector and track must be set up by CONVERT prior to call. / FLOPPY, HLT RETRY, JMS I (SDNCC /Wait for done. JMP .-1 TAD I FLOPPY /Get command. TAD UNIT /Get drive select bit LCD /Pass to RX8E TAD SECTOR JMS I (STRCC /Wait for him to ask for sector JMP .-1 XDR CLA TAD TRACK JMS I (STRCC /Now wait to give him the track JMP .-1 XDR CLA ISZ RTBLOK /Point to next sector TAD RTBLOK /Convert to track, sector JMS CONVERT TAD I FLOPPY /Get command TAD [-READ /Is it a read? SZA CLA JMP I FLOPPY /No, so don't wait for done. JMS I (SDNCC /Wait for read to complete JMP .-1 SER /Check for errors JMP I FLOPPY /No errors - return to caller. INIT /Init on error. STA TAD RTBLOK /Reset drive number. DCA RTBLOK ISZ ERRCNT /Tally up another error. JMP RETRY /And try again JMP I [FLOPERR /Routine to convert the RT-11 logical sector number to /the physical track and sector number. The RT-11 diskette /is written with a two-way interleave and a six sector /skew between tracks. This routine maps the logical block /to the physical block using an algorithm similar to that /used in the RT-11 RX01 handler. / / Called with AC=logical block number CONVERT,HLT MQL /Place sector # in MQ for display. MQA /Get it back. DCA LSN /Save logical sector # TAD [-7 /Initalize divide loop counter DCA DIVCNT TAD LSN CLL /Make sure link is clear. DIVLP, TAD [4600 /Divide sector by 26 (32 octal) SNL /To find track and sector # JMP ADD CLL SKP ADD, TAD [3200 CML RAL /Link is quotient bit. ISZ DIVCNT /Divide done yet? JMP DIVLP /Not yet. DCA TRKSEC /Now AC bits 0-4 are the sector, TAD TRKSEC /bits 5-11 are the track. AND [7600 /Isolate sector bits CLL RTL;RTL;RTL /Shift into position DCA SECTOR /Save it. TAD TRKSEC /Get track number AND [0177 /Only important bits. DCA TRACK /And save it. TAD SECTOR DECIMAL TAD [-13 /Set link if sector <= 13. OCTAL CLA TAD SECTOR RAL /Now have proper sector for interleave. DCA SECTOR /Save TAD TRACK /Get 2*track RAL TAD TRACK /3*track RAL /6*track TAD SECTOR /Now have skew factor in there. ISZ TRACK /Put track number in range 1-76 for /ANSI standard. Don't use track 0. MOD, TAD (-32 /Modulo sector to range -26,-1 SMA /Negative yet? JMP MOD /Keep trying. TAD [33 /Now put in range 1,26 DCA SECTOR /All done now. JMP I CONVERT LSN, 0 DIVCNT, 0 TRKSEC, 0 /Routine to unpack RAD50 filename into ascii buffer. /Unpacks the next six bytes of the directory (pointed to by /DIRECT) into the output buffer (pointed to by DIRPTR). GTNAME, HLT TAD [-3 /Have three char triplets. DCA NAMECT NAMELP, JMS TWOBYT /Get next two bytes into d.p. AC JMS I (DIV50 /Divide by 50 TAD ACH /Get third char DCA WS0 /Save it. DCA ACH /Clear out remainder. JMS I (DIV50 /Divide again. TAD ACL /First char JMS I (RAD50 /Stash in output buffer. TAD ACH /Middle char. JMS I (RAD50 /Stash TAD WS0 /Third char. JMS I (RAD50 ISZ NAMECT /Done all three? JMP NAMELP /Nope. JMP I GTNAME /Yup. NAMECT, 0 /Routine to get next two bytes from the directory /buffer into the double precision AC. / TWOBYT, HLT TAD I DIRECT /Get low byte DCA WS0 TAD I DIRECT /And high byte DCA WS1 TAD WS1 AND (360 /High bits of high byte CLL RTR;RTR /Shift into position DCA ACH /Save in d.p. AC TAD WS1 AND [17 /Low four bits of high byte now. CLL RTR;RTR;RAR /Shift into position. TAD WS0 /Add (or) in low byte DCA ACL /Save in low d.p. AC JMP I TWOBYT PAGE /Simpilified command decoder /Allows format similar to OS/8 to be used. /Does not support parenthesis; only /O,/I,/0,/1 /options. /O output is RT-11 /I input is RT-11 / /0 drive 0 (default)/1 drive 1. /Last option is used (ex. a<b/O/I/O/I; /I is used. / /format: *dev:out<dev:in/options (c/r or esc.) / /device names are illegal for the RT-11 device. DECODE, HLT REDO, JMS I (GETIN /Get a line of input TAD INCNT SZA CLA JMP INPOK TAD ESCAPE /Check for escape SZA CLA JMP I [7600 /Quit. JMP REDO /Retry. INPOK, TAD (INBUF-1 DCA AX0 /Reset pointer. DCA OPTION /Init flags. DCA UNIT /And unit number. SLASH, JMS I (SCAN /Look for a slash "/ JMP DONE /Not found, continue. TAD I AX0 /Get the option. DCA WS0 /Save it. TAD WS0 TAD (-"0 SNA JMP OPT0 /Said /0 TAD ("0-"1 SNA CLA JMP OPT1 /Said /1 TAD (OPTLST-1 DCA AX1 OPTLOOP,TAD I AX1 /Get char to test SNA JMP ENDOPT /Bad option. TAD WS0 SNA CLA JMP OPTFND /Found match. ISZ AX1 /Point past subroutine pointer. ISZ AX1 /And past flag setting. JMP OPTLOOP /Keep trying. /Command decoder continued OPTFND, TAD I AX1 /Get pointer DCA OPTION /Save. TAD I AX1 DCA OPTFLG /And i/o flag JMP SLASH ENDOPT, JMS I [PRTZRO /Bad option. BADOPT /"Bad slash option" JMP DECODE+1 OPT0, CLA SKP /Set unit zero. OPT1, TAD (20 /Set unit one. DCA UNIT /Store 0 or 1 in unit. JMP SLASH DONE, TAD OPTION SZA CLA JMP NAMES /Gave some option; go parse names JMS I [PRTZRO NOOPT /"No option selected" JMP DECODE+1 /Try again. /Parse off the RT-11 and OS/8 file names. /Also get the OS/8 device. NAMES, TAD (INBUF-1 /Reset the buffer pointer DCA AX0 TAD OPTFLG AND [INOS+OUTOS+INRT+OUTRT /Now non-zero if any /file names needed. SNA JMP I DECODE /No names. AND [OUTRT /Check if first is RT-11 or OS/8 SNA CLA JMP OSOUT JMS I (RTNAME /Get RT-11 name. SKP OSOUT, JMS I (OSNAME /Get OS/8 name TAD OPTFLG /See if any input file AND (INOS+INRT SNA CLA JMP I DECODE /None. All done TAD (INBUF-1 DCA AX0 /Reset buffer pointer JMS I (SCAN /Look for end of output file "< JMP NOBKAR /No <; check for = LESSTN, TAD OPTFLG AND [INRT /Check type of input SNA CLA JMP OSIN JMS I (RTNAME /Get name JMP I DECODE /Done OSIN, JMS I (OSNAME JMP I DECODE /Done NOINP, JMS I [PRTZRO NOINFL /Print "No input file" JMP I [CALLDEC NOBKAR, TAD (INBUF-1 /Reset pointer DCA AX0 JMS I [SCAN "= JMP NOINP /No equal either;no input file JMP LESSTN /Continue. PAGE /Directory listing routine /Reads, decodes and prints the directory of /the selected unit. LISTDR, HLT CLA IAC /Start with segment one. DCA DIRSG READSG, JMS I [GETDIR /Read the segment TAD I (BHIGHSG/Get the highest segment DCA HIGHSG /Save it. LOOPDR, TAD I (BLOCK1 /Get starting block of first file DCA BLK TAD (FILE1-1/Pointer to first file entry DCA DIRECT TAD (NAMBUF-1 DCA DIRPTR /Initialize name buffer pointer NXTENTR,ISZ DIRECT /Skip low byte of file type TAD I DIRECT /Get file type byte DCA TYPE /Save it. TAD TYPE CLL RAR SNA JMP TENT /1=Tentative file RAR SNA JMP EMPT /2=Empty file RAR SZA CLA JMP NXTSEG /10=End of directory segment JMS I (GTNAME /Permanent entry - get name JMS I [PRTLST /Print name 6 NAMBUF TAD (". /Print period between name & ext. JMS I [TTBUF JMS I [PRTLST /Print extension 3 NAMBUF+6 TAD (NAMBUF-1 DCA DIRPTR /Reset name pointer /Print rest of information now that past name. PASTNM, JMS I (SPACE3 /Print three spaces JMS I [TWOBYT /Get length of file TAD ACL JMS I [PRTDEC /Print in decimal ISZ DIRECT ISZ DIRECT /Point past job #, channel bytes. JMS I (SPACE3 TAD BLK /Starting block of this file JMS I [PRTDEC /Print it TAD BLK TAD ACL DCA BLK /Update block counter TAD TYPE /Only print date for perm. files. AND [4 /Permanent? SNA CLA JMP PASTDT /No date. JMS I [TWOBYT /Get date JMS I (SPACE3 JMS I (RTDATE /Print it PAST, TAD DIRECT /Point past extra words, TAD EXTRA /if any. DCA DIRECT JMS I (CRLFBF /Skip to next line. JMP NXTENTR PASTDT, TAD [2 TAD DIRECT DCA DIRECT JMP PAST TYPE, 0 BLK, 0 TENT, EMPT, TAD (6 /Point past name TAD DIRECT DCA DIRECT JMS I [PRTLST /Print "<Unused>" instead of name. 12 UNUSED JMP PASTNM /Do rest of entry. NXTSEG, TAD I (SEGLNK /Get link to next segment SNA /Is there another? JMP CLOSBF /Finish typing. DCA DIRSG /Save the link. JMP READSG /Read and decode it. CLOSBF, JMS I (CLOSTT JMP I LISTDR /List printer - buffers and prints list of characters. /Call: / JMS PRTLST / nchar / message / / Where nchar is the length and message is the / location of the text to type. / PRTLST, HLT TAD I PRTLST /Get length CIA /Negative now DCA LSTCTR ISZ PRTLST /Point to location. STA /Minus one for autoindex TAD I PRTLST /Get location pointer DCA AX0 /Store ISZ PRTLST /Point to return PRTLP, TAD I AX0 JMS I [TTBUF /Print char. ISZ LSTCTR /Check if done. JMP PRTLP JMP I PRTLST LSTCTR, 0 PAGE /Routine to convert RAD50 char to ascii /and put in buffer. / /Translation table: / / CHAR RAD50 / / blank 0 / A-Z 1-32 / $ 33 / . 34 / unused 35 / 0-9 36-47 / / RAD50, HLT SNA JMP BLANK /Zero is a blank TAD (-33 /Check for A-Z SMA JMP MORE50 /Nope, try the rest. TAD (333 /Restore and convert to ascii STASH50,DCA I DIRPTR /Stash it away JMP I RAD50 MORE50, SNA JMP DOLLAR /33 Is dollar sign. CIA CMA SNA JMP PERIOD /34 Is a period TAD (260-2 /Must be a number. Convert JMP STASH50 /and store. BLANK, TAD (240 JMP STASH50 DOLLAR, TAD ("$ JMP STASH50 PERIOD, TAD (". JMP STASH50 /Gets RT-11 format date from ACH and ACL and /converts to standard date string, outputting /to the tty buffer. RTDATE, HLT TAD ACL /First check for no date- SZA CLA JMP GOTDATE /We seem to have a date. TAD ACH /Is this zero? SNA CLA /Nope. Have a date. JMP NONE /Print "No date" instead. GOTDATE,TAD ACL AND (37 /Year bits only. DECIMAL TAD (72 /Add in starting year. OCTAL DCA YEAR /Save it. TAD ACL AND (1740 /Get day bits CLL RTR;RTR;RAR /Into position DCA DAY /And save TAD ACL /Get low order month bits AND (6000 CLL RTL;RAL DCA WS0 /Save for awhile TAD ACH /High order month bits AND [7 /Keep only good stuff CLL RTL TAD WS0 /And get low order too. DCA MONTH TAD DAY /Now print day JMS I [TWODEC TAD ("- JMS I [TTBUF TAD MONTH /Get pointer to month name DECIMAL TAD [-13 /Is month within range? SPA CLA JMP MONOK /Yup TAD (13 /Set to 13 (prints Bad for month) OCTAL SKP MONOK, TAD MONTH CIA /Subtract one (jan=0, feb=1, etc.) CLL CMA RTL /Each month is four chars long TAD (MONTHS /Add start of months name list DCA DATLOC /Put as arg of subroutine call. JMS I [PRTLST /Print month name 4 DATLOC, HLT TAD YEAR /Now print year JMS I [TWODEC JMP I RTDATE /Routine to print "No date" when there is none. / NONE, JMS I [PRTLST 11 NODATE JMP I RTDATE /All done here. MONTH, 0 DAY, 0 YEAR, 0 /Routine to read a directory segment into /the directory buffer. The segment desired /is in DIRSG. GETDIR, HLT TAD DIRSG /Check for real segment (<10) TAD (-10 SMA CLA JMP BADDIR /Bad segment # TAD [2 /A segment is two blocks long. DCA NBLOK TAD [DIRBUF DCA BUFPTR /Read to the directory buffer TAD DIRSG /Compute block number from segment number CLL RAL TAD [4 DCA RTBLOK /Read starting at this block. JMS I [READBLK/Read it. TAD I (BEXTRA CLL RAL /Get number of free bytes DCA EXTRA JMP I GETDIR /All done. BADDIR, JMS I [PRTZRO DIRBAD JMP I [CALLDEC /Scan routine /Looks for specified char in a buffer pointed /to by AX0. /call: JMS SCAN / Char to look for / found / not found SCAN, 0 TAD I SCAN CIA DCA WS1 ISZ SCAN SCANLP, TAD I AX0 /Get next buffered SNA JMP I SCAN /Not found TAD WS1 /See if matches SZA CLA JMP SCANLP /No match; keep looking. ISZ SCAN /Found; return to caller. JMP I SCAN PAGE /Teletype output routine. TTOUT, HLT TSF JMP .-1 TLS CLA CLL JMP I TTOUT SPACE3, HLT /PRINT 3 SPACES. TAD [-3 DCA SPCTR SPLOOP, TAD (" JMS TTBUF ISZ SPCTR JMP SPLOOP JMP I SPACE3 SPCTR, 0 /Print cr-lf CRLF, HLT TAD [215 JMS I [TTOUT TAD [212 JMS I [TTOUT JMP I CRLF CRLFBF, HLT TAD [215 JMS TTBUF TAD [212 JMS TTBUF JMP I CRLFBF TTBUF, HLT CHANGE, JMP SETUP /Changed to NOP after init. CDF 10 DCA I TTPTR /Stash character CDF 00 ISZ FULL /Check for full buffer. JMP I TTBUF /Now there - go back. TAD MAXLEN /Check if there is room left SNA CLA JMP FULLDV /More will overflow the file. JMS I (OSHAND /Call the handler 4210 /Write 2 pages from field 1 ISZ OSLEN /Count a block ISZ I (BLOCK ISZ MAXLEN NOP /Cover skip TAD [-400 DCA FULL TAD [DATABF-1 DCA TTPTR /Reset buffer pointer JMP I TTBUF /Return. SETUP, DCA WS0 /Save the char. TAD [-400 DCA FULL /Flag the buffer as empty TAD [DATABF-1 DCA TTPTR /Set the pointer TAD [NOP DCA CHANGE /Don't do this again. TAD WS0 JMP CHANGE FULL, 0 CLOSTT, HLT /Close the output buffer. STA DCA FULL /Set to immediately overflow. TAD CLOSTT /Move return to buffering routine DCA TTBUF TAD (232 /Get end file char. JMP TTBUF+1 /Print a string of characters /prints until hits a zero. PRTZRO, HLT STA TAD I PRTZRO DCA AX2 ISZ PRTZRO PZLOOP, CDF 10 /Field of messages. TAD I AX2 CDF 00 SNA JMP DONE0 JMS I [TTOUT JMP PZLOOP DONE0, JMS I [CRLF /Go to new line JMP I PRTZRO /Print the AC as a decimal number DECIMAL PRTDEC, HLT /Lifted from FUTIL, V6. JMS NUMOUT -1000 -100 -10 0 JMP I PRTDEC OCTAL TWODEC, HLT /Two digit decimal print AND [0177 JMS NUMOUT -12 0 JMP I TWODEC /Actual number output routine NUMOUT, HLT DCA NUMB /Save it NUM01, DCA NUMDGT /Clear digit counter CLA CLL TAD NUMB /Get current value TAD I NUMOUT /Minus digit being printed. SNL /Did it overflow? JMP NUM02 /No, too far! ISZ NUMDGT /Yes, bump digit. DCA NUMB /And update value JMP NUM01+1 NUM02, CLA CLL TAD NUMDGT /Output the digit TAD [260 JMS TTBUF ISZ NUMOUT /Get next arg TAD I NUMOUT /Done enough? SZA CLA JMP NUM01 /Nope, more to do. TAD NUMB /All done - output last digit TAD [260 JMS TTBUF JMP I NUMOUT /And return NUMB, 0 NUMDGT, 0 FULLDV, JMS I [PRTZRO DEVFUL JMP I [7605 PAGE /Routine to get input from console. Reads input from /keyboard to input buffer. Returns when return hit, unless /there are no chars in the buffer. Sets INCNT to the /number of characters hit. GETIN, HLT CLA CLL DCA INCNT /Init counter to zero. DCA ESCAPE /Clear terminated by escape flag. TAD (INBUF-1/Setup pointer to buffer. DCA AX0 PROMPT, TAD ("* /Print prompt char. JMS I [TTOUT INLOOP, KSF /Changed to CIF BATCH JMP .-1 / JMS I BATINP KRB /Get char. (Changed to NOP) AND [0177 /Set the parity bit. TAD [0200 CIA /Negate for scanning table DCA WS0 /Save it TAD (CHRLST-1 DCA AX1 /Point to character table CHKCHR, TAD I AX1 SNA /Table end? JMP STORE /No. store it. TAD WS0 SNA CLA JMP GETADR /Match! ISZ AX1 /Skip routine address JMP CHKCHR GETADR, TAD I AX1 DCA WS0 /Get routine address JMP I WS0 STORE, TAD WS0 CIA /Get char. back DCA WS0 /Save it. TAD WS0 AND [140 /Check if control char. SNA CLA JMP BEEP /Ring the bell if it is. TAD WS0 /Get it back. JMS I [TTOUT TAD WS0 DCA I AX0 /Store in buffer. ISZ INCNT /Bump counter JMP INLOOP BEEP, TAD ("G-100 /^G - BELL JMS I [TTOUT JMP INLOOP LFPAT=JMP INLOOP /Batch patch for loc. LINPAT /Special character handlers RETURN, DCA ESCAPE /Clear escape flag JMS I [CRLF /Skip to next line DCA I AX0 /Flag end of buffer. JMP I GETIN /And return. LINPAT, /Patched for BATCH to "JMP INLOOP" REPEAT, JMS I [CRLF /Repeat his input - new line TAD ("* /Print the prompt. JMS I [TTOUT TAD INCNT /Any input? SNA JMP INLOOP /If none, simply prompt. DCA LINCNT JMS I [TTYLST LINCNT, 0 INBUF JMP INLOOP /Now echo is done, back to him. ESC, TAD ("$ JMS I [TTOUT CLA CLL IAC /Set escape flag. JMP RETURN CLRIN, TAD ("^ JMS I [TTOUT TAD ("U JMS I [TTOUT /Type "^U" JMS I [CRLF JMP GETIN+1 /Reset buffer, cr/lf, prompt. /Rubout routine. This starts out as simply a routine to /echo the char being rubbed out. The initialization routine /checks for scope mode and overwrites this with a scope /mode routine if applicable. RUBOUT, TAD INCNT /Anything to be rubbed out? SNA CLA JMP PROMPT /Nope. TAD AX0 /Get pointer to last char DCA WS0 /which is the one to kill. TAD I WS0 /Get the char JMS I [TTOUT STA TAD INCNT /Reduce input counter DCA INCNT STA TAD AX0 /And back up pointer. DCA AX0 JMP INLOOP ZBLOCK 5 /Fill for overlay. /OS/8 Handler call routine. / / call: JMS OSHAND / funct / Where funct is the handler control word. / / DATABF is always used for the transfer. / OSHAND, HLT TAD I OSHAND /Get function DCA FUNCT ISZ OSHAND JMS I ENTRY /Call handler FUNCT, 0 DATABF BLOCK, 0 /Set by lookup/enter JMP OSERR JMP I OSHAND /Successful OSERR, SPA CLA /Fatal error? JMP BADERR /Yup. TAD OSCTR /Clear data available counters. CIA DCA OSLEN JMP I OSHAND /This forces eof on input. BADERR, JMS I [PRTZRO OS8ERR /"OS/8 I/O error" JMP I [7600 PAGE /Ascii to RAD50 conversion routine / /Converts the three cahrs pointed to by AX0 /to RAD50. Uses the FIVEBIT routine to get the /five bit form of the character and packs the three /chars into the double precision AC. / /formula:RAD50=(((c1*50)+c2)*50+c3) PAKNAM, HLT CLA CLL /Just in case. TAD I AX0 /Get first character JMS FIVEBIT /Convert to five bit. DCA ACL DCA ACH /Store in d.p. AC JMS MULT50 /Multiply by 50. TAD I AX0 JMS FIVEBIT /Get five bit equivalent DCA OPLO DCA OPHI /Save as operand for add. CLL JMS DPADD /Add the second char to the d.p. AC JMS MULT50 /Multiply by 50. TAD I AX0 /Third char. JMS FIVEBIT CLL DCA OPLO DCA OPHI JMS DPADD /All done now. JMP I PAKNAM /8 bit ASCII to 5 bit RAD50 conversion routine /Converts the sixbit equivalent of the character /to the special form used for RAD50. See the RAD50 /routine for details. FIVEBIT,HLT SNA /Zero stays zero. JMP I FIVEBIT AND [0077 /Six bits only. TAD (-40 /See it it is a letter. SPA JMP LETTER /Sure is. SNA JMP I FIVEBIT /Blank is zero. TAD (-4 SNA JMP DOLR5 /Is a dollar sign. TAD (-12 SNA JMP PERD5 /Is a period. TAD (34 /Must be a digit, so convert. JMP I FIVEBIT LETTER, TAD (40 /Restore the letter JMP I FIVEBIT DOLR5, TAD (33 JMP I FIVEBIT PERD5, TAD (34 JMP I FIVEBIT /Multiply d.p. AC by 50. Used by RAD50 packing routine. /Done by multiplying by 4 (shifting left 2) /and adding itself; then multiplying by 10 (shifting /left three). / /i.e. a*50 = (a*4+a)*10 / MULT50, HLT TAD ACL /Save the AC DCA OPLO /For the addition coming up. TAD ACH DCA OPHI CLL /Just in case. JMS I (DPRAL /Shift twice. JMS I (DPRAL JMS DPADD /Add in the original JMS I (DPRAL JMS I (DPRAL JMS I (DPRAL /Shift left three JMP I MULT50 /Return. /Double precision add routine. Adds op (OPLO & OPHI) /to the d.p. AC. DPADD, HLT CLL /Just in case. TAD ACL TAD OPLO /Get low order sum DCA ACL /Store RAL /Overflow bit to AC11 TAD ACH TAD OPHI /Add high order and overflow DCA ACH /Store JMP I DPADD /Divides double precision AC by 50. Used to unpack /RAD50 chars. Leaves remainder in ACH, Quotient in ACL. DIV50, HLT TAD (-14 /Setup loop counter DCA DIV5CT DIV5LP, CLL /Just in case! TAD ACH /Add -(24 0000) to dp AC TAD (-24 DCA ACH TAD ACH /Get sign of ACH in link. RAL CLA SZL JMP SHIFT0 /If link clear, restore and shift /a zero to quotient. Otherwise, don't /restore and shift a one. CML /Set link to correct sense ROTAT, JMS DPRAL /Shift d.p. AC left once. ISZ DIV5CT /Done dividing yet? JMP DIV5LP JMP I DIV50 /All done. SHIFT0, TAD ACH /Restore d.p. AC TAD (0024 DCA ACH JMP ROTAT /Shift zero to quotient. DIV5CT, 0 DPRAL, HLT /Shifts d.p. AC left one TAD ACL RAL DCA ACL /Rotate low order, save link. TAD ACH RAL /Link now in AC11 DCA ACH JMP I DPRAL /Which is o.k. /Print a string on the tty TTYLST, 0 TAD I TTYLST /Get number of chars to print CIA DCA TTCTR ISZ TTYLST STA TAD I TTYLST /Pointer to message DCA AX0 ISZ TTYLST TTLOOP, TAD I AX0 JMS I [TTOUT /Print it. ISZ TTCTR JMP TTLOOP JMP I TTYLST TTCTR, 0 PAGE /Parse a RT-11 filename from the input buffer. /Name goes to RTNAM (siz chars) and RTEXT (3 chars.) /Initally name and extension set to blanks. RTNAME, HLT JMS SETZRO /Initialize name and extension. 11 /9 (Decimal) locations. RTNAM TAD (RTNAM-1 DCA AX1 /Point to output buffer. GETRT, JMS NAMSCN /Parse next char. JMP PAKBYT /Pack the name into 6 bytes JMP DEVERR /Cannot give device for RT-11 JMP SETEXT /Hit a period DCA I AX1 /Store character. JMP GETRT /Loop for more. SETEXT, JMS SETZRO /Clear the extension now. 3 RTEXT TAD (RTEXT-1/Now store in extension buffer. DCA AX1 JMP GETRT DEVERR, JMS I [PRTZRO /Print error and retry. NORTDV /"Cannot specify RT-11 device" JMP I [CALLDEC PAKBYT, JMS I [BYTNAM JMP I RTNAME /Parse the OS/8 name. OSNAME, HLT JMS SETZRO /Initialize name and extension. 6 OSNAM JMS SETZRO 3 OSEXT TAD OPTFLG /Get Directory flag. AND (DIRIO SZA CLA TAD [4 /Default is TTY; not DSK. TAD (DEFDV-1/Point to default device list DCA AX1 TAD [-4 /Number of chars in device names. DCA WS0 TAD (OSDEV-1 DCA AX2 MOV1, CDF 10 TAD I AX1 /Move default device name CDF 0 DCA I AX2 /To OSDEV ISZ WS0 JMP MOV1 TAD (OSNAM-1/Setup store pointer DCA AX1 /Now scan the input for the OS/8 device name, etc. GETOS, JMS NAMSCN /Parse input JMP I OSNAME /All done. JMP DEVC /Hit a : JMP EXTN /Hit . DCA I AX1 /Others. JMP GETOS /Loop for more. DEVC, TAD (-4 /Move name to device words. DCA WS0 TAD (OSNAM DCA WS1 TAD (OSDEV DCA WS2 MOVELP, TAD I WS1 /Get a char from the name buffer DCA I WS2 /Store it in the extension buffer. DCA I WS1 /Clear out the name buffer. ISZ WS1 ISZ WS2 /Increment the pointers ISZ WS0 /Check counter JMP MOVELP TAD (OSNAM-1/Reset pointer to start of name buffer. DCA AX1 JMP GETOS EXTN, TAD (OSEXT-1/Point to extension buffer. DCA AX1 JMP GETOS /Name scanner /Used by command decoder to find certain chars. /call: JMS NAMSCN / end of name (end of buffer,or < found.) / colon / period / any other chars. / /Special chars. return with AC = 0; others with /AC = the char taken from the buffer. NAMSCN, HLT TAD I AX0 /Get next char. SNA JMP I NAMSCN /End of buffer. TAD (-"/ /Check for slash option. SNA JMP SLSH /If so, skip next. TAD ("/-"< /Is it <? SNA JMP I NAMSCN /Yup. TAD ("<-"= /How 'bout =? SNA JMP I NAMSCN /Yup. Treat like <. ISZ NAMSCN /Not end of name. TAD ("=-": /How 'bout colon? SNA JMP I NAMSCN /Yup. ISZ NAMSCN /Nope. TAD (":-". /Period? SNA JMP I NAMSCN /Yup. ISZ NAMSCN TAD (". /Restore and return. JMP I NAMSCN SLSH, ISZ AX0 /Skip the char. after the slash. JMP NAMSCN+1/And continue /Set specified locations to zero / /call: JMS SETZRO / number of locations / starting loc. / SETZRO, HLT TAD I SETZRO /Get no. of locations CIA DCA WS0 ISZ SETZRO STA TAD I SETZRO /Get pointer DCA AX1 ISZ SETZRO STLOOP, DCA I AX1 ISZ WS0 JMP STLOOP JMP I SETZRO PAGE /Pack the ascii device, filename and extension /into sixbit. SIXBIT, HLT JMS SIXPAC /Pack the device name 4 /Four chars. long OSDEV /From DEVIC /Into the "fetch" call. JMS SIXPAC /Now the name 6 OSNAM NAME /Into the name buffer JMS SIXPAC /And finally the extension 2 OSEXT NAME+3 JMP I SIXBIT /Do the actual ascii to sixbit packing / /call: JMS SIXBIT / no. chars to pack / source / dest / SIXPAC, HLT /I'll take michelob.... TAD I SIXPAC /Get # chars CLL RAR /Divided by two to get no. pairs. CIA DCA WS0 /Save counter ISZ SIXPAC STA TAD I SIXPAC /Get source pointer DCA AX0 ISZ SIXPAC STA TAD I SIXPAC /And destination DCA AX1 ISZ SIXPAC PACKLP, TAD I AX0 /Get first AND [77 /Only six bits CLL RTL;RTL;RTL /Shift into place DCA WS1 /And save TAD I AX0 /Get next AND [77 /Only six bits TAD WS1 /Get high byte DCA I AX1 /Store it ISZ WS0 JMP PACKLP JMP I SIXPAC /Fetch the OS/8 handler OSFETCH,HLT TAD (OS8HND+1 DCA DEVN+1 /Set up handler loc. and size. CIF 10 /Call the USR JMS I [200 FETCH DEVIC, 0 /Set up by decode and sixbit. DEVN, 0 /Gets device number OS8HND+1 /Space for 2 page handler. JMP BADHND /Handler does not exist! TAD DEVN+1 /Move entry point DCA ENTRY /To page zero TAD DEVN /Also device number DCA DEVNO JMP I OSFETCH /All done BADHND, JMS I [PRTZRO NOHND /Handler does not exist JMP I [CALLDEC /OS/8 Enter routine. Does an enter on the specified /output device. OSENTER,HLT CLA CLL IAC /Set initially infinite file length. DCA MAXLEN JMS OSCHK /Skip if file structured. JMP I OSENTER /Don't need to enter non file-struct. TAD I (NAME /Now see if we have a name. SZA CLA JMP NAMOK /Yup. JMS I [PRTZRO /No name - that's bad! FILNAM JMP I [CALLDEC /Try again, sport! NAMOK, TAD (NAME /Point to name DCA BLOK TAD DEVNO CIF 10 /Call USR JMS I [200 ENTER BLOK, NAME LEN, 0 JMP I (OS8ERR /Oops! TAD BLOK /Move starting block to handler DCA I (BLOCK /call routine TAD LEN /And the length to DCA MAXLEN /page zero. DCA OSLEN /zero the file length counter JMP I OSENTER /Check for file structured device OSCHK, HLT TAD DEVNO /This device TAD (7757 /Point to Device Control Word Table DCA WS0 CDF 10 /In field 1 TAD I WS0 /Get entry CDF 00 SPA CLA /Bit 0 = 1 if files. ISZ OSCHK /Skip return. JMP I OSCHK /OS/8 Close routine /Closes open tentative file. OSCLOSE, HLT TAD OSLEN /Get length of file DCA CLOSLN /Stash in USR call. TAD DEVNO /Need device # CIF 10 JMS I [200 CLOSE NAME CLOSLN, 0 JMP I (OS8ERR JMP I OSCLOSE JMP I OSENTER PAGE /Routine to look up the specified file /on the RT-11 device. Skips on return if the file /was found; sets RTBLOK to the starting block, /RTLEN to the file length. RTLOOK, HLT CLA CLL IAC DCA DIRSG /Start with directory segment 1. LP, JMS I [GETDIR /Read the directory segment. TAD (FILE1 /Setup pointer to first filename DCA SCANPTR TAD (BLOCK1-1 DCA DIRECT /Point to starting block of first JMS I [TWOBYT /file and get into d.p. AC TAD ACL DCA RTBLOK /Save starting block COMPAR, TAD SCANPTR /Point to status word for this entry DCA DIRECT TAD I DIRECT /Get status byte CLL RAR SNA JMP CNTBLK /1 = Tentative entry; count blocks. CLL RAR SNA JMP CNTBLK /2 = Empty file; count blocks. CLL RAR SZA CLA JMP NXTSG /10= End of segment. TAD (-6 /Must be permanent entry; check name. DCA WS0 /Counter for number of bytes in name. TAD (RTNAM-1/Point to name entered. DCA AX0 NAMLP, TAD I AX0 /Get entered byte (already negated) TAD I DIRECT /Add this file's name. SZA CLA JMP CNTBLK /Oops! Not this one. ISZ WS0 /Checked 'em all? JMP NAMLP /No. JMS I [TWOBYT /Yup. Get the length. TAD ACL DCA RTLEN ISZ RTLOOK /Flag succcess JMP I RTLOOK /Count the blocks of either empty or incorrect /Permanent files CNTBLK, TAD (7 /Point to length bytes TAD SCANPTR DCA DIRECT JMS I [TWOBYT /Get the length TAD ACL TAD RTBLOK /Add the start of this file DCA RTBLOK /To get start of next. NXT, TAD (16 /Update scan pointer to next TAD SCANPTR /entry. TAD EXTRA DCA SCANPTR JMP COMPAR /Keep going. NXTSG, TAD I (SEGLNK /Check if any more segments. SNA JMP I RTLOOK /Guess not. Return without skip. DCA DIRSG /Read next segment. JMP LP /Generates RAD50 equivalent of the entered /filename as six bytes in RTNAM. Negates the values /before storing. BYTNAM, HLT TAD (RTNAM-1 /Source pointer DCA AX0 TAD (RTNAM-1 /Dest. Pointer DCA AX1 TAD (-3 /Number of byte pairs. DCA BYTCTR BYTLP, JMS I (PAKNAM /Pack three chars into d.p. AC TAD ACL AND (377 /Convert to two bytes. CIA /Complement. DCA I AX1 /Store. TAD ACL /High byte now. AND [7400 CLL RTL;RTL;RAL DCA WS1 TAD ACH AND (0017 /High bits of high byte. CLL RTL;RTL TAD WS1 CIA /Negate it. DCA I AX1 /Store this too. ISZ BYTCTR /Done yet? JMP BYTLP /Nope. JMP I BYTNAM /All done! PAGE /Read a file from the RT-11 floppy and copy it /to the OS/8 file. RTREAD, HLT TAD RTBLOK /Save the starting block DCA BLKSAV READLP, TAD BLKSAV DCA RTBLOK /Point handler to first block TAD (DATABF /And the right buffer. DCA BUFPTR TAD RTLEN TAD (-3 /Want to read 3 blocks; is there SPA CLA /That many left? JMP LEFT /Nope. TAD (3 /Read 3 RT-11 blocks. SKP LEFT, TAD RTLEN /Read whatever's left. DCA BLKS /Save for later calculations. TAD BLKS DCA NBLOK /Stash for handler. CDF 10 /Buffer in field 1 JMS I (READBLK CDF 0 JMS REPACK /Repack as OS/8 output. CLA CLL IAC /#OS/8 blocks is one more than the number TAD BLKS /of RT-11 blocks. DCA WS0 /Save. TAD WS0 /See it OS/8 has that much room. TAD MAXLEN DCA MAXLEN /Link flips on overflow. SZL CLL JMP OVEROS /Not enough room. TAD WS0 /Restore size. CLL RTR;RTR;RTR /Set up page count for OS/8 handler TAD (4010 /Get rest of function code /(write; field 1) DCA WTCMD JMS I (OSHAND /Call handler for write. WTCMD, HLT CLA IAC /Update block count. TAD BLKS TAD OSLEN DCA OSLEN TAD I (BLOCK /Update OS/8 block # TAD BLKS IAC DCA I (BLOCK TAD BLKS /Decrement length left. CIA TAD RTLEN DCA RTLEN TAD BLKSAV /Update block pointer TAD BLKS DCA BLKSAV TAD RTLEN /See if any left. SZA CLA JMP READLP /Keep reading. JMP I RTREAD /All done. /Pack the RT-11 input (one byte per word) into /OS/8 format (3 bytes in two words) / REPACK, HLT TAD (DATABF-1/Initialize buffer pointers DCA AX0 TAD AX0 DCA AX1 TAD [-1000 /And the counters. This counts DCA WS0 /1000 groups of 4 12-bit words. CDF 10 /Point to buffer RPKLP, JMS TADIAX0 DCA WD1 /Get the next three bytes. JMS TADIAX0 DCA WD2 JMS TADIAX0 DCA WD3 TAD WD3 /Get the first word. AND (360 /High bits of third char CLL RTL;RTL /Into place. TAD WD1 /First char DCA I AX1 /Stash in output TAD WD3 /Get low bits AND (17 CLL RTR;RTR;RAR TAD WD2 /Get second char DCA I AX1 /Stash in buffer. ISZ WS0 JMP RPKLP CDF 0 /All done (at last!) JMP I REPACK TADIAX0,HLT TAD I AX0 IMAGE, SZA JMP I TADIAX0 TAD ("Z-100 /Make nulls (RT-11 eof) into JMP I TADIAX0 /^Z (OS/8 eof). WD1, 0 WD2, 0 WD3, 0 BLKSAV, 0 BLKS, 0 OVEROS, JMS I [PRTZRO /Print "OS/8 file overflow" OSBIG JMP I [CALLDEC PAGE /Enter a tentative file on the RT-11 device. /Returns starting block in RTBLOK / length in RTLEN. / RTENTER,HLT DCA BIGMT /Initialize: biggest empty to 0 blocks, DCA BIGSEG /Segment # of biggest empty. JMS I [RTLOOK /Try to find file with same name JMP NOSAME /File not found. JMS I (RTDEL /Delete it. NOP /Should skip (means file was found) NOSAME, CLA IAC /Find the biggest empty. DCA DIRSG MTLOOP, JMS I [GETDIR TAD (FILE1 /Start scanning this segment. DCA SCANPTR TAD (BLOCK1-1 DCA DIRECT JMS I [TWOBYT /Get starting block # of first file TAD ACL DCA RTBLOK MTFIND, TAD SCANPTR /Point to file type byte DCA DIRECT TAD I DIRECT TAD [-2 /Empty? SZA JMP NOTMT /Nope. TAD SCANPTR /Point to length. TAD [7 DCA DIRECT JMS I [TWOBYT /Get length TAD BIGMT /Check if biggest. CIA TAD ACL SPA SNA CLA JMP SMALR /Smaller than last. TAD ACL /Save data about this entry. DCA BIGMT TAD DIRSG DCA BIGSEG TAD SCANPTR DCA BIGPTR TAD RTBLOK DCA BIGBLK JMP SMALR NOTMT, TAD (-6 /Check if end of segment. SNA CLA JMP NEWSEG TAD DIRECT /Get length. TAD [6 DCA DIRECT JMS I [TWOBYT SMALR, TAD ACL /Update starting block TAD RTBLOK DCA RTBLOK TAD SCANPTR /Point to next entry. TAD [16 DCA SCANPTR JMP MTFIND /RT-11 Enter routine continued NEWSEG, TAD I (SEGLNK /Any next segment? SNA CLA JMP FNDEND /All done looking. DCA DIRSG /Look here now. JMP MTLOOP FNDEND, TAD BIGMT /Found any empties at all? SNA CLA JMP I (RTFULL /OOPS! No empties! TAD BIGSEG /Read the segment. DCA DIRSG JMS I [GETDIR TAD BIGPTR /Point to the entry DCA SCANPTR TAD SCANPTR TAD [16 /Check if next is empty. DCA DIRECT TAD I DIRECT /Get type byte. TAD [-2 SNA CLA JMP NEXTMT /Next is empty. JMS I (MAKMT /Make an empty. MOVE1, STA /Point to start of entry TAD BIGPTR DCA DIRECT DCA I DIRECT TAD [4 /Flag as permanent file entry. DCA I DIRECT JMS I (MOVNAM TAD DIRECT TAD [4 /Point to date words. DCA DIRECT JMS I (OSDATE /Set up date. TAD BIGMT DCA RTLEN /Save length. TAD BIGBLK /Restore block number. DCA RTBLOK JMP I RTENTER /Done! NEXTMT, TAD DIRECT TAD [6 /Point to size DCA DIRECT JMS I [TWOBYT /Get size TAD ACL TAD BIGMT /Merge the files. DCA BIGMT /Into one empty. JMP MOVE1 PAGE /Empty file entry creation routine MAKMT, HLT ENDLP, TAD SCANPTR /Look for the end of the segment DCA DIRECT TAD I DIRECT /Get type byte TAD [-10 SNA CLA /End of segment? JMP ENDSEG /Yup. TAD SCANPTR TAD [16 TAD EXTRA /Point to next DCA SCANPTR TAD SCANPTR /Check if out of range (past end of segment) TAD (-DIRBUF-2000+16 SPA SZA CLA JMP ENDLP /O.K. Keep looking. JMS I [PRTZRO /Tell him the segment is full. FULLSEG /He must squeeze, or something. JMP I [CALLDEC ENDSEG, TAD SCANPTR /Insert new end of segment flag TAD [16 TAD EXTRA DCA WS0 DCA I WS0 ISZ WS0 TAD [10 DCA I WS0 TAD SCANPTR /Move the entries starting from /the empty found down. TAD [15 TAD EXTRA /To pointer. DCA WS0 STA TAD SCANPTR DCA WS1 /From pointer. MOVEDN, TAD I WS1 DCA I WS0 STA /Back up pointers. TAD WS0 DCA WS0 STA TAD WS1 DCA WS1 TAD WS1 /Check if done. CMA TAD BIGPTR SZA CLA JMP MOVEDN JMP I MAKMT /Finished. /Routine to write a directory segment. /Used to rewrite the segement of the directory that the /file was entered into. This makes the file permanent. PUTDIR, HLT TAD [-10 /Counter for the no. of sectors DCA NSECS /In a segment. TAD (DIRBUF-1 DCA RTPTR /Point to directory buffer. TAD DIRSG /Get current segment no. CLL RAL TAD [4 /Convert to block number. CLL RTL DCA RTBLOK TAD [-10 DCA ERRCNT /Set error counter. TAD RTBLOK /Write a sector JMS I [CONVERT /Get physical location WRTSEC, JMS I (SDNCC JMP .-1 /Wait for done. SER /Check for errors SKP JMP I [WRTERR TAD [-200 DCA BYTCTR WRTRTY, TAD [FILL /Command LCD GETDTA, STR /Wait for data request. JMP .-1 TAD I RTPTR /Get data XDR CLA ISZ BYTCTR JMP GETDTA /Not yet. JMS I [FLOPPY /Do the write. WRITE ISZ NSECS /Check if done. JMP WRTSEC /Not yet JMP I PUTDIR /Finis. /OS/8 Lookup routine OSLOOK, HLT JMS I (OSCHK /Check filename, etc. JMP I OSLOOK /No lookup necessary (non file struct.) TAD (NAME DCA LOOKBLK TAD DEVNO CIF 10 /Call USR JMS I [200 LOOKUP LOOKBLK,NAME /Name on call, changed to block # LOOKLN, 0 /Becomes length of file. JMP I (FILER /No file found. TAD LOOKBLK DCA I (BLOCK /Move block to page 0 TAD LOOKLN DCA OSLEN /Length too. JMP I OSLOOK /Convert AC to two bytes in buffer /pointed to by DIRECT. BYTTWO, HLT DCA WS0 /Save it. TAD WS0 AND [377 DCA I DIRECT TAD WS0 AND [7400 CLL RTL;RTL;RAL DCA I DIRECT JMP I BYTTWO PAGE /Read the OS/8 file four blocks at a time. Unpack /this data and write as three RT-11 blocks. OSREAD, HLT DCA RTCTR /Counts number of RT-11 sectors written TAD RTBLOK /Save starting block. DCA I [BLKSAV TAD RTBLOK /Convert to sector number. CLL RTL DCA RTBLOK TAD RTLEN /Get size counter for empty. CLL RTL /No. of sectors CIA DCA MAXLEN /Save counter. OSRDLP, CLA CLL TAD OSLEN /Length left TAD [4 /Want to read 4 blocks. SNL CLA JMP RD4 /Have 4 or more left. TAD OSLEN CIA /Read whatever is left. SKP RD4, TAD [4 DCA OSCTR /No. OS/8 blocks to read. TAD OSCTR CLL RTR;RTR;RTR /Block count into position as page count. TAD [10 /Field of buffer DCA RDCMD /Save constructed command. JMS I [OSHAND /Call handler RDCMD, HLT TAD I [BLOCK /Point to next block of file. TAD OSCTR DCA I [BLOCK TAD [DATABF-1/Point to buffer DCA RTPTR TAD OSCTR /Get sector counter, which is CLL RAL /Three times the no. of OS/8 blocks. TAD OSCTR /3*X is 2*X+X. CIA DCA NSECS /Save counter. TAD RTBLOK JMS I [CONVERT WRTLP, ISZ RTCTR /Count another sector. ISZ MAXLEN /Check if done. SKP JMP RTFULL /No room left. TAD [-200 DCA BYTCTR SDN JMP .-1 SER SKP JMP I [WRTERR /Floppy write error OSRTY, TAD [FILL /Fill sector buffer. LCD CDF 10 /Change to buffer field. GETBYT, JMS OSUNPK /Get a byte. TRSKIP, STR JMP .-1 /Wait on request. XDR CLA ISZ BYTCTR JMP GETBYT /Get another byte. CDF 0 /Change data field back. FILLOK, JMS I [FLOPPY /Now write the data loaded. WRITE ISZ NSECS /Count another sector. JMP WRTLP /Keep writing. CHKDN, TAD OSLEN /See if more to read. TAD OSCTR SNA JMP I OSREAD /All through. DCA OSLEN /Save new count. JMP OSRDLP RTFULL, JMS I [PRTZRO NOROOM /Print "no room on floppy" JMP I [CALLDEC /RT-11 Floppy close routine. /Updates size of ENTERed file and empty following it; /also deletes any file with same name. RTCLOSE,HLT TAD RTCTR /Convert sector counter to block /count. This is done by dividing the /number of sectors by four. AND [3 /Remainder first. SZA CLA IAC /Add one for any remainder. DCA WS0 /Save. TAD RTCTR AND [7774 /Mask out remainder CLL RTR /Divide by 4 TAD WS0 /Add remainder DCA RTSIZE /Save size. TAD BIGPTR /Get pointer to file entry TAD [7 /Point to size. DCA DIRECT TAD RTSIZE /Get size of file created JMS I (BYTTWO /Convert AC to two bytes, put in buffer. TAD BIGPTR TAD [25 /Point to size of empty. DCA DIRECT TAD RTSIZE /Decrease empty by size of file. CIA TAD BIGMT JMS I (BYTTWO JMS I [PUTDIR /Write out directory JMP I RTCLOSE /All done. /OS/8 buffer unpacking routine / /Unpacks the three-for-two OS/8 data into /a stream of bytes. Converts ^Z (OS/8 end file) /to zeroes (RT-11 end of file.) OSUNPK, HLT JMP I GET /Call proper routine. GET, FIRST /Initially first of three. JMP I OSUNPK /Return with char. FIRST, TAD I RTPTR /Get first char. DCA HI /Save for making third. TAD HI JMS GET /Return; points GET to SECOND (sneaky!) SECOND, TAD I RTPTR /Get second DCA LO /Save for third. TAD LO JMS GET /Point to third. THIRD, TAD HI /Assemble third char. AND [7400 CLL RTR;RTR DCA WS0 TAD LO AND [7400 BSW CLL RTR TAD WS0 JMS GET /Return; points to jmp to FIRST. JMP FIRST HI, 0 LO, 0 PAGE /RT-11 delete routine. Deletes given file /from the floppy. Skips on return if the file /existed. RTDEL, HLT JMS I [RTLOOK /Look up the file JMP I RTDEL /Not found. ISZ RTDEL TAD SCANPTR /Get pointer to start of entry TAD [16 /Point to next file. DCA AX1 TAD I AX1 /Type of following file TAD [-2 /IS IT AN EMPTY? SNA CLA JMP SQUISH /Yup. move it over me TAD SCANPTR DCA AX1 TAD [2 /Flag for empty DCA I AX1 /Put in buffer JMS I [PUTDIR /Rewrite directory JMP I RTDEL SQUISH, TAD SCANPTR TAD (7 /Point to size of the empty DCA DIRECT JMS I [TWOBYT /Get the size TAD ACL DCA WS2 /Save it TAD DIRECT TAD (14 /Size of the next one TAD EXTRA DCA DIRECT JMS I [TWOBYT TAD WS2 TAD ACL /Combined size DCA WS0 TAD SCANPTR DCA AX1 TAD [2 /Flag an empty DCA I AX1 TAD SCANPTR TAD (7 /Size of first DCA DIRECT TAD WS0 /Get size JMS I (BYTTWO /Store it TAD SCANPTR TAD (15 TAD EXTRA DCA AX1 /Move the entries to here TAD AX1 TAD (16 /From here TAD EXTRA DCA AX2 MOVUP, TAD I AX2 DCA I AX1 TAD AX2 /Check for done TAD (-DIRBUF-2000 SZA CLA JMP MOVUP TAD (10 /Flag end of seg. DCA I AX1 JMS I [PUTDIR /Rewrite segment JMP I RTDEL /Done PAGE /RT-11 Date setting routine. Used by CLOSE /to set either the creation or current date /into the file. OSDATE, HLT DCA ACL /Init RT date storage DCA ACH CDF 10 TAD I (7666 /Get OS/8 date DCA DATE TAD I (1404 /Get no. addl. info. words from USR SNA CLA JMP NOAIW /No AIW's, no date, use current date. STA TAD I (17 /Pointer to date. DCA WS0 TAD I WS0 /Actual date word. SZA DCA DATE /Save date, if given. NOAIW, CDF 0 TAD DATE SNA JMP NODAT /No date. AND (7 /Year only. DCA WS0 /Save. CDF 10 TAD I (7666 /Get OS/8 date. CDF 0 AND (7 /Year only. CIA TAD WS0 /Get file's date. SMA SZA CLA /Skip if less than current year. TAD (-200 TAD I (7777 /Get extension bits. SPA CLA AND (600 CLL RTR;RTR /Into position. TAD WS0 /Now year-1970 TAD (-2 /Now RT-11 Year-1972. DCA ACL /Save TAD DATE AND (370 /Day bits CLL RTL /Into position for RT-11 TAD ACL /Get year saved DCA ACL /Save again TAD DATE AND (1400 /Low two month bits. CLL RTL /Into position. TAD ACL DCA ACL /Into saved low word. TAD DATE AND (6000 /High two month bits. CLL RTL;RAL /Into position. DCA ACH /Save NODAT, TAD ACL AND [0377 DCA I DIRECT TAD ACL AND [7400 CLL RTL;RTL;RAL DCA WS0 TAD ACH AND [17 CLL RTL;RTL TAD WS0 DCA I DIRECT JMP I OSDATE /Return. DATE, 0 /RT-11 Floppy ZERO (INIT) routine. /Writes zero directory on floppy. RTZER, HLT JMS I [PRTZRO AREYOU /Print "are you sure?" KCF /Clear away any spurious chars. KSF JMP .-1 KRB AND (177 TAD (200 TAD (-"Y SZA CLA JMP I RTZER /No. TAD ("Y JMS I [TTOUT /Print his response. JMS I (CRLF /New line TAD (DIRBUF-1 DCA AX1 TAD (ZDIR-1 DCA AX0 ZLOOP, TAD I AX0 SPA JMP ZEND DCA I AX1 JMP ZLOOP ZEND, CLA IAC DCA DIRSG JMS I [PUTDIR /Write as directory segment. JMP I RTZER PAGE /Directory input buffer. DIRBUF, BHIGHSG,.-.;.-. /Highest directory segment SEGLNK, .-.;.-. /Link to next segment .-.;.-. BEXTRA, .-.;.-. /Number of extra bytes BLOCK1, .-.;.-. /Starting block of first file FILE1, .-.;.-. /Start of file entries. *DIRBUF+2000 /Origin past buffer. /Months list MONTHS, "J;"a;"n;"- "F;"e;"b;"- "M;"a;"r;"- "A;"p;"r;"- "M;"a;"y;"- "J;"u;"n;"- "J;"u;"l;"- "A;"u;"g;"- "S;"e;"p;"- "O;"c;"t;"- "N;"o;"v;"- "D;"e;"c;"- "B;"a;"d;"- /RT-11 Zero directory ZDIR, 4;0 /4 Segments in the directory. 0;0 /Link to next segment. 1;0 /Highest open segment 0;0 /Extra bytes. 16;0 /First storage block 0;2 /Empty file entry 0;0 /Name 0;0 0;0 /Extension 340;1 /Size 0;0 /Job, channel # (F/B) 0;0 /Date 0;10 /End of segment 4000 /Terminator. OPTLST, -"Z;RTZERO;NOIO /Command decoder option table. -"D;DELETE;OUTRT /Format: negative option character; -"O;WRTRT;OUTRT+INOS /Address of routine to do;OPTFLG setting -"I;RDRT;OUTOS+INRT -"L;DIR;OUTOS+DIRIO 0 /Terminator. NAMBUF, ZBLOCK 12 /Filename buffer UNUSED, "<;"U;"n;"u;"s;"e;"d;">;" ;" ;" NODATE, "N;"o;" ;"d;"a;"t;"e;" ;" ;" NAME=.; *.+4 /Name buffers OSNAM=.; *.+10 OSEXT=.; *.+5 OSDEV=.; *.+4 RTNAM=.; *.+6 RTEXT=.; *.+6 INBUF=. RELOC RUBOUT TAD INCNT /Input buffer - contains scope SNA CLA /rubout routine. JMP INLOOP /Don't do anything if no chars. TAD BS /Print backspace JMS I TTPRT TAD SPC /space JMS I TTPRT TAD BS /backspace JMS I TTPRT STA /Reduce character counter TAD INCNT DCA INCNT STA /Back up pointer. TAD AX0 DCA AX0 JMP INLOOP TTPRT, TTOUT BS, 10 SPC, 240 RELOC RUBLEN=.-INBUF PAGE OS8HND=. TTPAT, RELOC TTOUT+2 JMS I BATPTR JMP I TTOUT BATPTR, BATOUT RELOC INPAT, RELOC INLOOP NOP JMS I BATINP JMP I [7605 /EOF ERROR RELOC *OS8HND+400 /OS/8 HANDLER LOADS HERE. FIELD 1 /Messages *2000 /Past USR. BADOPT, "B;"a;"d;" ;"s;"l;"a;"s;"h;" ;"o;"p;"t;"i;"o;"n;0 NOOPT, "N;"o;" ;"o;"p;"t;"i;"o;"n;" ;"f;"l;"a;"g;0 DIRBAD, "B;"a;"d;" ;"d;"i;"r;"e;"c;"t;"o;"r;"y;0 NOINFL, "N;"o;" ;"i;"n;"p;"u;"t;" ;"f;"i;"l;"e;0 NOHND, "H;"a;"n;"d;"l;"e;"r;" ;"f;"e;"t;"c;"h;" ;"f;"a;"i;"l;"e;"d;0 OS8ERR, "O;"S;"/;"8;" ;"I;"/;"O;"E;"r;"r;"o;"r;0 NORTDV, "C;"a;"n;"n;"o;"t;" ;"s;"p;"e;"c;"i;"f;"y " ;"R;"T;"-;"1;"1;" ;"d;"e;"v;"i;"c;"e;0 FILNAM, "N;"e;"e;"d;" ;"f;"i;"l;"e;" ;"n;"a;"m;"e;0 DEVFUL, "O;"u;"t;" ;"d;"e;"v;" ;"f;"u;"l;"l;0 NOTFND, "F;"i;"l;"e;" ;"n;"o;"t;" ;"f;"o;"u;"n;"d;0 FULLSEG, "S;"e;"g;"m;"e;"n;"t;" ;"f;"u;"l;"l;" "(;"S;"Q;"U;"E;"E;"Z;"E;" ;"f;"l;"o;"p;"p;"y;");0 NOROOM, "N;"o;" ;"r;"o;"o;"m;" ;"o;"n;" "f;"l;"o;"p;"p;"y;0 RXERR, "F;"l;"o;"p;"p;"y;" ;"I;"/;"O;" ;"e;"r;"r;"o;"r;0 OSBIG, "O;"S;"/;"8;" ;"F;"i;"l;"e;" ;"o;"v;"e;"r;"f;"l;"o;"w;0 AREYOU, "Z;"e;"r;"o;"-;"A;"r;"e;" ;"y;"o;"u;" ;"s;"u;"r;"e;"?;0 DEFDV, "D;"S;"K;0 /Default device specs. "T;"T;"Y;0 PAGE DATABF=. *.+3000 /3 RT-11 Blocks. $-$-$-$