TITLE EQUATE TABLE ; ;SNOOPY DISK OPERATING SYSTEM ;VERSION 1.2 August 14, 1981 ; ;WRITTEN BY RALPH E. BUCKNAM ;COPYRITE (C) 1981 ;ALL RIGHTS RESERVED ; ;EQUATE TABLE ; RAM EQU 0DFFFH ; ; ;Disk Driver's In/Out ports ; Select EQU 63H Cmd EQU 64H Stat EQU 64H Track EQU 65H Sect.or EQU 66H Data EQU 67H ; ;Constants for Disk ; TS.SEC EQU 1BH ;LARGE DISK VALUE MAX.K EQU 0F7H ;DISK KILLOBYTES MAX.SC EQU 0E5H ;LARGE DISK VALUE MAX.TR EQU 0B3H ;LARGE DISK VALUE ; ;Memory buffers ; TABSTA: EQU RAM-0FFFH BUFAD: EQU RAM-2B8H STAK: EQU BUFAD G.BUF EQU RAM-2A8H STKADR: EQU RAM-279H DIRECT EQU RAM-277H ;START OF DIRECTORY DR.END EQU RAM-1F8H ;END OF DIRECTORY B.MAP EQU RAM-1F7H ;START OF BIT MAP D.BUF EQU RAM-0F7H ;START OF DISK BUFFER ;START OF FILE POINTER D.BUF2 EQU RAM-0F5H ;END OF FILE POINTER D.BUF3 EQU RAM-0F3H ;EXECUTION POINTER D.BKLNG EQU RAM-0F1H ;LENGTH OF FILE F.NAME EQU RAM-0EFH ;FILE NAME F.TEXT EQU RAM-0EEH ;START OF TEXT D.SEC EQU RAM-79H L.Byte EQU RAM-77H SyByte EQU RAM-76H ; ;Disk Driver's linkages ; DMA EQU RAM-75H Sctr EQU RAM-73H TRK EQU RAM-72H ERSTAT EQU RAM-71H IDVS EQU RAM-65H SVSP EQU RAM-70H DRVBYT EQU RAM-6EH SECTOR EQU RAM-6DH ; FLAGS EQU RAM-6BH TYPE EQU RAM-6AH BRKAD2: EQU RAM-67H HERE4: EQU RAM-65H NXTNO: EQU RAM-63H NXTSM0: EQU RAM-61H RUN: EQU RAM-5FH JMPADR: EQU RAM-5DH TBYTE: EQU RAM-5AH BKBYT: EQU RAM-58H TBK1: EQU RAM-56H BK1: EQU RAM-54H TBK2: EQU RAM-52H BK2: EQU RAM-50H TBK3: EQU RAM-4EH BK3: EQU RAM-4CH TBK4: EQU RAM-4AH BK4: EQU RAM-48H HEREX: EQU RAM-46H SM0ADR: EQU RAM-44H OPSAVE: EQU RAM-42H STKAD2: EQU RAM-40H PAGENO: EQU RAM-3EH BKADR: EQU RAM-3CH BKADR2: EQU RAM-3AH SM0AD2: EQU RAM-38H HERE: EQU RAM-36H IBUF: EQU RAM-34H LNLENG: EQU RAM-33H BKLENG: EQU RAM-32H HEXAD EQU RAM-31H HEXAD2 EQU RAM-2FH HEXAD3 EQU RAM-2DH HEXADX EQU RAM-2BH HEXAD4 EQU RAM-29H OFSET EQU RAM-27H ; SAVESP: EQU RAM-0FH STACK2 EQU SAVESP PGBUF: EQU RAM-0DH BRKMSG: EQU RAM-0AH VDMBF: EQU RAM-09H VDMBF2: EQU RAM-07H SPEED: EQU RAM-05H ;ONE BYTE DrvChg EQU RAM-3H IOBYT: EQU RAM-02H INIBF: EQU RAM-1H VDMBA: EQU 0CC00H TITLE JUMP TABLE, INITILIZATION, & COMMAND PROCESSOR ; Start JR START2 INIT1: JR INIT1A ;JUMP TO INIT1 ROUTINE ; ;Master jump table ; OUTVDM JP START+1C10H ;Output to VDM LD A,C ;For CP/M List output's OUTLIN JP START+1C00H ;Output to List LD A,C ;For CP/M output's OUTPUT JP START+1C02H ;Main output INPUT JP START+1C04H ;Main input STATUS JP START+1C07H ;Main status input LSTAT JP START+1C0AH ;Status of list device IOinit JP START+1C0DH ;Jump to initilazation HOME JP Home. ;HOME DRIVE READ JP Read. ;READ A SECTOR WRITE JP Write$ ;Write a sector FORMAT JP FOR.MAT ;Format a disk JP M.DUMP ;Disk transfer routine ; START2 LD SP,STAK LD HL,INIBF ;CHECK FOR INIT. LD A,55H ;INIT BYTE CP (HL) ;FIRST INIT CHECK JR NZ,INIT0 ;NOT INITLIZED CPL ;COMPLEMENT ACCUM INC HL ;NEXT CHEK POINT CP (HL) ;SECOND CHECK FOR INIT. JR Z,INIT1A ;INITILIZED INIT0 LD A,55h ;Token for first test CALL MemCk ;Make first check JR NZ,INIT2 ;A error occured LD A,0AAH ;Token for second test CALL MemCk ;Make the second test JR NZ,INIT2 ;A Error occured XOR A ;Token for third test CALL MemCk ;Check if memory is ;zeroed ; INIT2 CALL IOinit ;Initilize IN/OUT boards XOR A LD (IOBYT),A LD (PGBUF+1),A LD (SPEED),A LD (DRVBYT),A ;SET FOR DRIVE 1 INC A LD (BRKMSG),A ;SET BREAK MSG FLAG LD HL,0AA55H ;Initilazation bytes LD (INIBF),HL ;Set program as ;Initialized DB 0FDH ;Make unpublished LD A,H ;Get original fill DB 0FDH ;Make unpublished CP L ;Compar start against ;The end fill character LD HL,MSG1 ;SNOOPY II JR Z,INIT3 ;NO ERRORS LD HL,MemErr ;A Error occured ; INIT3 CALL BUFOUT ;SEND MSG1 ; INIT1A: LD SP,STAK CALL CRLF ;GET A NEW LINE CALL CRLF ;INSERT EXTRA CRLF LD A,10H ;LINES PER DISPLAY STOP LD (L.Byte),A ;STORE THE VALUE LD A,(DRVBYT) ;GET DRIVE ADD 'A' CALL OUTPUT LD A,':' ;THE PROMPT CALL OUTPUT ; CALL INBUF ;GET COMMAND ; BUSCA LD HL,INIT1 ;WHERE TO RET PUSH HL ;PUSH IT ON THE STACK PUSH HL ;EQULIZING PUSH LD BC,(BUFAD) ;GET INPUT CHAR. LD DE,CLIST ; FIND POP HL ;REMOVE UNUSED RET. JP EX DE,HL ;CLIST PTR IN HL REG LD E,(HL) ;LOW BYTE INC HL LD D,(HL) INC HL PUSH DE ;PUSH ADDRESS LD E,(HL) ;GET FIRST NAME INC HL LD D,(HL) ;GET SECOND NAME INC HL LD A,E OR D ;TEST FOR END JP Z,ERR1 ;NO COMMAND EX DE,HL ;HIDE ADDRESS OR A ;CLEAR FLAGS SBC HL,BC ;TEST JR NZ,FIND ;KEEP LOOKING ; ;SCANNER ROUTINE FROM DMON ; LD DE,BUFAD+1 LD BC,HEXAD PUSH BC LD L,12 ;12 ZEROS XOR A ;GET A ZERO ; HXZERO LD (BC),A INC BC DEC L JR NZ,HXZERO ; POP BC ; SCA0: INC DE LD A,(DE) CP 0DH JR Z,SCA4 CP '0' ;IS IT A SEPERATOR JR NC,SCA0 ; SCA1: LD HL,0 ; SCA2: INC DE LD A,(DE) CP '0' JR C,SCA3 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL CALL TSTHX JP NC,ERR1 ADD L LD L,A JR SCA2 ; SCA3: LD A,L LD (BC),A INC BC LD A,H ;IN A BUFFER LD (BC),A ;AS HEX INC BC LD A,(DE) CP 0DH ;ARE WE FINSHED JR NZ,SCA1 ;NOPE! ; SCA4 CALL BLKIN CALL CRLF ;GET A NEW LINE LD BC,(BUFAD+2) ;EXTRA COMMAND BYTES LD DE,(HEXAD2) ;SECOND PARAMETER LD HL,(HEXAD) ;FIRST PARAMETER RET ;RETURN JP TO ROUTINE ; TITLE COMMAND TABLE ; ;COMMAND LIST ; CLIST DW DPHEX ;DUMP MEMORY DB 'DM' DW DPHEX4 ;DUMP HEX AND ASCII DB 'DA' DW DPHEX3 ;DUMP SYMBOLIC DB 'DS' DW DIR. ;DUMP DIRECTORY DB 'DI' DW ENTER ;ENTER INTO MEMORY DB 'EM' DW PASS.2 ;TWO PASS DISSASEMBLER DB '2P' DW JRCALC ;CALCULATE JUMP REAL. DB 'JR' DW INIT0 ;INITILIZE SNOOP DB 'I0' DW I.DISK ;INITILIZE DISK DB 'ID' DW GO ;GO DB 'GO' DW MARG ;MARG DB 'PG' DW K.FILE ;KILL FILE DB 'KI' DW R.FILE ;LOAD A DISK FILE DB 'LD' DW R.FILE ;LOAD AND MOVE A FILE DB 'LM' DW T.GET ;GET A TRACK DB 'GT' DW T.STORE ;PUT A TRACK DB 'PT' DW SR ;READ X SECTORS DB 'SR' DW SW ;WRITE X SECTORS DB 'SW' DW R.FILE ;LOAD AND RUN FILE DB 'RU' DW W.FILE ;WRITE A FILE ON DSK DB 'WF' DW BKSET ;SET UP BREAK POINT DB 'BK' DW R.BRK ;SET UP REBREAKS DB 'RB' DW DMODE ;DUMP REGISTERS DB 'BD' DW BCMODE ;BREAK CONTINUE DB 'BC' DW BGMODE ;SET A NEW BREAK AND ;CONTINUE DB 'BG' DW ZDOS ;GO TO ZDOS DB 'AA' DW DRIVE ;CHANGE DRIVES DB 'DV' DW SERCH ;SEARCH DB 'SM' DW SERCH ;SYMBOLIC SEARCH DB 'SS' DW VMEM ;VERIFY MEMORY DB 'VM' DW PROM ;PROM EROMS DB 'PM' DW MOVE ;MOVE MEMORY DB 'MM' DW MTEST ;TEST MEMORY DB 'TM' DW ZERO ;ZERO MEMORY DB 'ZM' DW Boot ;Load a CP/M type file DB 'FD' DW Sy.Get ;Get a CP/M type system DB 'SG' DW Sy.Put ;Put CP/M system on disk DB 'SP' DW Cp.Dsk ;Copy disk DB 'CD' DW O.Port ;Output to a port DB 'OP' DW I.Port ;Input from a port DB 'IP' DW FORMAT DB 'DF' ;Format a Disk DB 0,0,0,0 DB 0,0,0,0 DB 0,0,0,0 DB 0,0,0,0 DB 0,0,0,0 DB 0,0,0,0 DB 0,0,0,0 DB 0,0,0,0 ; TITLE SYSTEM UTILITIES #1 ; ;Initilization Memory check routine ; MemCk POP IX ;Save the return address ;becuase the program ;destroys the Stack. DB 0FDH ;Make unpublished ;instruction LD H,A ;Save the character in ;IY Resister LD HL,Start-1 LD DE,Start-2 LD BC,Start-1 LD (HL),A ;Store the character LDDR ;Fill the memory INC DE ;Backup LD A,(DE) ;Get the last char. DB 0FDH ;Unpublished CP H ;Test for the same DB 0FDH ;Make unpublished LD L,A ;Save results in IY' ;Register JP (IX) ;Do a return ; ERR1 LD HL,MSG3 ;Point to the error Msg. CALL BUFOUT ;Do the bitching JP INIT1 ;Start over ; FORCE: CP 61H RET C CP 7BH RET NC SUB 20H RET ; BLKIN OR A ;CLEAR FLAGS LD DE,(HEXAD) ;GET START LD HL,(HEXAD2) ;GET END SBC HL,DE ;GET RESULTS INC HL LD (HEXAD4),HL ;BLOCK LNGTH RET ; ;OFSET CALCULATION ; COFSET AND A ;CLEAR CARRY FLAG LD HL,0 LD DE,(HEXAD3) ;GET OFFSET SBC HL,DE JR Z,OFFSTR LD HL,(HEXAD) EX DE,HL AND A SBC HL,DE EX DE,HL LD HL,0 AND A SBC HL,DE OFFSTR: AND A EX DE,HL LD HL,0 SBC HL,DE LD (OFSET),HL ;STORE OFSET RET ; ;BUFFER INPUT ROUTINE ;ACCEPS UP TO 64 CHARACTERS. ; INBUFX CALL CRLF ;START WITH A NEW LINE ; INBUF: LD HL,BUFAD LD B,40H ; INB1: CALL INPUT CALL OUTPUT CALL FORCE ;MAKE UPPER CASE CP 15H ;TEST FOR CTRL U JR Z,INBUFX ;GET A NEW LINE CP 00H ;TEST FOR A NULL JR Z,INB1 ;NO EFFECT IF NULL CP 7FH ;TEST FOR DELETE JR Z,DELETE ;GO BACKSPACE LD (HL),A ;STORE DATA CP 0DH ;TEST FOR CR RET Z ;RETURN TO CALLER INC HL DJNZ INB1 ; JR ERR1 ; DELETE: LD A,40H ;INITIAL BUFF SIZE CP B JR Z,INB1 ;NO INPUTS YEAT INC B ;ADJ POINTERS DEC HL JR INB1 ; RSPACE LD A,' ' REPOT: CALL OUTPUT DJNZ REPOT ;MORE TO GO RET ; CRLF.5 LD A,10H LD (L.Byte),A ;Reset page counter ; CRLF: LD A,0DH ;CRLF WITH SWITCH CALL OUTPUT LD A,0AH ;TOKEN FOR LINE FEED CALL OUTPUT LD A,(IOBYT) ;GET THE DATA BYTE AND 27H ;DO THE TESTING JR NZ,CRLF.3 ;JUST CHECK FOR A ;KEY PRESS PUSH HL ;SAVE CALLERS HL REG. LD HL,L.Byte ;POINT TO THE REMAINING ;LINES TO BE OUTPUTED DEC (HL) ;REDUCE # OF LINES JR NZ,CRLF.2 ;MORE TO GO LD (HL),15 ;RELOAD THE COUNT ; CRLF.2 POP HL ;RETREIVE CALLERS REG. JR Z,CRLF.4 ;CHECK IF PROGRAM ;CONTINUES EXECUTION ; CRLF.3 CALL STATUS CP 0FFH ;TEST IF KEYPRESS RET NZ ;NO KEY PRESS CALL INPUT ;CLEAR BYTE THAT ;DID THE FLAGGING CRLF.4 CALL INPUT ;WAIT TILL A KEY IS ;PRESSED CP 0DH ;TEST FOR A CRET RET NZ ;CONTINUE JP INIT1 ;TERMINATE COMMAND ; BUFOUT: CALL CRLF ;GET NEW LINE ; BUFOT2 LD A,(HL) ;GET CHAR OR A ;TEST IF DONE RET Z PUSH AF ;SAVE FLAGS AND 7FH ;STRIP 7 BIT CALL OUTPUT POP AF RET M ;DONE INC HL JR BUFOT2 ;CONTINUE ; TSTHX SUB 30H ;TEST FOR HEX CP 10 ;LESS THAN A RET C ;YES IT IS 0-9 SUB 10H CP 7 ;A THROUGH F ONLY RET NC ;IT IS TO BIG ADD 9 SCF ;FLAG AS HEX RET ; ;This routine outputs the drive byte ; DrvOut JR C,DrvOt2 ;Do not get drive from ;memory LD A,(DrvByt) ;Get th drive byte DrvOt2 LD B,A ;Save byte in B Reg. JR Z,DrvOt3 ;Donot output message LD HL,DrvMsg ;Point to the message CALL BUFOT2 ;Output ' Drive ' DrvOt3 LD A,B ;Retreive drive Num. ADD 'A' ;Convert to a letter JP OUTPUT ;Output the drive Letter ; DrvMsg DM ' Drive ' ; ;Output the message with drive number ;and check if ready ; Ready2 CALL BUFOT2 ;Output the message OR A ;Clear the flags Ready3 CALL DrvOut ;Output the drive ;letter CALL CRLF.5 ;Get a new line ; ;Check to see if you really want a command ; Ready LD HL,R.Msg1 ;Point to message CALL BUFOT2 ;Output the message CALL CRLF ;Get a new line CALL INPUT ;Get response OR 20H ;Convert to upper case CP 'y' ;Cleck if ready RET Z ;Yes LD HL,R.Msg2 ;' Command terminated ' CALL BUFOT2 ;Output messaged CALL CRLF ;get a new line JP INIT1 ;End the mess ; R.Msg1 DM 'Ready (Y/N)' R.Msg2 DM 'Command terminated' TITLE SYSTEM COMMANDS #1 ; ;SUBROUTINE TO SET PAGE LENGTH ;AND SPACE BETWEEN PAGES ; MARG ;HL CONTAINS (HEXAD) MARG.2 LD A,L SUB H LD L,A LD (PGBUF),HL LD (PGBUF+2),A RET ; MSG1 DM 'Snoopy Dos' MSG3 DM 'ERROR' MemErr DM 'Memory is defective' ; ;EXECUTE AT SELECTED ADDRESS ; GO LD HL,(HEXAD) ;GIT THE GO ADDRESS PUSH HL LD BC,6 LD HL,HEXAD2 LD DE,HEXAD LDIR JP BLKIN ;SETUP BLOCK LINGTH ; ;ROUTINE TO ENTER HEX FROM THE KEYBOARD ; ENTER ;HL CONTAINS (HEXAD) ; ENTR1 CALL ADOUT2 ;O/P CURRENT ADD CALL MOUT2 ;OUTPUT AND SPACE CALL HEXTT PUSH AF CALL SPACE CALL MOUT ;OUTPUT FINAL POP AF JR NZ,BKK1 DEC HL DEC HL BKK1 INC HL CALL CRLF.5 ;Get a new line JR ENTR1 ; ;Output to a specified port ; O.Port ;DE and HL contains ;the info. LD C,L ;Move port no in L reg ;to C reg. LD A,E ;Move data to accum. CALL Binit2 ;Output the data LD HL,OpMsg ;Message pointer CALL BUFOT2 ;Output the message LD A,C ;Move Port to ACCUM CALL HEXOUT ;Output the port number OUT (C),E ;Do the outputing RET ; OpMsg DM ' is outputed from port # ' ; ;Input from port or ports ; I.Port ;De and HL registers ;contain the data LD C,L ;Move port to C Reg. ; IPort2 In A,(C) ;Get the input CALL Binit2 ;Output the data LD HL,InMsg ;Point to the message CALL BUFOT2 ;Output the message LD A,C ;Get the port number CALL HEXOUT ;Output port Number CALL CRLF.5 ;get a new line CALL INPUT ;Find out what to do CP 0DH ;Check for a carrage ;return RET Z ;The end of routine CP 07FH ;Check for a delete JR Z,IPort3 ;Backup port pointer CP ' ' ;Check for a space JR Z,IPort4 ;Advance the pointer JR IPort2 ;Get annother input ; IPort3 DEC C ;Backup pointer JR IPort2 ;Loop again ; IPort4 INC C ;Advance pointer JR IPort2 ;Loop again ; InMsg DM ' is inputted from port # ' TITLE SYSTEM UTILITIES #2 ; ;Convert nibbel to binary bits ; Binit3 CALL SPACE ;Output a space LD B,4 ;Work 4 bits ; Binit4 XOR A ;Get a zero RL C ;Rotate left ADC '0' ;Convert to bit CALL OUTPUT ;Output the bit DJNZ Binit4 ;Loop tile done ; RET ; ;Output the Binary and Hex values of a byte ; Binit LD A,(HL) ;Get the Mem. byte ; Binit2 PUSH BC ;Save callers reg PUSH AF ;Save byte to be ;processed LD C,A ;Save byte to be ;processed CALL Binit3 ;Process upper 4 bytes CALL Binit3 ;Process lower 4 bytes CALL SPACE2 ;output two spaces POP AF ;Retreive byte to be ;processed POP BC ;Retreive callers reg ; ;SUBROUTINE TO O/P REG IN HEX ; HEXOUT: PUSH BC ;SAVE LD B,A ;SAVE TEMP. CALL HEXO1 POP BC RET HEXO1: RRCA RRCA RRCA RRCA CALL CHASE ;CHANGE TO ASCII ; CHASE: AND 0FH ;MASK ADD 30H ;ADD '0' CP 3AH ;?>9 JR C,CH1 ADD 7 ;CHANG TO A-F CH1: CALL OUTPUT LD A,B RET ; HXOUT2 CALL HEXOUT JR SPACE ; ;OUT MEM BYT IN HEX ; MOUT: LD A,(HL) ;GET IT JR HEXOUT ;OUTPUT IT ; MOUT2 CALL MOUT ;OUTPUT MEM. JR SPACE2 ;OUTPUT 2 SPACES ; ;OUTPUT ADDRESS ; ADOUT: LD A,H ;GET HI ADRESS CALL HEXOUT ;0/P IT LD A,L ;AND THE LOW JR HEXOUT ;O/P IT ; ADOUT4 CALL SPACE ; ADOUT3 CALL ADOUT JR SPACE2 ; ADOUT2 CALL ADOUT ;OUTPUT ADDRESS JR SPACE ;OUTPUT A SPACE ; ;OFSET ADDRESS OUTPUT ROUTINE ; OFFADR: PUSH DE PUSH HL LD DE,(OFSET) ADD HL,DE CALL ADOUT POP HL POP DE RET ; OFFAD2 CALL OFFADR ;OUTPUT ADR JR SPACE ;OUTPUT A SPACE ; SPACE4 CALL SPACE2 ; SPACE2 CALL SPACE ; SPACE LD A,' ' ;GET A SPACE JP OUTPUT ;OUTPUT IT ; ;CONVERT HEXADECIMAL ACCUMULATOR TO DECIMAL ;NUMBER AND STORE ; G.NUM LD HL,G.BUF ;STORE HERE 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 LD (HL),0 ;STORE END POSITION LD HL,G.BUF JP BUFOT2 ;OUTPUT INFO ; ;INPUT CHARACTER FROM KEYBOARD ; HEXTT: CALL INPUT ;GET BYTE CP 0 ;IS IT A NULL JR Z,HEXTT CALL FORCE ;MAKE UPPER CASE CP 7FH ;TEST FOR DELETE RET Z ;YES CP ' ' ;IS IT S SPACE JR Z,NXT CALL OUTPUT CALL TSTHX ;IS IT VALID JR NC,NOPE LD B,A ;SAVE NEW DATA LD A,(HL) ;GET CURRENT DATA RLCA ;SAVE RIGHT HALF RLCA RLCA RLCA AND 0F0H OR B ;ADD IN NEW LD (HL),A JR HEXTT ;KEEP GOING ; NXT: OR A ;TURN OFF ZERO RET ; NOPE: POP AF ;CORRECT STACT RET TITLE SYSTEM COMMANDS # 2 ; ;DUMP HEX AND ASCII ; DPHEX4 DPHEX3 DPHEX EXX ;SAVE PARAMETERS CALL COFSET LD A,1 LD (BRKMSG),A ;RESET HEADER OUTPUT EXX ;RETREIVE (HEXAD) & ;(HEXAD2) LD A,(BUFAD+1) ;LOOK AT BUF. CP 'S' ;TEST FOR SYMBOLIC JP Z,ZDISAC ;DISASSEMBLE LD C,0 ;ZERO TEST BYTE REG. CP 'A' ;TEST FOR ASCII JR NZ,DPHEX1 ;DONOT SET FLAGS SET 0,C ;SET ASCII FLAG ; DPHEX1: PUSH BC ;PUSH DUMP TYPE PUSH HL EXX ;FLIP POP HL ;ADR IN PROPER POS POP BC ;RETREVE DUMP TYPE ; LD A,L AND 0FH ;STRIP OFF UPPER BITS INC A DEC A ;TEST FOR ZERO JR Z,DPHEX2 ;NO ADJUSTING REQ. ; LD B,A ;GET ADJ FACT IN B ZERHEX: DEC HL DJNZ ZERHEX ;REPEAT TILL ZERO ; DPHEX2: CALL MSTEST ;TEST FOR MESSAGE JR NOMSG ;GO TO WORK ; MSTEST: LD A,(BRKMSG) ;GET MSG BYTE BIT 0,A ;TEST FOR MSG RET Z ;NO MESSAGE PUSH HL LD HL,HEXMSG ;MESSAGE ADDRESS CALL BUFOT2 ;OUTPUT MSG POP HL XOR A ;ZERRO ACCUM LD (BRKMSG),A ;RESET MSG COUNTER RET ; NOMSG: CALL OFFADR ;OUTPUT ADDRESS CALL SPACE PUSH HL POP DE ;TRANSER COMPLEAT ; CALL OUTHEX ;OPUT 8 HEX BYTES CALL OUTHEX ;OPUT 8 HEX BYTES BIT 0,C ;TEST FOR ASCII JR Z,PASEND ;NO ASCII ; PUSH DE POP HL ;TRRANSFER COMPLETE CALL CRLF ;GET NEW LINE CALL MSTEST ;TEST FOR MSG CALL SPACE4 ;SET FOR 4 SPACES CALL OUTASC ;OUTPUT 8 ASCII BYTES CALL SPACE CALL OUTASC ;OUTPUT 8 ASCII BYTES CALL CRLF ;GET A CLEAN LINE ; PASEND: PUSH HL EXX ;Get back regs. POP HL ;PRESENT ADR AND A ;CLEAR CARRY FLAG SBC HL,DE ;MAKE END CALC. RET NC ;FINISHED ? EXX ;GET FRONT REGS. CALL CRLF ;GET NEW LINE JR DPHEX2 ;KEEP GOING ; OUTHEX: CALL SPACE LD B,8 ;8 HEX OUTPUTS HEX: LD A,(HL) PUSH BC CALL HXOUT2 ;OUTPUT BYTE POP BC ;RETREIVE DATA INC HL DJNZ HEX ;KEEP GOING RET ; OUTASC: LD B,8 ASCII: PUSH BC ;SAVE FLAGS CALL SPACE2 ;OUTPUT 2 SPACES POP BC ;RETREIVE FLAGS LD A,(HL) ;GET BYTE CALL CANCL ;CHECK FOR ASCII CALL OUTPUT INC HL ;ADVANCE COUNTER DJNZ ASCII RET ; CANCL: CP 20H ;LETER CHECK JR C,CNCL1 ;NO LETER CP 5FH ;TEST FOR BACK SPACE JR Z,CNCL1 CP 7EH RET C ; CNCL1: LD A,'.' ;SET TO OUTPUT (.) RET ; HEXMSG: DB ' 0 1 2 3 4 5 6 7 ' DB ' 8 9 A B C D E F' DB 0DH,8AH ; ;CHECK IF ZDOS IS IN PLACE AND GO TO ZDOS ; ZDOS LD HL,0B701H ;Z-DOS+1 LD A,(HL) ;GET BYTE CP 54H ;TEST JR NZ,ZErr2 ;Error has occured DEC HL LD A,(HL) ;GET FIRST BYTE CP 18H ZErr2 JP NZ,ERR1 JP (HL) ;GO TO Z-DOS ; ;CHANGE DRIVES ; DRIVE LD HL,DRVBYT ;WHERE DRIVE IS LD B,0 LD A,(BUFAD+2) ;GET LETTER CP 'B' ;TEST IF B JR NZ,D.DEF ;SET UP DRIVE A INC B D.DEF LD (HL),B ;STORE DRIVE NO RET ; ;ZERO ROUTINE -- ZERO A BLOCK OF MEMORY ;WITH SELECTED FILL ; ZERO: LD A,(HEXAD3) ;GET FILL LD B,A ZERO1: CALL ZBLOK ZERO2: LD (HL),B ;FILL BLOCK INC HL DEC DE LD A,E OR D ;CHECK FOR END JR NZ,ZERO2 ZBLOK: LD DE,(HEXAD4) ;GET BLKLN LD HL,(HEXAD) ;AND START RET ; MTEST: CALL ZERO ;MEMORY TEST DB 0C4H ;SKIP 3 BYTES TWR1: DEC (HL) INC HL ;NEXT TRW: LD A,B CP (HL) ;TEST CALL NZ,ZERR DEC DE LD A,E ;END CHECK OR D ;END CHECK JR NZ,TWR1 ;KEEP GOING ; DEC (HL) ;GET THE LAST ONE CALL ZBLOK ;SET UP AGAIN CALL MSTRS ;CHECK FOR ESCAPE DEC B ;NEXT CHAR JR NZ,TRW ; RET ;END OF ROUTINE ; ZERR PUSH HL LD HL,MSGA CALL BUFOUT POP HL CALL ADOUT PUSH HL LD HL,MSGB CALL BUFOT2 POP HL CALL Binit PUSH HL LD HL,MSGC CALL BUFOT2 POP HL LD A,B JP Binit2 ; MSGA: DB 'DATA AT:',0A0H MSGB: DB ' IS',0A0H MSGC: DB ' SHOULD BE',0A0H ; MSTRS: CALL STATUS ;CHECK IF KEY PRESS CP 0FFH ;TEST FOR KEYPRESS RET NZ ;NO KEY PRESS CALL INPUT ;GET DATA CP 1BH ;TEST FOR ESCAPE JP Z,INIT1 RET ; LDREG ;(HEXAD), Is in HL reg. LD DE,(HEXAD3) LD BC,(HEXAD4) RET ; MOVE: CALL LDREG CALL MOVER JR VMEM2 ; PROM: CALL LDREG LD A,64H M.MOVES CALL MOVER DEC A JR NZ,M.MOVES ; VMEM: CALL LDREG VMEM2: LD A,(DE) CPI JR Z,NO.ERR ; ;OUTPUT ERROR INFORMATION ; PUSH AF PUSH HL PUSH DE PUSH BC DEC HL CALL ADOUT4 CALL MOUT CALL SPACE4 ;MAKE 4 SPACES EX DE,HL CALL ADOUT4 CALL MOUT CALL CRLF POP BC POP DE POP HL POP AF ; NO.ERR: INC DE RET PO JR VMEM2 ;NEXT CHECK ; MOVER: PUSH HL PUSH DE PUSH BC LDIR POP BC POP DE POP HL RET ; ;SEARCH WITH SYMBOLIC DUMP ; SERCH: LD A,8 ;NUMBER OF DUMPS PER LINE LD (LNLENG),A ;STORE LINE LENGTH LD HL,MSGS1 ;MSG 1 OF SEARCH CALL BUFOUT LD HL,BUFAD+4 ;SET UP STRING CALL ENTR1 ;ENTER DATA LD DE,BUFAD+4 LD A,L ;CALCULATE STRING SUB E ;LENGTH INC A LD C,A ;STORE STRING LD B,A ;LENGTH LD HL,MSGS2 ;MSG 2 OF SEARCH CALL BUFOUT LD HL,BUFAD+4 SERT1: CALL MOUT CALL SPACE INC HL DEC C JR NZ,SERT1 ;OUTPUT INTIRE STRING LD C,B ;IT IS READY AGIN LD HL,MSGS3 ;MSG 3 OF SEARCH CALL BUFOUT CALL CRLF.5 ;GET NEW LINE CALL CRLF LD HL,(HEXAD) SER1: LD DE,BUFAD+4 LD C,B ;READY AGAIN PUSH HL SER2: LD A,(DE) CP (HL) INC DE INC HL JR NZ,SER3 DEC C JR NZ,SER2 POP HL CALL SEROUT ;SEARCH OUTPUT ROUTINE PUSH HL SER3: POP HL INC HL ; ;End check routine ; PUSH HL ;Save pointer LD HL,(HEXAD4) ;Get Number of bytes ;searched DEC HL ;Reduce the number LD (HEXAD4),HL ;store the new num. LD A,L ;Low byte to Accum. OR H ;Test for zero POP HL ;Retreive pointer RET Z ;End of routine JR SER1 ; MSGS1: DB 'ENTER SEARCH STRING IN HEX' DB 0DH,8AH MSGS2: DB '--->',0A0H MSGS3: DB 'IS LOCATED AT',0BAH ; SEROUT: PUSH HL EXX POP HL LD A,(BUFAD+1) CP 'S' ;TEST FOR SYMBOLIC JR Z,SEROT2 LD A,(LNLENG) ;HOW MANY TO GO LD C,A ;SAVE CP 08 JR Z,SERADR ;NO SPACES CALL SPACE4 ;Print 4 spaces ; SERADR: CALL ADOUT DEC C ;ONE LES LINE TO OUTPUT JR Z,RELOAD LD A,C ;GET POSITION SERSTR: LD (LNLENG),A ;STORE POSITION EXX RET ; RELOAD: CALL CRLF.5 ;GET NEW LINE LD A,8 JR SERSTR ;STORE ; ;SYMBOLIC SEARCH ; SEROT2: CALL CRLF ;GET NEW LINE CALL ADOUT ;OUTPUT ADR. CALL CRLF.5 ;GET A NEW LINE LD B,8 ;OUTPUT ADJ FACTOR PUSH HL ;MOVE TO DE REGS. POP DE EXPAND: DEC HL INC DE DJNZ EXPAND ;ADJ START AND STOP CALL ZDISAC ;DISASSEMBLE CALL CRLF.5 LD A,(BUFAD+2) ;GET CTRL CP '!' ;TEST CALL C,CRLF.4 ;WAIT FOR A KEY PRESS ;RETURN IF NOT A SPACE EXX RET ; ;JUMP REALITIVE CALCULATOR ; JRCALC EX DE,HL ;DE Reg. Contains where ;you are and HL Reg. ;contains where you are INC DE ;ADJUST INC DE ;ADJUST AND A ;CLEAR CARRY FLAG SBC HL,DE ;CALCULATE LD A,L ;TRANSFER RESULTS EX DE,HL ;TRANSFER FOR TESTING JP M,BKJMP ;BACKWARDS JUMP LD HL,07FH ;TEST VALUE SBC HL,DE ;TEST JP M,JrErr ; JROUT PUSH AF ;Save the jump byte LD HL,JrMsg2 ;Point to the message CALL BUFOT2 ;Output the message POP AF ;Retreive Jump byte JP HEXOUT ;Output the jump byte ; BKJMP LD HL,0FF80H ;TEST VALUE SBC HL,DE ;TEST JP P,JrErr JR JROUT ; JrErr LD HL,JrMsg1 JP BUFOT2 ;Output the message ; JrMsg1 DM 'Range Error' JrMsg2 DM 'The Jump Byte is ---> ' TITLE BREAK TRACE COMMAND ; ;SNOOPYS FAST TRACE ROUTINES ; DMODE CALL MSG JP OUTREG ; BCMODE ;Break continue BGMODE CALL DMODE ;OUTPUT REGISTERS ;Break set & Go LD A,1 LD (RUN),A LD (RUN+1),A LD A,0AH ;10 LINES LD (LNLENG),A LD A,(BUFAD+1) CP 'C' ;TEST FOR CONTINUE JP Z,CALCUL ;BREAK CONT. LD HL,(HEXAD) JP REGLD ; ;SET UP REBRAKS RB1, RB2, RB3, RB4, ; R.BRK LD A,C ;MOVE BUFAD+2 TO ACCUM. LD B,H LD C,L ;(HEXAD) IN BC REG. LD HL,TBYTE ;POINT REBRAK CTRL. ; CP '1' ;TEST FOR FIRST RBK JR NZ,RBK2 ;NOT HERE SET 0,(HL) ;ACTIVATE LD (TBK1),BC ;STORE TEST ADR LD (BK1),DE ;STORE BREAK ADR ; RBK2 CP '2' ;TEST FOR SECOND RBK JR NZ,RBK3 ;NOT HERE SET 1,(HL) ;ACTIVATE LD (TBK2),BC ;STORE TEST ADR LD (BK2),DE ;STORE BREAK ADR ; RBK3 CP '3' ;TEST FOR THIRD RBK JR NZ,RBK4 ;NOT HERE SET 2,(HL) ;ACTAVATE LD (TBK3),BC ;STORE LD (BK3),DE ;STORE ; RBK4 CP '4' ;TEST FOR FORTH RBK RET NZ ;NOT FOURTH RBK SET 3,(HL) ;SET BIT LD (TBK4),BC LD (BK4),DE RET ; ;SET INITIAL BREAK POINT. USED BY BK BKA ;COMMANDS ; BKSET LD (BKADR),HL ;STORE BREAK ADR. INC DE ;SET TO PAGE # 1 LD (PAGENO),DE ;STORE START PAGE # XOR A ;GET A ZERO LD HL,TBYTE ;REBREAK CTRL BYTE LD (HL),A ;SET UP FOR NO REBREAKS LD HL,(HEXAD) ;GET BRAK AD IN HL LD (BKADR),HL ;INITAL BREAKADR LD A,0C3H ;GET JP OPCODE IN ACCUM. LD (0030H),A ;PUT C3 AT 0030H LD DE,BKSAVE ;ADDRESS WHERE TO JP LD (0031H),DE ;RST 30 JP SAVE ROUT. LD (JMPADR),A ;PUT C3 AT JMPADR LD A,(HL) ;GET FIRST BYT OF OPCODE LD (OPSAVE),A ;SAVE BYT LD A,0F7H ;RST IN ACCUM LD (HL),A ;RST IN BREAK ADR LD A,10 ;NO OF BREAKS PER LINE LD (LNLENG),A ;STORE BK PER LINE LD A,1 ;INIT. LINES/COMM STOP LD (BKLENG),A ;STORE DATA LD (BRKMSG),A ;STORE COUNT FOR BK MSG LD HL,TYPE LD (HL),A LD A,(BUFAD+2) ;GET CHAR CP 'A' ;TEST FOR ADDRESS MODE JR NZ,INIT2X DEC (HL) ; INIT2X LD A,1 ;SETUP FOR 1 LINE LD (RUN),A LD (RUN+1),A RET ;COMPLETE ; ;SAVE REGISTERS. ; BKSAVE LD (STKADR),HL ; SAVE HL 80A6H-807AH POP HL ;GET BK ADR ;1 IN HL DEC HL ;BK ADR IN HL LD (BKADR2),HL;SAVE TRUE BK ADR LD (STKAD2),SP ;SAVE FOREIGN STACK LD SP,STKADR ;GET NEW STACK PUSH AF ;AF 80A4H-80A5H PUSH BC ;BC 80A2H-80A3H PUSH DE ;DE 80A0H-80A1H PUSH IX ;IX 809EH-809FH PUSH IY ;IY 809CH-809DH LD A,I ;GET I REG IN ACCUM PUSH AF ;I REG 809BH EX AF,AF' ;AUX ACCUM ON TOP EXX ;AUX REGS ON TOP PUSH AF ;AF' 8098H-8099H PUSH BC ;BC' 8096H-8097H PUSH DE ;DE' 8094H-8095H PUSH HL ;HL' 8092H-8093H LD SP,STAK ;GET MAIN STACK LD DE,(BKADR2);GET BREAK ADR IN DE LD HL,(BKADR) ;GET INTENDED ADR LD (HERE),HL ;STORE FOR BYTES AND A ;CLEAR CARRY FLAG SBC HL,DE ;COMPARE JP NZ,ERR1 LD (JMPADR+1),DE;PROCESES BYTE LD A,(OPSAVE) ;GET REPACMENT FOR RST LD (DE),A ;REPLACE BYTE CALL BYTES ;GET OPCODE INFO LD DE,BRKMSG ;GET THE BREAK MESSAGE ;POINTER ; ;TEST FOR LINE OR REGISTER OUTPUT ; LD A,(TYPE) ;GET TYPE IN ACCUM BIT 0,A ;TEST FOR TYPE JR NZ,REGS ; ;OUTPUT LINE NUMBERS ; LD HL,(PAGENO) ;GET PAGE NO IN ACCUM LD A,(DE) ;TEST FOR LINE NO. BIT 0,A ;TEST IF 1 OR 0 JR Z,OTLIN ;KNOW MSG CALL SPACE LD A,'L' ;GET L IN ACCUM CALL OUTPUT ;OUTPUT THE L CALL ADOUT2 ;LINE NO INC HL ;INCREASE PAGE NO LD (PAGENO),HL;STORE PAGE NO. XOR A ;ZERO ACCUM LD (DE),A ;ZERO BK MSG ; ;EXECUTE ONE STEP AND TEST IF COMMAND STOP ; OTLIN LD HL,(BKADR) ;GET BREAK ADR IN HL CALL SPACE CALL ADOUT LD HL,LNLENG ;GET LINE LENGTH IN (HL) DEC (HL) ;DEC NO. OF ADR IN LINE JP NZ,CALCUL ;CALC. NEXT INST. CALL CRLF.5 LD A,0AH ;NO OF ADRS. PER LINE LD (LNLENG),A ;STORE LINE LENGTH LD A,1 LD (DE),A ;RELOAD BREAK MSG JP CMAND ; REGS LD A,(DE) ;GET INFO TO DETERMINE BIT 0,A ;WEATHER TO PRINT REG. CALL NZ,MSG ;OUTPUT HEADER JR REGOUT ; MSG CALL SPACE LD HL,MSG9 ;THE HEADER CALL BUFOT2 XOR A LD (BRKMSG),A ;SET NO MESSAGE LD HL,(PAGENO);GET PAGE NO LD A,H OR A CALL NZ,HEXOUT CALL SPACE LD A,L ;NOW BYTE TO A INC HL LD (PAGENO),HL ;STORE NEW PAGE CALL G.NUM ;OUT PAGE NUM. IN DEC. CALL CRLF.5 RET ; REGOUT CALL OUTREG JR CMAND ; OUTREG CALL SPACE LD HL,STKADR-2;GET ADR OF A & F INC HL LD A,(HL) ;GET ACCUM IN ACCUM CALL HEXOUT ;OUT ACCUM CALL SPACE DEC HL LD A,(HL) ;GET FLAGS LD B,A ;GET FLAGS IN B REG LD A,'S' BIT 7,B ;TEST IF MINUS JR NZ,OUT1 LD A,'-' OUT1 CALL OUTPUT LD A,'Z' BIT 6,B ;TEST IF ZERO JR NZ,OUT2 LD A,'-' OUT2 CALL OUTPUT LD A,'V' BIT 2,B ;TEST PARITY JR NZ,OUT3 LD A,'-' OUT3 CALL OUTPUT LD A,'C' BIT 0,B ;TEST FOR CARRY JR NZ,OUT4 LD A,'-' OUT4 CALL OUTPUT CALL SPACE LD HL,(STKADR-4) ;GET BC IN HL CALL ADOUT2 ;OUT BC & & SPACE LD HL,(STKADR-6) ;GET DE IN HL CALL ADOUT2 ;OUT DE & SPACE LD HL,(STKADR) ;GET HL IN HL CALL ADOUT2 ;OUTPUT HL & SPACE CALL MOUT2 ;OUT MEMORY & SPACE LD HL,(STKADR-8) ;GET IX IN HL CALL ADOUT2 ;OUTPUT IX & SPACE LD HL,(STKADR-10) ;GET IY IN HL REG. CALL ADOUT2 ;OUT IY & SPACE LD HL,(STKAD2) ; GET FOREIGN STK IN HL ; CALL ADOUT2 ;OUT STACK ADR. & SPACE LD HL,(BKADR) ;GET BREAK ADR IN HL CALL ADOUT2 ;OUT BKEAK ADR. & SPACE CALL ZDISA ;CALL DISASSEMBLER JP CRLF.5 ;GET A NEW LINE ; ;BREAK TRACE COMMAND ROUTINES ; CMAND LD HL,RUN DEC (HL) JR Z,CMAND3 JR CALCUL ;KEEP GOING ; CMAND3 LD A,'?' ;GET PROMPT CALL OUTVDM INC HL ;POINT TO RUN1 WHICH IS ;NUMBER OF OUTPUTS PER ;COMMAND STOP ; CTRLX CALL INPUT CP 1BH ;ESCAPE JP Z,INIT1 CP ' ' JR Z,CONT1 ;CONTINUE NO MEG CP '/' JR Z,CONT2 ;CONTINUE MSG ; LD B,0 ;SET FLAG BYTE CP '1' ;TEST FOR ONE LINE JR NZ,CTRLB ;NOT ONE LINE INC B LD (HL),1 ;ONE LINE ; CTRLB CP '2' ;TEST IF 15 LINES JR NZ,CTRLC ;NOT IF LINES INC B LD (HL),0EH ;15 LINES ; CTRLC CP '3' ;TEST FOR 1 PAGE JR NZ,CTRLD ;NOT ONE PAGE INC B LD (HL),42H ;ONE PAGE ; CTRLD CP '4' ;TEST FOR 7FH LINES JR NZ,CTRLE INC B LD (HL),7FH ; CTRLE CP '5' ;TEST FOR 255 BYTES JR NZ,CTRLY INC B LD (HL),0FFH ; CTRLY DEC B ;TEST FLAG BYTE JR Z,CONT1 ;CONTINUE JR CTRLX ;TRY AGAIN FOR LEGAL ;INPUT ; CONT2 LD A,1 LD (BRKMSG),A ; CONT1 LD A,(HL) ;GET NO OF BYTES FOR ;A RUN DEC HL ;POINT TO RUN LD (HL),A ;STORE BYTES IN A RUN ; ;CALCULATE WHERE NEXT BYTE SHOULD GO ; CALCUL LD HL,(BKADR) ;GET POSITION LD A,(HL) ;GET CTRL BYTE IN ACCUM. LD B,A ;MOVE CTRL BYTE IN B REG LD A,(STKADR-2) ;GET FLAGS BIT 3,B ;TEST FOR 08H BIT HIGH JR NZ,FLGSTR CPL ;INVERT FLAGS FLGSTR LD (FLAGS),A ;STORE FLAGS LD DE,REGLD ;LOAD FOR RETURN JUMP PUSH DE ;PUSH JUMP INTO STACK ; ;TEST FOR CALLS, JUMPS, RETURNS AND ( )JUMPS ; LD A,(IBUF) ;GET CTRL BIT 6,A ;TEST FOR JUMP REALITIVEES JR NZ,JMPREL BIT 5,A ;TEST FOR (IY)JUMP JR NZ,JUMPIY BIT 4,A ;TEST FOR (IX)JUMP JR NZ,JUMPIX ; ;THIS ROUTINE TESTS FOR 8080 JUMPS ;CALLS AND RETURNS ; LD HL,(BKADR); GET BREAK ADR. IN HL LD A,(HL) ;GET CONTROL IN ACCUM. AND 0C0H ;GET HIGH OCTAL DIGIT CP 0C0H JR Z,FRQART ;IN ACCUMULATOR ; ;THIS ROUTINE CALCULATES WHERE THE NEXT ;BYTE GOES USING INFORMATION FROM BYTES ; NXTBYT LD A,(IBUF) ;GET CTRL AND 7 ;STRIP UNWANTED DATA LD B,A ;GET DATA IN B REG ADD1 INC HL DJNZ ADD1 ;INC TO B REG = 0 RET ; ;THIS ROUTINE TEST FOR CONDITIONAL CALLS ;JUMPS, RETURNS AND (HL) JUMPS ; FRQART LD A,(HL) ;GET CONTROL IN ACCUM. CP 0C3H ;TEST FOR JUMP JR Z,COND CP 0CDH ;TEST FOR CALL JR Z,COND CP 0C9H ;TEST FOR RETURN JR Z,XRET CP 0E9H ;TEST FOR (HL)JUMP JR Z,XPCHL AND 07H ; STRIP UPPER 4 BITS CP 00H ;TEST FOR CONDITIONAL RET JR Z,CRET CP 04H ; TEST FOR COND. CALLS JR Z,TEST CP 02H ;TEST FOR COND. JUMPS JR Z,TEST LD A,(HL) ;GET CTRL OR 38H CP 0FFH ;TEST FOR RST JR Z,XRST ;RST JR NXTBYT ;CALC. WHERE NXT BYTE IS ; JUMPIY LD HL,(STKADR-10) RET ; JUMPIX LD HL,(STKADR-8) RET ; XPCHL LD HL,(STKADR) RET ; COND LD HL,(SM0ADR) ;WHAT THE HELL IS THIS RET ; XRET CALL ADRRET ;GET ADDRES OF RET RET ; ADRRET LD (SM0AD2),SP;SAVE WORK STACK LD SP,(STKAD2);GET FOREIGN STACK POP HL ;GET RETURN ADR IN H&L LD SP,(SM0AD2);RET WORK STACK RET ; CRET CALL ADRRET LD (SM0ADR),HL;POKE RET ADR. LD HL,(BKADR);REPLACE BREAK ADR JR TEST ; JMPREL LD HL,(BKADR) ;GET POSITION IN HL LD A,(HL) ;GET CONTROL IN ACCUM. CP 018H ;TEST FOR JUMP REALITIVE JR Z,COND INC HL INC HL CP 010H ;TEST FOR DJNZ JR Z,XDJNZ ADD 0A0H ;MAKE STD. JP OPCODE JR TESTB ;TEST AS 8080 JUMPS ; ;DJNZ TEST ROUTINE ; XDJNZ LD A,(STKADR-3);GET B REG. IN A REG. DEC A RET Z JR COND ; ;TEST FOR WHICH CONDITION CARRY, ZERO ;PARITY, AND SIGN ; TEST CALL NXTBYT LD DE,(BKADR) LD A,(DE) ;GET CONTROL BYTe TESTB AND 0F0H ;STRIP LOWER 4 BITS CP 0C0H ;TEST FOR ZEROS JR Z,XZERO CP 0D0H ;TEST FOR CARRYS JR Z,XCARRY CP 0E0H ;TEST FOR PARITY JR Z,XPARIT ; ;TEST FOR SIGN ; LD A,(FLAGS) ;GET FLAGS IN ACCUM. BIT 7,A ;TEST FOR SIGN RET Z JR COND ; ;TEST FOR ZERO CONDITION ; XZERO LD A,(FLAGS) ;GET FLAGS IN ACCUM BIT 6,A ;TEST FOR ZERO RET Z JR COND ; ;TEST FOR CARRY CONDITION'S ; XCARRY LD A,(FLAGS) BIT 0,A ;TEST FOR CARRY RET Z JR COND ; ;TEST FOR PARITY CONDITIONS ; XPARIT LD A,(FLAGS) BIT 2,A ;TEST FOR PARITY FLAG RET Z JR COND ; XRST LD A,(HL) ;GET CTRL AND 38H ;CONVERT TO RST CP 30H ;TEST FOR RST 38 ERRX JP Z,ERR1 ;RST 38 WONT WORK LD L,A ;GET RST ADR IN L LD H,0 ;ZERO H REG RET ; ;LOAD REGISTERS AND EXECUTE ONE BYTE ; ; ;TEST FOR REBREAK ; REGLD LD A,H ;GET HIGH BIT IN A OR A ;TEST FOR 00 JR NZ,REGLD2 ;NO RST PROBLEMS LD A,L ;GET LOWER BYTE IN A ADD 0CEH ;ADD TEST FACTOR JR Z,ERRX ;NO NO INC A ;NEXT TEST JR Z,ERRX ;NO NO INC A ;LAST TEST JR Z,ERRX ;NO NO ; ;TEST FOR REBREAK ; REGLD2 LD (BKBYT),HL ;SAVE BREAK BYTE EX DE,HL ;SAVE BREAK ADDR. LD A,(TBYTE) ;GET TEST BYTE BIT 0,A ;TEST IF SET UP JR Z,TSX2 ;NOT THIS REBREAK OR A ;GET RID OF CARRY FLAG LD HL,(TBK1) ;TEST BYTE NO. 1 SBC HL,DE ;TEST JR NZ,TSX2 ;NO REBREAK LD HL,(BK1) ;GET NEW BREAK POINT JR BKMSG ;SETUP FOR NEW BREAK ; TSX2 BIT 1,A ;TEST IF SETUP JR Z,TSX3 ;NOT SET UP OR A ;CLEAR CARRY FLAG LD HL,(TBK2) ;TEST BREAK NO. 2 SBC HL,DE ;TEST JR NZ,TSX3 ;NO REBREAK LD HL,(BK2) ;GET NEW BREAK JR BKMSG ; TSX3 BIT 2,A ;TEST IF SET UP JR Z,TSX4 ;NOT SET UP OR A ;CLEAR CARRY FLAG LD HL,(TBK3) ;TEST BREAK NO. 3 SBC HL,DE ;TEST JR NZ,TSX4 ;NO REBREAK LD HL,(BK3) ;NEW BREAK POINT JR BKMSG ; TSX4 BIT 3,A ;TEST IF SETUP JR Z,REGLD0 ;NO BREAK POINT OR A ;CLEAR CARRY FLAG LD HL,(TBK4) ;GET TEST BREAK NO. 4 SBC HL,DE ;TEST JR NZ,REGLD0 ;NO REBREAK LD HL,(BK4) ;NEW BREAK POINT ; BKMSG LD (BKBYT),HL ;STORE NEW BREAK POINT CALL CRLF.5 LD HL,BKMSG2 CALL BUFOT2 CALL CRLF.5 ; REGLD0 LD HL,(BKBYT) ;GET NEW BREAK BYTE LD A,(IOBYT) ;GET IN OUT BYTE BIT 1,A ;TEST IF LIST ACTIVE CALL NZ,LSTAT ;WAIT IF LIST ACTIVE LD A,(HL) ;GET NEXT OPCODE LD (OPSAVE),A ;SAVE NEXT OP CODE LD A,0F7H ;LOAD RESTART OPCODE LD (HL),A ;POKE RST IN MEM. LD (BKADR),HL ;SAVE ADDRES OF BREAK LD SP,STKADR-20 POP HL POP DE POP BC POP AF EX AF,AF' EXX POP AF LD I,A POP IY POP IX POP DE POP BC POP AF POP HL LD SP,(STKAD2) ;GET ORIGNAL STACK JP JMPADR ;GET READY FOR NEXT BYTE ; MSG9 DB 'A FLAG B C D E H L M IX IY SP PC' DB ' PAGE # ',0A0H BKMSG2 DM 'REBREAK' TITLE Z80 DISASSEMBLER ; ;DISASSEMBLER COMMAND ROUTINE ; ZDISAC LD (HERE),HL ;STORE PRESSENT ADR PUSH DE PUSH HL CALL BYTES POP HL CALL OFFAD2 ;PRINT OUT ADR ;& TWO SPACES LD A,(IBUF) ;GET CTRL AND 7 ;STRIP OF FLAGS LD B,A ;GET BYTES IN B LD C,0AH ;TOTAL SPACES HEX0T CALL MOUT ;OUT ASCII BYTES INC HL ;INCREAD ADR DEC C ;DECREASE SPACES DEC C DJNZ HEX0T ;KEEP GOING ; PUSH HL ;STORE NEXT ADR LD B,C ;SET FOR RESPACE CALL RSPACE CALL ZDISA ;OUTPUT MNEMONIC POP DE ;GET NEXT HERE POP HL ;GET END ADR PUSH HL ;SAVE END ADR AND A ;CLEAR CARRY FLAG SBC HL,DE ;CALCULATE POP HL ;GET END ADR EX DE,HL ;PROPER POS RET C ;DONE CALL CRLF ;GET A NEW LINE JR ZDISAC ;Keep going ; BYTES LD HL,(HERE) ;GET POSITION LD A,(HL) ;GT CTRL BYT IN A CP 0CBH ;TEST FR CB FAMILY JR Z,TWOBYT CP 0DDH ;TEST FOR DD FAMLY JR Z,FAMDD CP 0FDH ;TEST FD FAMILY JR Z,FAMFD CP 0EDH ;TEST ED FAMILY JR Z,FAMED ; ;CHECK FOR JUMP REALITIVES ; LD BC,6 ;SIX JRS LD HL,TAB1 ;JR TABLE ADDR. CPIR ;SEARCH FOR JR JR Z,AJR ;JP IF JR ; ;NO SYMBAL TWO BYTE 8080 OPCODES ; LD BC,12H ;NO. OF TWO BYTS LD HL,TAB2 CPIR ;TEST FOR TWO BYTS JR Z,TWOBYT ; ;TEST FOR THREE BYTE 8080 OPCODES ;PRODUCING SYMBALS ; LD BC,1AH ;NO. OF THREE BYTS CPIR ;TEST FOR 3 BYTS JR Z,BYTES3 ; ;ONE BYTE 8080 ROUTINE ; LD A,1 ;ONE BYTE JR STIBUF ;STORE ; ;THIS ROUTINE SEPERATES TWO AND ;FOUR BYTE OF THE ED FAMILY OF ;Z80 OPCODES ; FAMED INC HL ;GET POINTER LD A,(HL) ;GET CONTROL BYTE LD HL,TAB3 ;GET TABLE ADDRES LD BC,8 ;NO. SM0 PRODUCERS CPIR ;TEST FOR SM000'S JR Z,SM0BYT ; ;TWO BYTE OPCODES ; TWOBYT LD A,2 JR STIBUF ;STORE ; ;STORE FLAGS AND NO. OF BYTES IN I ;REG AND STORE ADDRESS OF SM000 ; SM0BYT LD A,84H LD (IBUF),A ;STORE CTRL LD HL,(HERE) ;GET START OF INSTR. INC HL ;GET POSITION INC HL SM02 LD E,(HL) ;GET LOW ADDRESS INC HL LD D,(HL) ;GET HIGH ADDRESS EX DE,HL ;GET IN RIGHT POS JR STRSM0 ;STORE ; BYTES3 LD HL,(HERE) ;GET ADDRESS INC HL ;POINT LOW ADR. LD A,83H ;FLAG AND BYTES LD (IBUF),A ;STORE CTRL JR SM02 ; FAMDD INC HL LD A,(HL) CP 0E9H ;TEST FOR DDJMP JR NZ,FAMDFD LD A,12H ;SET FLAGS JR STIBUF ;STORE ; FAMFD INC HL LD A,(HL) CP 0E9H ;TEST FOR FDE9 JR NZ,FAMDFD LD A,22H ;SET FLAGS STIBUF LD (IBUF),A ;STORE CTRL RET ; ;DD &FD FAMILY ; FAMDFD LD HL,TAB4 ;DD & FD OPCODES LD BC,1AH ;NO. OF 3 BYTES CPIR ;TEST FOR 3 BYTES JR Z,ZBYTE3 LD BC,3 CPIR ;TETS FOR SM000S JR Z,SM0BYT CP 36H ;TEST FOR 36 JR Z,BYTES4 CP 0CBH ;TEST FOR CB'S JR Z,BYTES4 JR TWOBYT ; BYTES4 LD A,4 JR STIBUF ;STORE ; ZBYTE3 LD A,3 JR STIBUF ;STORE ; ;THIS ROUTINE CALCULATES JUMP RELITIVES ; AJR LD A,0C2H ;JR EXISTS LD (IBUF),A ;STORE CTRL LD HL,(HERE) ;GET POSITION INC HL LD A,(HL) ;GET JUMP BYTE INC HL LD C,A ;GET JP FACTOR IN C RLA ;TEST FOR 7 BIT HIGH SBC A ;GET 00 OF FF LD B,A ;GET RESULTS IN B ADD HL,BC ;GET RESULTS LD BC,(OFSET) ADD HL,BC STRSM0 LD (SM0ADR),HL ;STORE RESULTS RET ; ;TABLES OF CONTROL CHARACTERS ; TAB1 DB 10H ;JUMP REALITIVES DB 18H DB 20H DB 28H DB 30H DB 38H ; ;TAB 2 REMAING 8080 TWO AND THREE ;BYTE OPCODES ; TAB2 DB 06H ;18H N0. OF TW0BYTE DB 0EH DB 16H DB 1EH DB 26H DB 2EH DB 36H DB 3EH DB 0C6H ;ACUM MATH-LOG DB 0CEH DB 0D6H DB 0DEH DB 0E6H DB 0EEH DB 0F6H DB 0FEH DB 0D3H ;OUT DB 0DBH ;IN ; ;THREE BYTE 8080 ; DB 01H ;12 NO.3BYTES DB 11H DB 21H DB 31H DB 22H DB 2AH DB 32H DB 3AH DB 0C2H ;CALLS DB 0CAH DB 0CDH DB 0D2H DB 0DAH DB 0E2H DB 0EAH DB 0F2H DB 0FAH DB 0C3H ;JUMPS DB 0C4H DB 0CCH DB 0D4H DB 0DCH DB 0E4H DB 0ECH DB 0F4H DB 0FCH ; ;ED OPCODES ; TAB3 DB 43H DB 4BH DB 53H DB 5BH DB 63H DB 6BH DB 73H DB 7BH ; ;DD & FD OPCODES ; TAB4 DB 26H ;2 ADD. BYTES DB 2EH DB 34H DB 35H DB 46H DB 4EH DB 56H DB 5EH DB 66H DB 6EH DB 70H DB 71H DB 72H DB 73H DB 74H DB 75H DB 77H DB 7EH DB 86H ;MATH-LOGIC DB 8EH DB 96H DB 9EH DB 0A6H DB 0AEH DB 0B6H DB 0BEH ;1AH BYTES ; DB 21H ;SM0ING BYTES4 DB 22H DB 2AH ; ; ;DISASSEMBLER ROUTINES ; ZDISA XOR A ; ZERO ACCUMULATOR LD E,A ;STORE 00 IN D REG LD IY,(HERE) ;GET ADR OF DISA LD A,(IY+00) ;GET CNRL IN A REG CP 0CBH ;TEST FOR CB FAM JP Z,PCB ;CB PROCESS CP 0DDH ;TEST FOR DD FAMILY JR Z,PROCDD CP 0EDH ;TEST FOR ED FAMILY JR Z,PROCED CP 0FDH ;TEST FOR FD FAMILY JR Z,PROCFD ; PRODFD AND A ;CLEAR FLAGS CALL NPROC1 ;TEST FOR NO PROCESS JP NC,PROC1 ;PROCES AS NOPROCESS LD IX,TABPRI ;ADDRESS OF TABLE LD A,E ;GET DD-FD FLAGS CP 0 ;TEST FOR 8080 TYPE JR Z,DEFIND LD IX,TABDFD ;GET DD-FD TABLE DEFIND CALL PFIND JP C,PROC3 LD A,D ;GET CTRL OR 3FH ;GET LOWER 6 BITS CP 0BFH ;TEST FOR LGMATH JP Z,P23 LD A,D ;GET CTRL OR 38H CP 0FEH ;TEST FOR ACC. LGMATH JP Z,P24 JR ERR2 ; PROCDD SET 0,E ;SET DD FLAGS JR PDFD PROCFD SET 1,E ;SET FD FLAGS PDFD INC IY ;ADVANCE ADR LD A,(IY+00) ;GET CTRL IN A CP 0CBH ;TEST FOR DD-FD CB'S JP Z,PDFDCB ;DD CB ?? ?? JR PRODFD ;PROCESS AS 8080 TYPE ; ;ED PROCESS ; PROCED LD BC,15H ;NO OF NO PROCESS LD HL,TABN2 ;TABLE FOR ED INC IY ;GET PROPER POSITION LD A,(IY+00) ;GET CTRL AND A ;CLEAR FLAGS LD D,0EH ;CORRECT FOR TAB POSITION CALL NXTCP ;READY FOR TEST JP NC,PROC1 LD IX,TABED ;ED TABLE CALL PFIND JP C,PROC3 ;MATCH HAS BEEN MADE ERR2 LD HL,TBERR2 ;? JP MSGOUT ;OUT ? ; ;TEST FOR NO PROCESS OPCODES ; NPROC1 LD BC,0EH ;NO OF OPCODES LD HL,TABN1 ;TAB OF NO PROCESS OPCODES LD D,0 ;GET 00 IN D REG NXTCP CPI ;CHECK FOR MATCH RET Z ;READY FOR PROCESS PUSH AF INC D ;INCREASE FOR MSG OUT POP AF ;RETREIVE FLAGS JP PE,NXTCP ;KEEP SEARCHING LD A,(IY+00) LD D,A SCF ;FLAG NO MATCH RET ;RETURN TO CALLER ; ;SETUP FOR OPCODE REQ PROCESS ; PFIND LD A,(IX+00) ;GET DATA BYTE CP 0FFH ;CHECK FOR END RET Z ;END OF TABLE AND 0C0H ;STRIP OFF LOWER BYTES RLCA RLCA INC A LD B,A ;GET READY FOR DJNZ LD HL,ORIT-1 ;LOAD ADDRESS OF OR'S ADVOR INC HL DJNZ ADVOR LD A,D ;GET CTRL BYTE IN A OR (HL) CP (IX+02) ;IS THERE A MATCH JR Z,NEXSTP ;MATCH HAS BEEN MADE INC IX INC IX INC IX JR PFIND ; NEXSTP SCF ;SET CARRY FLAG RET ;RET TO CALLER ; ; ORIT DB 00H ;NO OR DB 30H ; OR 30H DB 38H ; OR 38H DB 3FH ; OR 3FH ; TABN1 DB 00H ;NOP DB 07H ;RLCA DB 0FH ;RRCA DB 17H ;RLA DB 1FH ;RRA DB 27H ;DAA DB 2FH ;CPL DB 37H ;SCF DB 3FH ;CCF DB 0C9H ;RET DB 0D9H ;EXX DB 0F3H ;DI DB 0FBH ;EI DB 76H ;HALT ; TABN2 DB 67H ;RRD DB 6FH ;RLD DB 0A0H ;LDI DB 0A1H ;CPI DB 0A2H ;IND DB 0A3H ;OUTI DB 0A8H ;LDD DB 0A9H ;CPD DB 0AAH ;IND DB 0ABH ;OUTD DB 0B0H ;LDIR DB 0B1H ;CPRI DB 0B2H ;INIR DB 0B3H ;OTIR DB 0B8H ;LDDR DB 0B9H ;CPDR DB 0BAH ;INDR DB 0BBH ;OTDR DB 44H ;NEG DB 45H ;RETN DB 4DH ;RETI ; ;PRIMARY FINDER TABLE ; TABDFD DB 00H,22H,36H;DD/FD 36 LD DB 00H,18H,66H;FD 66 LD H,(IY+00) DB 00H,18H,6EH;FD 6E LD L,(IY+00) DB 00H,19H,74H;FD 74 LD (IY+00),H DB 00H,19H,75H;FD 75 LD (IY+00),L ; TABPRI DB 01H,00H,08H;08 EX AF,AF' DB 02H,01H,10H;10 DJNZ DB 16H,01H,18H;18 JR DB 96H,03H,38H;20 JR NZ,XXXX 16+80 DB 40H,04H,31H;01 LD BC,XX 00+40 DB 4DH,05H,39H;09 ADD HL,BC 0D+40 DB 80H,06H,3AH;02 LD ??? 00+80 DB 47H,07H,33H;03 INC BC 07+40 DB 48H,08H,3BH;0B DEC BC 08+40 DB 87H,09H,3CH;04 INC B 07+80 DB 88H,0AH,3DH;05 DEC B 08+80 DB 80H,1BH,3EH;06 LD B,XX 00+80 DB 84H,0BH,0F8H;C0 RET NZ 04+40 DB 0C0H,14H,7FH;40 LD B,B DB 46H,0CH,0F1H;C1 POP BC 06+40 DB 09H,0DH,0E9H;E9 JP (HL) DB 00H,0EH,0F9H;F9 LD SP,HL DB 89H,0FH,0FAH;C2 JP NZ,XXXX 09+80 DB 09H,02H,0C3H;C3 JP DB 0AH,11H,0D3H;D3 OUT DB 0BH,10H,0DBH;DB IN A,XX DB 01H,12H,0E3H;EX SP,HL PROCESS ? F9 DB 01H,13H,0EBH;EB EX DE,HL DB 83H,0FH,0FCH;C4 CALL NZ,XXXX 03+80 DB 45H,0CH,0F5H;C5 PUSH BC 05+40 DB 03H,02H,0CDH;CALL XXXX DB 8CH,15H,0FFH;RST 00 0C+80 DB 0FFH ;END OF TABLE ; ;PRIMARY FINDER ED TABLE ; TABED DB 8BH,16H,78H;ED 40 IN B,(C) DB 8AH,17H,79H;ED 41 OUT (C),B DB 50H,05H,72H;ED 52 SBC HL,BC DB 4EH,05H,7AH;ED 4A ADC HL,BC DB 40H,1CH,73H;ED 43 LD (XXXX),BC DB 40H,1DH,7BH;ED 4B LD BC,(XXXX) DB 95H,1EH,7EH;ED 46 IM 0 DB 00H,1FH,47H;ED 47 LD I,A DB 00H,20H,57H;ED 57 LD A,I DB 00H,21H,4FH;ED 4F LD R,A DB 00H,1AH,5FH;ED 5F LD A,R DB 0FFH ;END OF TABLE ; ; PCOMD PUSH DE LD D,0 ;GET ZERO IN D REG. LD B,87H ;SET FOR NO REPOT LD A,(IX+01) ;GET PROCESS IN ACC. ADD A LD E,A ;GET OFFSET IN E LD HL,PRCOMD ;GET START OF TABLE ADD HL,DE ;GET TABLE POSITION LD E,(HL) ;GET LOW BYTE INC HL LD D,(HL) ;GET HIGH BYTE EX DE,HL ;GET JP ADR IN HL POP DE ;RETREIVE DATA JP (HL) ; ; PRCOMD DW P00 ;00 08 EX AF,AF' DW P01 ;01 10 DJNZ DW P01 ;01 C3 CD [JP CALL] DW P03 ;03 20 JR COND DW P04 ;04 21 LD HL,XXXX DW P05 ;05 09 ADD HL,BC+ DW P06 ;06 2A ???,??? DW P07 ;07 23 INC ?? DW P07 ;08 2B DEC ?? DW P09 ;09 2C INC ? DW P09 ;0A 35 DEC ? DW P0B ;0B F0 RET COND DW P25 ;0C E5 PUSH ?? DW P0D ;0D JP (??) DW P0E ;0E LD SP,?? DW P0F ;0F F2 JP COND DW P10 ;10 DB IN A,XX DW P11 ;D3 OUT XX,A DW P12 ;12 E3 (SP),?? DW P13 ;13 EB EX DE,HL DW P14 ;14 40 LD ?,? DW P15 ;15 FF RST DW P16 ;16 ED 78 IN ?,(C) DW P17 ;17 ED 79 OUT (C),? DW P18 ;18 ?? 6E66 LD ?,(IX+??) DW P19 ;19 ?? 7475 LD ?,(IX,??) DW P1A ;1A ED 5A LD A,R DW P1B ;1B LD ?,XX DW P1C ;1C ED 43 LD (XXXX),BC DW P1D ;1D ED 4B LD BC(XXXX) DW P1E ;1E ED46 IM ? DW P1F ;1F ED 47 LD I,A DW P20 ;20 ED 4F LD A,I DW P21 ;21 ED 57 LD R,A DW P22 ;22 DD 35 LD (IX+?),XX ; ; ;OUTPUTING MESSAGE FINDER ; MSGFND INC C DEC C JR Z,MSGOUT ;READY FOR MSG JR MXTEST ADV INC HL MXTEST LD A,(HL) ;GET CHAR. IN A AND A JP P,ADV ;NOT AT END INC HL DEC C JR Z,MSGOUT JR MXTEST ; MSGOUT LD A,(HL) PUSH AF AND 7FH BIT 5,A ;TEST FOR TOKEN JR NZ,TOKTST ;JP TO TEST TOKEN NOTOKE CALL OUTPUT DEC B TOKRET POP AF ;RETREIVE AF INC HL AND A RET M JR MSGOUT ; ;ADDITIONAL TOKENS WILL BE ADDED LATER ; TOKTST BIT 6,A ;IF HIGH TOKEN JR Z,NOTOKE ;NUMBER OR SPACE CP 61H JR Z,HEXOT1 CP 62H JR Z,ADOUT.2 CP 63H JR Z,TOK3 ;HL,IX,IY CP 64H JR Z,TOK4 ;(HL),(IX+XX),(IY+XX) CP 65H JR Z,TOK5 ;H X Y CP 66H JR Z,TOK6 ;L X' Y' CP 67H ;TEST FOR NO OUTPUT JR Z,TOKRET ;NO OUTPUT JP ERR1 ; TOK4 PUSH HL ;SAVE ADR LD HL,TOK4B ;(IX+XX) BIT 0,E ;TEST FOR DD JR NZ,TOKOUT BIT 1,E ;TEST FOR ED LD HL,TOK4C ;(IY+XX) JR NZ,TOKOUT LD HL,TOK4A ;(HL) TOKOUT CALL MSGOUT POP HL ;RETREIVE MSG ADR JR TOKRET ; TOK3 PUSH HL ;SAVE ADR LD HL,TOK3B ;IX BIT 0,E ;TEST FOR DD JR NZ,TOKOUT LD HL,TOK3C ;IY BIT 1,E ;TEST FOR FD JR NZ,TOKOUT LD HL,TOK3A ;HL JR TOKOUT ; TOK5 PUSH HL ;SAVE ADR LD HL,TOK5B ;X BIT 0,E ;TEST FOR DD JR NZ,TOKOUT LD HL,TOK5C ;Y BIT 1,E ;TEST FOR FD JR NZ,TOKOUT LD HL,TOK5A ;H JR TOKOUT ; TOK6 PUSH HL ;SAVE ADR LD HL,TOK6B ;;X' BIT 0,E ;TEST FOR DD JR NZ,TOKOUT LD HL,TOK6C ;Y' BIT 1,E ;TEST FOR FD JR NZ,TOKOUT LD HL,TOK6A ;L JR TOKOUT ; HEXOT1 LD A,(IY+01) CALL HEXOUT JP TOKRET ; ADOUT.2 PUSH HL ;SAVE MSG ADR LD HL,(SM0ADR);GET ADR CALL ADOUT POP HL RES 7,B ;SET FOR REPOT JP TOKRET ; ;ROTATOR ROUTINE ;HL CONTAINS MESSAGE ADR. ; AND30 LD A,D ;GET CTRL RES 6,A ;ZERO 6 BIT RRCA ;GET DATA IN PROP POS JR AND38A AND38 LD A,D ;GET CTRL AND38A RRCA RRCA RRCA JR AND07A AND07 LD A,D AND07A AND 07H ;STRIP UPPER BITS LD C,A ;GET DATA IN C REG. CALL MSGFND RET ; ; ;ARGUMENT PROCESSES ; P00 LD HL,PT00 ;ROCESS 00 JR MSGOT2 ; P01 LD HL,PT01 ;PROCESS 01 JR MSGOT2 ; ; P10 LD HL,PT10 ;PROCESS 10 JR MSGOT2 ; P11 LD HL,PT11 ;PROCESS 11 JR MSGOT2 ; P13 LD HL,PT13 ;PROCESS 13 JR MSGOT2 ; P0D LD HL,PT0D ;(HL) JR MSGOT2 ; P0E LD HL,PT0E ;SP,HL IX IY JR MSGOT2 ; P15 LD A,D ;GET CTRL AND 38H ;CONVERT TO RST NO. JP HEXOUT ; P12 LD HL,PT12 ;(SP),HL IX IY JR MSGOT2 ; P1A LD HL,PT1A ;A,R JR MSGOT2 ; P1F LD HL,PT1F ;I,A JR MSGOT2 ; P20 LD HL,PT20 ;A,I JR MSGOT2 ; P21 LD HL,PT21 ;R,A JR MSGOT2 ; P05 LD HL,PT5A ;HL, CALL MSGOUT ;OUTPUT HL, JR P07 ;BC DE ?? SP ; P03 LD A,D ;GET CTRL IN A SUB 20H ;ADJ FOR ROT LD D,A ;STORE VALUE CALL P0B ;OUT COND P03A LD HL,PT03 ;,XXXX JR MSGOT2 ; P0B LD HL,PT0F ;CONDITIONALS JR AND38B ;OUTPUT ; P0F CALL P0B ;OUT CONDITIONALS JR P03A ; P04 CALL P07 ;BC DE ?? SP JR P03A ;OUTPUT ; P07 LD HL,PT5B ;BC DE ?? SP AND30B JR AND30 ;OUT REG. ; P09 LD HL,PT14 ;B C D E ?? JR AND38B ;OUTPUT ; P1B CALL P09 ;B C D E ? ? P1BA LD HL,PT1B ;,XX MSGOT2 JP MSGOUT ; P14 CALL P09 ;B C D E ? ? CALL COMMA ;, P14B LD HL,PT14 ;B C D E ? ? JR AND07B ;OUTPUT ; P23B LD B,06H ;SET FOR REPOT LD HL,TABMN4 ;ADD ADC SUB CALL AND38 ;OUTPUT MNEMONIC CALL RSPACE ;SET FOR SIX SPACES LD B,8AH ;SET FOR NO REPOT LD HL,PT22 ;TABLE OF PREFIXES CALL AND38 ;OUTPUT PREFIXES RET ;RETURN TO CALLER ; P23 CALL P23B ;SAVE MEMORY JR P14B ;B C D E ? ? ; P24 CALL P23B ;SAVE MEMORY LD HL,PT1B+1 ;XX JR MSGOT2 ;OUTPUT XX ; P16 CALL P17B ;H L ? A LD HL,PT16A ;,(C) JP MSGOUT ;OUTPUT ,(C) ; P17 LD HL,PT16A+1;(C) CALL MSGOUT CALL COMMA ;OUT , P17B LD HL,PT16B ;H L ? A AND38B JP AND38 ;OUTPUT REG ; P1C LD HL,PT06B ;(XXXX) CALL MSGOUT CALL COMMA ;OUT , JR P07 ;BC DE ?? SP ; P1D CALL P07 ;BC DE ?? SP LD HL,PT06A ;,(XXXX) JR MSGOT2 ; P1E LD HL,PT1E ;0 ? JR AND38B ;OUTPUT IT ; P18 LD HL,PT23 ;B C D E H CALL AND38 CALL COMMA ;OUT , JR P14B ;B C D E ? ? ; P19 CALL P09 ;B C D E ? ? CALL COMMA ;OUT , P19B LD HL,PT23 ;B C D E H L AND07B JP AND07 ; P22 CALL P09 ;B C D E ? ? INC IY JR P1BA ; P25 LD HL,PT25 ;BC DE ?? AF JP AND30 ;OUTPUT ; SUBCB LD A,D ;GET CTRL IN ACUM. LD B,06H ;6 SPACES AND 0C0H ;STRIP LOWER BITS RRCA RRCA RRCA LD HL,TABCB ;-- BIT RES CALL AND38A ;OUTPUT REG. LD A,B ;GET REPOT NO IN A. CP 06H ;TEST FOR OUTPUT JR NZ,CRSPAC ;HEAD FOR REPOT LD HL,TABCB1 ;RLC, RRC, RL RR CALL AND38 ;OUTPUT ROTATE TYPE CRSPAC CALL RSPACE ;OUT SPACES LD B,08AH ;NO RESPACE LD A,D ;GET CTRL AND 0C0H ;STRIP LOWER BITS CP 00H ;TEST FOR ROTATES RET Z ;NO BIT NO. LD HL,TBCB2 ;0, 1, 2, 3, CALL AND38 ;OUTPUT BIT NO. SCF ;SET CARRY FLAG RET ;RETURN TO CALLER ; PCB LD D,(IY+01) ;GET CTRL IN D CALL SUBCB ;PRINT OUT MNEMONIC JR P19B ;B C D E H L ; PDFDCB LD D,(IY+02) ;GET CTRL CALL SUBCB ;OUTPUT MNEMONIC JR C,DFDCB ;PROCESS BIT RES SET SUBCB1 LD HL,TCBDFD ;(IY+??)B JR AND07B ;OUTPUT ; DFDCB LD A,D ;GET CTRL AND A ;TEST FOR BIT JP M,SUBCB1 ;NOT BIT LD HL,TCBFDF ;(IY+??) JR AND07B ;OUTPUT ; P06 LD HL,PT06 ;???,??? JP AND38 ;OUTPUT IT ; COMMA LD HL,OUTXXX ;, JP MSGOUT ;OUT , ; ;OUTPUT MNEMONIC FOR NONPROCESS OPCODES ; PROC1 LD C,D ;GET CTRL IN C REG LD HL,TABMN1 LD B,86H ;SET FOR NO REPOT JP MSGFND ; ; PROC3 LD HL,TABMN3 ;GET TBL IN HL REG LD A,(IX+00) AND 3FH ;STRIP UPPER 2 BITS LD C,A ;GET CTRL IN C REG LD B,6 ;MAX OF 6 SPACES CALL MSGFND ;OUTPUT MNEMONIC CALL RSPACE JP PCOMD ; TABMN1 DB 'NO',0D0H ;00 NOP DB 'RLC',0C1H;01 RLCA DB 'RRC',0C1H;02 RRCA DB 'RL',0C1H ;03 RLA DB 'RR',0C1H ;04 RRA DB 'DA',0C1H ;05 DAA DB 'CP',0CCH ;06 CPL DB 'SC',0C6H ;07 SCF DB 'CC',0C6H ;08 CCF DB 'RE',0D4H ;09 RET DB 'EX',0D8H ;0A EXX DB 'D',0C9H ;0B DI DB 'E',0C9H ;0C EI DB 'HAL',0D4H;0D HALT ; ;ED ONE BYTE MNOMICS ; TABMN2 DB 'RR',0C4H ;0E RRD DB 'RL',0C4H ;RLD DB 'LD',0C9H ;0FH LDI DB 'CP',0C9H ;10 CPI DB 'IN',0C9H ;11 INI DB 'OUT',0C9H;12 OUTI DB 'LD',0C4H ;13 LDD DB 'CP',0C4H ;14 CPD DB 'IN',0C4H ;15 IND DB 'OUT',0C4H;16 OUTD DB 'LDI',0D2H;17 LDIR DB 'CPI',0D2H;18 CPIR DB 'INI',0D2H;19 INIR DB 'OTI',0D2H;1A OTIR DB 'LDD',0D2H;1B LDDR DB 'CPD',0D2H;1C CPDR DB 'IND',0D2H;1D INDR DB 'OTD',0D2H;1E OTDR DB 'NE',0C7H ;1F NEG DB 'RET',0CEH;20 RETN DB 'RET',0C9H;22 RETI END TABLE ; ;PROCESS MNEMONIC DATA BYTE MESSAGES ; TABMN3 DB 'L',0C4H ;00 LD DB 'E',0D8H ;01 EX DB 'DJN',0DAH;02 DJNZ DB 'CAL',0CCH;03 CALL DB 'RE',0D4H ;04 RET DB 'PUS',0C8H;05 PUSH DB 'PO',0D0H ;06 POP DB 'IN',0C3H ;07 INC DB 'DE',0C3H ;08 DEC DB 'J',0D0H ;09 JP DB 'OU',0D4H ;0A OUT DB 'I',0CEH ;0B IN DB 'RS',0D4H ;0C RST TABMN4 DB 'AD',0C4H ;OD ADD DB 'AD',0C3H ;0E ADC DB 'SU',0C2H ;0F SUB DB 'SB',0C3H ;10 SUB DB 'AN',0C4H ;11 AND DB 'XO',0D2H ;12 XOR DB 'O',0D2H ;13 OR DB 'C',0D0H ;14 CP DB 'I',0CDH ;15 IM DB 'J',0D2H ;16 JR END TABLE ; TOK3A DB 'H',0CCH ;HL TOK3B DB 'I',0D8H ;IY TOK3C DB 'I',0D9H ;IY TOK4A DB '(HL',0A9H;(HL) TOK4B DB '(IX+',61H,0A9H;(IX+??) TOK4C DB '(IY+',61H,0A9H;(IY+??) TOK5A DB 0C8H ;H TOK5B DB 0D8H ;X TOK5C DB 0D9H ;Y TOK6A DB 0CCH ;L TOK6B DB 58H,0A7H ;X' TOK6C DB 59H,0A7H ;Y' ; PT00 DB 'AF,AF',0A7H;AF,AF' PT01 DB 0E2H ;SM0ADR OUT PT10 DB 'A,',0E1H ;A,XX PT11 DB 61H,',',0C1H;XX,A PT13 DB 'DE,H',0CCH;DE,HL PT0D DB 28H,63H,0A9H;(??) PT0E DB 'SP,',0E3H;SP,?? PT12 DB '(SP),',0E3H;(SP),?? PT1A DB 'A,',0D2H ;A,R PT1F DB 'I,',0C1H ;I,A PT20 DB 'A,',0C9H ;I,A PT21 DB 'R,',0C1H ;R,A PT5A DB 63H,0ACH ;??, PT5B DB 42H,0C3H ;BC DB 44H,0C5H ;DE DB 0E3H ;?? DB 53H,0D0H ;SP PT03 DB 2CH,0E2H ;,XXXX PT0F DB 4EH,0DAH ;NZ DB 0DAH ;Z DB 4EH,0C3H ;NC DB 0C3H ;C DB 50H,0CFH ;PO DB 50H,0C5H ;PE DB 0D0H ;P DB 0CDH ;M PT22 DB 41H,0ACH ;A, DB 41H,0ACH ;A, DB 0E7H ;NO OUTPUT DB 41H,0ACH ;A, DB 0E7H ;NO OUTPUT DB 0E7H ;DITO DB 0E7H ;DITO DB 0E7H ;DITO PT14 DB 0C2H,0C3H,0C4H,0C5H;B C D E DB 0E5H,0E6H,0E4H,0C1H;? ? ? A PT23 DB 0C2H,0C3H,0C4H,0C5H;B C D E DB 0C8H,0CCH ;H L DB 28H,48H,4CH,0A9H;(HL) DB 0C1H ;A OUTXXX DB 0ACH ;, PT1B DB 2CH,0E1H ;,XX PT06 DB '(BC),',0C1H;(BC),A DB 'A,(BC',0A9H;A,(BC) DB '(DE),',0C1H;(DE),A DB 'A,(DE',0A9H;A,(DE) DB 28H,62H ;(XXXX DB 29H,2CH,0E3H;),?? DB 63H ;?? PT06C DB 2CH,28H,62H,0A9H;,(XXXX) DB 28H,62H,29H;(XXXX) DB 2CH,0C1H ;,A DB 41H ;A PT06A DB 2CH ;USED BY P1D PT06B DB 28H,62H,0A9H;(XXXX) USED BY P1C PT16A DB 2CH,28H,43H,0A9H;,(C) PT16B DB 0C2H,0C3H ;B C DB 0C4H,0C5H ;DE DB 0C8H,0CCH ;H L DB 0F8H,0C1H ;? A PT1E DB 0B0H,0BFH ;0 ? DB 0B1H,0B2H ;1 2 DB 0BFH,0BFH ;? ? DB 0BFH ;? TBERR2 DB 0BFH ;? TABCB DB 0E7H ;NO PROCESS DB 'BI',0D4H ;BIT DB 'RE',0D3H ;RES DB 'SE',0D4H ;SET TABCB1 DB 'RL',0C3H ;RLC DB 'RR',0C3H ;RRC DB 'R',0CCH ;RL DB 'R',0D2H ;RR DB 'SL',0C1H ;SLA DB 'SR',0C1H ;SRA DM 'SLL' DB 'SR',0CCH ;SRL TCBDFD DB 64H,3AH,0C2H;(IY+XX)B DB 64H,3AH,0C3H;C DB 64H,3AH,0C4H;D DB 64H,3AH,0C5H;E DB 64H,3AH,0C8H;H DB 64H,3AH,0CCH;L DB 0E4H ;(IY+??) DB 64H,3AH,0C1H;A TCBFDF DB 64H,0BAH ;(IY+??) *B DB 64H,0BAH ;*C DB 64H,0BAH ;*D DB 64H,0BAH ;*E DB 64H,0BAH ;*H DB 64H,0BAH ;*C DB 0E4H ;(IY+??) DB 64H,0BAH ;*A TBCB2 DB 30H,0ACH ;0, DB 31H,0ACH ;1, DB 32H,0ACH ;2, DB 33H,0ACH ;3, DB 34H,0ACH ;4, DB 35H,0ACH ;5, DB 36H,0ACH ;6, DB 37H,0ACH ;7, PT25 DB 42H,0C3H ;BC DB 44H,0C5H ;DE DB 0E3H ;?? DB 41H,0C6H ;AF ;END TABLE ; TITLE TWO PASS Z80 DISASSEMBLER ; ;TWO PASS ROUTINES ; PASS.2 CALL COFSET ;SET UP PAGE AND OFFSET CALL MAKSYM ;MAKE SYMBAL TABLE LD A,(BUFAD+2);GET SECOND BYTE CP '1' ;TEST FOR 1 JP Z,DISSA1 ;MAKE DISASSEMBLY ONLY CP '2' ;TEST FOR 2 JR Z,ZDISA2 ;DISA, AND CROSS REF. CP '3' ;TEST FOR 3 JP NZ,ERR1 JP CRREF2 ;MAKE CR TABLE ; ;DISASSEMBLE & CROSS REFFERENCE ; ZDISA2 CALL DISSA1 ;MAKE DISSASEMBLY JP CRREF ;MAKE TABLE ; ; ;THIS ROUTINE MAKES THE SYMBOL TABLE ; CLYSMB LD DE,TABSTA ;START ADR SYMBOL TABLE LD H,D ;GET ADR IN H REG LD L,E ;AND IN L REG. XOR A LD (HL),A ;POKE OO TABLE START INC DE LD BC,0BFCH ;TABLE LENGTH LDIR DEC (HL) ;GET FF IN MEM. LD BC,4 LDIR RET ; ;THIS IS THE SEARCH AND INSERT ROUTINE ; SEAINS LD IY,TABSTA LD DE,(SM0ADR);ADR POINTED TO SER4 LD A,(IY+0) ;COUNTER BYTE LD H,(IY+1) ;HIGH ADR LD L,(IY+2) ;LOW ADR CP 0FFH ;END TABLE? RET Z OR A ;END TAB. ENTRIES? JR Z,INS1 AND A ;CLEAR CARRY FLAG SBC HL,DE ;CHECK JR Z,INS2 ;MATCHED? JR C,INCAY ;KEEP SEARCHING JR TRANS. ;TRANSFER ROUTINE INCAY INC IY INC IY ;GET READY INC IY JR SER4 ;JUMP SEARCH ; ;LOAD INFORMATION TO BE TRANSFERED ; TRANS. LD A,1 ;SET FOR FIRST EX AF,AF' ;EXCH ACCUMS EXX ;EXCH REGISTERS INS3 LD A,(IY+0) ;GET CONTROL CHAR. LD D,(IY+1) ;HIGH ADR. LD E,(IY+2) ;LOW ADR. CP 0FFH ;END OF TBL? RET Z OR A ;END OF INSERTS? JR Z,STORE CALL STORE INC IY ;GET NEXT INC IY ;TABLE POSITION INC IY ; " " JR INS3 ;KEEP GOING STORE EX AF,AF' EXX STORE1 LD (IY+0),A ;STORE A LD (IY+1),D ;STORE HIGHER ADR. LD (IY+2),E ;STORE LOWER ADR RET INS1 INC A ;INCREASE A TO 1 JR STORE1 INS2 INC (IY+0) ;INCREASE COUNTER RET ; ;MAKE THE SYMBOL TABLE IN MEMORY ; MAKSYM CALL CLYSMB ;CLEAR SYMBOL TBL LD HL,(HEXAD) ;GET START LD (HEREX),HL ;STORE START ADR. CONT LD HL,(HEREX) ;GET POSITION LD (HERE),HL;POKE FO BYTES CALL BYTES LD A,(IBUF) ;GET CTRL BIT 7,A ;TEST FOR SM0 JR Z,HERE2 ;JMP NO SM0 CALL SEAINS ;SEARCH AND INSERT HERE2 LD HL,(HEREX) ;GET PRESENT POS. LD A,(IBUF) ;GET CTRL AND 7 ;STRIP OFF FLAGS LD B,A ;GET IN B REG. INCA INC HL ;INCA HL BY ONE DJNZ INCA ;INCREASE TO B=0 LD (HEREX),HL ;STORE NEXT POS. AND A ;CLEAR CARRY FLAG LD DE,(HEXAD2) ;GET END SBC HL,DE ;CALCULATE RESULTS RET Z RET NC ;RESULTS POSITIVE JR CONT ;CONTINUE ; SM0IT LD IX,0 LD IY,TABSTA SM0IT2 LD A,(IY+0) ;THE NUMBER OF SM0S. LD H,(IY+1) ;HIGH ADR. LD L,(IY+2) ;LOW ADR. AND A ;CLEAR CARRY FLAG SBC HL,DE ;CHECK RET Z ;RETURN WITH SM0 JR NC,XRA ;TOO FAR! INC IY INC IY INC IY ;READY FOR NEXT INC IX ;INCREASE SM0 NO. JR SM0IT2 ;KEEP GOING XRA XOR A ;ZERO ACCUM. RET ; ;THIS ROUTINE OUTPUTS THE SM00 ;NUMBER ; OUTSM0 CALL SPACE LD A,':' CALL OUTPUT PUSH IX POP HL ;TRANSFERED LD A,H CALL CHASE LD A,L CALL HEXOUT RET ; OUTSM2 LD B,10 ;NO. SM0 SPACES CALL SM0IT CP 0 ;0 IN ACCUM. RET Z ;YES PUSH AF ;SAVE NUMBER OF CALLS CALL OUTSM0 CALL SPACE POP AF ;GET NO OF CALLS CALL HEXOUT LD B,2 ;LOAD FOR SREPOT RET ; ;TWO PASS DISASSEMBLER ROUTINE ; DISSA1 LD HL,(HEXAD) ;GET STARD ADR. ; REPEAT LD (HEREX),HL ;STORE PRESENT ADR. PUSH HL LD (HERE),HL;POKE FOR BYTES CALL BYTES ;GET CTRL IN I REG. POP HL ;RETREIVE HL CALL OFFAD2 ;ADDRESS AND 2 SPACES LD A,(IBUF) ;GET CTRL AND 7 ;STRIP FLAGS LD B,A ;GET BYTES IN B REG. LD C,9 ;MAX SPACES HEXOT2 CALL MOUT ;OUT IT INC HL ;INCREASE ADDRESS DEC C ;REDUCE SPACES DEC C DJNZ HEXOT2 ;REPEAT LD B,C ;SET FOR RSPACE CALL RSPACE ;OUTPUT SPACES LD (HERE4),HL ;SAVE NEXT ADR. LD DE,(HEREX) ;READY FOR SM0IT LD HL,(OFSET) ADD HL,DE ;CALCULATE EX DE,HL CALL OUTSM2 ;OUT SM0 & NUMBER CALL RSPACE ;OUT REMAING SPACES LD HL,(HEREX) ;GET POSITION LD (HERE),HL ;START DISASA OUT CALL ZDISA ;CALL DISASS. BIT 7,B ;TEST IF REPOT CALL Z,RSPACE ;REPOT LD A,(IBUF) ;GET CTRL BIT 7,A ;TEST FOR SM0 JR Z,ENDCHX ;JP NO SM0 LD DE,(SM0ADR) ;READR FOR SM0IT CALL SM0IT ;GET SM0 NO. CALL SPACE CALL OUTSM0 ;OUTPUT NUMBER ENDCHX LD DE,(HERE4) ;NEXT ADR LD HL,(HEXAD2) ;END ADR. AND A ;CLEAR CARY FLAG SBC HL,DE ;CHECK RET C ; " " " LD HL,(HERE4) ;GET NEXT ADR. CALL CRLF ;GET A NEW LINE JR REPEAT ;KEEP GOING ; ; ;THIES ROUTINES OUTPUT THE ;CROSS REFFERENCE TABLE ; CRREF CALL CRLF ;GET A NEW LINE LD A,0CH ;GET A FORM FEED CALL OUTPUT ;OUT A FORM FEED ; ;GET SM0 AND OUT SM0 LINE ; CRREF2 LD IY,TABSTA ;TABLE START LD IX,0-1 ;0 SM0S LD (NXTSM0),IY ;STORE LD (NXTNO),IX ;STORE ; ;RETURN HERE FOR REPEAT ; RPEAT2 LD IY,(NXTSM0) ;RETREAIVE LD IX,(NXTNO) ; " LD A,(IY+0) ; NO CALLS LD H,(IY+1) ;HIGH ADR. LD L,(IY+2) ;LOW ADR. INC IY INC IY INC IY LD (NXTSM0),IY ;STORE NXT INC IX LD (NXTNO),IX LD (SM0AD2),HL ;SAVE SM0 ADR. LD DE,(HEXAD3) ;GET OFFSET ADD HL,DE ;GET RESULTS LD (HERE),HL ;STORE CP 0FFH ;END TBL? RET Z OR A ;END INSERTS? RET Z PUSH AF ;SAVE N0. CALLS CALL OUTSM0 ;OUTPUT CALL SPACE POP AF ;RETREIVE CALL HEXOUT ;OUT NO. CALLS CALL SPACE2 ;OUTPUT TWO SPACES LD HL,(SM0AD2) ;GET ADR. OF SM0 CALL ADOUT ;OUTPUT ADR. CALL SPACE2 ;OUTPUT TWO SPACES CALL BYTES CALL ZDISA ;CALL 8080-Z80 DIS. CALL SM0USR ;OUTPUT SM0USR CALL CRLF CALL SPACE JR RPEAT2 ;KEEP GOING ; SM0USR LD HL,(HEXAD) ;GET START CONT3 LD (HEREX),HL ;STORE LD (HERE),HL;POKE FOR BYTES CALL BYTES ;GET CONTROL LD A,(IBUF) ;GET CTRL BIT 7,A ;IS IT AS SM0 JR Z,CHKEND ;NO SMO LD DE,(SM0ADR) ;PROGRAM SM0 ADR. LD HL,(SM0AD2) ;TABLE SMO ADR. AND A ;CLEAR CARRY FLAG SBC HL,DE ;CALCULATE JR NZ,CHKEND ;NO MATCH CALL CRLF ;GET NEW LINE LD HL,(HEREX) ;GET PRESENT POS CALL OFFAD2 ;OUTPUT ADDRESS LD HL,(HEREX) ;GET PRESENT ADR. LD (HERE),HL;STORE FOR ZDISA CALL ZDISA ;CALL DISASSEMBLER CHKEND LD A,(IBUF) ;GET CTRL AND 7 ;STRIP LD B,A ;GET BYTES IN B LD HL,(HEREX) ;GET PRES ADR. NXTADR INC HL DJNZ NXTADR ;GO TO ZERO EX DE,HL ;SAVE IN DE REG LD HL,(HEXAD2) ;GET END ADR AND A ;CLEAR CARY FLAG SBC HL,DE RET C ;END? EX DE,HL ;GET NEXT IN HL REG. JR CONT3 ;CONI TITLE DISK UTILITY COMMANDS ; ;Boot up a CP/M type operating system ; Boot CALL HOME ;HOME THE DRIVE LD DE,0 ;WHERE TO LOAD THE ;THE BOOT LOADER PUSH DE ;MAKE IT A RET. JUMP LD (DMA),DE ;STORE THE TRANSFER ADR. INC DE ;SETUP TO READ SECTOR 1 ;TRACK 0 XOR A ;SET FOR READ JP RD.WR2 ;GO READ THE SECTOR AND ;JUMP TO THE LOADER ; ;Get track 0 & 1 for a system transfer ; Sy.Get LD A,55H ;Token for setup LD (SyByte),A ;Store setup token XOR A ;Token for Read ; SyPut2 LD (DMA),HL ;Store the DMA adr. LD DE,1 ;Set track 0 sector 1 LD (SECTOR),DE ;Store track and sector LD B,52 ;Number of sectors for ;the transfer LD (TYPE),A ;Store the read o write ;token JP M.DUMP ;Do the work ; ;Put a system on a disk ; Sy.Put LD A,(SyByte) ;Get the transfer byte CP 55H ;Test if initilized JP NZ,ERR1 ;Not setup LD A,1 ;Token fo write JR SyPut2 ;Continue elsewhere ; ;Copy disk for drive X to drive Y ; Cp.Dsk Push HL ;Save the DMA adr. LD HL,ERR1 ;Point to the error ;routine PUSH HL ;Make a return jump LD A,C ;Get the source drive SUB 'A' ;Convert to drive RET M ;Not a drive CP 2 ;Test if to large RET NC ;Too large LD C,A ;Save the source drive LD A,B ;Get the designation ;drive SUB 'A' ;Convert to drive RET M ;Not a drive number CP 2 ;Test if to many drives RET NC ;Not a existant drive CP C ;Test for the same drive RET Z ;Was same drive LD B,A ;Save drive number POP HL ;Remove the RET Jump POP HL ;Retreive the DMA Adr. PUSH AF ;Save the designation ;Drive LD A,C ;Get the source drive EXX ;Save the data registers PUSH AF ;Hide the source drive LD HL,D.Msg8 ;Copy disk from CALL BUFOT2 ;Output the message POP BC ;Retreive source drive OR A ;Clear the flags LD A,B ;Get drive number SCF ;Set the carry flag ;Do not get the Mem byte CALL DrvOut ;Output drive info LD HL,D.Msg9 ;Output the ' to' CALL BUFOT2 ;Do the outputing POP BC ;Retreive the designation ;drive OR A ;Clear the flags LD A,B ;Get the drive No. SCF ;Set the carry flag Call Ready3 ;output the data EXX ;Retreive Data regs. PUSH HL ;Start a transfer POP IX ;Finish the transfer LD H,77 ;77 tracks LD L,0 ;Start at zero track LD IY,IOBYT ;Point to the I/O byte SET 7,(IY+00) ;Go into unskewed mode ; Tr.Loop LD A,0 ;Token to read CALL CdTrans ;Read 7 tracks LD A,1 ;Token to write CALL CdTrans ;Write 7 tracks LD A,L ;Move the present ;Track to Accum. ADD 7 ;Move to the next tracks ;to be transfered LD L,A ;Save the value LD A,H ;Move remaining sectors ;to the accumulator SUB 7 ;Reduce track count LD H,A ;Saving remaning sectors JR NZ,Tr.Loop ;More to transfer ; RES 7,(IY+00) ;Return to the skewed ;mode PUSH BC CALL Home POP BC LD A,C ;Get source drive LD (DRVBYT),A ;Swtich drives JP Home ;End of routine ; CdTrans OR A ;Test if read or write LD (TYPE),A ;Store type of transfer LD A,C ;Source byte to A JR Z,CdTr2 ;Is a read ; LD A,B ;Was a write CdTr2 LD (DRVBYT),A ;Store the drive LD (DMA),IX ;Store DMA Adr. LD E,1 ;Sector 1 LD D,L ;Next track PUSH DE ;Strat transfer EXX ;Go to the back side POP DE ;Complete transfer of ;track and sector LD B,26*7 ;Number of sectors to ;transfer LD (SECTOR),DE ;Store Track and Sector Call M.DUMP ;Transfer the data EXX ;Retreive the registors RET ; ;READ X SECTORS FROM DISK ; SR XOR A JR D.RD2 ; ;WRITE X SECTORS FROM DISK ; SW LD A,1 D.RD2 LD (TYPE),A ;STORE TYPE OF OPERATION LD HL,(HEXADX) ;GET ADDRESS LD (DMA),HL ;STORE DMA CALL ADOUT2 ;OUTPUT ADDRES & SP LD HL,HEXAD ;GET THE POINTER LD B,(HL) ;SECTORS TO B INC HL INC HL LD D,(HL) ;START TRACK TO D INC HL INC HL LD E,(HL) ;START SECTOR TO E LD (SECTOR),DE ;STORE START INC B ;ZERO TEST DEC B JP Z,ILL.SEC ;COMPLAIN CALL M.DUMP ;TRANSFER DATA CALL SPACE DEC HL CALL ADOUT ;OUTPUT END RET ;END OF ROUTINE ; ;GET A TRACK ROUTINE ; T.GET XOR A ;FLAG FOR READ JR T.GET2 ;STORE TYPE ; ;STORE A TRACK ROUTINE ; T.STORE LD A,1 ;FLAG FOR REED T.GET2 LD (TYPE),A ;STORE OPERATION EX DE,HL ;(HEXAD2) IN HL REG. ;(HEXAD) IN DE REG LD (DMA),HL ;STORE DMA ADR LD A,D OR A ;TEST FOR ZERO JP NZ,ERR1 ;NO GOOD LD D,E LD E,1 ;FIRST SECTOR OF TRK. LD (SECTOR),DE ;STORE START ; T.DUMP PUSH HL ;SAVE ADDRESS LD HL,D.MSG1 ;'+ TRACK NO ' CALL BUFOT2 ;OUTPUT MSG POP HL LD A,D ;GET TRACK NO IN A CALL HXOUT2 ;OUT TRACK & SPACE CALL SPACE CALL ADOUT2 ;OUTPUT ADR. & SPACE LD B,TS.SEC-1 ;SET FOR 26 SECTORS CALL M.DUMPS ;GO TO WORK DEC HL ;POINT TO LAST BYTE CALL ADOUT ;OUTPUT END INC HL CALL CRLF CALL INPUT CP ' ' ;TEST IF SPACE JR Z,T.DUMP ;CONTINUE ; RET ;END OF ROUTINE ; M.DUMP PUSH BC CALL RD.WR ;GET A SECTOR CALL ADVANC ;ADVANCE POINTER POP BC DJNZ M.DUMP ;CONTINUE ; RET ; ;ADVANCE DMA TO NEXT POSITION ; ADVANC LD HL,(DMA) LD DE,80H ADD HL,DE LD (DMA),HL ; ;ADVANCE TO NEXT SECTOR AND WHEN NECESSARY ;ADVANCE TO NEXT TRACK ; LD DE,(SECTOR) ;GET TRACK AND SECTOR INC E ;MOVE TO NEXT SEC LD A,TS.SEC ;TEST FACTOR CP E ;TEST JR NZ,S.STORE ;STORE TRACK AND SEC LD E,1 ;START AGAIN INC D ;NEXT TRACK S.STORE LD (SECTOR),DE ;STORE SECTORS RET ; ;READ OR WRITE A SECTOR ; RD.WR2 LD (SECTOR),DE ;STORE TRACK AND SEC. RD.WR0 LD (TYPE),A ;STORE READ OR WRITE RD.WR LD DE,(SECTOR) ;GET TRACK AND SECTOR LD A,(IOBYT) ;Get Skewing info RLA ;Test for Skewin JR C,N.Skew ;Was not skewed ; ;UNSKEW ROUTINE ; LD HL,TRANS ;POINT TO THE TABLE LD B,0 ;ZERO THE REGISTER LD C,E ;TRANSFER THE RAW SEC. DEC C ADD HL,BC ;POINT TO WHERE IT IS ;ON THE DISK LD E,(HL) ;GET THE SEKWED SECTOR ; N.Skew LD (Sctr),DE ;STORE TRACK AND " XOR A ;GET A ZERO OR E ;CERTIFY SECTOR JR Z,ILL.SEC ;ILLEGAL SECTOR ADD MAX.SC ;TEST FOR MAX SEC JR C,ILL.SEC ;ILLEGAL SECTOR LD A,MAX.TR ;MAX TRACKS ADD A,D ;TEST FOR MAX TRACKS JR C,END.DSK ;END DISK LD A,(TYPE) ;READ OR WRITE OR A ;TEST PUSH AF ;SAVE CALL NZ,WRITE ;WRITE A SECTOR JR NZ,DSK.ERR ;ERROR OCCURED POP AF XOR A,1 CALL NZ,READ ;READ A SECTOR JR NZ,DSK.ERR ;ERROR OCCURED RET ; ILL.SEC LD HL,D.MSG2 JR D.ERR2 ; END.DSK LD HL,D.MSG3 JR D.ERR2 ; N.FILE LD HL,D.MSG5 JR D.ERR2 ; WrgDsk LD HL,D.MsgB ;Point to error message JR D.ERR2 ;Output the message ; N.DSPC LD HL,D.MSG6 JR D.ERR2 ; DSK.ERR LD HL,D.MSG4 D.ERR2 CALL BUFOUT ;OUTPUT BITCH JP INIT1 ;START OVER ; D.MSG1 DM '+ TRACK NO. ' D.MSG2 DM 'ILLEGAL SECTOR NO.!' D.MSG3 DM 'END OF DISK!' D.MSG4 DM 'DISK ERROR' D.MSG5 DM 'FILE NOT FOUND' D.MSG6 DM 'NO DIRECTORY SPACE' D.Msg7 DM 'Initilize FDOS disk in' D.Msg8 DM 'Copy disk from' D.Msg9 DM ' to ' D.MsgB DM 'Disk not a FDOS disk' ; TRANS DB 1H,7H,0DH,13H,19H,5H DB 0BH,11H,17H,3H,9H,0FH DB 15H,2H,8H,0EH,14H,1AH DB 6H,0CH,12H,18H,4H,0AH DB 10H,16H TITLE FDOS DISK OPERATING SYSTEM ; ;INITILIZE FDOS DISK ; I.DISK LD HL,D.Msg7 ;I DISK MESSAGE CALL Ready2 ;Output the message ;and check if ready LD HL,DIRECT ;START OF DIRECTORY LD DE,DIRECT+1 LD BC,180H XOR A LD (HL),A LDIR ;ZERO DIRECTORY LD A,7 ;RESERVE FIRST 3 LD (B.MAP),A ;SECTORS FOR DIR. LD A,0FFH LD (DR.END),A ;SET END OF DIR. ; D.PUT LD A,1 ;TOKEN FOR WRITE ; D.GET LD (TYPE),A ;SET FOR READ OR WRITE LD IX,IOBYT ;POINT TO I/O BYTE RES 7,(IX+00) ;READ AND WRITE IN ;SKEWED MODE LD B,3 ;THREE SECTORS LD DE,1 ;START TRACK AND SEC. LD (SECTOR),DE ;STORE SECTOR LD HL,DIRECT ;ADDRESS OF DIRECTORY LD (DMA),HL ;STORE DMA ADDRESS CALL M.DUMP ;READ OR WRITE DIR. LD HL,D.BUF ;SETUP DEFALT DMA LD (DMA),HL ;STORE DEFALT DMA RET ; NX.SEC LD HL,(D.SEC) ;GET SECTOR NO. INC L LD A,TS.SEC ;END SECTOR FACTOR CP L JR NZ,NX.SC2 ;NOT LAST SECTOR LD L,1 INC H LD A,MAX.TR ;MAX. TRACK FACTOR ADD H JP C,END.DSK ;END OF DISK NX.SC2 LD (D.SEC),HL ;STORE VALUE ; ;FOR A GIVEN TRACK AND SECTOR POINT TO ADDRESS ;IN BIT MAP AND C REG. CONTAINS ONE BIT HIGH ;WHICH IS THE POSITION IN THE BYTE ; BT.POS LD DE,0 LD HL,(D.SEC) ;GET TRACK AND SEC LD B,D ;ZERO B REG LD C,L ;SECTOR TO DEC C LD E,H ;TRACKS IN E LD L,E ;TRACKS IN L LD H,D ;ZERO TO H REG. ADD HL,DE ;DE X1 HL X2 ; ;LARGE DISK MULTIPLY TO 26 ROUTINE ; EX DE,HL ;DE X2 HL X1 ADD HL,DE ;DE X2 HL X3 EX DE,HL ;DE X3 HL X2 ADD HL,HL ;DE X3 HL X4 ADD HL,HL ;DE X3 HL X8 ADD HL,HL ;DE X3 HL X16 SBC HL,DE ;HL X13 ADD HL,HL ;HL X26 ; ADD HL,BC ;INCLUDE ODD SECTORS LD A,L AND 7 ;GET POSITION FACTOR LD C,A ;SAVE IN C SRL H RR L SRL H RR L SRL H RR L ;DIVIDE BY 8 COMPLETE LD DE,B.MAP ;START OF BIT MAP ADD HL,DE ;POSITION IN BIT MAP EX DE,HL LD HL,HAMMER ADD HL,BC ;POINT TO HAMMER LD C,(HL) ;HAMMER IN C EX DE,HL ;POSITION IN HL RET ; HAMMER DB 1,2,4,8 DB 10H,20H,40H,80H ; ;SETUP TO READ DISK FILE ; SETUP XOR A CALL D.GET ;GET DIRECTORY LD A,(DIRECT+3) ;GET THE TEST BYTE CP 0AFH ;Test if is a XOR a JP Z,WrgDsk ;Is not a FDOS Disk LD A,(HEXAD) ;GET FILE NAME CP 3FH ;TEST FOR MAX JP NC,ERR1 ;NOT A LEGAN NO. ADD A LD B,0 LD C,A LD HL,DIRECT ;START OF DIRECTORY ADD HL,BC ;FILE START TR. & SEC. LD A,(HL) ;GET SECTOR INC HL LD D,(HL) ;GET TRACK LD E,A ;TRACK & SEC. IN POS. OR D ;TEST FOR FILE JP Z,N.FILE ;NO FILE XOR A CALL RD.WR2 ;GET THE SECTOR RET ; ;READ A FDOS DISK FILE ; R.FILE CALL SETUP ; ;DETERMINT WHAT KIND OF READ ; LD A,(BUFAD+1) CP 'U' ;TEST FOR [ RU ] CALL Z,RUN.2 CP 'M' ;TEST FOR [ LM ] CALL Z,LD.MOV CP 'D' ;TEST FOR [ LD ] CALL Z,LOAD LD (HEXAD),HL ;SET WHERE TO GO ;WHEN DONE WITH READ ; ;DETERMINE START OF OBJECT CODE ; LD HL,F.TEXT ;START OF THE TEXT PUSH HL ;SAVE THE POINTER CALL BUFOUT ;OUTPUT THE FILE NAME POP HL CALL CRLF ;GET A NEW LINE LD BC,75H ;BYTES IN BUFFER ; S.LOOP LD A,(HL) INC HL DEC BC OR A JR NZ,S.LOOP ;CONTINUE TESTING ; EX DE,HL LD HL,(D.BKLNG) ;DISK BLOCK ;LENGTH LD A,H OR A JR NZ,D.SUB LD A,L SUB C ;TEST FOR SIZE JR NC,D.SUB LD C,L ;VALUE OF D.BLK LENGTH D.SUB OR A ;CLEAR FLAGS SBC HL,BC LD (HEXAD4),HL ;STORE REMAINING LENGTH LD HL,(D.BUF) ;PICK UP START ADR EX DE,HL ;READY FOR LDIR ; READ.L LDIR ;TRANSFER DATA LD BC,7EH ;LOAD 126 BYTES LD HL,(HEXAD4) ;GET LENGTH LD A,H OR L ;TEST IF DONE JP Z,GO ;PROCESS AS A GO LD A,H ;HIGH LENGTH IN A OR A ;TEST JR NZ,RD.SUB LD A,L SUB C ;TEST JR NC,RD.SUB LD C,L RD.SUB OR A SBC HL,BC LD (HEXAD4),HL ;STORE BLOCK LENGTH LD HL,D.BUF ;START OF TRANSFER EXX ;HIDE DATA LD DE,(D.SEC) ;GET SECTOR XOR A CALL RD.WR2 ;CALL READ WRITE EXX JR READ.L ;CONTINUE ; LD.MOV LD HL,(HEXAD2) ;GET LOAD ADDRESS LD (D.BUF),HL ;STORE NEW LOAD ADR ; LOAD LD HL,INIT1 ;GO TO HERE WHEN ;FILE IS LOADED RET ; RUN.2 LD HL,(D.BUF3) ;RUN ADDRESS RET ; ;WRITE A FDOS DISK FILE ; W.FILE XOR A ;SET TO READ CALL D.GET ;GET DIRECTORY LD HL,DIRECT ;START OF DIRECTORY LD C,0FFH ;0-1 ; FNLOOP INC C ;NEXT NAME LD A,(HL) ;GET BYTE INC HL OR (HL) ;TEST INC HL JP M,N.DSPC ;NO DIRECTORY SPACE JR NZ,FNLOOP ;KEEP LOOKING FOR NAME ; LD A,C ;FILE NAME IN ACUM LD (F.NAME),A ;STORE NAME DEC HL PUSH HL ;SAVE POSITION LD HL,1 LD (D.SEC),HL ;START SECTOR CALL V.FIND POP HL ;POSITION IN DIRECT LD DE,(D.SEC) ;GET START SECTOR LD (HL),D ;STORE TRACK AND DEC HL ;AND SECTOR IN LD (HL),E ;DIRECTORY ; ;MAKE ADDRESSES AND TEXT IN START OF FILE ; CALL CRLF ;GET A NEW LINE LD HL,F.NAME ;POINT TO FILE NAME CALL MOUT2 ;OUT FILE NAME AND SPACE LD HL,(HEXAD) ;GET START ADR LD (D.BUF),HL ;STORE START CALL ADOUT2 ;OUTPUT ADDRESS AND SPACE LD HL,(HEXAD2) ;GET END ADR LD (D.BUF2),HL ;STORE END ADR. CALL ADOUT2 ;OUTPUT ADR. AND SPACE CALL SPACE LD HL,(HEXAD3) ;GET EXECUTION ADR LD (D.BUF3),HL ;STORE EXC. ADR LD HL,(HEXAD4) ;GET BLOCK LENGTH LD (D.BKLNG),HL ;STORE LENGTH OF FILE CALL INBUF ;INPUT TEXT LD DE,F.TEXT LD BC,9 ;BYTES USED LD HL,BUFAD ;START OF INPUT BUFF ; EX DE,HL ; ;TRANSFER FROM BUFAD TO DISK BUFFER ; TRLOOP LD (HL),B ;PLACE A ZERO LD A,(DE) ;GET CHAR INC BC INC DE ;ADVANCE POINTERS CP 0DH ;TEST FOR END JR Z,W.CONT ;CONTINUE ELSEWHERE LD (HL),A ;STORE INPUT INC HL JR TRLOOP ;CONTINUE ; W.CONT INC HL ;ADVANCE BUFFER ;POINTER EX DE,HL ;DBUF POINT IN DE LD HL,(HEXAD4) ;GET BLOCK LENGTH LD A,7EH ;FULL WRITE SUB C ;SUBTRACT BYTES USED LD C,A ;REMAINING BUFFER LD A,1 ;FLAG AS MORE SECTORS EX AF,AF' ;HIDE LD A,H ;TEST FOR SIZE OR A JR NZ,W.SUB LD A,L SUB C JR NC,W.SUB XOR A ;FLAG AS END EX AF,AF' ;HIDE W.SUB OR A ;CLEAR FLAGS SBC HL,BC ;GET REMAINING BYTES LD (HEXAD4),HL ;STORE LD HL,(HEXAD) ;START OF SAVE ; W.LOOP LDIR ;TRANSFER OBJECT CODE LD DE,D.BUF ;RESET START EX AF,AF' ;END OF FILE? OR A ;TEST JR Z,W.END ;END OF WRITE PUSH HL ;SAVE SOURCE POS. LD BC,7EH LD HL,(HEXAD4) ;GET REMAINING BYTES LD A,1 ;FLAG AS TO CONTINUE EX AF,AF' ;HIDE LD A,H OR A ;TEST JR NZ,W.SUB2 LD A,L SUB C JR NC,W.SUB2 XOR A ;FLAG AS END EX AF,AF' ;HIDE LD C,L W.SUB2 OR A ;CLEAR FLAGS SBC HL,BC ;CALCULATE LD (HEXAD4),HL ;STORE NEW LENGTH POP HL EXX ;HIDE DATA LD HL,(D.SEC) ;GET OLD SECTOR LD (SECTOR),HL ;STORE SECTOR FOR ;WRITE CALL V.FIND ;FIND A EMPTY SECTOR ;IN DE REG LD A,1 LD (TYPE),A ;SET FOR WRITE CALL RD.WR0 ;WRITE SECTOR EXX ;RETREIVE LDIR INFO JR W.LOOP ;KEEP WRITING ; W.END LD HL,(D.SEC) ;GET TRACK AND SEC LD (SECTOR),HL ;STORE SECTOR FOR ;WRITE LD HL,0 LD (D.SEC),HL ;SET AS END OF FILE LD A,1 ;SET FOR WRITE CALL RD.WR0 ;WRITE SECTOR JP D.PUT ;STORE DIRECTORY ; ;FIND EMPTY SECTOR ; V.FIND CALL NX.SEC LD A,C ;HAMMER IN A AND (HL) JR NZ,V.FIND ;KEEP SEARCHING ; LD A,C ;HAMMER IN A OR (HL) ;SET AS USED LD (HL),A ;STORE BIT BYTE RET ; ;KILL A SPECIFIED FDOS FILE ; K.FILE CALL SETUP ; K.LOOP LD DE,(D.SEC) ;GET SECOND SEC LD A,D OR E ;TEST FOR END OF FILE JR Z,KFILE2 ;GO TO END ROUTINE PUSH DE ;SAVE TRACK & SEC. CALL BT.POS ;GET POSITION IN ;BIT MAP LD A,C ;HAMMER IN A CPL AND (HL) LD (HL),A ;SECTOR MADE VACANT XOR A ;SET FOR READ POP DE ;RETREIVE TRACK & SEC CALL RD.WR2 JR K.LOOP ;KEEP GOING ; KFILE2 LD A,(HEXAD) ;GET NAME ADD A LD D,0 LD E,A LD HL,DIRECT ;START OF DIRECT ADD HL,DE ;POINT TO FILE IN ;DIRECTORY LD E,(HL) INC HL LD D,(HL) ;GOT TRACK AND SEC. LD (D.SEC),DE ;STORE VALUE XOR A LD (HL),A ;TRACK IN DIR. 00 DEC HL LD (HL),A ;FILE IS VACANT CALL BT.POS ;GET POSITION LD A,C CPL AND (HL) LD (HL),A ;STORE AS VACANT JP D.PUT ;STORE NEW DIRECT ; ;OUTPUT THE LIST OF FILES ON A FDOS DISK ; DIR. XOR A CALL D.GET ;GET DIRECTORY LD HL,DIRECT ;START OF DIRECT ; D.LOOP LD E,(HL) ;GET SECTOR INC HL LD D,(HL) ;GET TRACK INC HL LD A,D OR E ;TEST JP M,DIR.3 ;OUTPUT FREE DISK JR Z,D.LOOP ;NO FILE LD (SECTOR),DE ;STORE SECTOR EXX ;HIDE DATA XOR A CALL RD.WR0 ;GET THE SECTOR LD HL,F.NAME ;POINT TO FILE NAME CALL MOUT2 ;OUTPUT NAME AND SPACE LD HL,(D.BUF) ;GET START OFF FILE CALL ADOUT2 ;OUT ADDRESS AND SPACE LD HL,(D.BUF2) ;GET END ADDRES CALL ADOUT4 ;OUT ADDRESS AND SPACE LD HL,F.TEXT CALL BUFOT2 ;OUTPUT RESULTS CALL CRLF ;GET A NEW LINE EXX JR D.LOOP ;KEEP GOING ; ;OUTPUT FREE KILLOBYTES ; DIR.3 LD HL,B.MAP LD DE,0 LD BC,8FFH ; SIZE.L LD A,(HL) ;GET MAP INC HL ; S.LP2 RRCA ;TEST JR NC,S.LP3 ;NOT USED INC DE S.LP3 DJNZ S.LP2 ;TEST BYTE ; LD B,8 ;RESET DEC C ;TEST NO OF BYTES JR NZ,SIZE.L ;MORE BYTES TO TEST ; LD C,E ;SAVE LOW BIT LD B,3 ;SET FOR DIVIDE BY 8 ; S.LP4 SRL D RR E DJNZ S.LP4 ;KEEP DIVIDING ; LD A,C ;ODD BITS TO A AND 7 ;TEST IF ANY HIGH JR Z,S.LP5 ;NONE ARE USED INC DE S.LP5 LD HL,S.MSG ;KB REMAINING CALL BUFOUT ;OUTPUT MESSAGE LD A,MAX.K ;MAX. KILLOBYTE FOR ;DISK SUB E ;SUBTRACT K.BYTES USED CALL G.NUM ;OUTPUT FILE SIZE LD A,'K' JP OUTPUT ;END OF ROUTINE ; S.MSG DM 'Unused Killobytes on disk ' TITLE FORMAT DISK COMMAND ; ;TRACK FORMAT ROUTINE ; ;Modified IMB 3740 format--128 bytes/sector. ;The 40 FFH's bytes has been changed to 50 FFH's ;bytes. This assures snychronization of the ;disk controler clock. ; TrkFmt DB 0FDH ;Make unpublished LD A,H ;Get the track in ;in the accumulator OUT Data,A ;Output Trk # to Disk LD D,1AH ;Token to seek with ;out verify CALL CmdI ;Seek track LD HL,1A01H ;26 Sectors, start at ;Sector 1 LD B,32H ;Setup for 50 0FFH's ;IBM Spec. 40 0FFH's CALL SetWait ;Setup wait states LD A,0F4H ;Token to write track OUT Cmd,A ;Output write command CALL FF.Out ;Output the FFH's ;followed by 6 00H's LD A,0FCH ;Token for index mark OUT Data,A ;Output index mark ; ;Write a sector with required ID bytes ; SecFmt LD B,1AH ;Setup for 26 0FFH's CALL FF.Out ;Output FFH's followed ;By 6 00H's LD A,0FEH ;Token for ID Mark OUT Data,A ;Output ID Mark IN A,Track ;Get Track # from ;Controler OUT Data,A ;Output the current track XOR A ;Token for side # 1 OUT Data,A ;Output side Number LD A,L ;Get present sector # OUT Data,A ;Output sector number XOR A ;Token for a 128 byte ;Sector OUT Data,A ;Output sector size LD A,0F7H ;Token for two CRC ;Nibbles OUT Data,A ;Output the CRC byte LD B,0BH ;Setup for 11 0FFH's CALL FF.Out ;Output the 11 0FFH's ;Folowed by 6 00H's LD A,0FBH ;Token for start of ;Data field OUT Data,A ;Output data field token ; ;Setup for a data field of 128 bytes ; LD B,80H ;Set length of data field LD A,0E5H ;Fill for data field ; D.Fill OUT Data,A ;Fill the data field DJNZ D.Fill ;Loop till done ; LD A,0F7H ;Token for two CRC's ;nibbles OUT Data,A ;Output the CRC byte INC L ;Increas sector number DEC H ;Reduce remaining sectors LD A,0FFH ;Get a exta FFH OUT Data,A ;Output the FFH JR NZ,SecFmt ;Loop till track is ;Done ; LD E,80H ;Error mask CALL Err.Ck ;Check for errors XOR A ;Token for no errors RET ; FF.Out LD A,0FFH ;A null token ; FF.Loop OUT Data,A ;Output A Null byte DJNZ FF.Loop ; LD B,06H ;Setup for 6 00H bytes XOR A ;Get a 00H ; Out.00H OUT Data,A ;Output the 00H's DJNZ Out.00H ; RET ; FormMsg DM 'Format disk in' ; ;Format command routine ; FOR.MAT LD HL,FormMsg ;Point to format Msg. CALL Ready2 ;Output the message ;and check if ready CALL HOME ;Home and setup drive DB 0FDH ;Make unpublished LD H,0 ;Set start at track 0 ; F.Next Call TrkFmt ;Format a track DB 0FDH ;Make unpublished INC H ;Advance track pointer LD A,4DH ;Max tracks in Accum. DB 0FDH ;Make unpublished CP H ;Check for the end JR NZ,F.Next ;More tracks to format ; ;Falls into the Home ;Routine LIST ON TITLE DISK DRIVERS ; ;VERSAFLOOPY ROUTINES ; ;Rewritten for Z80 code by Ralph E. Bucknam ;January 1981 ; Home. LD (SVSP),SP ;Save the Stack CALL DrvSet ;SET UP THE DRIVE IF ;REQUIRED LD D,0BH ;HOME TOKEN ;& ENGAGE HEAD ; ;PROCESS TYPE [ I ] COMMANDS ;D Registor contains the command ; CmdI LD E,80H ;ERROR MASK ; CmdI.W IN A,Stat ;GET THE STATUS RRCA ;TEST IF BUSY JR C,CmdI.W ;WAIT TILL NOT BUSY ; IN A,Select ;GET DATA FROM PORT AND 1FH ;SAVE LOWER BITS OR 60H ;SET 5 & 6 BITS HIGH OUT Select,A ;OUTPUT THE WAIT ;COMMAND LD A,D ;COMMAND TO A OUT Cmd,A ;DO IT LD A,90H ;THE WAIT FACTOR ; Wait.2 DEC A JP NZ,Wait.2 ;WAIT TILL ZERO ; ;Error checking routine ;Error mask is in E Regisitor ; Err.Ck IN A,Stat ;GET THE STATUS RRCA ;TEST IF READY JR C,Err.Ck ;WAIT TILL READY ; ;Dissable the wait states ; IN A,Select ;GET THE DATA OR 0E0H ;TURN WAIT STATE OFF OUT Select,A ;DISABLE THE WAIT STATES ; ;Do the error checking ; IN A,Stat ;GET THE STATUS AND E ;AND WITH ERROR MASK RET Z ;NO ERRORS ; ;Disk error routine ; DskErr LD (ErStat),A ;Save the status LD (IDVS),DE ;SAVE THE DATA ABOUT ;THE COMMAND OR 1 ;SET A ERROR FLAG LD SP,(SVSP) ;GET ORIGINAL CALLERS ;STACK RET ;RETURN TO THE ORIGINAL ;CALLER ; ;READ OR WRITE A SECTOR SETUP ; Read. LD HL,88FEH ;TOKEN TO READ SECTOR ;& THE ERROR MASK JR Write.2 ;CONTINUE ELSE WHERE ; Write$ LD HL,0A8FCH ;TOKEN TO WRITE SECTOR ;& THE ERROR MASK ; Write.2 LD B,10 ;TEN TRIES ; W.Write PUSH BC ;SAVE THE NUMBER OF ;RETRIES CALL RedWrit ;READ OR WRITE THE ;SECTOR POP BC ;RETRIEVE # OF RETRIES RET Z ;NO ERRORS DJNZ W.Write ;TRY AGAIN ; XOR A ;CLEAR THE ACCUMULATOR INC A ;CLEAR THE ZERO FLAG ;AND RETURN THE ACCUM. ;WITH A 1 RET ;RETURN WITH ERROR ;FLAGS SET ; ;Seek the dseried track routine ; Seek IN A,Track ;GET THE LAST TRACK LD C,A ;SAVE IT IN C REG. LD A,(TRK) ;GET THE DESIRED TRACK CP 4DH ;TEST IF TO LARGE JP NC,END.DSK ;A error occured CP C ;TEST IF THE SAME RET Z ;SAME TRACK LD C,A ;SAVE THE DESIRED TRACK LD B,3 ;THREE TRIES ; R.Seek LD A,C ;GET THE DESIRED TRACK OUT Data,A ;OUTPUT DISIRED TRACK LD D,1FH ;TOKEN FOR SEEK CALL CmdI ;SEEK THE TRACK LD A,Stat ;GET THE STATUS AND 10H ;TEST FOR SEEK ERROR RET Z ;NO ERRORS LD D,0BH ;TOKEN TO HOME WITH ;HEAD ENGAGED CALL CmdI ;GO TO HOME DJNZ R.Seek ;TRY AGAIN ; LD A,20H ;TOKEN FOR SEEK ERROR JR DskErr ;ANOUNCE SEEK ERROR ; ;Check if correct drive is selected and select ;a new drive if necessary. ; DrvSet IN A,Select ;GET INFO ON THE DRIVES CPL ;INVERT THE DATA AND 0FH ;STRIP OTHER DATA OFF JR Z,DrSel ;NO DRIVE SELECTED LD C,0FFH ;ROTATE FACTOR ; DrvS0 INC C ;MAKE C RET 1 HIGHER RRA ;CARRYS ARE INCLUDED JR NC,DrvS0 ;LOOP TILL BITS ARE IN ;THE RIGHT SPOT ; LD A,(DRVBYT) ;Get the drive # AND 3 ;MAKE SHURE NUMBER IS ;RIGHT CP C ;COMPARE DESIRE AGAINST ;WHAT IS SELECTED RET Z ;THE SAME DRIVE ; ;Select desired drive ; DrSel LD A,(DRVBYT) ;GET DRIVE # AND 3 ;MAKE RIGHT OR A ;TEST FOR DRIVE 0 LD C,A ;SAVE DESIRED DRIVE LD A,1 ;SET FOR DRIVE 0 JR Z,DrSel3 ;IS DRIVE 0 ; DrSel2 RLCA ;MAKE UP DRIVE BYTE DEC C JR NZ,DrSel2 ;LOOP TILL DONE ; DrSel3 CPL ;INVERT DATA OUT Select,A ;SEND IT TO DRIVE PORT LD C,23H ;TOKEN FOR 23 MS WAIT ; M.Sec1 LD A,8EH ;TOKEN FOR 1 MS WAIT ; M.Sec2 DEC A JP NZ,M.Sec2 ;LOOP FOR 1 MS ; DEC C ;ONE LESS PASS JR NZ,M.Sec1 ;LOOP TILL DONE ; LD E,80H ;ERROR MASK IN A,Stat ;GET STATUS AND E ;TEST IF BUSY SCF ;Set flag the there ;has been a drive change RET Z ;NO PROBLEMS ; ;Error has occured ; POP AF ;REMOVE LAST CALLERS ;RETURN ADDRESS LD A,40H ;ERROR TOKEN JP DskErr ;HANDEL AS A ERROR ; ;MAIN READ OR WRITE ROUTINE ; ;H Reg. contains the read or write token ;L Reg. contains the error mask ; RedWrit LD (SVSP),SP ;Save callers return ;address CALL DrvSet ;CHECK AND SELECT THE ;PROPER DRIVE JR NC,SeekIt ;Drive change did not ;occure ; ;Turn select drive, read into memory Track and ;sector of the selected drive and update the ;disk controlers track register ; TrkFind LD A,1 ;Token command not ;complete LD (DrvChg),A ;Store the token PUSH HL ;Save commands LD HL,IDVS ;Where to store data LD DE,0C4F8H ;Command and Error mask LD BC,467H ;Bytes to read and ;Command CALL SetWait ;Setup wait states LD A,D ;Get Command OUT Cmd,A ;Output the command INIR ;Read the data POP HL ;Retreive callers ;Commands CALL Err.Ck ;Check for errors XOR A ;Get a Zero LD (DrvChg),A ;Command completed LD A,(IDVS) ;Get the track which ;the new disk is on OUT Track,A ;Output the track info ; SeekIt LD A,(DrvChg) ;Command completed ? OR A ;Test JR NZ,TrkFind ;Find the track CALL Seek ;SEEK THE DESIRED TRACK LD A,(Sctr) ;Get the desired sector OUT Sect.or,A ;SELECT DESIRED SECTOR ; ;Enable the wait states ; CALL SetWait ;Setup wait states ; ;Check to see if head is down ; LD D,H ;MOVE THE COMMAND TO ;D REG. LD E,L ;MOVE THE ERROR MASK ;TO E REG. LD A,0D0H ;TOKEN FOR FORCED ;INTERUPTS OUT Cmd,A ;SETUP FORCED INTERUPTS LD A,4 ;SETUP FOR SOME DELAY ; F.Wait DEC A JR NZ,F.Wait ;WAIT TILL TIME IS UP ; IN A,Stat ;GET STATUS AND 20H ;TEST IF HEAD WAS DOWN JR NZ,R.W.2 ;HEAD WAS DOWN SET 2,D ;LOAD HEAD BIT ; R.W.2 PUSH HL ;SAVE THE COMMAND ;AND ERROR MASK LD HL,(DMA) ;Get the transfer adr. LD B,80H ;NUMBER OF BYTES TO ;BE TRANSFERED ; LD A,D ;Move the command to ;the accumulator LD C,Data ;Disk data port BIT 5,A ;Read or write command? JR NZ,Write2 ;ITS A WRITE COMMAND ; ;Read a sector ; OUT Cmd,A ;Output the read command INIR ;Read the intire sector JR Write3 ;Continue else where ; ;Write a sector ; Write2 OUT Cmd,A ;Output write command OTIR ;Write the intire sector ; Write3 POP HL ;Retreive R/W token CALL Err.Ck ;Check for a error XOR A ;Set zero flag RET ; ;Set Up wait states routine ; SetWait IN A,Select ;Get the port info AND 1FH ;Setup for wait states OUT Select,A ;Setup wait states RET ; END ct ;Get the port info AND 1FH ;Setup for w