; ;Z-DOS Z80 DISK OPERATING SYSTEM ;VERSION 1.1 ; ;WRITTEN BY RALPH E. BUCKNAM ;COPYRIGHT (C) 1979 ;ALL RIGHTS RESERVED ; ; ;EQUATE TABLE ; BDOS EQU 0C106H W.BOOT EQU 0CA03H ; ORG 0B700H ; START JR START2 ;JUMP OVER ROUTINES ; ;MAIN DISK ENTRY POINT TO BDOS ; ;OUTPUT CHARACTER WHICH IS IN ACCUMULATOR ; OUTS LD E,A LD C,2 ;TOKEN FOR OUTPUT JR JBDOS ; ;CHECK FOR KEY PRESS AND INPUT IF PRESSED ; ICHECK LD C,0BH ;TOKEN FOR STATUS CK CALL JBDOS ;CHECK FOR INPUT OR A ;TEST RET Z ;INPUT TO CLEAR BUFFER ; INPUT LD C,1 ;TOKEN FOR INPUT CALL JBDOS ;GET INPUT OR A RET ; F.BDOS LD DE,FCB ;ADR FILE CTRL BLOCK ; JBDOS JP BDOS ; DBUFAD DB 0,0 ;ADDRESS OF DISK BUFFER ; L.END DB 0,0 ;END OF LOAD ; DRIVE DB 0,0 ;STORE DRIVE INFO ; ;SET UP DEFAULT BUFFER ; D.BUF LD DE,(DBUFAD) ;ADDRESS OF DEFAULT BUF ; S.DMA LD C,1AH ;TOKEN TO SET DMA JR JBDOS ;GO TO BDOS ; ;MESSAGE FINDING ROUTINE ; MSGFIND LD DE,MSGTBL-1 ;ADR. OF MESSAGE TABLE M.FIND JR M.TEST ;TEST IF END ; MSLOOP INC DE ;POINT TO CHAR. LD A,(DE) ;GET CHAR RLCA ;TEST OF END MSG JR NC,MSLOOP ;NOT AT END ; M.TEST DJNZ MSLOOP ;MSG. NOT FOUND ; INC DE JR DAT.OUT ;OUTPUT DATA ; DATOUT LD (HL),'$' ;STORE END TOKEN LD DE,(BUFAD) ;GET START OF BUFFER ; DAT.OUT LD C,09 ;TOKEN FOR BUF OUT JR JBDOS ;OUTPUT BUFFER ; CR.LF LD DE,CRLF.0 ;ADDRESS OF MESAGE JR DAT.OUT ;OUTPUT A CR.LF ; BUFAD DB 0,0 ;FIRST HEX ADDRESS ; HEXAD DB 0,0 ; HEXAD2 DB 0,0 ; ;ENTER FROM WARM BOOT - MAKES DISK MAP ; STARTER LD SP,START+0A00H CALL RESET ;MAKE BIT MAP START3 CALL CR.LF ;START WITH A NEW LINE ; ;SETUP BUFFERED INPUT LINE ; START2 LD SP,START+0A00H ;GET A NEW STACK LD HL,END.IT ;PREPAIR FOR RET. JUMP PUSH HL ;RETURN JUMP COMPLETE LD C,19H ;TOKEN FOR PRESSENT DRIVE CALL JBDOS ;GET PRESENT DRIVE ADD 41H ;CONVERT TO LETTER LD DE,MSGTBL ;START OF MESSABE TBL LD (DE),A ;PRESENT DRIVE STORED CALL DAT.OUT ;OUTPUT DATA ; BUFLINE LD C,21H ;TOKEN TO GET ADD OF ;AUXILARY BUFFER CALL JBDOS ;GET POSITION LD (DBUFAD),HL ;STORE ADDRESS OF ;DISK BUFFER LD DE,0080H ;POSITION OFFSET ADD HL,DE ;GET START POSITION EX DE,HL ;LETS PLAY LD HL,0002H ;START OF BUFFER ADD HL,DE ;GET START OF BUFFER LD (BUFAD),HL ;STORE BUFFER ADR. T_ Í··ÈÍ··É ¿ÃÁÚÛ : í[·ïÁ¿0ûù6$í[G· ÖÅ¿÷\Ü  1 ÁÍ:½ÍB·1 Á!sºåÍ·ÆA¿Í>·ø1øø1øÀøô÷ ŽÓ¤ÇD A,7FH ;LENGHT OF BUFFER LD (HL),A ;START OF BUFFER ; LD C,0AH ;INPUT BUFLINE TOKEN CALL JBDOS ; POP HL ;GET POSITION DEC HL ;POINT TO # OF CHARS. LD B,(HL) ;GET COUNT OF CHAR INC B ;ONE BEOND END ; Z.LOOP INC HL ;HEAD FOR POSITION DJNZ Z.LOOP ;NOT THERE ; XOR A LD (HL),A ;SET END OF BUFFER CALL D.BUF ;SETUP DEFALT BUFFER CALL CR.LF ;GET A NEW LINE ; ;CHECK FOR DRIVE CHANGE ; LD A,(IX+00) ;GET FIRST BYTE CP 00H ;TEST FOR NO ENTRIES JR Z,START2 ;SUPER NO NO!!!!!!! LD A,':' ;GET DRIVE CHAR. CP (IX+01) ;TEST IF CHANGE LD (DRIVE),A ;SAVE NO DRIVE TOKEN CALL Z,D.SW.1 ;SWITCH IF NECCESARY ; ;FIND COMMAND ROUTINE ; LD B,0 ;ZERO TOKEN COUNTER PUSH IX ;START TRANSFER POP HL ;END TRANSFER LD IY,CNAMES ;COMMAND NAMES ; F.LOOP LD A,(IY+00) ;GET ASCII BYTE OR A ;TEST FOR END TABLE JP Z,RUNS ;END OF TABLE AND 7FH ;STRIP HIGH BYTE XOR (HL) ;TEST FOR MATCH JR NZ,NO.MATCH ;SETUP FOR NEXT TEST BIT 7,(IY+00) ;TEST FOR END NAME JR NZ,FOUND INC HL ;NEXT POSITION INC IY JR F.LOOP ;TRY NEXT BYTE ; NO.MATC INC B ;NEXT TOKNE PUSH IX ;START OVER AGAIN POP HL JR NX.NAME ;FIND NEXT NAME ; N.LOOP INC IY ; NX.NAME BIT 7,(IY+00) ;TEST FOR END JR Z,N.LOOP ;NOT END OF NAME ; INC IY ;START OF NAME JR F.LOOP ;TRY AGAIN ; ;VICTOR TO COMMAND ; FOUND INC HL ;NEXT CHARACTER PUSH HL ;TRANSFER POP IX ;COMPLETE CALL F.START ;REMOVE SPACES LD HL,CMDTBL ;ADDRESS OF COMD TABLE LD C,B ;TRANSFER TOKEN LD B,0 ADD HL,BC ADD HL,BC LD E,(HL) ;GET LOW BYTE INC HL LD H,(HL) ;GET HIGH BYTE LD L,E ;READY FOR VICTOR JP (HL) ;OFF TO WORK ; ;DRIVE SWITCH NO. 1 ; D.SW.1 LD C,19H CALL JBDOS LD B,A ;SAVE PRESENT DRIVE LD A,(IX+00) ;GET NEW DRIVE CP 'A' ;LESS THAN [ A ]? JP C,SYNTAX ;ILLEGAL CP 'C' ;GREATER THAN [ B ]? JP NC,SYNTAX ;ILLEGAL INC IX INC IX SUB 41H ;CONVERT TO D. NUMBER CP B ;TEST IF SAME RET Z ;NO DRIVE CHANGE LD E,A ;SETUP FOR DRIVE CHANGE LD A,B ;GET OLD DRIVE LD (DRIVE),A ;STORE OLD DRIVE ; SWDRIVE LD C,0EH ;TOKEN FOR DRIVE CHANGE CALL JBDOS ;SWITCH DRIVES RET ; ;DRIVE SWITCH NO 2 ; D.SW.2 LD A,(DRIVE) ;GET DRIVE INFO CP ':' RET Z ;NO DRIVE CHANGE LD E,A ;TRANSFER DRIVE INFO JR SWDRIVE ;SWITCH DRIVE ; ;SAVE DISK FILE COMMANDS - ********** ; ;SAVE COMMAND ; SAVE CALL C.VERT ;GET NUMBER OF PAGES EX DE,HL ADD HL,HL ;X2 ADD HL,HL ;X4 ADD HL,HL ;X8 ADD HL,HL ;X16 ADD HL,HL ;X32 ADD HL,HL ;X64 ADD HL,HL ;X128 ADD HL,HL ;X256 ; LD A,H OR L ;TEST FOR ZERO JP Z,SYNTAX ;NO GOOD PUSH HL ;SAVE PROGRAM LENGTH CALL X.FCB ;MAKE FCB CALL F.START ;REMOVE EXTRA SPACES POP DE LD HL,(HEXAD) ;START OF READ ADD HL,DE ;LENGTH OF READ LD (HEXAD2),HL ;STORE JR SAVE.X ;PUT PROGRAM ON DISK ; ;HEX SAVE COMMAND ; HSAVE CALL X.FCB ;MAKE UP FCB CALL C.HEX ;GET HEX START ADR ; SSAVE2 LD A,H OR L ;TEST IF NUMBER EXISTS JP Z,SYNTAX ;NO GOOD INC HL ;ADVANCE TO CORECT LD (HEXAD2),HL ;STORE END ADDRESS OR A ;CLEAR CARRY FLAG LD DE,(HEXAD) ;GET START SBC HL,DE ;CHECK OUT INFO JP C,SYNTAX ;NO GOOD JR SAVE.X ;SAVE THE FILE ; ;SPECIFIC SAVE COMMAND ; SSAVE CALL X.FCB ;MAKE UP FCB CALL C.HEX ;GET START ADDRESS EX DE,HL ;EXCHANGE CALL C.HEX ;GET END ADDRESS LD (HEXAD),DE ;STORE START JR SSAVE2 ;FINISH ELSEWHARE ; ;RESAVE COMMAND ; RSAVE XOR A ;GET A ZERO LD (FCB+12),A ;SET EXTENTS TO ZERO LD HL,(L.END) ;GET END ADDRESS LD A,H OR L ;TEST IF USED JP Z,SYNTAX LD (HEXAD2),HL ;SET END ADDRESS LD DE,FCB+13 ;END OF NAME LD B,21 ;CHARS TO ZERO OUT XOR A ;GET A ZERO CALL FILLS ;ZERO OUT UNWANTED CALL SAVE.X ;SAVE FILE JP RESET2 ;DESTROY FILE LENGTH RET ; ;LOADS MEMORY ON THE ASSIGNED DISK ; SAVE.X CALL D.BUF ;SETUP DEFALUT BUFFER ; ;CALCULATE NUMBER OF SECTORS IN FILE ; LD DE,(HEXAD) ;START OF FILE LD HL,(HEXAD2) ;END OF FILE CALL SECTORS ;GET SECTOR INFO ; ;SETUP TO WRITE SECTOR ; LD DE,80H ;SECTOR LENGTH LD HL,(HEXAD) ;START OF SAVE PUSH HL ;FIRST DMA ADDRESS EXX ;HIDE DATA ;BLOCK LD C,13H ;TOKEN FOR DELETE FILE CALL F.BDOS ;KILL OLD FILE IF IT ;EXISTED LD C,16H ;TOKEN FOR CREATE FILE CALL F.BDOS ;CREATE FILE CP 0FFH ;TEST FOR ERROR JP Z,N.DIRS ;NO DIRECTORY SPACE CALL F.OPEN ;OPEN FILE JR WRIT.3 ;WRITE FIRST SECTOR ; ;WRITE SECTOR LOOP - WRITES SECTORS TILL DONE ; WRIT.2 EXX ;GET FILE INFO DEC BC ;REDUCE SECTOR COUNT LD A,B ;START END CHECK OR C ;TEST FOR END JR Z,WRIT.4 ;WRITING IS DONE ADD HL,DE ;NEXT DMA PUSH HL ;READY FOR TRANSFER EXX ;HIDE DATA AGAIN ; WRIT.3 POP DE ;GET DMA ADDRESS LD C,1AH ;TOKEN TO SET DMA CALL BDOS ;SET DMA ADDRESS LD C,15H ;TOKEN FOR WRITE RECORD LD DE,FCB ;POINT TO FCB CALL BDOS ;WRITE RECORD OR A ;TEST FOR ERROR JP Z,WRIT.2 ;CONINUE WRITING ; DEC A ;TEST FOR NO DIRECTORY ;SPACE JP Z,N.DIRS ;ERROR OCCURED JP D.FULL ;DISK FULL ; ;CLOSE FILE ROUTINE ; WRIT.4 CALL D.BUF ;SET DEFAULT BUFFER LD C,10H ;TOKEN TO CLOSE FILE CALL F.BDOS ;CLOSE FILE INC A ;TEST FOR ERROR JP Z,CL.ERR ;CLOSE ERROR HAS OCCURED ;TERMINATE ROUTINE RET ;END OF ROUTINE ; ; ;READ DISK FILE COMMANDS - ********** ; RUNS PUSH HL ;START TRANSFER POP IX ;TRANSFER COMPLETE ; ;CHECK FOR PERMANENT DRIVE CHANGE ; LD HL,(BUFAD) ;GET START OF BUFFER DEC HL ;BACK UP LD A,(HL) ;HOW MANY ENTRIES CP 3 JR NC,RUNS.X ;NOT DRIVE CHAR INC HL INC HL LD A,(HL) ;GET CHAR CP ':' ;TEST FOR COLON JP Z,START2 ;WAS JUST DRIVE CHANGE ; ;SETUP TO READ FILE ; RUNS.X CALL RUNS.2 ;DO THE WORK RUNS.3 CALL D.SW.2 ;SWITCH DRIVE IF NEC. LD DE,80H ;DEFALT BUFFER PUSH DE CALL S.DMA ;SET DMA POP BC LD A,B ;CHEAP ZEROS LD D,A LD E,A LD H,A LD L,A CALL 0100H ;GO TO PROGRAM JP START3 ;RESTART Z-DOS JP START2 ; RUNS.2 CALL RESET2 ;RESET STARTS CALL M.FCB ;MAKE FIRST PART FCB CP '.' ;NOT PEROIDS JP Z,SYNTAX CALL LOAD.X ;READ THE DISK LD A,(FCB+15) ;GET EXTENT SIZE PUSH AF ;SAVE CALL LD.GO2 ;TRANSFER INFO POP AF ;RETREIVE DATA LD (5CH+15),A ;STORE INFO RET ; ; ;COM COMMAND ; COM CALL RUNS.2 ;DO THE WORK LD B,8 ;TOKEN FOR MSG CALL MSGFIND ;OUTPUT MESSAGE CALL INPUT ;GET DECISION CP 'Y' ;TEST IF RUN PUSH AF CALL CR.LF ;GET A NEW LINE POP AF JR Z,RUNS.3 ;GO TO PROGRAM RET ; ;LOAD COMMAND ; LOAD CALL X.FCB ;SETUP FCB ; LOAD.2 CALL LOAD.X ;READ FILE LD C,20H ;TOKEN TO GET DMA CALL JBDOS ;GET START OF LAST DMA DEC HL ;BACK 1 LD (L.END),HL ;STORE END OF LOAD L.BYTE PUSH HL LD B,0EH ;TOKEN FOR MSG CALL MSGFIND ;OUTPUT MESSAGE POP HL CALL ADOUT ;OUTPUT ADDRESS CALL CR.LF ;GET NEW LINE RET ; ;LOAD SPECIFIC COMMAND ; SLOAD CALL X.FCB ;SETUP FCB JP NZ,SYNTAX ;MUST BE A SPACE CALL C.HEX ;GET FIRST ADDRESS LD (HEXAD),HL ;STORE START ADDRESS JR LOAD.2 ;FINISH UP ELSEWHARE ; ;FIND MAX SECTORS OF LOAD ; LOAD.X LD DE,START ;THE LIMIT OF LOAD LD HL,0FF50H ;BACKUP FACTOR ADD HL,DE ;STOP LOAD HERE LD DE,(HEXAD) ;START OF LOAD CALL SECTORS ;GET SECTOR INFO LD A,B OR C ;TEST FOR ZERO JP Z,N.SPACE ; ;SETUP TO READ SECTOR ; LD DE,80H ;SECTOR LENGTH LD HL,(HEXAD) ;START OF LOAD EXX ;HIDE DATA LD HL,(HEXAD) ;GET DMA ADDRESS. PUSH HL ;HIDE ADDRESS CALL F.OPEN ;OPEN FILE JR READ.3 ;START READING ; ;READ SECTOR LOOP - READ TILL DONE ; READ.2 EXX ;GET DRIVE INFO DEC BC ;ONE LESS SECTOR LD A,B ;TO FAR TEST OR C ;TEST JP Z,N.SPACE ;TO FAR ERROR ADD HL,DE ;NEW DMA ADDRESS PUSH HL ;TRANSFER DAM ADDR. EXX ;HIDE DATA ; READ.3 POP DE ;GET DMA ADDR LD C,1AH ;TOKEN FOR SET DMA CALL BDOS ;SET DMA ADDRESS LD C,14H ;TOKEN FOR READ SECTOR LD DE,FCB ;POINT TO FCB CALL BDOS ;READ FILE DEC A ;TEST FOR END JP NZ,READ.2 ;CONTINUE READING ; RET ;END OF READ ROUTINE ; ;TRANSFER DATA TO HOST PROGRAM AFTER A LOAD GO ;FILE HAS BEEN LOADED ; LD.GO2 LD HL,5CH ;START OF DEFAULT BUFF CALL I.FCB ;INITILIZE FIRST FCB LD HL,6CH ;START OF SECOND D. FCB CALL I.FCB ;INITILIZE SECOND FCB ; ;TRANSFER REMAING INFO INTO 80H BUFFER ; PUSH IX POP IY ;TRANSFER START LD HL,80H ;ADR WHERE BUFFER ;COUNT GOES LD DE,81H ;FIRST CHARE GOES HERE LD B,0 ;BYTE COUNTER LD A,(IY+00) ;GET CHAR OR A ;TEST RET Z ;NO DATA ; TRANS LD A,(IY+00) ;GET CHAR INC IY ;NEXT CHAR OR A LD (DE),A ;STORE CHAR. JR Z,LD.GO3 ;END OF LINE INC DE ;NEXT STORE INC B ;INCER LINE LENGTH JR TRANS ;MORE TO GO ; LD.GO3 INC DE ;2 [ 00 ] FOR END XOR A ;END OF DATA LD (DE),A INC DE LD (DE),A LD (HL),B ;STORE LINE LENGTH LD A,5 ;SETUP FOR ERROR BYTE LD (E.BYTE),A ;SETUP TO RETUR HERE ;ON A ERROR EXX ;GET ON BACK SIDE LD DE,5CH ;START OF DEFALUT FCB EXX DB 0FDH,2EH,02 ; [ LD Y',2 ] ;MAKE TWO LOOPS ; ;MAKE FCB FOR HOAST AND TRANSFER TO DEFAULT ;BUFFER IF COMMAND LINE IS OK ; LD.GO4 LD HL,FCB ;START OF FCB CALL I.FCB ;INITILIZE FCB CALL F.START ;REMOVE SPACES LD A,(IX+01) ;A [ : ] ? CP ':' ;TEST JR NZ,LD.GO5 ;NO DRIVE CHANGE LD A,(IX+00) ;GET CHARICTOR SUB '@' ;CONVERT LD (FCB),A ;STORE DRIVE CHANGE INC IX INC IX ; LD.GO5 CALL M.FCB1 ;MAKE FIRST PART CP 0FFH ;TEST JR Z,LD.GO6 CP '.' ;TEST FOR PEROID JR NZ,LD.GO6 ;NO GOOD CALL M.FCB3 ;FINISH FCB CP 0FFH ;TEST JR Z,LD.GO6 ;NO GOOD ; ;TRANSFER FILE CONTROL BLOCK ; EXX ;RECOVER TRANSFER INFO LD HL,FCB ;START OF TRANSFER LD BC,16 ;BYTES TO BE TFER. LDIR ;TRANSFER FCB EXX ;HIDE INFO DB 0FDH,2DH ;DEC Y' JR NZ,LD.GO4 ;MORE TO GO ; RET ;DONE ; LD.GO6 EXX LD A,(FCB) ;GET DRIVE INFO LD (DE),A ;STORE DRIVE INFO RET ; ; ;ERASE DISK FILE COMMANDS - ********** ; ;DESTROY ALL FILES COMMAND ; DESTROY LD HL,FCB CALL I.FCB ;INITILIZE FCB LD DE,FCB+1 ;START INFO LD B,11 ;11 [ ? ] CALL WILDS ;PLACE THOES [ ? ] JR ERA.2 ;DESTROY ALL FILES ; ERA CALL X.FCB ;MAKE UP FCB ; ERA.2 CALL RESET2 CALL F.FILE ;FIND FILE AND ;SWITCH DRIVES IF NEC. ; LD C,13H ;TOKEN FOR DELETE CALL F.BDOS ;KILL FILE JR END.IT ; ;FINED DISK FILE ON SPECIFIED DISK DRIVE ; F.FILE LD C,11H ;TOKEN FOR FIND FILE CALL F.BDOS ;FIND FILE CP 0FFH ;TEST IF FOUND RET NZ ;FILE HAS BEEN FOUND. ; ;DISK ERROR ROUTINES ; N.FIND LD B,03 ;TOKNE, FILE NOT FOUND DB 21H ; N.SPACE LD B,07 ;TOKEN NO LOAD ROOM DB 21H ; CL.ERR LD B,0CH ;TOKEN, CAN'T CLOSE FILE DB 21H ; SYNTAX LD B,04 ;SYNTAX ERROR TOKEN DB 21H ; N.DIRS LD B,05 ;NO DIRECTORY SPACE DB 21H ; D.FULL LD B,06 ;TOKEN FOR DISK FULL DB 21H ; CX.ERR LD B,0FH ;TOKEN FOR CKSUM ERROR DB 21H ; F.EXIS LD B,09 ;FILE EXISTS TOKEN ; CALL MSGFIND ;OUTPUT ERROR END.IT CALL D.SW.2 ;SWITCH DRIVES IF REQ. LD B,2 ;TOKEN FOR CRLF CALL MSGFIND ;GET A NEW LINE JP START ;START OVER AGAIN ; ;OPEN FILE ROUTINE ; F.OPEN LD C,0FH ;TOKEN TO OPEN FILLE CALL F.BDOS ;OPEN FILE INC A ;TEST IF FOUND RET NZ ;FOUND JR N.FIND ;FILE NOT FOUND ; ; ;DIRECTORY COMMAND - ********** ; DIR CALL FCBX.0 ;SET UP COMMAND LINE CALL RESET2 LD A,'?' ;GET A QUESTION MARK LD (FCB+12),A ;MAKE EXTENT WILD LD DE,FCB+1 ;START OF FILE NAME LD A,(IX+00) ;GET FIRST CHAR CP 0 ;TEST FOR END CMD LINE JR Z,W.CARD ;SET FOR WILD CARD CP '*' ;TEST FOR * LD B,8 ;8 ? IN CASE PUSH AF ;FOX AND GOOS CALL Z,WILDS ;MAKE NAME WILD POP AF CALL NZ,M.FCB1 ;TRANSFER FIL NAME LD A,(IX+00) ;GET INST. BYTE CP 0 ;TEST FOR END LD A,(IX+01) ;GET NEXT CHAR ;FILE TYPE IF NEC. JR Z,SYNTAX ;NO GOOD JR Z,W.TEST ;TEST FOR WILD CARD CP '*' ;TEST FOR WILD CARD PUSH AF ;PLAY FOX AND GOOSE LD B,3 ;3 ? INCASE CALL Z,WILDS2 ;MAKE TYPE WILD POP AF CALL NZ,M.FCB3 ;TRANSFER FILE TYPE LD A,'?' ;SETUP FOR WILD CARD LD B,11 ;TEST 11 TIMES LD HL,FCB+1 ;START OF NAME ; W.TEST CP (HL) ;TEST FOR WILD CARD INC HL JR Z,T.MAKE ;MAKE TABLE DJNZ W.TEST ;MORE BYTES TO TEST ; JP F.INFO ;GET FILE INFOR ; W.CARD LD B,12 ;MAKE 12 ? CALL WILDS ; ;FIND DIRECTORY INFOMATION AND OUTPUT DISK DATA ; T.MAKE CALL F.FILE ;FINE DISK FILE ON ;SPECIFIED DRIVE DB 0FDH,2EH,3 ; [LD X',3 ] SET ;LINE LENGTH ; ;T.LOOP ROUTINE FINDS AND OUTPUTS ONE DIRECTORY ;BLOCK ; D.LOOP LD HL,(DBUFAD) ;ADDRESS OF BUFFER INC HL ;START OF NAMES LD DE,20H ;SPACE PER DIRECTORY AND 3 ;GET OFSET FACTOR CP 0 ;TEST FOR NO OFFSET JR Z,DIR.2 ;NO OFSET LD B,A ; ;CALCULATE OFFSET IN DISK BUFFER ; O.LOOP ADD HL,DE DJNZ O.LOOP ; ;TRANSFER NAME TO OUTPUT BUFFER ; DIR.2 LD DE,(BUFAD) ;START OF TRANSFER EX DE,HL LD BC,0820H ;B = 8 TIMES, C = ' ' LD (HL),C ;STORE A SPACE INC HL ; ;DETERMINE POSITION IN OUTPUT BUFFER IF START ;OUTPUT A SPACE. IF NOT START OUTPUT [ | ] ; DB 0FDH,7DH ;[ LD A,X' ] ;GET POSITION CP 3 ;TEST POSITION LD A,'|' JR NZ,SID ;OUTPUT | LD A,C ;OUTPUT ' ' ; SID LD (HL),A ;STORE CHAR. INC HL LD (HL),C ;SPACE INC HL ; ;TRANSFER NAME ; CALL ZNLOOP ;TRANSFER NAME LD (HL),'.' ;STORE A SEPERATOR INC HL LD B,3 ; ;TRANSFER FILE TYPE ; CALL ZNLOOP ;TRANSFER F. TYPE ; ;GET EXTENT BYTE AND OUTPUT SPACES IF 0 ELSE ;OUTPUT EXTENT NUMBER IN ONE DIGIT HEX. ; LD A,(DE) ;GET EXTENT BYTE CP 0 ;TEST FOR EXTENT JR Z,N.EXT ;NO EXTENT LD (HL),'+' ;STORE A [ + ] INC HL LD A,(DE) ;GET EXTEND BYTE CALL CHASE ;CONVERT STORE JR SIZE ; N.EXT LD (HL),C ;SPACE INC HL LD (HL),C ;SPACE INC HL ; ;CALCULATE NUMBER OF KILOBYTES IN THE EXTENT. THEN ;PRINT OUT THE OUTPUT BUFFER ; SIZE INC DE ;GET IN POSITION INC DE INC DE LD A,(DE) ;GET BYTE LD B,A ;MOVE FOR PROCESSING SRL B SRL B SRL B ;CONVERT TO KILOBYTES AND 7 ;TEST FOR ADVANCE JR Z,N.ADVAN ;NO ADVANCE INC B ;INCREASE BY ONE ; N.ADVAN LD A,B CALL G.NUM ;CONVERT TO DECIMAL CALL DATOUT ;OUTPUT DATA ; ;CHECK LINE POSITION AND OUTPUT A CR.LF IF END ;OF LINE IS REACHED ; DB 0FDH ,2DH ;[ DEC Y' ] TEST FOR ;END OF LINE JR NZ,N.CRLF ;NOT AT END OF LINE DB 0FDH,2EH,3 ;RESET LINE LENGTH CALL CR.LF ;GET A NEW LINE ; ;FIND NEXT DIRECTORY ENTRY AND LOOP AGAIN ; N.CRLF LD C,12H ;TOKEN CALL F.BDOS ;GET INFO CP 0FFH ;TEST IF FOUND JR NZ,D.LOOP ;MORE DIRECTORY TO ;WORK ; ;CALCULATE NUMBER OF REMAING FREE KILLOBYTES ;ON DISK AND OUTPUT THE DATE ; DB 0FDH,2CH ;[ INC Y' ] DB 0FDH,2DH ;[ DEC Y' ] TEST FOR ;ZERO CALL NZ,CR.LF ;OUTPUT REMAINING ;TABLE DATE CALL CR.LF LD B,0AH ;MESSAGE TOKEN CALL MSGFIND ;OUTPUT MESSAGE LD C,19H ;TOKEN FOR GETTING DRIVE CALL JBDOS ;GET DRIVE NO ADD 41H ;CONVERT TO ASCII LD HL,(BUFAD) ;OUTPUT BUFFER LD (HL),A ;STORE DRIVE NO INC HL LD (HL),':' ;STORE [ : ] INC HL LD (HL),' ' INC HL PUSH HL ;SAVE BUFFER POSITION ; ;FIND BIT MAP AND CALCULATE NO OF USED CLUSTERS ; LD C,1BH ;TOKEN FOR BIT MAP ADR. CALL JBDOS ;GET ADDRESS LD BC,2000H ;32 BYTES; 0 SECTORS ; ;CALCULATE SECTORS USED ; S.LOOP LD D,8 ;8 CLUSTERS PER BYTE LD A,(HL) ;GET BITE BYTE INC HL ;POINT TO NEXT BYTE ; B.LOOP RLCA ;CARRY IF CLUSTER IS ;USED JR NC,N.USE ;NOT USED INC C ;ADD 1 TO CLUSTER COUNT ; N.USE DEC D ;ONE LES BIT TO CHECK JR NZ,B.LOOP ;MORE BITS TO CHECK ; DJNZ S.LOOP ;MORE BYTES TO CHECK ; ;GET MAX HEX SECTORS ; LD HL,BDOS ;GET ADDRESS LD L,3EH ;POINT TO MAX SECTORS LD A,(HL) ;GET MAX SECTORS INC A ;TOTAL NUM. OF CLUSTERS ;AVAILABLE ON DISK SUB C ;SUBTRACT USED CLUSTERS POP HL ;GET BUFFER POSITION GNUMS CALL G.NUM ;GET DECIMAL NUMBER ;AND STORE INFO. LD (HL),'K' ;GET A 'K' FOR KBYTES INC HL CALL DATOUT ;OUTPUT DATA CALL CR.LF ;TEMIMNATE LINE JP END.IT ;END OF ROUTINE ; ;CONVERT HEXADECIMAL ACCUMULATOR TO DECIMAL ;NUMBER AND STORE ; G.NUM PUSH HL ;SAVE START LD BC,0230H ;3 DIGITS, ASCII [ 0 ] LD D,C ;TRANSFER THAT 30H ; G.NUM2 CP 100 ;TEST FOR 100 DEC. JR C,G.NUM3 ;TO SMALL INC D ;ADVANCE BY 100 SUB 100 ;SUBTRACT 100 DEC. JR G.NUM2 ;TRY AGAIN ; G.NUM3 LD (HL),D ;STORE COUNT INC HL LD D,C ;TRANSFER 30H ; G.NUM4 CP 10 ;TEST FOR 10 DECIMAL JR C,G.NUM5 ;NO 10'S INC D ;ADVANCE COUNT SUB 10 ;SUBTRACT 10 DECIMAL JR G.NUM4 ; G.NUM5 LD (HL),D ;STORE NUMBER INC HL OR C ;CONVERT TO NUMBER LD (HL),A ;STORE NUMBER INC HL EX (SP),HL ;STORE END POSITION ; ;FILL LEADING ZEROS WITH SPACES ; G.NUM6 LD A,30H ;LOAD A ASCII ZERO CP (HL) ;TEST IF ZERO JR NZ,G.NUM7 ;NO MORE FILL LD (HL),' ' ;REPLACE WITH SPACE INC HL DJNZ G.NUM6 ;TRY NEXT DIGIT ; G.NUM7 POP HL ;RETREIVE END POSITION RET ; ;CONVERT HEX DIGIT TO ASCII CHARACTER ; CHASE AND 0FH ;STRIP OFF UPER ADD 30H ;MAKE INTO ASCII CP 3AH ;TEST FOR LETTER JR C,CHASE2 ;NO LETTER ADD 7 ;CONVERT TO LETTER ; CHASE2 LD (HL),A ;STORE DIGIT INC HL RET ; ZNLOOP LD A,(DE) ;GET CHAR CP '$' ;TEST FOR TROUBLES JR NZ,DLX ;NO TROUBLES LD A,';' ;CHANGE CHARACTER DLX LD (HL),A ;STORE CHAR INC HL ;NEXT POSITION INC DE DJNZ ZNLOOP ;MORE TO TRANSFER ; RET ; ;PRINT INFOMATION ABOUT DISK FILE ; F.INFO CALL F.FILE ;FIND DISK FILE ON ;DRIVE SPECIFIED ; LD C,0 ;ZERO FILE SIZE PUSH BC ;HIDE ; ;POINT TO WHERE CLUSTER NUMBERS START AND ;COUNT CLUSTERS IN EXTENT ; INFLOOP LD HL,(DBUFAD) ;ADDRESS OF BUFFER LD DE,10H ;OFFSET ADD HL,DE ;START OF NAMES LD DE,20H ;STEP VALUE AND 3 ;STRIP UPPERS JR Z,F.INF5 ;NO ADVANCE LD B,A ;SET FOR DJNZ ; F.INF4 ADD HL,DE ;ADVANCE POINTER DJNZ F.INF4 ;KEEP ADVANCING ; ;TEST FOR USED CLUSTERS ; F.INF5 XOR A ;TEST CHARACTER POP BC ;RETREIVE CLUSTER USED LD B,10H ;16 TRIES ; F.INF6 CP (HL) ;TEST IF USED JR Z,F.INF7 ;END OF CLUSTERS INC HL INC C ;ADVANCE CLUSTER COUNT DJNZ F.INF6 ;KEEP TESTING ; ;CHECK IF THERE IS A NOTHER EXTENT ; F.INF7 PUSH BC ;SAVE COUNT LD C,12H ;TOKEN FOR FIND NEXT CALL F.BDOS ;GET INFO CP 0FFH ;TEST FOR EXISTANCE JR NZ,INFLOOP ;KEEP COUNTING ; ;PRINT OUT MESSAGE AND PROCESS DATA ; CALL CR.LF ;GET A NEW LINE LD B,0BH ;MESSAGE TOKEN CALL MSGFIND ;OUTPUT MESSAGE POP BC ;RETREIVE COUNT LD A,C ;TRANSFER COUNT LD HL,(BUFAD) JP GNUMS ;CONTINUE ELSE WHERE ; ; ;RENAME COMMAND - *********** ; RENAME CALL X.FCB ;MAKE UP FILE CONTROL ;BLOCK CP '=' ;MUST BE A EQUAL SIGN JP NZ,SYNTAX ; ;FIND IF FILE EXISTS ; LD C,11H CALL F.BDOS INC A ;TEST IF FOUND JP NZ,F.EXIS ;FILE EXISTS ; LD BC,10H ;BYTES TO MOVE LD HL,FCB ;START OF FCB LD DE,FCB+10H ;WHERE TO PLACE NAME LDIR ;MOVE PRESENT FILE NAME ; LD B,11 ;NO OF SPACE REQ LD A,' ' ;FILL DATA LD DE,FCB+1 ;WHERE TO START CALL FILLS ;FILL WITH SPACES ; CALL F.START ;GET START OR A ;TEST FOR END JP Z,SYNTAX CALL M.FCB1 ;MAKE PART ONE FCB CP '.' ;TEST JP NZ,SYNTAX CALL M.FCB3 ;FINISH FILE CTRL BLK. ; CALL F.FILE ;FIND IF FILE EXISTS LD C,17H ;TOKEN FOR RENAME FILE CALL F.BDOS ;RENAME FILE JP END.IT ;END OF COMMAND ; ; ;TYPE OUT ASCII FILE FROM LINE X TO LINE Y ; TYPE CALL X.FCB ;MAKE UP FILE CONTROL ;BLOCK AND TEST FOR ' ' JP NZ,SYNTAX ;NO GOOD ; ;ZERO OUT BUFFERS ; XOR A ;GET A ZERO LD B,4 ;4 SPACES LD HL,HEXAD CALL FILLS ;PLACE ZEROS IN HEXADS LD HL,0100H ;START OF SAVE LD (L.END),HL ; CALL C.VERT ;CONVERT DECIMAL NO. DEC DE ;ONE LESS LD (HEXAD),DE ;STORE WHERE TO START ;PRINTING CALL C.VERT ;GET SECOND NUMBER LD (HEXAD2),DE ;STORE BYTES TO BE ;PRINTED LD A,E OR D ;TEST FOR NUMBER JP Z,SYNTAX ;NO GOOD ; ;ZERO OUT LINE COUNTER ; LD HL,N.MSG LD B,4 LD A,30H ; Z.COUNT LD (HL),A ;PLACE A ASCII ZERO INC HL DJNZ Z.COUNT ;KEEP GOINT ; LD (HL),31H ;START AT ONE ; ;SET UP TO READ FILE ; LD B,0FEH ;TOKEN FOR NO PRINT LD DE,(HEXAD) ;GET NO. OF NO PRINTS LD A,E OR D ;TEST FOR ZERO JR NZ,NPRIN2 ;NO PRINT ; ;PRINT AT START OF FILE ; EX DE,HL ;GET ZEROWED REG IN HL DEC HL ;MAKE 0FFFFH LD B,03 ;TOKEN FOR PRINT LD DE,(HEXAD2) ;GET COUNT LD (HEXAD2),HL ;STORE END FLAG ; ;SET UP FOR OUTPUT CYCLE ; NPRIN2 EXX ;HIDE DATA CALL B.OPEN ;OPEN FILE SETUP BYTER ; ;OUTPUT CHARACTER AND SWITCHING ROUTINES ; TYPE.4 CALL BYTER ;GET CHARACTER CP 1AH ;TEST FOR END JR Z,ENDER ;END OF ROUTINE OR A ;TEST FOR NON ASCII JP M,T.END EXX ;GET HIDDEN RREGS CP B PUSH AF ;SAVE OUTPUT BYTE CP 0AH ;TEST FOR LINE FEED JR NZ,TYPE.5 ;DONOT INCREASE LINE NO. CALL A.CNT ;ADVANCE COUNT INC B ;FLAG FOR POSSABLE OUTPUT ;OF LINE NUMBER DEC DE LD A,E ;GET READY FOR OR D ;END OF MODE JR NZ,OUT.IT ;NOT END LD B,03 ;SET FOR OUTPUT LD DE,(HEXAD2) ;GET OUTPUT BYTE LD HL,0FFFFH ;END CHAR LD (HEXAD2),HL ;STORE END INC HL INC HL ;SET HL TO 1 ADD HL,DE ;TEST FOR END ROUTINE JR C,ENDER JR OUT.IT ;MAYBE? ; ;TEST FOR LINE NUMBER OUTPUT ; TYPE.5 BIT 0,B ;TEST IF LINE NUMBER ;OUTPUT JR Z,OUT.IT ;NO LINE NO. TEST DEC B ;CLEAR TEST FLAG BIT 7,B ;TEST FOR OUTPUT JR NZ,OUT.IT ;NO OUTPUT FLAG SET EXX ;HIDE DATA LD B,0DH ;OUTPUT NUMBERS CALL MSGFIND ;OUT LINE NUMBER EXX ;HIDE DATA ; OUT.IT EXX ;HIDE DATA POP AF JR C,XCHECK ;NO OUTPUT OR STORE LD DE,(L.END) ;PICK UP POINTER LD (DE),A ;STORE BYTE LD HL,START-32 ;END OF LOAD EX AF,AF' LD A,H ;START OF 16 BIT CPL ;COMPLEMENT LD H,A LD A,L CPL LD L,A EX AF,AF' INC HL ;COMPLEMENT DONE ADD HL,DE ;TEST IF TO FAR JR C,NO.INC ;DO NOT INC DE REG INC DE ; NO.INC LD (L.END),DE ;STORE POINTER CALL OUTS ;OUTPUT DATA ; XCHECK CALL ICHECK ;TEST FOR A INPUT JP NZ,END.IT ;SIGN TO STOP JR TYPE.4 ;CONTINUE ; ;END TYPE ROUTINE ; ENDER LD HL,(L.END) ;PICK UP POINTER LD C,0AH ;GET A LINE FEED IN C LD (HL),C ;STORE THAT LINE FEED INC HL LD BC,101AH ;16 POKES OF EOF CHAR ; E.LOOP LD (HL),C ;STORE EOF CHARS 1AH INC HL DJNZ E.LOOP ; PUSH HL CALL CR.LF ;GET A NEW LINE POP HL CALL L.BYTE ;OUTPUT END ADDRESS ; T.END CALL RESET ;DISINABLE RESAVE JP END.IT ; ;GO COMMAND - *********** ; GO CALL C.HEX ;GET HEX ADDRESS LD DE,BDOS ;ADDRESS BDOS INPUTS LD BC,W.BOOT ;WHERE TO RESET Z-DOS JP (HL) ;GO TO ASSIGNED ADDRESS ; ;RESET ZDOS, SELECT DRIVE A ; RESET LD C,0DH ;TOKEN FOR RESET JP JBDOS ;RESET SYSTEM ; ; ;HEX DISK LOADER ROUTINE ; HEX CALL RESET2 ;GET ZEROS IN HEXAD2 CALL M.FCB ;SET UP FIRST PART OF ;FILE CONTROL BLOCK CP '.' ;TEST FOR PERIOD JP Z,SYNTAX CP 0 ;TEST FOR END JR Z,HEX.2 ;NO OFFSET ; ;SETUP OFSET ; CALL C.HEX ;GET RUN ADD LD A,L CPL LD E,A LD A,H CPL LD D,A INC DE ;16 BIT COMPLEMT DONE CALL C.HEX ;GET LOAD ADD ADD HL,DE ;FOUND OFFSET LD (HEXAD2),HL ;STORE OFFSET ; ;SETUP FILE TYPE HEX ; HEX.2 LD HL,FCB+9 ;FILE TYPE STARTS HERE LD (HL),'H' ;'HEX' FILE TYPE INC HL LD (HL),'E' INC HL LD (HL),'X' ; CALL B.OPEN ;OPEN FILE FOR BYTER JR LOOP1 ;GO TO LOADER ROUTINE ; ;BYTER ROUTINE - GETS INFO FROM DISK AND KEEPS ;TRACK OF THE SUPPLY OF BYTES ; BYTER DB 0FDH,2DH ;DEC Y' DEC BUF SIZE JR Z,BYTER2 ;NO MORE DATA LD A,(IX+00) ;GET CHAR. INC IX RET ; BYTER2 LD IX,(DBUFAD) ;GET START OF BUFFER DB 0FDH,6CH ;RESET BUFFER SIZE ;LD Y',Y LD C,14H ;TOKEN FOR READ FILE CALL F.BDOS ;READ A SECTOR OR A ;TEST IF DONE JP NZ,END.IT ;DONE JR BYTER ;LOOP AGAIN ; LOOP1 LD E,0 LD C,E ; LOOP2 EXX ;HIDE DATA CALL BYTER ;GET BYTE EXX ;RETREIVE DATA AND 7FH ;STRIP 7 BIT PUSH AF ;STORE TILL NEADED LD A,E ;GET FLAG OR A ;IS IT ZERO JR NZ,X1 ;NO, PROCESS AS HEX POP AF CP ':' ;TEST FOR [ : ] JR NZ,LOOP2 ;KEEP WAITING LD E,81H ;SET FLAG FOR COUNT BYTE JR LOOP2 ;GET ANOTHER CHAR. ; ;WE ARE PUTTING TOGETHER A BYTE ;FLAG BIT 7 = 1 HIGH DIGIT OF BYTE ;FLAG BIT 7 = 0 LOW DIGIT OF BYTE ; X1 JP P,Y1 ;JUMP IF LOW DIGIT AND 7FH ;STRIP LD E,A ;PUT FLAG IN E REG POP AF ;GET CHAR CALL TSTHX ;CONVERT TO HEX ADD A ADD A ADD A ADD A ;MAKE HIGH PART OF BYTE LD D,A ;SAVE NIBLE IN D REG JR LOOP2 ; Y1 POP AF ;RETREIVE CHAR CALL TSTHX ;CONVERT OR D ;MAKE UP BYTE LD D,A ;SAVE IT IN D REG ADD C ;ADD IT INTO CHECKSUM LD C,A ;SAVE RUNNING CHECKSUM LD A,E ;GET FLAG DEC A ;THEN DESPACH ON IT JR Z,COUNT DEC A JR Z,HADD DEC A JR Z,LADD DEC A JR Z,TYPE.X DEC A JR Z,PUT LD A,C ;CHECK CHECKSUM OR A ;MUST BE ZERO JR Z,LOOP1 ;WAS ZERO ; JP CX.ERR ;CHECKSUM ERROR ; ;PUT A DATA BYTE IN CORE ; PUT PUSH HL ;SAVE MEMORY POINTER PUSH DE ;SAVE OUTPUT BYTE LD DE,(HEXAD2) ;GET OFFSET FACTOR ADD HL,DE PUSH HL LD DE,START-4 ;BACK UP 4 LD A,E CPL LD E-A LD A,D CPL LD D,A INC DE ;16 BIT COMPLEMENT DONE ADD HL,DE JP C,N.SPACE ;GO NO SPACE ERROR POP HL POP DE LD (HL),D ;STORE BYTE LD (HEXAD),HL ;STORE END ADDRESS POP HL INC HL ;ADVANCE LD E,85H ;RESET FLAG DEC B ;REDUCE COUNT JR NZ,LOOP2 ;GO BACK FORE MORE DATA INC E ;SET OUT OF DATA JR LOOP2 ;CHECKSUM ; ; ;IGNORE A TYPE BYTE ; TYPE.X LD E,85H ;SET FLAG FOR DATA JR LOOP2 ;GO GET DATA ; ;GET LOW BYTE OF ADDRESS ; LADD LD L,D ;GET BYTE IN L REG LD E,84H ;SET FLAG FOR TYPE JR LOOP2 ; ;GET HIGH BYTE OF ADDRESS ; HADD LD H,D ;PUT BYTE IN H REG. LD E,83H ;SET FLAG FOR LOW ADDR. JR LOOP2 ; ;GET COUNT BYTE ; COUNT LD B,D ;STORE COUNT IN B LD A,D ;CHECK FOR END OF FILE OR A ;TEST JR Z,STOP ;THE END HAS COME LD E,82H ;SET FLAG FOR ADDR. BYTE JP LOOP2 ;MORE ; STOP LD HL,(HEXAD) ;GET LAST BYTE CALL L.BYTE ;OUTPUT END ADDRESS ;CRLF RET ; B.OPEN CALL F.FILE CALL F.OPEN LD IY,8101H ;SETUP BYTE COUNT RET ; ;START OF SECTOR'S ROUTINE ; ;CALCULATES BYTES AVAILABLE THEN CONVERTS INTO ;SECTORS. USED TO SET MAXIUM NUMBER OF SECTORS ;READ BY THE LOAD ROUTINE. THE WRITE ROUTINE ;USES THIS ROUTINE TO DETERMINE HOW MANY SECTORS ;TO WRITE ; SECTORS XOR A ;CLEAR CARRY FLAG SBC HL,DE ;GET BYTE COUNT LD A,L ;LESS THAN PAGE TO A. LD L,H ;PAGES TO L LD H,0 ;ZERO OUT H REG. ADD HL,HL ;CONVERT PAGES TO ;SECTORS BIT 7,A ;SECTOR TEST NO. 1 JR Z,NOSEC2 ;NO SECTOR HERE INC HL ;SECTOR EXISTED ; NOSEC2 AND 7FH ;SECTOR TEST NO 2 JR Z,TESTEND ;NO SECTOR HERE INC HL ;SECTOR EXISTS ; TESTEND LD B,H LD C,L RET ; ;RESET BUFFADS ; RESET2 LD HL,0 ;GET 16 BIT ZERO LD (HEXAD2),HL LD (L.END),HL ;SET NO RESAVES INC H ;0100H ADR. OF GO GO LD (HEXAD),HL RET ; ;MAKE FILE CONTROL BLOCK ; X.FCB CALL RESET2 ;RESET HEXAD AND HEXAD2 CALL M.FCB ;START FILE CTRL BLOCK CP '.' ;TEST FOR PERIOD JP NZ,SYNTAX ;MUST BE A PERIOD CALL M.FCB3 ;FINISH FCB CP ' ' ;TEST FOR SPACE RET ;RETURN TO CALLER ; ;MOVES DATA FROM INPUT BUFFER TO FILE CONTROL ;WITH DEFALT FILE TYPE {COM} ; M.FCB XOR A ;GET A ZERO LD (E.BYTE),A ;JP SYNTAX ON ERROR ; CALL FCBX.0 ;SETUP DATA ; M.FCB1 LD DE,FCB+1 ;ADDRESS OF FILE CONTROL ;BLOCK LD B,8 ;MAX NUMBER OF SPACES LD A,(IX+00) ;GET FIRST CHAR. CALL CHECKER ;TEST IF LEGAL LD (DE),A ;STORE ; M.FCB2 INC IX ;ADVANCE INC DE LD A,(IX+00) ;GET NEXT CHAR. CP 0 ;TEST FOR END RET Z ;END OF COMMAND LINE CP '.' ;TEST FOR DELIMETER RET Z ;DONE CP ' ' ;TEST FOR SPACE RET Z ;END OF COMMAND CALL CHECKER ;CHECK OUT CHAR. LD (DE),A ;STORE CHARACTER DJNZ M.FCB2 ;MORE TO GO ; JR CK.ERR ;SYNTAX ERROR ; ;PART 2 OF MAKE FILE CONTROL BLOCK ;SETS UP FILE TYPE ; M.FCB3 LD DE,FCB+9 ;START OF FILE TYPE ; INC IX ;NEXT SOURCE POSITION LD B,3 ;MAX OF THREE CHAR. ; M.FCB5 LD A,(IX+00) ;GET CHARACTER CP 0 ;TEST FOR END JR Z,CK.ERR ;TOO SOON CALL CHECKER ;CHECK OUT CHAR LD (DE),A ;STORE CHARACTER. INC IX INC DE DJNZ M.FCB5 ;MORE TO GO ; LD A,(IX+00) ;GET CHARICTOR RET ; WILDS2 LD DE,FCB+9 ;START AT RIGHT PLACE ; WILDS LD A,'?' ;GET A QUSTION MARK ; FILLS LD (DE),A INC DE DJNZ FILLS ;MORE TO GO ; INC IX ;POINT TO NEXT BYTE RET ; ;SETUP ROUTINE ; ;ZERO OUT FILE CONTROL BLOCK AND INSTALE ;DEFUALT FILE NAME {COM} ; FCBX.0 LD HL,FCB ;ADDRESS OF BUFFER CALL I.FCB ;INITILIZE FCB XOR A LD (HL),A ;ZERO END CHAR ; ;PLACE DEFALT FILE TYPE IN FILE CONTROL BLOCK ; LD HL,FCB+9 ;FILE TYPE STARTS HERE LD (HL),'C' ;'COM' FILE TYPE INC HL LD (HL),'O' INC HL LD (HL),'M' RET ; ;INITILIZE FILE CONTROL BLOCK WITH 00 AND SPACES ; I.FCB LD BC,2020H ;B REG 20 TIMES, C REG ;' ' PUSH HL ;SAVE START XOR A ;GET A ZERO ; FLOOP LD (HL),A ;PLACE A ZERO INC HL DJNZ FLOOP ;CONTINUE ; EX DE,HL ;SAVE END ADDRESS POP HL INC HL LD B,11 ;READY FOR SPACES ; SPACES LD (HL),C ;PLACE A SPACE INC HL DJNZ SPACES ;MORE SPACES ; EX DE,HL ;END IN HL REG. RET ; ;TEST FOR ILLEGAL CHARACTERS ;CHARACTER TO BE TESTED IS IN A ; CHECKER LD HL,CK.ERR ;CHECK WHAT TO DO PUSH HL ;MAKE RETUNS JUMP CP '"' ;TEST FOR [ " ] RET C ;CHAR IS CTRL CHAR RET Z ;IS A SPACE ; ;FORCE UPPER CASE TO LOWER CASE ; CP 61H JR C,CHECK3 ;NOT UPPER CASE CP 7BH ;ABOVE UPPER CASE JR NC,CHECK3 ;NO FORCE AND 5FH ;MAKE LOWER CASE ; CHECK3 CP ' ' ;TEST FOR ASTRIST RET C ;SYNTAX ERROR CP '>' RET Z CP '<' RET Z CP 7FH ;UNDERLINE BACK SPACE RET Z CP '.' RET Z CP ';' RET Z CP ':' RET Z ; POP HL ;REMOVE RETURN JUMP ;TO ERROR RET ; ;CHECK WHAT TO DO WHEN A COMMAND LINE HAS ;A ERROR ; CK.ERR LD A,(E.BYTE) CP 0 ;SYNTAX ERROR ON 0 JP Z,SYNTAX POP AF ;REMOVE RETURN TO ;CHECKER LD A,0FFH ;LOAD FLAG BYTE RET ;RETURN TO ORIGINAL ;CALLER ; F.START LD A,(IX+00) ;GET CHAR CP ' ' ;TEST FOR SPACE RET NZ ;NO SPACE INC IX ;TRY NEXT PLACE JR F.START ; HEXOUT LD B,A ;SAVE CHAR. RRCA ;GET IN POSITION RRCA RRCA RRCA CALL CHASE ;MAKE AND STORE HIGH BIT LD A,B ;RETREIVE FOR LOW BYTE JP CHASE ;MAKE LOW BYTE ; ADOUT EX DE,HL ;IN POSITION LD HL,(BUFAD) ;START OF BUFFER LD A,D ;READY CALL HEXOUT ;OUTPUT HIGH ADD LD A,E ;READY CALL HEXOUT ;OUTPUT LOW BYTE LD A,'H' ;H FOR END LD (HL),A ;STORE INC HL JP DATOUT ;OUTPUT ADDRESS ; ;ADVANCE COUNTER BY ONE ; A.CNT LD HL,N.MSG+4 ;LOWEST DIGIT ; A.CNT2 LD A,(HL) ;GET CHAR CP '9' ;TEST FOR MAX JR Z,N.DIG ;ZERO | NEXT DIGIT INC (HL) ;INCREAS NUM. BY 1 RET ; N.DIG LD (HL),30H ;ZERO DIGIT DEC HL ;POINT TO NEXT HIGHER ;DIGIT JR A.CNT2 ;NEXT TEST ; ;CONVERT ASCII DECIMAL NUMBER TO HEX NUMBER ; C.VERT CALL F.START ;REMOVE SPACES LD DE,0 JR C.TEST ;TEST IF LEGAL ; V.C5 LD A,(IX+00) ;GET CHAR ; C.TEST INC IX ;POINT TO NEXT CHAR ; ;CHECK FOR END OF ROUTINE AND TEST ;IF CHARACTER IS LEGAL ; OR A ;TEST FOR END RET Z CP ' ' ;TEST FOR SPACE RET Z ;END OF DEC. NO. CP ':' JR NC,S.ERR ;TO LARGE CP 30H JR C,S.ERR ;TO SMALL ; ;ADD NEXT NUMBER INTO PRODUCT ; PUSH AF ;SAVE NUMBER LD HL,1998H ;LOAD DATE BYTES OR A ;CLEAR CARRY FLAG SBC HL,DE ;TEST JR C,S.ERR ;ERROR HAS OCCURED LD H,D LD L,E ADD HL,DE ADD HL,HL ADD HL,DE ADD HL,HL POP AF SUB 30H ;CONVERT TO HEX LD E,A LD D,0 ;READY TO ADD IT ADD HL,DE ;NEW NUMBER ADDED INTO ;OLD NUMBER EX DE,HL ;PROPER POSITION JR V.C5 ;ADD NEXT NUMBER ; ;CONVERT ASCII HEX TO 2 DIGIT HEX NUMBER ; C.HEX CALL F.START ;REMOVE SPACES LD B,5 ;MAX CHAR INPUT LD HL,0 ;ZERO HL REG OR A ;TEST FOR 00H RET Z ; C.HEX2 LD A,(IX+00) ;GET FIRST CHAR CP 30H ;TEST FOR SEPERATOR RET C ;DONE INC IX ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL CALL TSTHX ;TEST IF HEX JR NC,S.ERR ;NOT HEX ADD L LD L,A ;INCLUDE NEW DATA DJNZ C.HEX2 ;CONTINUE ; S.ERR JP SYNTAX ;TOO MANY INPUTS ; ;TEST FOR HEX ; TSTHX SUB 30H ;TEST FOR HEX CP 10 ;LESS THAN [ : ] RET C ;CHAR. WAS 0 TO 9 SUB 10H ;GET READY FOR HEX CP 7 ;TEST FOR A THROUGH F RET NC ;NOT A THORUGH F ADD 9 ;CONVERT TO HEX SCF ;SET CARRY FLAG RET ;RETURN AS HEX ; E.BYTE DB 0 ; FCB DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0 ; ;MESSAGE TABLE ; MSGTBL DM 'A>>' ;PROMPT ;01 CRLF.0 DB 0DH,8AH ;CRLF ;02 DM 'FILE NOT FOUND' ;03 DM 'SYNTAX ERROR' ;04 DM 'NO DIRECTORY SPACE' ;05 DM 'DISK FULL' ;06 DM 'NO LOAD ROOM' ;07 DM 'READY Y/N ? ' ;08 DM 'FILE EXISTS' ;09 DM ' BYTES REMAINING ON ' ;0A DM ' FILE SIZE ' ;0B DM 'CANNOT CLOSE FILE' ;0C N.MSG DM '00000 ' ;0D DM 'LAST BYTE LOADED ' ;0E DM 'CHECKSUM ERROR' ;0F ; ;ASCII COMMAND TABLE ; CNAMES DM 'SAVE' ;00 DM 'ERASE' ;01 DM 'DIR' ;02 DM 'RENAME' ;03 DM 'TYPE' ;04 DM 'GO' ;05 DM 'RESET' ;06 DM 'LOAD' ;07 DM 'COM' ;08 DM 'SLOAD' ;09 DM 'HSAVE' ;0A DM 'SSAVE' ;0B DM 'RESAVE' ;0C DM 'DESTROY ALL FILES' ;0D DM 'HEX' ;0E DB 0 ; ;COMMAND TABLE ; CMDTBL DW SAVE ;00 DW ERA ;01 DW DIR ;02 DW RENAME ;03 DW TYPE ;04 DW GO ;05 DW RESET ;06 DW LOAD ;07 DW COM ;08 DW SLOAD ;09 DW HSAVE ;0A DW SSAVE ;0B DW RSAVE ;0C DW DESTROY ;0D DW HEX ;0E ; END  ;08 DW SLOAD ;09 DW HSAVE ;0A DW SSAVE ;0B DW RSAVE ;0C DW DESTROY ;0D DW HEX ;0E ; END