diff --git a/emu/c++ b/c++ similarity index 100% rename from emu/c++ rename to c++ diff --git a/cpm/22srcimg/22src1.img b/cpm/22srcimg/22src1.img deleted file mode 100644 index d005ca8..0000000 Binary files a/cpm/22srcimg/22src1.img and /dev/null differ diff --git a/cpm/22srcimg/22src2.img b/cpm/22srcimg/22src2.img deleted file mode 100644 index 46c047e..0000000 Binary files a/cpm/22srcimg/22src2.img and /dev/null differ diff --git a/cpm/cpm2-asm/CPM22.ASM b/cpm/cpm2-asm/CPM22.ASM deleted file mode 100644 index 4784bca..0000000 --- a/cpm/cpm2-asm/CPM22.ASM +++ /dev/null @@ -1,3739 +0,0 @@ - -;************************************************************** -;* -;* C P / M version 2 . 2 -;* -;* Reconstructed from memory image on February 27, 1981 -;* -;* by Clark A. Calkins -;* -;************************************************************** -; -; Set memory limit here. This is the amount of contigeous -; ram starting from 0000. CP/M will reside at the end of this space. -; -MEM EQU 62 ;for a 62k system (TS802 TEST - WORKS OK). -; -IOBYTE EQU 3 ;i/o definition byte. -TDRIVE EQU 4 ;current drive name and user number. -ENTRY EQU 5 ;entry point for the cp/m bdos. -TFCB EQU 5CH ;default file control block. -TBUFF EQU 80H ;i/o buffer and command line storage. -TBASE EQU 100H ;transiant program storage area. -; -; Set control character equates. -; -CNTRLC EQU 3 ;control-c -CNTRLE EQU 05H ;control-e -BS EQU 08H ;backspace -TAB EQU 09H ;tab -LF EQU 0AH ;line feed -FF EQU 0CH ;form feed -CR EQU 0DH ;carriage return -CNTRLP EQU 10H ;control-p -CNTRLR EQU 12H ;control-r -CNTRLS EQU 13H ;control-s -CNTRLU EQU 15H ;control-u -CNTRLX EQU 18H ;control-x -CNTRLZ EQU 1AH ;control-z (end-of-file mark) -DEL EQU 7FH ;rubout -; -; Set origin for CP/M -; - ORG (MEM-7)*1024 -; -CBASE JMP COMMAND ;execute command processor (ccp). - JMP CLEARBUF ;entry to empty input buffer before starting ccp. - -; -; Standard cp/m ccp input buffer. Format is (max length), -; (actual length), (char #1), (char #2), (char #3), etc. -; -INBUFF DB 127 ;length of input buffer. - DB 0 ;current length of contents. - DB 'Copyright' - DB ' 1979 (c) by Digital Research ' - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -INPOINT DW INBUFF+2;input line pointer -NAMEPNT DW 0 ;input line pointer used for error message. Points to -; ;start of name in error. -; -; Routine to print (A) on the console. All registers used. -; -PRINT MOV E,A ;setup bdos call. - MVI C,2 - JMP ENTRY -; -; Routine to print (A) on the console and to save (BC). -; -PRINTB PUSH B - CALL PRINT - POP B - RET -; -; Routine to send a carriage return, line feed combination -; to the console. -; -CRLF MVI A,CR - CALL PRINTB - MVI A,LF - JMP PRINTB -; -; Routine to send one space to the console and save (BC). -; -SPACE MVI A,' ' - JMP PRINTB -; -; Routine to print character string pointed to be (BC) on the -; console. It must terminate with a null byte. -; -PLINE PUSH B - CALL CRLF - POP H -PLINE2 MOV A,M - ORA A - RZ - INX H - PUSH H - CALL PRINT - POP H - JMP PLINE2 -; -; Routine to reset the disk system. -; -RESDSK MVI C,13 - JMP ENTRY -; -; Routine to select disk (A). -; -DSKSEL MOV E,A - MVI C,14 - JMP ENTRY -; -; Routine to call bdos and save the return code. The zero -; flag is set on a return of 0ffh. -; -ENTRY1 CALL ENTRY - STA RTNCODE ;save return code. - INR A ;set zero if 0ffh returned. - RET -; -; Routine to open a file. (DE) must point to the FCB. -; -OPEN MVI C,15 - JMP ENTRY1 -; -; Routine to open file at (FCB). -; -OPENFCB XRA A ;clear the record number byte at fcb+32 - STA FCB+32 - LXI D,FCB - JMP OPEN -; -; Routine to close a file. (DE) points to FCB. -; -CLOSE MVI C,16 - JMP ENTRY1 -; -; Routine to search for the first file with ambigueous name -; (DE). -; -SRCHFST MVI C,17 - JMP ENTRY1 -; -; Search for the next ambigeous file name. -; -SRCHNXT MVI C,18 - JMP ENTRY1 -; -; Search for file at (FCB). -; -SRCHFCB LXI D,FCB - JMP SRCHFST -; -; Routine to delete a file pointed to by (DE). -; -DELETE MVI C,19 - JMP ENTRY -; -; Routine to call the bdos and set the zero flag if a zero -; status is returned. -; -ENTRY2 CALL ENTRY - ORA A ;set zero flag if appropriate. - RET -; -; Routine to read the next record from a sequential file. -; (DE) points to the FCB. -; -RDREC MVI C,20 - JMP ENTRY2 -; -; Routine to read file at (FCB). -; -READFCB LXI D,FCB - JMP RDREC -; -; Routine to write the next record of a sequential file. -; (DE) points to the FCB. -; -WRTREC MVI C,21 - JMP ENTRY2 -; -; Routine to create the file pointed to by (DE). -; -CREATE MVI C,22 - JMP ENTRY1 -; -; Routine to rename the file pointed to by (DE). Note that -; the new name starts at (DE+16). -; -RENAM MVI C,23 - JMP ENTRY -; -; Get the current user code. -; -GETUSR MVI E,0FFH -; -; Routne to get or set the current user code. -; If (E) is FF then this is a GET, else it is a SET. -; -GETSETUC:MVI C,32 - JMP ENTRY -; -; Routine to set the current drive byte at (TDRIVE). -; -SETCDRV CALL GETUSR ;get user number - ADD A ;and shift into the upper 4 bits. - ADD A - ADD A - ADD A - LXI H,CDRIVE;now add in the current drive number. - ORA M - STA TDRIVE ;and save. - RET -; -; Move currently active drive down to (TDRIVE). -; -MOVECD LDA CDRIVE - STA TDRIVE - RET -; -; Routine to convert (A) into upper case ascii. Only letters -; are affected. -; -UPPER CPI 'a' ;check for letters in the range of 'a' to 'z'. - RC - CPI '{' - RNC - ANI 5FH ;convert it if found. - RET -; -; Routine to get a line of input. We must check to see if the -; user is in (BATCH) mode. If so, then read the input from file -; ($$$.SUB). At the end, reset to console input. -; -GETINP LDA BATCH ;if =0, then use console input. - ORA A - JZ GETINP1 -; -; Use the submit file ($$$.sub) which is prepared by a -; SUBMIT run. It must be on drive (A) and it will be deleted -; if and error occures (like eof). -; - LDA CDRIVE ;select drive 0 if need be. - ORA A - MVI A,0 ;always use drive A for submit. - CNZ DSKSEL ;select it if required. - LXI D,BATCHFCB - CALL OPEN ;look for it. - JZ GETINP1 ;if not there, use normal input. - LDA BATCHFCB+15;get last record number+1. - DCR A - STA BATCHFCB+32 - LXI D,BATCHFCB - CALL RDREC ;read last record. - JNZ GETINP1 ;quit on end of file. -; -; Move this record into input buffer. -; - LXI D,INBUFF+1 - LXI H,TBUFF ;data was read into buffer here. - MVI B,128 ;all 128 characters may be used. - CALL HL2DE ;(HL) to (DE), (B) bytes. - LXI H,BATCHFCB+14 - MVI M,0 ;zero out the 's2' byte. - INX H ;and decrement the record count. - DCR M - LXI D,BATCHFCB;close the batch file now. - CALL CLOSE - JZ GETINP1 ;quit on an error. - LDA CDRIVE ;re-select previous drive if need be. - ORA A - CNZ DSKSEL ;don't do needless selects. -; -; Print line just read on console. -; - LXI H,INBUFF+2 - CALL PLINE2 - CALL CHKCON ;check console, quit on a key. - JZ GETINP2 ;jump if no key is pressed. -; -; Terminate the submit job on any keyboard input. Delete this -; file such that it is not re-started and jump to normal keyboard -; input section. -; - CALL DELBATCH;delete the batch file. - JMP CMMND1 ;and restart command input. -; -; Get here for normal keyboard input. Delete the submit file -; incase there was one. -; -GETINP1 CALL DELBATCH;delete file ($$$.sub). - CALL SETCDRV ;reset active disk. - MVI C,10 ;get line from console device. - LXI D,INBUFF - CALL ENTRY - CALL MOVECD ;reset current drive (again). -; -; Convert input line to upper case. -; -GETINP2 LXI H,INBUFF+1 - MOV B,M ;(B)=character counter. -GETINP3 INX H - MOV A,B ;end of the line? - ORA A - JZ GETINP4 - MOV A,M ;convert to upper case. - CALL UPPER - MOV M,A - DCR B ;adjust character count. - JMP GETINP3 -GETINP4 MOV M,A ;add trailing null. - LXI H,INBUFF+2 - SHLD INPOINT ;reset input line pointer. - RET -; -; Routine to check the console for a key pressed. The zero -; flag is set is none, else the character is returned in (A). -; -CHKCON MVI C,11 ;check console. - CALL ENTRY - ORA A - RZ ;return if nothing. - MVI C,1 ;else get character. - CALL ENTRY - ORA A ;clear zero flag and return. - RET -; -; Routine to get the currently active drive number. -; -GETDSK MVI C,25 - JMP ENTRY -; -; Set the stabdard dma address. -; -STDDMA LXI D,TBUFF -; -; Routine to set the dma address to (DE). -; -DMASET MVI C,26 - JMP ENTRY -; -; Delete the batch file created by SUBMIT. -; -DELBATCH:LXI H,BATCH ;is batch active? - MOV A,M - ORA A - RZ - MVI M,0 ;yes, de-activate it. - XRA A - CALL DSKSEL ;select drive 0 for sure. - LXI D,BATCHFCB;and delete this file. - CALL DELETE - LDA CDRIVE ;reset current drive. - JMP DSKSEL -; -; Check to two strings at (PATTRN1) and (PATTRN2). They must be -; the same or we halt.... -; -VERIFY LXI D,PATTRN1;these are the serial number bytes. - LXI H,PATTRN2;ditto, but how could they be different? - MVI B,6 ;6 bytes each. -VERIFY1 LDAX D - CMP M - JNZ HALT ;jump to halt routine. - INX D - INX H - DCR B - JNZ VERIFY1 - RET -; -; Print back file name with a '?' to indicate a syntax error. -; -SYNERR CALL CRLF ;end current line. - LHLD NAMEPNT ;this points to name in error. -SYNERR1 MOV A,M ;print it until a space or null is found. - CPI ' ' - JZ SYNERR2 - ORA A - JZ SYNERR2 - PUSH H - CALL PRINT - POP H - INX H - JMP SYNERR1 -SYNERR2 MVI A,'?' ;add trailing '?'. - CALL PRINT - CALL CRLF - CALL DELBATCH;delete any batch file. - JMP CMMND1 ;and restart from console input. -; -; Check character at (DE) for legal command input. Note that the -; zero flag is set if the character is a delimiter. -; -CHECK LDAX D - ORA A - RZ - CPI ' ' ;control characters are not legal here. - JC SYNERR - RZ ;check for valid delimiter. - CPI '=' - RZ - CPI '_' - RZ - CPI '.' - RZ - CPI ':' - RZ - CPI ';' - RZ - CPI '<' - RZ - CPI '>' - RZ - RET -; -; Get the next non-blank character from (DE). -; -NONBLANK:LDAX D - ORA A ;string ends with a null. - RZ - CPI ' ' - RNZ - INX D - JMP NONBLANK -; -; Add (HL)=(HL)+(A) -; -ADDHL ADD L - MOV L,A - RNC ;take care of any carry. - INR H - RET -; -; Convert the first name in (FCB). -; -CONVFST MVI A,0 -; -; Format a file name (convert * to '?', etc.). On return, -; (A)=0 is an unambigeous name was specified. Enter with (A) equal to -; the position within the fcb for the name (either 0 or 16). -; -CONVERT LXI H,FCB - CALL ADDHL - PUSH H - PUSH H - XRA A - STA CHGDRV ;initialize drive change flag. - LHLD INPOINT ;set (HL) as pointer into input line. - XCHG - CALL NONBLANK;get next non-blank character. - XCHG - SHLD NAMEPNT ;save pointer here for any error message. - XCHG - POP H - LDAX D ;get first character. - ORA A - JZ CONVRT1 - SBI 'A'-1 ;might be a drive name, convert to binary. - MOV B,A ;and save. - INX D ;check next character for a ':'. - LDAX D - CPI ':' - JZ CONVRT2 - DCX D ;nope, move pointer back to the start of the line. -CONVRT1 LDA CDRIVE - MOV M,A - JMP CONVRT3 -CONVRT2 MOV A,B - STA CHGDRV ;set change in drives flag. - MOV M,B - INX D -; -; Convert the basic file name. -; -CONVRT3 MVI B,08H -CONVRT4 CALL CHECK - JZ CONVRT8 - INX H - CPI '*' ;note that an '*' will fill the remaining - JNZ CONVRT5 ;field with '?'. - MVI M,'?' - JMP CONVRT6 -CONVRT5 MOV M,A - INX D -CONVRT6 DCR B - JNZ CONVRT4 -CONVRT7 CALL CHECK ;get next delimiter. - JZ GETEXT - INX D - JMP CONVRT7 -CONVRT8 INX H ;blank fill the file name. - MVI M,' ' - DCR B - JNZ CONVRT8 -; -; Get the extension and convert it. -; -GETEXT MVI B,03H - CPI '.' - JNZ GETEXT5 - INX D -GETEXT1 CALL CHECK - JZ GETEXT5 - INX H - CPI '*' - JNZ GETEXT2 - MVI M,'?' - JMP GETEXT3 -GETEXT2 MOV M,A - INX D -GETEXT3 DCR B - JNZ GETEXT1 -GETEXT4 CALL CHECK - JZ GETEXT6 - INX D - JMP GETEXT4 -GETEXT5 INX H - MVI M,' ' - DCR B - JNZ GETEXT5 -GETEXT6 MVI B,3 -GETEXT7 INX H - MVI M,0 - DCR B - JNZ GETEXT7 - XCHG - SHLD INPOINT ;save input line pointer. - POP H -; -; Check to see if this is an ambigeous file name specification. -; Set the (A) register to non zero if it is. -; - LXI B,11 ;set name length. -GETEXT8 INX H - MOV A,M - CPI '?' ;any question marks? - JNZ GETEXT9 - INR B ;count them. -GETEXT9 DCR C - JNZ GETEXT8 - MOV A,B - ORA A - RET -; -; CP/M command table. Note commands can be either 3 or 4 characters long. -; -NUMCMDS EQU 6 ;number of commands -CMDTBL DB 'DIR ' - DB 'ERA ' - DB 'TYPE' - DB 'SAVE' - DB 'REN ' - DB 'USER' -; -; The following six bytes must agree with those at (PATTRN2) -; or cp/m will HALT. Why? -; -PATTRN1 DB 0,22,0,0,0,0;(* serial number bytes *). -; -; Search the command table for a match with what has just -; been entered. If a match is found, then we jump to the -; proper section. Else jump to (UNKNOWN). -; On return, the (C) register is set to the command number -; that matched (or NUMCMDS+1 if no match). -; -SEARCH LXI H,CMDTBL - MVI C,0 -SEARCH1 MOV A,C - CPI NUMCMDS ;this commands exists. - RNC - LXI D,FCB+1 ;check this one. - MVI B,4 ;max command length. -SEARCH2 LDAX D - CMP M - JNZ SEARCH3 ;not a match. - INX D - INX H - DCR B - JNZ SEARCH2 - LDAX D ;allow a 3 character command to match. - CPI ' ' - JNZ SEARCH4 - MOV A,C ;set return register for this command. - RET -SEARCH3 INX H - DCR B - JNZ SEARCH3 -SEARCH4 INR C - JMP SEARCH1 -; -; Set the input buffer to empty and then start the command -; processor (ccp). -; -CLEARBUF:XRA A - STA INBUFF+1;second byte is actual length. -; -;************************************************************** -;* -;* -;* C C P - C o n s o l e C o m m a n d P r o c e s s o r -;* -;************************************************************** -;* -COMMAND LXI SP,CCPSTACK;setup stack area. - PUSH B ;note that (C) should be equal to: - MOV A,C ;(uuuudddd) where 'uuuu' is the user number - RAR ;and 'dddd' is the drive number. - RAR - RAR - RAR - ANI 0FH ;isolate the user number. - MOV E,A - CALL GETSETUC;and set it. - CALL RESDSK ;reset the disk system. - STA BATCH ;clear batch mode flag. - POP B - MOV A,C - ANI 0FH ;isolate the drive number. - STA CDRIVE ;and save. - CALL DSKSEL ;...and select. - LDA INBUFF+1 - ORA A ;anything in input buffer already? - JNZ CMMND2 ;yes, we just process it. -; -; Entry point to get a command line from the console. -; -CMMND1 LXI SP,CCPSTACK;set stack straight. - CALL CRLF ;start a new line on the screen. - CALL GETDSK ;get current drive. - ADI 'a' - CALL PRINT ;print current drive. - MVI A,'>' - CALL PRINT ;and add prompt. - CALL GETINP ;get line from user. -; -; Process command line here. -; -CMMND2 LXI D,TBUFF - CALL DMASET ;set standard dma address. - CALL GETDSK - STA CDRIVE ;set current drive. - CALL CONVFST ;convert name typed in. - CNZ SYNERR ;wild cards are not allowed. - LDA CHGDRV ;if a change in drives was indicated, - ORA A ;then treat this as an unknown command - JNZ UNKNOWN ;which gets executed. - CALL SEARCH ;else search command table for a match. -; -; Note that an unknown command returns -; with (A) pointing to the last address -; in our table which is (UNKNOWN). -; - LXI H,CMDADR;now, look thru our address table for command (A). - MOV E,A ;set (DE) to command number. - MVI D,0 - DAD D - DAD D ;(HL)=(CMDADR)+2*(command number). - MOV A,M ;now pick out this address. - INX H - MOV H,M - MOV L,A - PCHL ;now execute it. -; -; CP/M command address table. -; -CMDADR DW DIRECT,ERASE,TYPE,SAVE - DW RENAME,USER,UNKNOWN -; -; Halt the system. Reason for this is unknown at present. -; -HALT LXI H,76F3H ;'DI HLT' instructions. - SHLD CBASE - LXI H,CBASE - PCHL -; -; Read error while TYPEing a file. -; -RDERROR LXI B,RDERR - JMP PLINE -RDERR DB 'Read error',0 -; -; Required file was not located. -; -NONE LXI B,NOFILE - JMP PLINE -NOFILE DB 'No file',0 -; -; Decode a command of the form 'A>filename number{ filename}. -; Note that a drive specifier is not allowed on the first file -; name. On return, the number is in register (A). Any error -; causes 'filename?' to be printed and the command is aborted. -; -DECODE CALL CONVFST ;convert filename. - LDA CHGDRV ;do not allow a drive to be specified. - ORA A - JNZ SYNERR - LXI H,FCB+1 ;convert number now. - LXI B,11 ;(B)=sum register, (C)=max digit count. -DECODE1 MOV A,M - CPI ' ' ;a space terminates the numeral. - JZ DECODE3 - INX H - SUI '0' ;make binary from ascii. - CPI 10 ;legal digit? - JNC SYNERR - MOV D,A ;yes, save it in (D). - MOV A,B ;compute (B)=(B)*10 and check for overflow. - ANI 0E0H - JNZ SYNERR - MOV A,B - RLC - RLC - RLC ;(A)=(B)*8 - ADD B ;.......*9 - JC SYNERR - ADD B ;.......*10 - JC SYNERR - ADD D ;add in new digit now. -DECODE2 JC SYNERR - MOV B,A ;and save result. - DCR C ;only look at 11 digits. - JNZ DECODE1 - RET -DECODE3 MOV A,M ;spaces must follow (why?). - CPI ' ' - JNZ SYNERR - INX H -DECODE4 DCR C - JNZ DECODE3 - MOV A,B ;set (A)=the numeric value entered. - RET -; -; Move 3 bytes from (HL) to (DE). Note that there is only -; one reference to this at (A2D5h). -; -MOVE3 MVI B,3 -; -; Move (B) bytes from (HL) to (DE). -; -HL2DE MOV A,M - STAX D - INX H - INX D - DCR B - JNZ HL2DE - RET -; -; Compute (HL)=(TBUFF)+(A)+(C) and get the byte that's here. -; -EXTRACT LXI H,TBUFF - ADD C - CALL ADDHL - MOV A,M - RET -; -; Check drive specified. If it means a change, then the new -; drive will be selected. In any case, the drive byte of the -; fcb will be set to null (means use current drive). -; -DSELECT XRA A ;null out first byte of fcb. - STA FCB - LDA CHGDRV ;a drive change indicated? - ORA A - RZ - DCR A ;yes, is it the same as the current drive? - LXI H,CDRIVE - CMP M - RZ - JMP DSKSEL ;no. Select it then. -; -; Check the drive selection and reset it to the previous -; drive if it was changed for the preceeding command. -; -RESETDR LDA CHGDRV ;drive change indicated? - ORA A - RZ - DCR A ;yes, was it a different drive? - LXI H,CDRIVE - CMP M - RZ - LDA CDRIVE ;yes, re-select our old drive. - JMP DSKSEL -; -;************************************************************** -;* -;* D I R E C T O R Y C O M M A N D -;* -;************************************************************** -; -DIRECT CALL CONVFST ;convert file name. - CALL DSELECT ;select indicated drive. - LXI H,FCB+1 ;was any file indicated? - MOV A,M - CPI ' ' - JNZ DIRECT2 - MVI B,11 ;no. Fill field with '?' - same as *.*. -DIRECT1 MVI M,'?' - INX H - DCR B - JNZ DIRECT1 -DIRECT2 MVI E,0 ;set initial cursor position. - PUSH D - CALL SRCHFCB ;get first file name. - CZ NONE ;none found at all? -DIRECT3 JZ DIRECT9 ;terminate if no more names. - LDA RTNCODE ;get file's position in segment (0-3). - RRC - RRC - RRC - ANI 60H ;(A)=position*32 - MOV C,A - MVI A,10 - CALL EXTRACT ;extract the tenth entry in fcb. - RAL ;check system file status bit. - JC DIRECT8 ;we don't list them. - POP D - MOV A,E ;bump name count. - INR E - PUSH D - ANI 03H ;at end of line? - PUSH PSW - JNZ DIRECT4 - CALL CRLF ;yes, end this line and start another. - PUSH B - CALL GETDSK ;start line with ('A:'). - POP B - ADI 'A' - CALL PRINTB - MVI A,':' - CALL PRINTB - JMP DIRECT5 -DIRECT4 CALL SPACE ;add seperator between file names. - MVI A,':' - CALL PRINTB -DIRECT5 CALL SPACE - MVI B,1 ;'extract' each file name character at a time. -DIRECT6 MOV A,B - CALL EXTRACT - ANI 7FH ;strip bit 7 (status bit). - CPI ' ' ;are we at the end of the name? - JNZ DRECT65 - POP PSW ;yes, don't print spaces at the end of a line. - PUSH PSW - CPI 3 - JNZ DRECT63 - MVI A,9 ;first check for no extension. - CALL EXTRACT - ANI 7FH - CPI ' ' - JZ DIRECT7 ;don't print spaces. -DRECT63 MVI A,' ' ;else print them. -DRECT65 CALL PRINTB - INR B ;bump to next character psoition. - MOV A,B - CPI 12 ;end of the name? - JNC DIRECT7 - CPI 9 ;nope, starting extension? - JNZ DIRECT6 - CALL SPACE ;yes, add seperating space. - JMP DIRECT6 -DIRECT7 POP PSW ;get the next file name. -DIRECT8 CALL CHKCON ;first check console, quit on anything. - JNZ DIRECT9 - CALL SRCHNXT ;get next name. - JMP DIRECT3 ;and continue with our list. -DIRECT9 POP D ;restore the stack and return to command level. - JMP GETBACK -; -;************************************************************** -;* -;* E R A S E C O M M A N D -;* -;************************************************************** -; -ERASE CALL CONVFST ;convert file name. - CPI 11 ;was '*.*' entered? - JNZ ERASE1 - LXI B,YESNO ;yes, ask for confirmation. - CALL PLINE - CALL GETINP - LXI H,INBUFF+1 - DCR M ;must be exactly 'y'. - JNZ CMMND1 - INX H - MOV A,M - CPI 'Y' - JNZ CMMND1 - INX H - SHLD INPOINT ;save input line pointer. -ERASE1 CALL DSELECT ;select desired disk. - LXI D,FCB - CALL DELETE ;delete the file. - INR A - CZ NONE ;not there? - JMP GETBACK ;return to command level now. -YESNO DB 'All (y/n)?',0 -; -;************************************************************** -;* -;* T Y P E C O M M A N D -;* -;************************************************************** -; -TYPE CALL CONVFST ;convert file name. - JNZ SYNERR ;wild cards not allowed. - CALL DSELECT ;select indicated drive. - CALL OPENFCB ;open the file. - JZ TYPE5 ;not there? - CALL CRLF ;ok, start a new line on the screen. - LXI H,NBYTES;initialize byte counter. - MVI M,0FFH ;set to read first sector. -TYPE1 LXI H,NBYTES -TYPE2 MOV A,M ;have we written the entire sector? - CPI 128 - JC TYPE3 - PUSH H ;yes, read in the next one. - CALL READFCB - POP H - JNZ TYPE4 ;end or error? - XRA A ;ok, clear byte counter. - MOV M,A -TYPE3 INR M ;count this byte. - LXI H,TBUFF ;and get the (A)th one from the buffer (TBUFF). - CALL ADDHL - MOV A,M - CPI CNTRLZ ;end of file mark? - JZ GETBACK - CALL PRINT ;no, print it. - CALL CHKCON ;check console, quit if anything ready. - JNZ GETBACK - JMP TYPE1 -; -; Get here on an end of file or read error. -; -TYPE4 DCR A ;read error? - JZ GETBACK - CALL RDERROR ;yes, print message. -TYPE5 CALL RESETDR ;and reset proper drive - JMP SYNERR ;now print file name with problem. -; -;************************************************************** -;* -;* S A V E C O M M A N D -;* -;************************************************************** -; -SAVE CALL DECODE ;get numeric number that follows SAVE. - PUSH PSW ;save number of pages to write. - CALL CONVFST ;convert file name. - JNZ SYNERR ;wild cards not allowed. - CALL DSELECT ;select specified drive. - LXI D,FCB ;now delete this file. - PUSH D - CALL DELETE - POP D - CALL CREATE ;and create it again. - JZ SAVE3 ;can't create? - XRA A ;clear record number byte. - STA FCB+32 - POP PSW ;convert pages to sectors. - MOV L,A - MVI H,0 - DAD H ;(HL)=number of sectors to write. - LXI D,TBASE ;and we start from here. -SAVE1 MOV A,H ;done yet? - ORA L - JZ SAVE2 - DCX H ;nope, count this and compute the start - PUSH H ;of the next 128 byte sector. - LXI H,128 - DAD D - PUSH H ;save it and set the transfer address. - CALL DMASET - LXI D,FCB ;write out this sector now. - CALL WRTREC - POP D ;reset (DE) to the start of the last sector. - POP H ;restore sector count. - JNZ SAVE3 ;write error? - JMP SAVE1 -; -; Get here after writing all of the file. -; -SAVE2 LXI D,FCB ;now close the file. - CALL CLOSE - INR A ;did it close ok? - JNZ SAVE4 -; -; Print out error message (no space). -; -SAVE3 LXI B,NOSPACE - CALL PLINE -SAVE4 CALL STDDMA ;reset the standard dma address. - JMP GETBACK -NOSPACE DB 'No space',0 -; -;************************************************************** -;* -;* R E N A M E C O M M A N D -;* -;************************************************************** -; -RENAME CALL CONVFST ;convert first file name. - JNZ SYNERR ;wild cards not allowed. - LDA CHGDRV ;remember any change in drives specified. - PUSH PSW - CALL DSELECT ;and select this drive. - CALL SRCHFCB ;is this file present? - JNZ RENAME6 ;yes, print error message. - LXI H,FCB ;yes, move this name into second slot. - LXI D,FCB+16 - MVI B,16 - CALL HL2DE - LHLD INPOINT ;get input pointer. - XCHG - CALL NONBLANK;get next non blank character. - CPI '=' ;only allow an '=' or '_' seperator. - JZ RENAME1 - CPI '_' - JNZ RENAME5 -RENAME1 XCHG - INX H ;ok, skip seperator. - SHLD INPOINT ;save input line pointer. - CALL CONVFST ;convert this second file name now. - JNZ RENAME5 ;again, no wild cards. - POP PSW ;if a drive was specified, then it - MOV B,A ;must be the same as before. - LXI H,CHGDRV - MOV A,M - ORA A - JZ RENAME2 - CMP B - MOV M,B - JNZ RENAME5 ;they were different, error. -RENAME2 MOV M,B; reset as per the first file specification. - XRA A - STA FCB ;clear the drive byte of the fcb. -RENAME3 CALL SRCHFCB ;and go look for second file. - JZ RENAME4 ;doesn't exist? - LXI D,FCB - CALL RENAM ;ok, rename the file. - JMP GETBACK -; -; Process rename errors here. -; -RENAME4 CALL NONE ;file not there. - JMP GETBACK -RENAME5 CALL RESETDR ;bad command format. - JMP SYNERR -RENAME6 LXI B,EXISTS;destination file already exists. - CALL PLINE - JMP GETBACK -EXISTS DB 'File exists',0 -; -;************************************************************** -;* -;* U S E R C O M M A N D -;* -;************************************************************** -; -USER CALL DECODE ;get numeric value following command. - CPI 16 ;legal user number? - JNC SYNERR - MOV E,A ;yes but is there anything else? - LDA FCB+1 - CPI ' ' - JZ SYNERR ;yes, that is not allowed. - CALL GETSETUC;ok, set user code. - JMP GETBACK1 -; -;************************************************************** -;* -;* T R A N S I A N T P R O G R A M C O M M A N D -;* -;************************************************************** -; -UNKNOWN CALL VERIFY ;check for valid system (why?). - LDA FCB+1 ;anything to execute? - CPI ' ' - JNZ UNKWN1 - LDA CHGDRV ;nope, only a drive change? - ORA A - JZ GETBACK1;neither??? - DCR A - STA CDRIVE ;ok, store new drive. - CALL MOVECD ;set (TDRIVE) also. - CALL DSKSEL ;and select this drive. - JMP GETBACK1;then return. -; -; Here a file name was typed. Prepare to execute it. -; -UNKWN1 LXI D,FCB+9 ;an extension specified? - LDAX D - CPI ' ' - JNZ SYNERR ;yes, not allowed. -UNKWN2 PUSH D - CALL DSELECT ;select specified drive. - POP D - LXI H,COMFILE ;set the extension to 'COM'. - CALL MOVE3 - CALL OPENFCB ;and open this file. - JZ UNKWN9 ;not present? -; -; Load in the program. -; - LXI H,TBASE ;store the program starting here. -UNKWN3 PUSH H - XCHG - CALL DMASET ;set transfer address. - LXI D,FCB ;and read the next record. - CALL RDREC - JNZ UNKWN4 ;end of file or read error? - POP H ;nope, bump pointer for next sector. - LXI D,128 - DAD D - LXI D,CBASE ;enough room for the whole file? - MOV A,L - SUB E - MOV A,H - SBB D - JNC UNKWN0 ;no, it can't fit. - JMP UNKWN3 -; -; Get here after finished reading. -; -UNKWN4 POP H - DCR A ;normal end of file? - JNZ UNKWN0 - CALL RESETDR ;yes, reset previous drive. - CALL CONVFST ;convert the first file name that follows - LXI H,CHGDRV;command name. - PUSH H - MOV A,M ;set drive code in default fcb. - STA FCB - MVI A,16 ;put second name 16 bytes later. - CALL CONVERT ;convert second file name. - POP H - MOV A,M ;and set the drive for this second file. - STA FCB+16 - XRA A ;clear record byte in fcb. - STA FCB+32 - LXI D,TFCB ;move it into place at(005Ch). - LXI H,FCB - MVI B,33 - CALL HL2DE - LXI H,INBUFF+2;now move the remainder of the input -UNKWN5 MOV A,M ;line down to (0080h). Look for a non blank. - ORA A ;or a null. - JZ UNKWN6 - CPI ' ' - JZ UNKWN6 - INX H - JMP UNKWN5 -; -; Do the line move now. It ends in a null byte. -; -UNKWN6 MVI B,0 ;keep a character count. - LXI D,TBUFF+1;data gets put here. -UNKWN7 MOV A,M ;move it now. - STAX D - ORA A - JZ UNKWN8 - INR B - INX H - INX D - JMP UNKWN7 -UNKWN8 MOV A,B ;now store the character count. - STA TBUFF - CALL CRLF ;clean up the screen. - CALL STDDMA ;set standard transfer address. - CALL SETCDRV ;reset current drive. - CALL TBASE ;and execute the program. -; -; Transiant programs return here (or reboot). -; - LXI SP,BATCH ;set stack first off. - CALL MOVECD ;move current drive into place (TDRIVE). - CALL DSKSEL ;and reselect it. - JMP CMMND1 ;back to comand mode. -; -; Get here if some error occured. -; -UNKWN9 CALL RESETDR ;inproper format. - JMP SYNERR -UNKWN0 LXI B,BADLOAD;read error or won't fit. - CALL PLINE - JMP GETBACK -BADLOAD DB 'Bad load',0 -COMFILE DB 'COM' ;command file extension. -; -; Get here to return to command level. We will reset the -; previous active drive and then either return to command -; level directly or print error message and then return. -; -GETBACK CALL RESETDR ;reset previous drive. -GETBACK1:CALL CONVFST ;convert first name in (FCB). - LDA FCB+1 ;if this was just a drive change request, - SUI ' ' ;make sure it was valid. - LXI H,CHGDRV - ORA M - JNZ SYNERR - JMP CMMND1 ;ok, return to command level. -; -; ccp stack area. -; - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -CCPSTACK:EQU $ ;end of ccp stack area. -; -; Batch (or SUBMIT) processing information storage. -; -BATCH DB 0 ;batch mode flag (0=not active). -BATCHFCB:DB 0,'$$$ SUB',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; File control block setup by the CCP. -; -FCB DB 0,' ',0,0,0,0,0,' ',0,0,0,0,0 -RTNCODE DB 0 ;status returned from bdos call. -CDRIVE DB 0 ;currently active drive. -CHGDRV DB 0 ;change in drives flag (0=no change). -NBYTES DW 0 ;byte counter used by TYPE. -; -; Room for expansion? -; - DB 0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; Note that the following six bytes must match those at -; (PATTRN1) or cp/m will HALT. Why? -; -PATTRN2 DB 0,22,0,0,0,0;(* serial number bytes *). -; -;************************************************************** -;* -;* B D O S E N T R Y -;* -;************************************************************** -; -FBASE JMP FBASE1 -; -; Bdos error table. -; -BADSCTR DW ERROR1 ;bad sector on read or write. -BADSLCT DW ERROR2 ;bad disk select. -RODISK DW ERROR3 ;disk is read only. -ROFILE DW ERROR4 ;file is read only. -; -; Entry into bdos. (DE) or (E) are the parameters passed. The -; function number desired is in register (C). -; -FBASE1 XCHG ;save the (DE) parameters. - SHLD PARAMS - XCHG - MOV A,E ;and save register (E) in particular. - STA EPARAM - LXI H,0 - SHLD STATUS ;clear return status. - DAD SP - SHLD USRSTACK;save users stack pointer. - LXI SP,STKAREA;and set our own. - XRA A ;clear auto select storage space. - STA AUTOFLAG - STA AUTO - LXI H,GOBACK;set return address. - PUSH H - MOV A,C ;get function number. - CPI NFUNCTS ;valid function number? - RNC - MOV C,E ;keep single register function here. - LXI H,FUNCTNS;now look thru the function table. - MOV E,A - MVI D,0 ;(DE)=function number. - DAD D - DAD D ;(HL)=(start of table)+2*(function number). - MOV E,M - INX H - MOV D,M ;now (DE)=address for this function. - LHLD PARAMS ;retrieve parameters. - XCHG ;now (DE) has the original parameters. - PCHL ;execute desired function. -; -; BDOS function jump table. -; -NFUNCTS EQU 41 ;number of functions in followin table. -; -FUNCTNS DW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - DW SETIOB,PRTSTR,RDBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - DW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - DW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - DW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - DW RTN,WTSPECL -; -; Bdos error message section. -; -ERROR1 LXI H,BADSEC ;bad sector message. - CALL PRTERR ;print it and get a 1 char responce. - CPI CNTRLC ;re-boot request (control-c)? - JZ 0 ;yes. - RET ;no, return to retry i/o function. -; -ERROR2 LXI H,BADSEL ;bad drive selected. - JMP ERROR5 -; -ERROR3 LXI H,DISKRO ;disk is read only. - JMP ERROR5 -; -ERROR4 LXI H,FILERO ;file is read only. -; -ERROR5 CALL PRTERR - JMP 0 ;always reboot on these errors. -; -BDOSERR DB 'Bdos Err On ' -BDOSDRV DB ' : $' -BADSEC DB 'Bad Sector$' -BADSEL DB 'Select$' -FILERO DB 'File ' -DISKRO DB 'R/O$' -; -; Print bdos error message. -; -PRTERR PUSH H ;save second message pointer. - CALL OUTCRLF ;send (cr)(lf). - LDA ACTIVE ;get active drive. - ADI 'A' ;make ascii. - STA BDOSDRV ;and put in message. - LXI B,BDOSERR;and print it. - CALL PRTMESG - POP B ;print second message line now. - CALL PRTMESG -; -; Get an input character. We will check our 1 character -; buffer first. This may be set by the console status routine. -; -GETCHAR LXI H,CHARBUF;check character buffer. - MOV A,M ;anything present already? - MVI M,0 ;...either case clear it. - ORA A - RNZ ;yes, use it. - JMP CONIN ;nope, go get a character responce. -; -; Input and echo a character. -; -GETECHO CALL GETCHAR ;input a character. - CALL CHKCHAR ;carriage control? - RC ;no, a regular control char so don't echo. - PUSH PSW ;ok, save character now. - MOV C,A - CALL OUTCON ;and echo it. - POP PSW ;get character and return. - RET -; -; Check character in (A). Set the zero flag on a carriage -; control character and the carry flag on any other control -; character. -; -CHKCHAR CPI CR ;check for carriage return, line feed, backspace, - RZ ;or a tab. - CPI LF - RZ - CPI TAB - RZ - CPI BS - RZ - CPI ' ' ;other control char? Set carry flag. - RET -; -; Check the console during output. Halt on a control-s, then -; reboot on a control-c. If anything else is ready, clear the -; zero flag and return (the calling routine may want to do -; something). -; -CKCONSOL:LDA CHARBUF ;check buffer. - ORA A ;if anything, just return without checking. - JNZ CKCON2 - CALL CONST ;nothing in buffer. Check console. - ANI 01H ;look at bit 0. - RZ ;return if nothing. - CALL CONIN ;ok, get it. - CPI CNTRLS ;if not control-s, return with zero cleared. - JNZ CKCON1 - CALL CONIN ;halt processing until another char - CPI CNTRLC ;is typed. Control-c? - JZ 0 ;yes, reboot now. - XRA A ;no, just pretend nothing was ever ready. - RET -CKCON1 STA CHARBUF ;save character in buffer for later processing. -CKCON2 MVI A,1 ;set (A) to non zero to mean something is ready. - RET -; -; Output (C) to the screen. If the printer flip-flop flag -; is set, we will send character to printer also. The console -; will be checked in the process. -; -OUTCHAR LDA OUTFLAG ;check output flag. - ORA A ;anything and we won't generate output. - JNZ OUTCHR1 - PUSH B - CALL CKCONSOL;check console (we don't care whats there). - POP B - PUSH B - CALL CONOUT ;output (C) to the screen. - POP B - PUSH B - LDA PRTFLAG ;check printer flip-flop flag. - ORA A - CNZ LIST ;print it also if non-zero. - POP B -OUTCHR1 MOV A,C ;update cursors position. - LXI H,CURPOS - CPI DEL ;rubouts don't do anything here. - RZ - INR M ;bump line pointer. - CPI ' ' ;and return if a normal character. - RNC - DCR M ;restore and check for the start of the line. - MOV A,M - ORA A - RZ ;ingnore control characters at the start of the line. - MOV A,C - CPI BS ;is it a backspace? - JNZ OUTCHR2 - DCR M ;yes, backup pointer. - RET -OUTCHR2 CPI LF ;is it a line feed? - RNZ ;ignore anything else. - MVI M,0 ;reset pointer to start of line. - RET -; -; Output (A) to the screen. If it is a control character -; (other than carriage control), use ^x format. -; -SHOWIT MOV A,C - CALL CHKCHAR ;check character. - JNC OUTCON ;not a control, use normal output. - PUSH PSW - MVI C,'^' ;for a control character, preceed it with '^'. - CALL OUTCHAR - POP PSW - ORI '@' ;and then use the letter equivelant. - MOV C,A -; -; Function to output (C) to the console device and expand tabs -; if necessary. -; -OUTCON MOV A,C - CPI TAB ;is it a tab? - JNZ OUTCHAR ;use regular output. -OUTCON1 MVI C,' ' ;yes it is, use spaces instead. - CALL OUTCHAR - LDA CURPOS ;go until the cursor is at a multiple of 8 - - ANI 07H ;position. - JNZ OUTCON1 - RET -; -; Echo a backspace character. Erase the prevoius character -; on the screen. -; -BACKUP CALL BACKUP1 ;backup the screen 1 place. - MVI C,' ' ;then blank that character. - CALL CONOUT -BACKUP1 MVI C,BS ;then back space once more. - JMP CONOUT -; -; Signal a deleted line. Print a '#' at the end and start -; over. -; -NEWLINE MVI C,'#' - CALL OUTCHAR ;print this. - CALL OUTCRLF ;start new line. -NEWLN1 LDA CURPOS ;move the cursor to the starting position. - LXI H,STARTING - CMP M - RNC ;there yet? - MVI C,' ' - CALL OUTCHAR ;nope, keep going. - JMP NEWLN1 -; -; Output a (cr) (lf) to the console device (screen). -; -OUTCRLF MVI C,CR - CALL OUTCHAR - MVI C,LF - JMP OUTCHAR -; -; Print message pointed to by (BC). It will end with a '$'. -; -PRTMESG LDAX B ;check for terminating character. - CPI '$' - RZ - INX B - PUSH B ;otherwise, bump pointer and print it. - MOV C,A - CALL OUTCON - POP B - JMP PRTMESG -; -; Function to execute a buffered read. -; -RDBUFF LDA CURPOS ;use present location as starting one. - STA STARTING - LHLD PARAMS ;get the maximum buffer space. - MOV C,M - INX H ;point to first available space. - PUSH H ;and save. - MVI B,0 ;keep a character count. -RDBUF1 PUSH B - PUSH H -RDBUF2 CALL GETCHAR ;get the next input character. - ANI 7FH ;strip bit 7. - POP H ;reset registers. - POP B - CPI CR ;en of the line? - JZ RDBUF17 - CPI LF - JZ RDBUF17 - CPI BS ;how about a backspace? - JNZ RDBUF3 - MOV A,B ;yes, but ignore at the beginning of the line. - ORA A - JZ RDBUF1 - DCR B ;ok, update counter. - LDA CURPOS ;if we backspace to the start of the line, - STA OUTFLAG ;treat as a cancel (control-x). - JMP RDBUF10 -RDBUF3 CPI DEL ;user typed a rubout? - JNZ RDBUF4 - MOV A,B ;ignore at the start of the line. - ORA A - JZ RDBUF1 - MOV A,M ;ok, echo the prevoius character. - DCR B ;and reset pointers (counters). - DCX H - JMP RDBUF15 -RDBUF4 CPI CNTRLE ;physical end of line? - JNZ RDBUF5 - PUSH B ;yes, do it. - PUSH H - CALL OUTCRLF - XRA A ;and update starting position. - STA STARTING - JMP RDBUF2 -RDBUF5 CPI CNTRLP ;control-p? - JNZ RDBUF6 - PUSH H ;yes, flip the print flag filp-flop byte. - LXI H,PRTFLAG - MVI A,1 ;PRTFLAG=1-PRTFLAG - SUB M - MOV M,A - POP H - JMP RDBUF1 -RDBUF6 CPI CNTRLX ;control-x (cancel)? - JNZ RDBUF8 - POP H -RDBUF7 LDA STARTING;yes, backup the cursor to here. - LXI H,CURPOS - CMP M - JNC RDBUFF ;done yet? - DCR M ;no, decrement pointer and output back up one space. - CALL BACKUP - JMP RDBUF7 -RDBUF8 CPI CNTRLU ;cntrol-u (cancel line)? - JNZ RDBUF9 - CALL NEWLINE ;start a new line. - POP H - JMP RDBUFF -RDBUF9 CPI CNTRLR ;control-r? - JNZ RDBUF14 -RDBUF10 PUSH B ;yes, start a new line and retype the old one. - CALL NEWLINE - POP B - POP H - PUSH H - PUSH B -RDBUF11 MOV A,B ;done whole line yet? - ORA A - JZ RDBUF12 - INX H ;nope, get next character. - MOV C,M - DCR B ;count it. - PUSH B - PUSH H - CALL SHOWIT ;and display it. - POP H - POP B - JMP RDBUF11 -RDBUF12 PUSH H ;done with line. If we were displaying - LDA OUTFLAG ;then update cursor position. - ORA A - JZ RDBUF2 - LXI H,CURPOS;because this line is shorter, we must - SUB M ;back up the cursor (not the screen however) - STA OUTFLAG ;some number of positions. -RDBUF13 CALL BACKUP ;note that as long as (OUTFLAG) is non - LXI H,OUTFLAG;zero, the screen will not be changed. - DCR M - JNZ RDBUF13 - JMP RDBUF2 ;now just get the next character. -; -; Just a normal character, put this in our buffer and echo. -; -RDBUF14 INX H - MOV M,A ;store character. - INR B ;and count it. -RDBUF15 PUSH B - PUSH H - MOV C,A ;echo it now. - CALL SHOWIT - POP H - POP B - MOV A,M ;was it an abort request? - CPI CNTRLC ;control-c abort? - MOV A,B - JNZ RDBUF16 - CPI 1 ;only if at start of line. - JZ 0 -RDBUF16 CMP C ;nope, have we filled the buffer? - JC RDBUF1 -RDBUF17 POP H ;yes end the line and return. - MOV M,B - MVI C,CR - JMP OUTCHAR ;output (cr) and return. -; -; Function to get a character from the console device. -; -GETCON CALL GETECHO ;get and echo. - JMP SETSTAT ;save status and return. -; -; Function to get a character from the tape reader device. -; -GETRDR CALL READER ;get a character from reader, set status and return. - JMP SETSTAT -; -; Function to perform direct console i/o. If (C) contains (FF) -; then this is an input request. If (C) contains (FE) then -; this is a status request. Otherwise we are to output (C). -; -DIRCIO MOV A,C ;test for (FF). - INR A - JZ DIRC1 - INR A ;test for (FE). - JZ CONST - JMP CONOUT ;just output (C). -DIRC1 CALL CONST ;this is an input request. - ORA A - JZ GOBACK1 ;not ready? Just return (directly). - CALL CONIN ;yes, get character. - JMP SETSTAT ;set status and return. -; -; Function to return the i/o byte. -; -GETIOB LDA IOBYTE - JMP SETSTAT -; -; Function to set the i/o byte. -; -SETIOB LXI H,IOBYTE - MOV M,C - RET -; -; Function to print the character string pointed to by (DE) -; on the console device. The string ends with a '$'. -; -PRTSTR XCHG - MOV C,L - MOV B,H ;now (BC) points to it. - JMP PRTMESG -; -; Function to interigate the console device. -; -GETCSTS CALL CKCONSOL -; -; Get here to set the status and return to the cleanup -; section. Then back to the user. -; -SETSTAT STA STATUS -RTN RET -; -; Set the status to 1 (read or write error code). -; -IOERR1 MVI A,1 - JMP SETSTAT -; -OUTFLAG DB 0 ;output flag (non zero means no output). -STARTING:DB 2 ;starting position for cursor. -CURPOS DB 0 ;cursor position (0=start of line). -PRTFLAG DB 0 ;printer flag (control-p toggle). List if non zero. -CHARBUF DB 0 ;single input character buffer. -; -; Stack area for BDOS calls. -; -USRSTACK:DW 0 ;save users stack pointer here. -; - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -STKAREA EQU $ ;end of stack area. -; -USERNO DB 0 ;current user number. -ACTIVE DB 0 ;currently active drive. -PARAMS DW 0 ;save (DE) parameters here on entry. -STATUS DW 0 ;status returned from bdos function. -; -; Select error occured, jump to error routine. -; -SLCTERR LXI H,BADSLCT -; -; Jump to (HL) indirectly. -; -JUMPHL MOV E,M - INX H - MOV D,M ;now (DE) contain the desired address. - XCHG - PCHL -; -; Block move. (DE) to (HL), (C) bytes total. -; -DE2HL INR C ;is count down to zero? -DE2HL1 DCR C - RZ ;yes, we are done. - LDAX D ;no, move one more byte. - MOV M,A - INX D - INX H - JMP DE2HL1 ;and repeat. -; -; Select the desired drive. -; -SELECT LDA ACTIVE ;get active disk. - MOV C,A - CALL SELDSK ;select it. - MOV A,H ;valid drive? - ORA L ;valid drive? - RZ ;return if not. -; -; Here, the BIOS returned the address of the parameter block -; in (HL). We will extract the necessary pointers and save them. -; - MOV E,M ;yes, get address of translation table into (DE). - INX H - MOV D,M - INX H - SHLD SCRATCH1 ;save pointers to scratch areas. - INX H - INX H - SHLD SCRATCH2 ;ditto. - INX H - INX H - SHLD SCRATCH3 ;ditto. - INX H - INX H - XCHG ;now save the translation table address. - SHLD XLATE - LXI H,DIRBUF ;put the next 8 bytes here. - MVI C,8 ;they consist of the directory buffer - CALL DE2HL ;pointer, parameter block pointer, - LHLD DISKPB ;check and allocation vectors. - XCHG - LXI H,SECTORS ;move parameter block into our ram. - MVI C,15 ;it is 15 bytes long. - CALL DE2HL - LHLD DSKSIZE ;check disk size. - MOV A,H ;more than 256 blocks on this? - LXI H,BIGDISK - MVI M,0FFH ;set to samll. - ORA A - JZ SELECT1 - MVI M,0 ;wrong, set to large. -SELECT1 MVI A,0FFH ;clear the zero flag. - ORA A - RET -; -; Routine to home the disk track head and clear pointers. -; -HOMEDRV CALL HOME ;home the head. - XRA A - LHLD SCRATCH2;set our track pointer also. - MOV M,A - INX H - MOV M,A - LHLD SCRATCH3;and our sector pointer. - MOV M,A - INX H - MOV M,A - RET -; -; Do the actual disk read and check the error return status. -; -DOREAD CALL READ - JMP IORET -; -; Do the actual disk write and handle any bios error. -; -DOWRITE CALL WRITE -IORET ORA A - RZ ;return unless an error occured. - LXI H,BADSCTR;bad read/write on this sector. - JMP JUMPHL -; -; Routine to select the track and sector that the desired -; block number falls in. -; -TRKSEC LHLD FILEPOS ;get position of last accessed file - MVI C,2 ;in directory and compute sector #. - CALL SHIFTR ;sector #=file-position/4. - SHLD BLKNMBR ;save this as the block number of interest. - SHLD CKSUMTBL;what's it doing here too? -; -; if the sector number has already been set (BLKNMBR), enter -; at this point. -; -TRKSEC1 LXI H,BLKNMBR - MOV C,M ;move sector number into (BC). - INX H - MOV B,M - LHLD SCRATCH3;get current sector number and - MOV E,M ;move this into (DE). - INX H - MOV D,M - LHLD SCRATCH2;get current track number. - MOV A,M ;and this into (HL). - INX H - MOV H,M - MOV L,A -TRKSEC2 MOV A,C ;is desired sector before current one? - SUB E - MOV A,B - SBB D - JNC TRKSEC3 - PUSH H ;yes, decrement sectors by one track. - LHLD SECTORS ;get sectors per track. - MOV A,E - SUB L - MOV E,A - MOV A,D - SBB H - MOV D,A ;now we have backed up one full track. - POP H - DCX H ;adjust track counter. - JMP TRKSEC2 -TRKSEC3 PUSH H ;desired sector is after current one. - LHLD SECTORS ;get sectors per track. - DAD D ;bump sector pointer to next track. - JC TRKSEC4 - MOV A,C ;is desired sector now before current one? - SUB L - MOV A,B - SBB H - JC TRKSEC4 - XCHG ;not yes, increment track counter - POP H ;and continue until it is. - INX H - JMP TRKSEC3 -; -; here we have determined the track number that contains the -; desired sector. -; -TRKSEC4 POP H ;get track number (HL). - PUSH B - PUSH D - PUSH H - XCHG - LHLD OFFSET ;adjust for first track offset. - DAD D - MOV B,H - MOV C,L - CALL SETTRK ;select this track. - POP D ;reset current track pointer. - LHLD SCRATCH2 - MOV M,E - INX H - MOV M,D - POP D - LHLD SCRATCH3;reset the first sector on this track. - MOV M,E - INX H - MOV M,D - POP B - MOV A,C ;now subtract the desired one. - SUB E ;to make it relative (1-# sectors/track). - MOV C,A - MOV A,B - SBB D - MOV B,A - LHLD XLATE ;translate this sector according to this table. - XCHG - CALL SECTRN ;let the bios translate it. - MOV C,L - MOV B,H - JMP SETSEC ;and select it. -; -; Compute block number from record number (SAVNREC) and -; extent number (SAVEXT). -; -GETBLOCK:LXI H,BLKSHFT;get logical to physical conversion. - MOV C,M ;note that this is base 2 log of ratio. - LDA SAVNREC ;get record number. -GETBLK1 ORA A ;compute (A)=(A)/2^BLKSHFT. - RAR - DCR C - JNZ GETBLK1 - MOV B,A ;save result in (B). - MVI A,8 - SUB M - MOV C,A ;compute (C)=8-BLKSHFT. - LDA SAVEXT -GETBLK2 DCR C ;compute (A)=SAVEXT*2^(8-BLKSHFT). - JZ GETBLK3 - ORA A - RAL - JMP GETBLK2 -GETBLK3 ADD B - RET -; -; Routine to extract the (BC) block byte from the fcb pointed -; to by (PARAMS). If this is a big-disk, then these are 16 bit -; block numbers, else they are 8 bit numbers. -; Number is returned in (HL). -; -EXTBLK LHLD PARAMS ;get fcb address. - LXI D,16 ;block numbers start 16 bytes into fcb. - DAD D - DAD B - LDA BIGDISK ;are we using a big-disk? - ORA A - JZ EXTBLK1 - MOV L,M ;no, extract an 8 bit number from the fcb. - MVI H,0 - RET -EXTBLK1 DAD B ;yes, extract a 16 bit number. - MOV E,M - INX H - MOV D,M - XCHG ;return in (HL). - RET -; -; Compute block number. -; -COMBLK CALL GETBLOCK - MOV C,A - MVI B,0 - CALL EXTBLK - SHLD BLKNMBR - RET -; -; Check for a zero block number (unused). -; -CHKBLK LHLD BLKNMBR - MOV A,L ;is it zero? - ORA H - RET -; -; Adjust physical block (BLKNMBR) and convert to logical -; sector (LOGSECT). This is the starting sector of this block. -; The actual sector of interest is then added to this and the -; resulting sector number is stored back in (BLKNMBR). This -; will still have to be adjusted for the track number. -; -LOGICAL LDA BLKSHFT ;get log2(physical/logical sectors). - LHLD BLKNMBR ;get physical sector desired. -LOGICL1 DAD H ;compute logical sector number. - DCR A ;note logical sectors are 128 bytes long. - JNZ LOGICL1 - SHLD LOGSECT ;save logical sector. - LDA BLKMASK ;get block mask. - MOV C,A - LDA SAVNREC ;get next sector to access. - ANA C ;extract the relative position within physical block. - ORA L ;and add it too logical sector. - MOV L,A - SHLD BLKNMBR ;and store. - RET -; -; Set (HL) to point to extent byte in fcb. -; -SETEXT LHLD PARAMS - LXI D,12 ;it is the twelth byte. - DAD D - RET -; -; Set (HL) to point to record count byte in fcb and (DE) to -; next record number byte. -; -SETHLDE LHLD PARAMS - LXI D,15 ;record count byte (#15). - DAD D - XCHG - LXI H,17 ;next record number (#32). - DAD D - RET -; -; Save current file data from fcb. -; -STRDATA CALL SETHLDE - MOV A,M ;get and store record count byte. - STA SAVNREC - XCHG - MOV A,M ;get and store next record number byte. - STA SAVNXT - CALL SETEXT ;point to extent byte. - LDA EXTMASK ;get extent mask. - ANA M - STA SAVEXT ;and save extent here. - RET -; -; Set the next record to access. If (MODE) is set to 2, then -; the last record byte (SAVNREC) has the correct number to access. -; For sequential access, (MODE) will be equal to 1. -; -SETNREC CALL SETHLDE - LDA MODE ;get sequential flag (=1). - CPI 2 ;a 2 indicates that no adder is needed. - JNZ STNREC1 - XRA A ;clear adder (random access?). -STNREC1 MOV C,A - LDA SAVNREC ;get last record number. - ADD C ;increment record count. - MOV M,A ;and set fcb's next record byte. - XCHG - LDA SAVNXT ;get next record byte from storage. - MOV M,A ;and put this into fcb as number of records used. - RET -; -; Shift (HL) right (C) bits. -; -SHIFTR INR C -SHIFTR1 DCR C - RZ - MOV A,H - ORA A - RAR - MOV H,A - MOV A,L - RAR - MOV L,A - JMP SHIFTR1 -; -; Compute the check-sum for the directory buffer. Return -; integer sum in (A). -; -CHECKSUM:MVI C,128 ;length of buffer. - LHLD DIRBUF ;get its location. - XRA A ;clear summation byte. -CHKSUM1 ADD M ;and compute sum ignoring carries. - INX H - DCR C - JNZ CHKSUM1 - RET -; -; Shift (HL) left (C) bits. -; -SHIFTL INR C -SHIFTL1 DCR C - RZ - DAD H ;shift left 1 bit. - JMP SHIFTL1 -; -; Routine to set a bit in a 16 bit value contained in (BC). -; The bit set depends on the current drive selection. -; -SETBIT PUSH B ;save 16 bit word. - LDA ACTIVE ;get active drive. - MOV C,A - LXI H,1 - CALL SHIFTL ;shift bit 0 into place. - POP B ;now 'or' this with the original word. - MOV A,C - ORA L - MOV L,A ;low byte done, do high byte. - MOV A,B - ORA H - MOV H,A - RET -; -; Extract the write protect status bit for the current drive. -; The result is returned in (A), bit 0. -; -GETWPRT LHLD WRTPRT ;get status bytes. - LDA ACTIVE ;which drive is current? - MOV C,A - CALL SHIFTR ;shift status such that bit 0 is the - MOV A,L ;one of interest for this drive. - ANI 01H ;and isolate it. - RET -; -; Function to write protect the current disk. -; -WRTPRTD LXI H,WRTPRT;point to status word. - MOV C,M ;set (BC) equal to the status. - INX H - MOV B,M - CALL SETBIT ;and set this bit according to current drive. - SHLD WRTPRT ;then save. - LHLD DIRSIZE ;now save directory size limit. - INX H ;remember the last one. - XCHG - LHLD SCRATCH1;and store it here. - MOV M,E ;put low byte. - INX H - MOV M,D ;then high byte. - RET -; -; Check for a read only file. -; -CHKROFL CALL FCB2HL ;set (HL) to file entry in directory buffer. -CKROF1 LXI D,9 ;look at bit 7 of the ninth byte. - DAD D - MOV A,M - RAL - RNC ;return if ok. - LXI H,ROFILE;else, print error message and terminate. - JMP JUMPHL -; -; Check the write protect status of the active disk. -; -CHKWPRT CALL GETWPRT - RZ ;return if ok. - LXI H,RODISK;else print message and terminate. - JMP JUMPHL -; -; Routine to set (HL) pointing to the proper entry in the -; directory buffer. -; -FCB2HL LHLD DIRBUF ;get address of buffer. - LDA FCBPOS ;relative position of file. -; -; Routine to add (A) to (HL). -; -ADDA2HL ADD L - MOV L,A - RNC - INR H ;take care of any carry. - RET -; -; Routine to get the 's2' byte from the fcb supplied in -; the initial parameter specification. -; -GETS2 LHLD PARAMS ;get address of fcb. - LXI D,14 ;relative position of 's2'. - DAD D - MOV A,M ;extract this byte. - RET -; -; Clear the 's2' byte in the fcb. -; -CLEARS2 CALL GETS2 ;this sets (HL) pointing to it. - MVI M,0 ;now clear it. - RET -; -; Set bit 7 in the 's2' byte of the fcb. -; -SETS2B7 CALL GETS2 ;get the byte. - ORI 80H ;and set bit 7. - MOV M,A ;then store. - RET -; -; Compare (FILEPOS) with (SCRATCH1) and set flags based on -; the difference. This checks to see if there are more file -; names in the directory. We are at (FILEPOS) and there are -; (SCRATCH1) of them to check. -; -MOREFLS LHLD FILEPOS ;we are here. - XCHG - LHLD SCRATCH1;and don't go past here. - MOV A,E ;compute difference but don't keep. - SUB M - INX H - MOV A,D - SBB M ;set carry if no more names. - RET -; -; Call this routine to prevent (SCRATCH1) from being greater -; than (FILEPOS). -; -CHKNMBR CALL MOREFLS ;SCRATCH1 too big? - RC - INX D ;yes, reset it to (FILEPOS). - MOV M,D - DCX H - MOV M,E - RET -; -; Compute (HL)=(DE)-(HL) -; -SUBHL MOV A,E ;compute difference. - SUB L - MOV L,A ;store low byte. - MOV A,D - SBB H - MOV H,A ;and then high byte. - RET -; -; Set the directory checksum byte. -; -SETDIR MVI C,0FFH -; -; Routine to set or compare the directory checksum byte. If -; (C)=0ffh, then this will set the checksum byte. Else the byte -; will be checked. If the check fails (the disk has been changed), -; then this disk will be write protected. -; -CHECKDIR:LHLD CKSUMTBL - XCHG - LHLD ALLOC1 - CALL SUBHL - RNC ;ok if (CKSUMTBL) > (ALLOC1), so return. - PUSH B - CALL CHECKSUM;else compute checksum. - LHLD CHKVECT ;get address of checksum table. - XCHG - LHLD CKSUMTBL - DAD D ;set (HL) to point to byte for this drive. - POP B - INR C ;set or check ? - JZ CHKDIR1 - CMP M ;check them. - RZ ;return if they are the same. - CALL MOREFLS ;not the same, do we care? - RNC - CALL WRTPRTD ;yes, mark this as write protected. - RET -CHKDIR1 MOV M,A ;just set the byte. - RET -; -; Do a write to the directory of the current disk. -; -DIRWRITE:CALL SETDIR ;set checksum byte. - CALL DIRDMA ;set directory dma address. - MVI C,1 ;tell the bios to actually write. - CALL DOWRITE ;then do the write. - JMP DEFDMA -; -; Read from the directory. -; -DIRREAD CALL DIRDMA ;set the directory dma address. - CALL DOREAD ;and read it. -; -; Routine to set the dma address to the users choice. -; -DEFDMA LXI H,USERDMA;reset the default dma address and return. - JMP DIRDMA1 -; -; Routine to set the dma address for directory work. -; -DIRDMA LXI H,DIRBUF -; -; Set the dma address. On entry, (HL) points to -; word containing the desired dma address. -; -DIRDMA1 MOV C,M - INX H - MOV B,M ;setup (BC) and go to the bios to set it. - JMP SETDMA -; -; Move the directory buffer into user's dma space. -; -MOVEDIR LHLD DIRBUF ;buffer is located here, and - XCHG - LHLD USERDMA; put it here. - MVI C,128 ;this is its length. - JMP DE2HL ;move it now and return. -; -; Check (FILEPOS) and set the zero flag if it equals 0ffffh. -; -CKFILPOS:LXI H,FILEPOS - MOV A,M - INX H - CMP M ;are both bytes the same? - RNZ - INR A ;yes, but are they each 0ffh? - RET -; -; Set location (FILEPOS) to 0ffffh. -; -STFILPOS:LXI H,0FFFFH - SHLD FILEPOS - RET -; -; Move on to the next file position within the current -; directory buffer. If no more exist, set pointer to 0ffffh -; and the calling routine will check for this. Enter with (C) -; equal to 0ffh to cause the checksum byte to be set, else we -; will check this disk and set write protect if checksums are -; not the same (applies only if another directory sector must -; be read). -; -NXENTRY LHLD DIRSIZE ;get directory entry size limit. - XCHG - LHLD FILEPOS ;get current count. - INX H ;go on to the next one. - SHLD FILEPOS - CALL SUBHL ;(HL)=(DIRSIZE)-(FILEPOS) - JNC NXENT1 ;is there more room left? - JMP STFILPOS;no. Set this flag and return. -NXENT1 LDA FILEPOS ;get file position within directory. - ANI 03H ;only look within this sector (only 4 entries fit). - MVI B,5 ;convert to relative position (32 bytes each). -NXENT2 ADD A ;note that this is not efficient code. - DCR B ;5 'ADD A's would be better. - JNZ NXENT2 - STA FCBPOS ;save it as position of fcb. - ORA A - RNZ ;return if we are within buffer. - PUSH B - CALL TRKSEC ;we need the next directory sector. - CALL DIRREAD - POP B - JMP CHECKDIR -; -; Routine to to get a bit from the disk space allocation -; map. It is returned in (A), bit position 0. On entry to here, -; set (BC) to the block number on the disk to check. -; On return, (D) will contain the original bit position for -; this block number and (HL) will point to the address for it. -; -CKBITMAP:MOV A,C ;determine bit number of interest. - ANI 07H ;compute (D)=(E)=(C and 7)+1. - INR A - MOV E,A ;save particular bit number. - MOV D,A -; -; compute (BC)=(BC)/8. -; - MOV A,C - RRC ;now shift right 3 bits. - RRC - RRC - ANI 1FH ;and clear bits 7,6,5. - MOV C,A - MOV A,B - ADD A ;now shift (B) into bits 7,6,5. - ADD A - ADD A - ADD A - ADD A - ORA C ;and add in (C). - MOV C,A ;ok, (C) ha been completed. - MOV A,B ;is there a better way of doing this? - RRC - RRC - RRC - ANI 1FH - MOV B,A ;and now (B) is completed. -; -; use this as an offset into the disk space allocation -; table. -; - LHLD ALOCVECT - DAD B - MOV A,M ;now get correct byte. -CKBMAP1 RLC ;get correct bit into position 0. - DCR E - JNZ CKBMAP1 - RET -; -; Set or clear the bit map such that block number (BC) will be marked -; as used. On entry, if (E)=0 then this bit will be cleared, if it equals -; 1 then it will be set (don't use anyother values). -; -STBITMAP:PUSH D - CALL CKBITMAP;get the byte of interest. - ANI 0FEH ;clear the affected bit. - POP B - ORA C ;and now set it acording to (C). -; -; entry to restore the original bit position and then store -; in table. (A) contains the value, (D) contains the bit -; position (1-8), and (HL) points to the address within the -; space allocation table for this byte. -; -STBMAP1 RRC ;restore original bit position. - DCR D - JNZ STBMAP1 - MOV M,A ;and stor byte in table. - RET -; -; Set/clear space used bits in allocation map for this file. -; On entry, (C)=1 to set the map and (C)=0 to clear it. -; -SETFILE CALL FCB2HL ;get address of fcb - LXI D,16 - DAD D ;get to block number bytes. - PUSH B - MVI C,17 ;check all 17 bytes (max) of table. -SETFL1 POP D - DCR C ;done all bytes yet? - RZ - PUSH D - LDA BIGDISK ;check disk size for 16 bit block numbers. - ORA A - JZ SETFL2 - PUSH B ;only 8 bit numbers. set (BC) to this one. - PUSH H - MOV C,M ;get low byte from table, always - MVI B,0 ;set high byte to zero. - JMP SETFL3 -SETFL2 DCR C ;for 16 bit block numbers, adjust counter. - PUSH B - MOV C,M ;now get both the low and high bytes. - INX H - MOV B,M - PUSH H -SETFL3 MOV A,C ;block used? - ORA B - JZ SETFL4 - LHLD DSKSIZE ;is this block number within the - MOV A,L ;space on the disk? - SUB C - MOV A,H - SBB B - CNC STBITMAP;yes, set the proper bit. -SETFL4 POP H ;point to next block number in fcb. - INX H - POP B - JMP SETFL1 -; -; Construct the space used allocation bit map for the active -; drive. If a file name starts with '$' and it is under the -; current user number, then (STATUS) is set to minus 1. Otherwise -; it is not set at all. -; -BITMAP LHLD DSKSIZE ;compute size of allocation table. - MVI C,3 - CALL SHIFTR ;(HL)=(HL)/8. - INX H ;at lease 1 byte. - MOV B,H - MOV C,L ;set (BC) to the allocation table length. -; -; Initialize the bitmap for this drive. Right now, the first -; two bytes are specified by the disk parameter block. However -; a patch could be entered here if it were necessary to setup -; this table in a special mannor. For example, the bios could -; determine locations of 'bad blocks' and set them as already -; 'used' in the map. -; - LHLD ALOCVECT;now zero out the table now. -BITMAP1 MVI M,0 - INX H - DCX B - MOV A,B - ORA C - JNZ BITMAP1 - LHLD ALLOC0 ;get initial space used by directory. - XCHG - LHLD ALOCVECT;and put this into map. - MOV M,E - INX H - MOV M,D -; -; End of initialization portion. -; - CALL HOMEDRV ;now home the drive. - LHLD SCRATCH1 - MVI M,3 ;force next directory request to read - INX H ;in a sector. - MVI M,0 - CALL STFILPOS;clear initial file position also. -BITMAP2 MVI C,0FFH ;read next file name in directory - CALL NXENTRY ;and set checksum byte. - CALL CKFILPOS;is there another file? - RZ - CALL FCB2HL ;yes, get its address. - MVI A,0E5H - CMP M ;empty file entry? - JZ BITMAP2 - LDA USERNO ;no, correct user number? - CMP M - JNZ BITMAP3 - INX H - MOV A,M ;yes, does name start with a '$'? - SUI '$' - JNZ BITMAP3 - DCR A ;yes, set atatus to minus one. - STA STATUS -BITMAP3 MVI C,1 ;now set this file's space as used in bit map. - CALL SETFILE - CALL CHKNMBR ;keep (SCRATCH1) in bounds. - JMP BITMAP2 -; -; Set the status (STATUS) and return. -; -STSTATUS:LDA FNDSTAT - JMP SETSTAT -; -; Check extents in (A) and (C). Set the zero flag if they -; are the same. The number of 16k chunks of disk space that -; the directory extent covers is expressad is (EXTMASK+1). -; No registers are modified. -; -SAMEXT PUSH B - PUSH PSW - LDA EXTMASK ;get extent mask and use it to - CMA ;to compare both extent numbers. - MOV B,A ;save resulting mask here. - MOV A,C ;mask first extent and save in (C). - ANA B - MOV C,A - POP PSW ;now mask second extent and compare - ANA B ;with the first one. - SUB C - ANI 1FH ;(* only check buts 0-4 *) - POP B ;the zero flag is set if they are the same. - RET ;restore (BC) and return. -; -; Search for the first occurence of a file name. On entry, -; register (C) should contain the number of bytes of the fcb -; that must match. -; -FINDFST MVI A,0FFH - STA FNDSTAT - LXI H,COUNTER;save character count. - MOV M,C - LHLD PARAMS ;get filename to match. - SHLD SAVEFCB ;and save. - CALL STFILPOS;clear initial file position (set to 0ffffh). - CALL HOMEDRV ;home the drive. -; -; Entry to locate the next occurence of a filename within the -; directory. The disk is not expected to have been changed. If -; it was, then it will be write protected. -; -FINDNXT MVI C,0 ;write protect the disk if changed. - CALL NXENTRY ;get next filename entry in directory. - CALL CKFILPOS;is file position = 0ffffh? - JZ FNDNXT6 ;yes, exit now then. - LHLD SAVEFCB ;set (DE) pointing to filename to match. - XCHG - LDAX D - CPI 0E5H ;empty directory entry? - JZ FNDNXT1 ;(* are we trying to reserect erased entries? *) - PUSH D - CALL MOREFLS ;more files in directory? - POP D - JNC FNDNXT6 ;no more. Exit now. -FNDNXT1 CALL FCB2HL ;get address of this fcb in directory. - LDA COUNTER ;get number of bytes (characters) to check. - MOV C,A - MVI B,0 ;initialize byte position counter. -FNDNXT2 MOV A,C ;are we done with the compare? - ORA A - JZ FNDNXT5 - LDAX D ;no, check next byte. - CPI '?' ;don't care about this character? - JZ FNDNXT4 - MOV A,B ;get bytes position in fcb. - CPI 13 ;don't care about the thirteenth byte either. - JZ FNDNXT4 - CPI 12 ;extent byte? - LDAX D - JZ FNDNXT3 - SUB M ;otherwise compare characters. - ANI 7FH - JNZ FINDNXT ;not the same, check next entry. - JMP FNDNXT4 ;so far so good, keep checking. -FNDNXT3 PUSH B ;check the extent byte here. - MOV C,M - CALL SAMEXT - POP B - JNZ FINDNXT ;not the same, look some more. -; -; So far the names compare. Bump pointers to the next byte -; and continue until all (C) characters have been checked. -; -FNDNXT4 INX D ;bump pointers. - INX H - INR B - DCR C ;adjust character counter. - JMP FNDNXT2 -FNDNXT5 LDA FILEPOS ;return the position of this entry. - ANI 03H - STA STATUS - LXI H,FNDSTAT - MOV A,M - RAL - RNC - XRA A - MOV M,A - RET -; -; Filename was not found. Set appropriate status. -; -FNDNXT6 CALL STFILPOS;set (FILEPOS) to 0ffffh. - MVI A,0FFH ;say not located. - JMP SETSTAT -; -; Erase files from the directory. Only the first byte of the -; fcb will be affected. It is set to (E5). -; -ERAFILE CALL CHKWPRT ;is disk write protected? - MVI C,12 ;only compare file names. - CALL FINDFST ;get first file name. -ERAFIL1 CALL CKFILPOS;any found? - RZ ;nope, we must be done. - CALL CHKROFL ;is file read only? - CALL FCB2HL ;nope, get address of fcb and - MVI M,0E5H ;set first byte to 'empty'. - MVI C,0 ;clear the space from the bit map. - CALL SETFILE - CALL DIRWRITE;now write the directory sector back out. - CALL FINDNXT ;find the next file name. - JMP ERAFIL1 ;and repeat process. -; -; Look through the space allocation map (bit map) for the -; next available block. Start searching at block number (BC-1). -; The search procedure is to look for an empty block that is -; before the starting block. If not empty, look at a later -; block number. In this way, we return the closest empty block -; on either side of the 'target' block number. This will speed -; access on random devices. For serial devices, this should be -; changed to look in the forward direction first and then start -; at the front and search some more. -; -; On return, (DE)= block number that is empty and (HL) =0 -; if no empry block was found. -; -FNDSPACE:MOV D,B ;set (DE) as the block that is checked. - MOV E,C -; -; Look before target block. Registers (BC) are used as the lower -; pointer and (DE) as the upper pointer. -; -FNDSPA1 MOV A,C ;is block 0 specified? - ORA B - JZ FNDSPA2 - DCX B ;nope, check previous block. - PUSH D - PUSH B - CALL CKBITMAP - RAR ;is this block empty? - JNC FNDSPA3 ;yes. use this. -; -; Note that the above logic gets the first block that it finds -; that is empty. Thus a file could be written 'backward' making -; it very slow to access. This could be changed to look for the -; first empty block and then continue until the start of this -; empty space is located and then used that starting block. -; This should help speed up access to some files especially on -; a well used disk with lots of fairly small 'holes'. -; - POP B ;nope, check some more. - POP D -; -; Now look after target block. -; -FNDSPA2 LHLD DSKSIZE ;is block (DE) within disk limits? - MOV A,E - SUB L - MOV A,D - SBB H - JNC FNDSPA4 - INX D ;yes, move on to next one. - PUSH B - PUSH D - MOV B,D - MOV C,E - CALL CKBITMAP;check it. - RAR ;empty? - JNC FNDSPA3 - POP D ;nope, continue searching. - POP B - JMP FNDSPA1 -; -; Empty block found. Set it as used and return with (HL) -; pointing to it (true?). -; -FNDSPA3 RAL ;reset byte. - INR A ;and set bit 0. - CALL STBMAP1 ;update bit map. - POP H ;set return registers. - POP D - RET -; -; Free block was not found. If (BC) is not zero, then we have -; not checked all of the disk space. -; -FNDSPA4 MOV A,C - ORA B - JNZ FNDSPA1 - LXI H,0 ;set 'not found' status. - RET -; -; Move a complete fcb entry into the directory and write it. -; -FCBSET MVI C,0 - MVI E,32 ;length of each entry. -; -; Move (E) bytes from the fcb pointed to by (PARAMS) into -; fcb in directory starting at relative byte (C). This updated -; directory buffer is then written to the disk. -; -UPDATE PUSH D - MVI B,0 ;set (BC) to relative byte position. - LHLD PARAMS ;get address of fcb. - DAD B ;compute starting byte. - XCHG - CALL FCB2HL ;get address of fcb to update in directory. - POP B ;set (C) to number of bytes to change. - CALL DE2HL -UPDATE1 CALL TRKSEC ;determine the track and sector affected. - JMP DIRWRITE ;then write this sector out. -; -; Routine to change the name of all files on the disk with a -; specified name. The fcb contains the current name as the -; first 12 characters and the new name 16 bytes into the fcb. -; -CHGNAMES:CALL CHKWPRT ;check for a write protected disk. - MVI C,12 ;match first 12 bytes of fcb only. - CALL FINDFST ;get first name. - LHLD PARAMS ;get address of fcb. - MOV A,M ;get user number. - LXI D,16 ;move over to desired name. - DAD D - MOV M,A ;keep same user number. -CHGNAM1 CALL CKFILPOS;any matching file found? - RZ ;no, we must be done. - CALL CHKROFL ;check for read only file. - MVI C,16 ;start 16 bytes into fcb. - MVI E,12 ;and update the first 12 bytes of directory. - CALL UPDATE - CALL FINDNXT ;get te next file name. - JMP CHGNAM1 ;and continue. -; -; Update a files attributes. The procedure is to search for -; every file with the same name as shown in fcb (ignoring bit 7) -; and then to update it (which includes bit 7). No other changes -; are made. -; -SAVEATTR:MVI C,12 ;match first 12 bytes. - CALL FINDFST ;look for first filename. -SAVATR1 CALL CKFILPOS;was one found? - RZ ;nope, we must be done. - MVI C,0 ;yes, update the first 12 bytes now. - MVI E,12 - CALL UPDATE ;update filename and write directory. - CALL FINDNXT ;and get the next file. - JMP SAVATR1 ;then continue until done. -; -; Open a file (name specified in fcb). -; -OPENIT MVI C,15 ;compare the first 15 bytes. - CALL FINDFST ;get the first one in directory. - CALL CKFILPOS;any at all? - RZ -OPENIT1 CALL SETEXT ;point to extent byte within users fcb. - MOV A,M ;and get it. - PUSH PSW ;save it and address. - PUSH H - CALL FCB2HL ;point to fcb in directory. - XCHG - LHLD PARAMS ;this is the users copy. - MVI C,32 ;move it into users space. - PUSH D - CALL DE2HL - CALL SETS2B7 ;set bit 7 in 's2' byte (unmodified). - POP D ;now get the extent byte from this fcb. - LXI H,12 - DAD D - MOV C,M ;into (C). - LXI H,15 ;now get the record count byte into (B). - DAD D - MOV B,M - POP H ;keep the same extent as the user had originally. - POP PSW - MOV M,A - MOV A,C ;is it the same as in the directory fcb? - CMP M - MOV A,B ;if yes, then use the same record count. - JZ OPENIT2 - MVI A,0 ;if the user specified an extent greater than - JC OPENIT2 ;the one in the directory, then set record count to 0. - MVI A,128 ;otherwise set to maximum. -OPENIT2 LHLD PARAMS ;set record count in users fcb to (A). - LXI D,15 - DAD D ;compute relative position. - MOV M,A ;and set the record count. - RET -; -; Move two bytes from (DE) to (HL) if (and only if) (HL) -; point to a zero value (16 bit). -; Return with zero flag set it (DE) was moved. Registers (DE) -; and (HL) are not changed. However (A) is. -; -MOVEWORD:MOV A,M ;check for a zero word. - INX H - ORA M ;both bytes zero? - DCX H - RNZ ;nope, just return. - LDAX D ;yes, move two bytes from (DE) into - MOV M,A ;this zero space. - INX D - INX H - LDAX D - MOV M,A - DCX D ;don't disturb these registers. - DCX H - RET -; -; Get here to close a file specified by (fcb). -; -CLOSEIT XRA A ;clear status and file position bytes. - STA STATUS - STA FILEPOS - STA FILEPOS+1 - CALL GETWPRT ;get write protect bit for this drive. - RNZ ;just return if it is set. - CALL GETS2 ;else get the 's2' byte. - ANI 80H ;and look at bit 7 (file unmodified?). - RNZ ;just return if set. - MVI C,15 ;else look up this file in directory. - CALL FINDFST - CALL CKFILPOS;was it found? - RZ ;just return if not. - LXI B,16 ;set (HL) pointing to records used section. - CALL FCB2HL - DAD B - XCHG - LHLD PARAMS ;do the same for users specified fcb. - DAD B - MVI C,16 ;this many bytes are present in this extent. -CLOSEIT1:LDA BIGDISK ;8 or 16 bit record numbers? - ORA A - JZ CLOSEIT4 - MOV A,M ;just 8 bit. Get one from users fcb. - ORA A - LDAX D ;now get one from directory fcb. - JNZ CLOSEIT2 - MOV M,A ;users byte was zero. Update from directory. -CLOSEIT2:ORA A - JNZ CLOSEIT3 - MOV A,M ;directories byte was zero, update from users fcb. - STAX D -CLOSEIT3:CMP M ;if neither one of these bytes were zero, - JNZ CLOSEIT7 ;then close error if they are not the same. - JMP CLOSEIT5 ;ok so far, get to next byte in fcbs. -CLOSEIT4:CALL MOVEWORD;update users fcb if it is zero. - XCHG - CALL MOVEWORD;update directories fcb if it is zero. - XCHG - LDAX D ;if these two values are no different, - CMP M ;then a close error occured. - JNZ CLOSEIT7 - INX D ;check second byte. - INX H - LDAX D - CMP M - JNZ CLOSEIT7 - DCR C ;remember 16 bit values. -CLOSEIT5:INX D ;bump to next item in table. - INX H - DCR C ;there are 16 entries only. - JNZ CLOSEIT1;continue if more to do. - LXI B,0FFECH;backup 20 places (extent byte). - DAD B - XCHG - DAD B - LDAX D - CMP M ;directory's extent already greater than the - JC CLOSEIT6 ;users extent? - MOV M,A ;no, update directory extent. - LXI B,3 ;and update the record count byte in - DAD B ;directories fcb. - XCHG - DAD B - MOV A,M ;get from user. - STAX D ;and put in directory. -CLOSEIT6:MVI A,0FFH ;set 'was open and is now closed' byte. - STA CLOSEFLG - JMP UPDATE1 ;update the directory now. -CLOSEIT7:LXI H,STATUS;set return status and then return. - DCR M - RET -; -; Routine to get the next empty space in the directory. It -; will then be cleared for use. -; -GETEMPTY:CALL CHKWPRT ;make sure disk is not write protected. - LHLD PARAMS ;save current parameters (fcb). - PUSH H - LXI H,EMPTYFCB;use special one for empty space. - SHLD PARAMS - MVI C,1 ;search for first empty spot in directory. - CALL FINDFST ;(* only check first byte *) - CALL CKFILPOS;none? - POP H - SHLD PARAMS ;restore original fcb address. - RZ ;return if no more space. - XCHG - LXI H,15 ;point to number of records for this file. - DAD D - MVI C,17 ;and clear all of this space. - XRA A -GETMT1 MOV M,A - INX H - DCR C - JNZ GETMT1 - LXI H,13 ;clear the 's1' byte also. - DAD D - MOV M,A - CALL CHKNMBR ;keep (SCRATCH1) within bounds. - CALL FCBSET ;write out this fcb entry to directory. - JMP SETS2B7 ;set 's2' byte bit 7 (unmodified at present). -; -; Routine to close the current extent and open the next one -; for reading. -; -GETNEXT XRA A - STA CLOSEFLG;clear close flag. - CALL CLOSEIT ;close this extent. - CALL CKFILPOS - RZ ;not there??? - LHLD PARAMS ;get extent byte. - LXI B,12 - DAD B - MOV A,M ;and increment it. - INR A - ANI 1FH ;keep within range 0-31. - MOV M,A - JZ GTNEXT1 ;overflow? - MOV B,A ;mask extent byte. - LDA EXTMASK - ANA B - LXI H,CLOSEFLG;check close flag (0ffh is ok). - ANA M - JZ GTNEXT2 ;if zero, we must read in next extent. - JMP GTNEXT3 ;else, it is already in memory. -GTNEXT1 LXI B,2 ;Point to the 's2' byte. - DAD B - INR M ;and bump it. - MOV A,M ;too many extents? - ANI 0FH - JZ GTNEXT5 ;yes, set error code. -; -; Get here to open the next extent. -; -GTNEXT2 MVI C,15 ;set to check first 15 bytes of fcb. - CALL FINDFST ;find the first one. - CALL CKFILPOS;none available? - JNZ GTNEXT3 - LDA RDWRTFLG;no extent present. Can we open an empty one? - INR A ;0ffh means reading (so not possible). - JZ GTNEXT5 ;or an error. - CALL GETEMPTY;we are writing, get an empty entry. - CALL CKFILPOS;none? - JZ GTNEXT5 ;error if true. - JMP GTNEXT4 ;else we are almost done. -GTNEXT3 CALL OPENIT1 ;open this extent. -GTNEXT4 CALL STRDATA ;move in updated data (rec #, extent #, etc.) - XRA A ;clear status and return. - JMP SETSTAT -; -; Error in extending the file. Too many extents were needed -; or not enough space on the disk. -; -GTNEXT5 CALL IOERR1 ;set error code, clear bit 7 of 's2' - JMP SETS2B7 ;so this is not written on a close. -; -; Read a sequential file. -; -RDSEQ MVI A,1 ;set sequential access mode. - STA MODE -RDSEQ1 MVI A,0FFH ;don't allow reading unwritten space. - STA RDWRTFLG - CALL STRDATA ;put rec# and ext# into fcb. - LDA SAVNREC ;get next record to read. - LXI H,SAVNXT;get number of records in extent. - CMP M ;within this extent? - JC RDSEQ2 - CPI 128 ;no. Is this extent fully used? - JNZ RDSEQ3 ;no. End-of-file. - CALL GETNEXT ;yes, open the next one. - XRA A ;reset next record to read. - STA SAVNREC - LDA STATUS ;check on open, successful? - ORA A - JNZ RDSEQ3 ;no, error. -RDSEQ2 CALL COMBLK ;ok. compute block number to read. - CALL CHKBLK ;check it. Within bounds? - JZ RDSEQ3 ;no, error. - CALL LOGICAL ;convert (BLKNMBR) to logical sector (128 byte). - CALL TRKSEC1 ;set the track and sector for this block #. - CALL DOREAD ;and read it. - JMP SETNREC ;and set the next record to be accessed. -; -; Read error occured. Set status and return. -; -RDSEQ3 JMP IOERR1 -; -; Write the next sequential record. -; -WTSEQ MVI A,1 ;set sequential access mode. - STA MODE -WTSEQ1 MVI A,0 ;allow an addition empty extent to be opened. - STA RDWRTFLG - CALL CHKWPRT ;check write protect status. - LHLD PARAMS - CALL CKROF1 ;check for read only file, (HL) already set to fcb. - CALL STRDATA ;put updated data into fcb. - LDA SAVNREC ;get record number to write. - CPI 128 ;within range? - JNC IOERR1 ;no, error(?). - CALL COMBLK ;compute block number. - CALL CHKBLK ;check number. - MVI C,0 ;is there one to write to? - JNZ WTSEQ6 ;yes, go do it. - CALL GETBLOCK;get next block number within fcb to use. - STA RELBLOCK;and save. - LXI B,0 ;start looking for space from the start - ORA A ;if none allocated as yet. - JZ WTSEQ2 - MOV C,A ;extract previous block number from fcb - DCX B ;so we can be closest to it. - CALL EXTBLK - MOV B,H - MOV C,L -WTSEQ2 CALL FNDSPACE;find the next empty block nearest number (BC). - MOV A,L ;check for a zero number. - ORA H - JNZ WTSEQ3 - MVI A,2 ;no more space? - JMP SETSTAT -WTSEQ3 SHLD BLKNMBR ;save block number to access. - XCHG ;put block number into (DE). - LHLD PARAMS ;now we must update the fcb for this - LXI B,16 ;newly allocated block. - DAD B - LDA BIGDISK ;8 or 16 bit block numbers? - ORA A - LDA RELBLOCK ;(* update this entry *) - JZ WTSEQ4 ;zero means 16 bit ones. - CALL ADDA2HL ;(HL)=(HL)+(A) - MOV M,E ;store new block number. - JMP WTSEQ5 -WTSEQ4 MOV C,A ;compute spot in this 16 bit table. - MVI B,0 - DAD B - DAD B - MOV M,E ;stuff block number (DE) there. - INX H - MOV M,D -WTSEQ5 MVI C,2 ;set (C) to indicate writing to un-used disk space. -WTSEQ6 LDA STATUS ;are we ok so far? - ORA A - RNZ - PUSH B ;yes, save write flag for bios (register C). - CALL LOGICAL ;convert (BLKNMBR) over to loical sectors. - LDA MODE ;get access mode flag (1=sequential, - DCR A ;0=random, 2=special?). - DCR A - JNZ WTSEQ9 -; -; Special random i/o from function #40. Maybe for M/PM, but the -; current block, if it has not been written to, will be zeroed -; out and then written (reason?). -; - POP B - PUSH B - MOV A,C ;get write status flag (2=writing unused space). - DCR A - DCR A - JNZ WTSEQ9 - PUSH H - LHLD DIRBUF ;zero out the directory buffer. - MOV D,A ;note that (A) is zero here. -WTSEQ7 MOV M,A - INX H - INR D ;do 128 bytes. - JP WTSEQ7 - CALL DIRDMA ;tell the bios the dma address for directory access. - LHLD LOGSECT ;get sector that starts current block. - MVI C,2 ;set 'writing to unused space' flag. -WTSEQ8 SHLD BLKNMBR ;save sector to write. - PUSH B - CALL TRKSEC1 ;determine its track and sector numbers. - POP B - CALL DOWRITE ;now write out 128 bytes of zeros. - LHLD BLKNMBR ;get sector number. - MVI C,0 ;set normal write flag. - LDA BLKMASK ;determine if we have written the entire - MOV B,A ;physical block. - ANA L - CMP B - INX H ;prepare for the next one. - JNZ WTSEQ8 ;continue until (BLKMASK+1) sectors written. - POP H ;reset next sector number. - SHLD BLKNMBR - CALL DEFDMA ;and reset dma address. -; -; Normal disk write. Set the desired track and sector then -; do the actual write. -; -WTSEQ9 CALL TRKSEC1 ;determine track and sector for this write. - POP B ;get write status flag. - PUSH B - CALL DOWRITE ;and write this out. - POP B - LDA SAVNREC ;get number of records in file. - LXI H,SAVNXT;get last record written. - CMP M - JC WTSEQ10 - MOV M,A ;we have to update record count. - INR M - MVI C,2 -; -;* This area has been patched to correct disk update problem -;* when using blocking and de-blocking in the BIOS. -; -WTSEQ10 NOP ;was 'dcr c' - NOP ;was 'dcr c' - LXI H,0 ;was 'jnz wtseq99' -; -; * End of patch. -; - PUSH PSW - CALL GETS2 ;set 'extent written to' flag. - ANI 7FH ;(* clear bit 7 *) - MOV M,A - POP PSW ;get record count for this extent. -WTSEQ99 CPI 127 ;is it full? - JNZ WTSEQ12 - LDA MODE ;yes, are we in sequential mode? - CPI 1 - JNZ WTSEQ12 - CALL SETNREC ;yes, set next record number. - CALL GETNEXT ;and get next empty space in directory. - LXI H,STATUS;ok? - MOV A,M - ORA A - JNZ WTSEQ11 - DCR A ;yes, set record count to -1. - STA SAVNREC -WTSEQ11 MVI M,0 ;clear status. -WTSEQ12 JMP SETNREC ;set next record to access. -; -; For random i/o, set the fcb for the desired record number -; based on the 'r0,r1,r2' bytes. These bytes in the fcb are -; used as follows: -; -; fcb+35 fcb+34 fcb+33 -; | 'r-2' | 'r-1' | 'r-0' | -; |7 0 | 7 0 | 7 0| -; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| -; | overflow | | extra | extent | record # | -; | ______________| |_extent|__number___|_____________| -; also 's2' -; -; On entry, register (C) contains 0ffh if this is a read -; and thus we can not access unwritten disk space. Otherwise, -; another extent will be opened (for writing) if required. -; -POSITION:XRA A ;set random i/o flag. - STA MODE -; -; Special entry (function #40). M/PM ? -; -POSITN1 PUSH B ;save read/write flag. - LHLD PARAMS ;get address of fcb. - XCHG - LXI H,33 ;now get byte 'r0'. - DAD D - MOV A,M - ANI 7FH ;keep bits 0-6 for the record number to access. - PUSH PSW - MOV A,M ;now get bit 7 of 'r0' and bits 0-3 of 'r1'. - RAL - INX H - MOV A,M - RAL - ANI 1FH ;and save this in bits 0-4 of (C). - MOV C,A ;this is the extent byte. - MOV A,M ;now get the extra extent byte. - RAR - RAR - RAR - RAR - ANI 0FH - MOV B,A ;and save it in (B). - POP PSW ;get record number back to (A). - INX H ;check overflow byte 'r2'. - MOV L,M - INR L - DCR L - MVI L,6 ;prepare for error. - JNZ POSITN5 ;out of disk space error. - LXI H,32 ;store record number into fcb. - DAD D - MOV M,A - LXI H,12 ;and now check the extent byte. - DAD D - MOV A,C - SUB M ;same extent as before? - JNZ POSITN2 - LXI H,14 ;yes, check extra extent byte 's2' also. - DAD D - MOV A,B - SUB M - ANI 7FH - JZ POSITN3;same, we are almost done then. -; -; Get here when another extent is required. -; -POSITN2 PUSH B - PUSH D - CALL CLOSEIT ;close current extent. - POP D - POP B - MVI L,3 ;prepare for error. - LDA STATUS - INR A - JZ POSITN4 ;close error. - LXI H,12 ;put desired extent into fcb now. - DAD D - MOV M,C - LXI H,14 ;and store extra extent byte 's2'. - DAD D - MOV M,B - CALL OPENIT ;try and get this extent. - LDA STATUS ;was it there? - INR A - JNZ POSITN3 - POP B ;no. can we create a new one (writing?). - PUSH B - MVI L,4 ;prepare for error. - INR C - JZ POSITN4 ;nope, reading unwritten space error. - CALL GETEMPTY;yes we can, try to find space. - MVI L,5 ;prepare for error. - LDA STATUS - INR A - JZ POSITN4 ;out of space? -; -; Normal return location. Clear error code and return. -; -POSITN3 POP B ;restore stack. - XRA A ;and clear error code byte. - JMP SETSTAT -; -; Error. Set the 's2' byte to indicate this (why?). -; -POSITN4 PUSH H - CALL GETS2 - MVI M,0C0H - POP H -; -; Return with error code (presently in L). -; -POSITN5 POP B - MOV A,L ;get error code. - STA STATUS - JMP SETS2B7 -; -; Read a random record. -; -READRAN MVI C,0FFH ;set 'read' status. - CALL POSITION;position the file to proper record. - CZ RDSEQ1 ;and read it as usual (if no errors). - RET -; -; Write to a random record. -; -WRITERAN:MVI C,0 ;set 'writing' flag. - CALL POSITION;position the file to proper record. - CZ WTSEQ1 ;and write as usual (if no errors). - RET -; -; Compute the random record number. Enter with (HL) pointing -; to a fcb an (DE) contains a relative location of a record -; number. On exit, (C) contains the 'r0' byte, (B) the 'r1' -; byte, and (A) the 'r2' byte. -; -; On return, the zero flag is set if the record is within -; bounds. Otherwise, an overflow occured. -; -COMPRAND:XCHG ;save fcb pointer in (DE). - DAD D ;compute relative position of record #. - MOV C,M ;get record number into (BC). - MVI B,0 - LXI H,12 ;now get extent. - DAD D - MOV A,M ;compute (BC)=(record #)+(extent)*128. - RRC ;move lower bit into bit 7. - ANI 80H ;and ignore all other bits. - ADD C ;add to our record number. - MOV C,A - MVI A,0 ;take care of any carry. - ADC B - MOV B,A - MOV A,M ;now get the upper bits of extent into - RRC ;bit positions 0-3. - ANI 0FH ;and ignore all others. - ADD B ;add this in to 'r1' byte. - MOV B,A - LXI H,14 ;get the 's2' byte (extra extent). - DAD D - MOV A,M - ADD A ;and shift it left 4 bits (bits 4-7). - ADD A - ADD A - ADD A - PUSH PSW ;save carry flag (bit 0 of flag byte). - ADD B ;now add extra extent into 'r1'. - MOV B,A - PUSH PSW ;and save carry (overflow byte 'r2'). - POP H ;bit 0 of (L) is the overflow indicator. - MOV A,L - POP H ;and same for first carry flag. - ORA L ;either one of these set? - ANI 01H ;only check the carry flags. - RET -; -; Routine to setup the fcb (bytes 'r0', 'r1', 'r2') to -; reflect the last record used for a random (or other) file. -; This reads the directory and looks at all extents computing -; the largerst record number for each and keeping the maximum -; value only. Then 'r0', 'r1', and 'r2' will reflect this -; maximum record number. This is used to compute the space used -; by a random file. -; -RANSIZE MVI C,12 ;look thru directory for first entry with - CALL FINDFST ;this name. - LHLD PARAMS ;zero out the 'r0, r1, r2' bytes. - LXI D,33 - DAD D - PUSH H - MOV M,D ;note that (D)=0. - INX H - MOV M,D - INX H - MOV M,D -RANSIZ1 CALL CKFILPOS;is there an extent to process? - JZ RANSIZ3 ;no, we are done. - CALL FCB2HL ;set (HL) pointing to proper fcb in dir. - LXI D,15 ;point to last record in extent. - CALL COMPRAND;and compute random parameters. - POP H - PUSH H ;now check these values against those - MOV E,A ;already in fcb. - MOV A,C ;the carry flag will be set if those - SUB M ;in the fcb represent a larger size than - INX H ;this extent does. - MOV A,B - SBB M - INX H - MOV A,E - SBB M - JC RANSIZ2 - MOV M,E ;we found a larger (in size) extent. - DCX H ;stuff these values into fcb. - MOV M,B - DCX H - MOV M,C -RANSIZ2 CALL FINDNXT ;now get the next extent. - JMP RANSIZ1 ;continue til all done. -RANSIZ3 POP H ;we are done, restore the stack and - RET ;return. -; -; Function to return the random record position of a given -; file which has been read in sequential mode up to now. -; -SETRAN LHLD PARAMS ;point to fcb. - LXI D,32 ;and to last used record. - CALL COMPRAND;compute random position. - LXI H,33 ;now stuff these values into fcb. - DAD D - MOV M,C ;move 'r0'. - INX H - MOV M,B ;and 'r1'. - INX H - MOV M,A ;and lastly 'r2'. - RET -; -; This routine select the drive specified in (ACTIVE) and -; update the login vector and bitmap table if this drive was -; not already active. -; -LOGINDRV:LHLD LOGIN ;get the login vector. - LDA ACTIVE ;get the default drive. - MOV C,A - CALL SHIFTR ;position active bit for this drive - PUSH H ;into bit 0. - XCHG - CALL SELECT ;select this drive. - POP H - CZ SLCTERR ;valid drive? - MOV A,L ;is this a newly activated drive? - RAR - RC - LHLD LOGIN ;yes, update the login vector. - MOV C,L - MOV B,H - CALL SETBIT - SHLD LOGIN ;and save. - JMP BITMAP ;now update the bitmap. -; -; Function to set the active disk number. -; -SETDSK LDA EPARAM ;get parameter passed and see if this - LXI H,ACTIVE;represents a change in drives. - CMP M - RZ - MOV M,A ;yes it does, log it in. - JMP LOGINDRV -; -; This is the 'auto disk select' routine. The firsst byte -; of the fcb is examined for a drive specification. If non -; zero then the drive will be selected and loged in. -; -AUTOSEL MVI A,0FFH ;say 'auto-select activated'. - STA AUTO - LHLD PARAMS ;get drive specified. - MOV A,M - ANI 1FH ;look at lower 5 bits. - DCR A ;adjust for (1=A, 2=B) etc. - STA EPARAM ;and save for the select routine. - CPI 1EH ;check for 'no change' condition. - JNC AUTOSL1 ;yes, don't change. - LDA ACTIVE ;we must change, save currently active - STA OLDDRV ;drive. - MOV A,M ;and save first byte of fcb also. - STA AUTOFLAG;this must be non-zero. - ANI 0E0H ;whats this for (bits 6,7 are used for - MOV M,A ;something)? - CALL SETDSK ;select and log in this drive. -AUTOSL1 LDA USERNO ;move user number into fcb. - LHLD PARAMS ;(* upper half of first byte *) - ORA M - MOV M,A - RET ;and return (all done). -; -; Function to return the current cp/m version number. -; -GETVER MVI A,022h ;version 2.2 - JMP SETSTAT -; -; Function to reset the disk system. -; -RSTDSK LXI H,0 ;clear write protect status and log - SHLD WRTPRT ;in vector. - SHLD LOGIN - XRA A ;select drive 'A'. - STA ACTIVE - LXI H,TBUFF ;setup default dma address. - SHLD USERDMA - CALL DEFDMA - JMP LOGINDRV;now log in drive 'A'. -; -; Function to open a specified file. -; -OPENFIL CALL CLEARS2 ;clear 's2' byte. - CALL AUTOSEL ;select proper disk. - JMP OPENIT ;and open the file. -; -; Function to close a specified file. -; -CLOSEFIL:CALL AUTOSEL ;select proper disk. - JMP CLOSEIT ;and close the file. -; -; Function to return the first occurence of a specified file -; name. If the first byte of the fcb is '?' then the name will -; not be checked (get the first entry no matter what). -; -GETFST MVI C,0 ;prepare for special search. - XCHG - MOV A,M ;is first byte a '?'? - CPI '?' - JZ GETFST1 ;yes, just get very first entry (zero length match). - CALL SETEXT ;get the extension byte from fcb. - MOV A,M ;is it '?'? if yes, then we want - CPI '?' ;an entry with a specific 's2' byte. - CNZ CLEARS2 ;otherwise, look for a zero 's2' byte. - CALL AUTOSEL ;select proper drive. - MVI C,15 ;compare bytes 0-14 in fcb (12&13 excluded). -GETFST1 CALL FINDFST ;find an entry and then move it into - JMP MOVEDIR ;the users dma space. -; -; Function to return the next occurence of a file name. -; -GETNXT LHLD SAVEFCB ;restore pointers. note that no - SHLD PARAMS ;other dbos calls are allowed. - CALL AUTOSEL ;no error will be returned, but the - CALL FINDNXT ;results will be wrong. - JMP MOVEDIR -; -; Function to delete a file by name. -; -DELFILE CALL AUTOSEL ;select proper drive. - CALL ERAFILE ;erase the file. - JMP STSTATUS;set status and return. -; -; Function to execute a sequential read of the specified -; record number. -; -READSEQ CALL AUTOSEL ;select proper drive then read. - JMP RDSEQ -; -; Function to write the net sequential record. -; -WRTSEQ CALL AUTOSEL ;select proper drive then write. - JMP WTSEQ -; -; Create a file function. -; -FCREATE CALL CLEARS2 ;clear the 's2' byte on all creates. - CALL AUTOSEL ;select proper drive and get the next - JMP GETEMPTY;empty directory space. -; -; Function to rename a file. -; -RENFILE CALL AUTOSEL ;select proper drive and then switch - CALL CHGNAMES;file names. - JMP STSTATUS -; -; Function to return the login vector. -; -GETLOG LHLD LOGIN - JMP GETPRM1 -; -; Function to return the current disk assignment. -; -GETCRNT LDA ACTIVE - JMP SETSTAT -; -; Function to set the dma address. -; -PUTDMA XCHG - SHLD USERDMA ;save in our space and then get to - JMP DEFDMA ;the bios with this also. -; -; Function to return the allocation vector. -; -GETALOC LHLD ALOCVECT - JMP GETPRM1 -; -; Function to return the read-only status vector. -; -GETROV LHLD WRTPRT - JMP GETPRM1 -; -; Function to set the file attributes (read-only, system). -; -SETATTR CALL AUTOSEL ;select proper drive then save attributes. - CALL SAVEATTR - JMP STSTATUS -; -; Function to return the address of the disk parameter block -; for the current drive. -; -GETPARM LHLD DISKPB -GETPRM1 SHLD STATUS - RET -; -; Function to get or set the user number. If (E) was (FF) -; then this is a request to return the current user number. -; Else set the user number from (E). -; -GETUSER LDA EPARAM ;get parameter. - CPI 0FFH ;get user number? - JNZ SETUSER - LDA USERNO ;yes, just do it. - JMP SETSTAT -SETUSER ANI 1FH ;no, we should set it instead. keep low - STA USERNO ;bits (0-4) only. - RET -; -; Function to read a random record from a file. -; -RDRANDOM:CALL AUTOSEL ;select proper drive and read. - JMP READRAN -; -; Function to compute the file size for random files. -; -WTRANDOM:CALL AUTOSEL ;select proper drive and write. - JMP WRITERAN -; -; Function to compute the size of a random file. -; -FILESIZE:CALL AUTOSEL ;select proper drive and check file length - JMP RANSIZE -; -; Function #37. This allows a program to log off any drives. -; On entry, set (DE) to contain a word with bits set for those -; drives that are to be logged off. The log-in vector and the -; write protect vector will be updated. This must be a M/PM -; special function. -; -LOGOFF LHLD PARAMS ;get drives to log off. - MOV A,L ;for each bit that is set, we want - CMA ;to clear that bit in (LOGIN) - MOV E,A ;and (WRTPRT). - MOV A,H - CMA - LHLD LOGIN ;reset the login vector. - ANA H - MOV D,A - MOV A,L - ANA E - MOV E,A - LHLD WRTPRT - XCHG - SHLD LOGIN ;and save. - MOV A,L ;now do the write protect vector. - ANA E - MOV L,A - MOV A,H - ANA D - MOV H,A - SHLD WRTPRT ;and save. all done. - RET -; -; Get here to return to the user. -; -GOBACK LDA AUTO ;was auto select activated? - ORA A - JZ GOBACK1 - LHLD PARAMS ;yes, but was a change made? - MVI M,0 ;(* reset first byte of fcb *) - LDA AUTOFLAG - ORA A - JZ GOBACK1 - MOV M,A ;yes, reset first byte properly. - LDA OLDDRV ;and get the old drive and select it. - STA EPARAM - CALL SETDSK -GOBACK1 LHLD USRSTACK;reset the users stack pointer. - SPHL - LHLD STATUS ;get return status. - MOV A,L ;force version 1.4 compatability. - MOV B,H - RET ;and go back to user. -; -; Function #40. This is a special entry to do random i/o. -; For the case where we are writing to unused disk space, this -; space will be zeroed out first. This must be a M/PM special -; purpose function, because why would any normal program even -; care about the previous contents of a sector about to be -; written over. -; -WTSPECL CALL AUTOSEL ;select proper drive. - MVI A,2 ;use special write mode. - STA MODE - MVI C,0 ;set write indicator. - CALL POSITN1 ;position the file. - CZ WTSEQ1 ;and write (if no errors). - RET -; -;************************************************************** -;* -;* BDOS data storage pool. -;* -;************************************************************** -; -EMPTYFCB:DB 0E5H ;empty directory segment indicator. -WRTPRT DW 0 ;write protect status for all 16 drives. -LOGIN DW 0 ;drive active word (1 bit per drive). -USERDMA DW 080H ;user's dma address (defaults to 80h). -; -; Scratch areas from parameter block. -; -SCRATCH1:DW 0 ;relative position within dir segment for file (0-3). -SCRATCH2:DW 0 ;last selected track number. -SCRATCH3:DW 0 ;last selected sector number. -; -; Disk storage areas from parameter block. -; -DIRBUF DW 0 ;address of directory buffer to use. -DISKPB DW 0 ;contains address of disk parameter block. -CHKVECT DW 0 ;address of check vector. -ALOCVECT:DW 0 ;address of allocation vector (bit map). -; -; Parameter block returned from the bios. -; -SECTORS DW 0 ;sectors per track from bios. -BLKSHFT DB 0 ;block shift. -BLKMASK DB 0 ;block mask. -EXTMASK DB 0 ;extent mask. -DSKSIZE DW 0 ;disk size from bios (number of blocks-1). -DIRSIZE DW 0 ;directory size. -ALLOC0 DW 0 ;storage for first bytes of bit map (dir space used). -ALLOC1 DW 0 -OFFSET DW 0 ;first usable track number. -XLATE DW 0 ;sector translation table address. -; -; -CLOSEFLG:DB 0 ;close flag (=0ffh is extent written ok). -RDWRTFLG:DB 0 ;read/write flag (0ffh=read, 0=write). -FNDSTAT DB 0 ;filename found status (0=found first entry). -MODE DB 0 ;I/o mode select (0=random, 1=sequential, 2=special random). -EPARAM DB 0 ;storage for register (E) on entry to bdos. -RELBLOCK:DB 0 ;relative position within fcb of block number written. -COUNTER DB 0 ;byte counter for directory name searches. -SAVEFCB DW 0,0 ;save space for address of fcb (for directory searches). -BIGDISK DB 0 ;if =0 then disk is > 256 blocks long. -AUTO DB 0 ;if non-zero, then auto select activated. -OLDDRV DB 0 ;on auto select, storage for previous drive. -AUTOFLAG:DB 0 ;if non-zero, then auto select changed drives. -SAVNXT DB 0 ;storage for next record number to access. -SAVEXT DB 0 ;storage for extent number of file. -SAVNREC DW 0 ;storage for number of records in file. -BLKNMBR DW 0 ;block number (physical sector) used within a file or logical sector. -LOGSECT DW 0 ;starting logical (128 byte) sector of block (physical sector). -FCBPOS DB 0 ;relative position within buffer for fcb of file of interest. -FILEPOS DW 0 ;files position within directory (0 to max entries -1). -; -; Disk directory buffer checksum bytes. One for each of the -; 16 possible drives. -; -CKSUMTBL:DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; Extra space ? -; - DB 0,0,0,0 -; -;************************************************************** -;* -;* B I O S J U M P T A B L E -;* -;************************************************************** -; -BOOT JMP 0 ;NOTE WE USE FAKE DESTINATIONS -WBOOT JMP 0 -CONST JMP 0 -CONIN JMP 0 -CONOUT JMP 0 -LIST JMP 0 -PUNCH JMP 0 -READER JMP 0 -HOME JMP 0 -SELDSK JMP 0 -SETTRK JMP 0 -SETSEC JMP 0 -SETDMA JMP 0 -READ JMP 0 -WRITE JMP 0 -PRSTAT JMP 0 -SECTRN JMP 0 -; -;* -;****************** E N D O F C P / M ***************** -;* - diff --git a/cpm/cpm2-asm/CPM22.Z80 b/cpm/cpm2-asm/CPM22.Z80 deleted file mode 100644 index 115d8c5..0000000 --- a/cpm/cpm2-asm/CPM22.Z80 +++ /dev/null @@ -1,3738 +0,0 @@ -;************************************************************** -;* -;* C P / M version 2 . 2 -;* -;* Reconstructed from memory image on February 27, 1981 -;* -;* by Clark A. Calkins -;* -;************************************************************** -; -; Set memory limit here. This is the amount of contigeous -; ram starting from 0000. CP/M will reside at the end of this space. -; -MEM EQU 62 ;for a 62k system (TS802 TEST - WORKS OK). -; -IOBYTE EQU 3 ;i/o definition byte. -TDRIVE EQU 4 ;current drive name and user number. -ENTRY EQU 5 ;entry point for the cp/m bdos. -TFCB EQU 5CH ;default file control block. -TBUFF EQU 80H ;i/o buffer and command line storage. -TBASE EQU 100H ;transiant program storage area. -; -; Set control character equates. -; -CNTRLC EQU 3 ;control-c -CNTRLE EQU 05H ;control-e -BS EQU 08H ;backspace -TAB EQU 09H ;tab -LF EQU 0AH ;line feed -FF EQU 0CH ;form feed -CR EQU 0DH ;carriage return -CNTRLP EQU 10H ;control-p -CNTRLR EQU 12H ;control-r -CNTRLS EQU 13H ;control-s -CNTRLU EQU 15H ;control-u -CNTRLX EQU 18H ;control-x -CNTRLZ EQU 1AH ;control-z (end-of-file mark) -DEL EQU 7FH ;rubout -; -; Set origin for CP/M -; - ORG (MEM-7)*1024 -; -CBASE: JP COMMAND ;execute command processor (ccp). - JP CLEARBUF ;entry to empty input buffer before starting ccp. - -; -; Standard cp/m ccp input buffer. Format is (max length), -; (actual length), (char #1), (char #2), (char #3), etc. -; -INBUFF: DEFB 127 ;length of input buffer. - DEFB 0 ;current length of contents. - DEFB 'Copyright' - DEFB ' 1979 (c) by Digital Research ' - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -INPOINT:DEFW INBUFF+2 ;input line pointer -NAMEPNT:DEFW 0 ;input line pointer used for error message. Points to -; ;start of name in error. -; -; Routine to print (A) on the console. All registers used. -; -PRINT: LD E,A ;setup bdos call. - LD C,2 - JP ENTRY -; -; Routine to print (A) on the console and to save (BC). -; -PRINTB: PUSH BC - CALL PRINT - POP BC - RET -; -; Routine to send a carriage return, line feed combination -; to the console. -; -CRLF: LD A,CR - CALL PRINTB - LD A,LF - JP PRINTB -; -; Routine to send one space to the console and save (BC). -; -SPACE: LD A,' ' - JP PRINTB -; -; Routine to print character string pointed to be (BC) on the -; console. It must terminate with a null byte. -; -PLINE: PUSH BC - CALL CRLF - POP HL -PLINE2: LD A,(HL) - OR A - RET Z - INC HL - PUSH HL - CALL PRINT - POP HL - JP PLINE2 -; -; Routine to reset the disk system. -; -RESDSK: LD C,13 - JP ENTRY -; -; Routine to select disk (A). -; -DSKSEL: LD E,A - LD C,14 - JP ENTRY -; -; Routine to call bdos and save the return code. The zero -; flag is set on a return of 0ffh. -; -ENTRY1: CALL ENTRY - LD (RTNCODE),A ;save return code. - INC A ;set zero if 0ffh returned. - RET -; -; Routine to open a file. (DE) must point to the FCB. -; -OPEN: LD C,15 - JP ENTRY1 -; -; Routine to open file at (FCB). -; -OPENFCB:XOR A ;clear the record number byte at fcb+32 - LD (FCB+32),A - LD DE,FCB - JP OPEN -; -; Routine to close a file. (DE) points to FCB. -; -CLOSE: LD C,16 - JP ENTRY1 -; -; Routine to search for the first file with ambigueous name -; (DE). -; -SRCHFST:LD C,17 - JP ENTRY1 -; -; Search for the next ambigeous file name. -; -SRCHNXT:LD C,18 - JP ENTRY1 -; -; Search for file at (FCB). -; -SRCHFCB:LD DE,FCB - JP SRCHFST -; -; Routine to delete a file pointed to by (DE). -; -DELETE: LD C,19 - JP ENTRY -; -; Routine to call the bdos and set the zero flag if a zero -; status is returned. -; -ENTRY2: CALL ENTRY - OR A ;set zero flag if appropriate. - RET -; -; Routine to read the next record from a sequential file. -; (DE) points to the FCB. -; -RDREC: LD C,20 - JP ENTRY2 -; -; Routine to read file at (FCB). -; -READFCB:LD DE,FCB - JP RDREC -; -; Routine to write the next record of a sequential file. -; (DE) points to the FCB. -; -WRTREC: LD C,21 - JP ENTRY2 -; -; Routine to create the file pointed to by (DE). -; -CREATE: LD C,22 - JP ENTRY1 -; -; Routine to rename the file pointed to by (DE). Note that -; the new name starts at (DE+16). -; -RENAM: LD C,23 - JP ENTRY -; -; Get the current user code. -; -GETUSR: LD E,0FFH -; -; Routne to get or set the current user code. -; If (E) is FF then this is a GET, else it is a SET. -; -GETSETUC: LD C,32 - JP ENTRY -; -; Routine to set the current drive byte at (TDRIVE). -; -SETCDRV:CALL GETUSR ;get user number - ADD A,A ;and shift into the upper 4 bits. - ADD A,A - ADD A,A - ADD A,A - LD HL,CDRIVE ;now add in the current drive number. - OR (HL) - LD (TDRIVE),A ;and save. - RET -; -; Move currently active drive down to (TDRIVE). -; -MOVECD: LD A,(CDRIVE) - LD (TDRIVE),A - RET -; -; Routine to convert (A) into upper case ascii. Only letters -; are affected. -; -UPPER: CP 'a' ;check for letters in the range of 'a' to 'z'. - RET C - CP '{' - RET NC - AND 5FH ;convert it if found. - RET -; -; Routine to get a line of input. We must check to see if the -; user is in (BATCH) mode. If so, then read the input from file -; ($$$.SUB). At the end, reset to console input. -; -GETINP: LD A,(BATCH) ;if =0, then use console input. - OR A - JP Z,GETINP1 -; -; Use the submit file ($$$.sub) which is prepared by a -; SUBMIT run. It must be on drive (A) and it will be deleted -; if and error occures (like eof). -; - LD A,(CDRIVE) ;select drive 0 if need be. - OR A - LD A,0 ;always use drive A for submit. - CALL NZ,DSKSEL ;select it if required. - LD DE,BATCHFCB - CALL OPEN ;look for it. - JP Z,GETINP1 ;if not there, use normal input. - LD A,(BATCHFCB+15) ;get last record number+1. - DEC A - LD (BATCHFCB+32),A - LD DE,BATCHFCB - CALL RDREC ;read last record. - JP NZ,GETINP1 ;quit on end of file. -; -; Move this record into input buffer. -; - LD DE,INBUFF+1 - LD HL,TBUFF ;data was read into buffer here. - LD B,128 ;all 128 characters may be used. - CALL HL2DE ;(HL) to (DE), (B) bytes. - LD HL,BATCHFCB+14 - LD (HL),0 ;zero out the 's2' byte. - INC HL ;and decrement the record count. - DEC (HL) - LD DE,BATCHFCB ;close the batch file now. - CALL CLOSE - JP Z,GETINP1 ;quit on an error. - LD A,(CDRIVE) ;re-select previous drive if need be. - OR A - CALL NZ,DSKSEL ;don't do needless selects. -; -; Print line just read on console. -; - LD HL,INBUFF+2 - CALL PLINE2 - CALL CHKCON ;check console, quit on a key. - JP Z,GETINP2 ;jump if no key is pressed. -; -; Terminate the submit job on any keyboard input. Delete this -; file such that it is not re-started and jump to normal keyboard -; input section. -; - CALL DELBATCH ;delete the batch file. - JP CMMND1 ;and restart command input. -; -; Get here for normal keyboard input. Delete the submit file -; incase there was one. -; -GETINP1:CALL DELBATCH ;delete file ($$$.sub). - CALL SETCDRV ;reset active disk. - LD C,10 ;get line from console device. - LD DE,INBUFF - CALL ENTRY - CALL MOVECD ;reset current drive (again). -; -; Convert input line to upper case. -; -GETINP2:LD HL,INBUFF+1 - LD B,(HL) ;(B)=character counter. -GETINP3:INC HL - LD A,B ;end of the line? - OR A - JP Z,GETINP4 - LD A,(HL) ;convert to upper case. - CALL UPPER - LD (HL),A - DEC B ;adjust character count. - JP GETINP3 -GETINP4:LD (HL),A ;add trailing null. - LD HL,INBUFF+2 - LD (INPOINT),HL ;reset input line pointer. - RET -; -; Routine to check the console for a key pressed. The zero -; flag is set is none, else the character is returned in (A). -; -CHKCON: LD C,11 ;check console. - CALL ENTRY - OR A - RET Z ;return if nothing. - LD C,1 ;else get character. - CALL ENTRY - OR A ;clear zero flag and return. - RET -; -; Routine to get the currently active drive number. -; -GETDSK: LD C,25 - JP ENTRY -; -; Set the stabdard dma address. -; -STDDMA: LD DE,TBUFF -; -; Routine to set the dma address to (DE). -; -DMASET: LD C,26 - JP ENTRY -; -; Delete the batch file created by SUBMIT. -; -DELBATCH: LD HL,BATCH ;is batch active? - LD A,(HL) - OR A - RET Z - LD (HL),0 ;yes, de-activate it. - XOR A - CALL DSKSEL ;select drive 0 for sure. - LD DE,BATCHFCB ;and delete this file. - CALL DELETE - LD A,(CDRIVE) ;reset current drive. - JP DSKSEL -; -; Check to two strings at (PATTRN1) and (PATTRN2). They must be -; the same or we halt.... -; -VERIFY: LD DE,PATTRN1 ;these are the serial number bytes. - LD HL,PATTRN2 ;ditto, but how could they be different? - LD B,6 ;6 bytes each. -VERIFY1:LD A,(DE) - CP (HL) - JP NZ,HALT ;jump to halt routine. - INC DE - INC HL - DEC B - JP NZ,VERIFY1 - RET -; -; Print back file name with a '?' to indicate a syntax error. -; -SYNERR: CALL CRLF ;end current line. - LD HL,(NAMEPNT) ;this points to name in error. -SYNERR1:LD A,(HL) ;print it until a space or null is found. - CP ' ' - JP Z,SYNERR2 - OR A - JP Z,SYNERR2 - PUSH HL - CALL PRINT - POP HL - INC HL - JP SYNERR1 -SYNERR2:LD A,'?' ;add trailing '?'. - CALL PRINT - CALL CRLF - CALL DELBATCH ;delete any batch file. - JP CMMND1 ;and restart from console input. -; -; Check character at (DE) for legal command input. Note that the -; zero flag is set if the character is a delimiter. -; -CHECK: LD A,(DE) - OR A - RET Z - CP ' ' ;control characters are not legal here. - JP C,SYNERR - RET Z ;check for valid delimiter. - CP '=' - RET Z - CP '_' - RET Z - CP '.' - RET Z - CP ':' - RET Z - CP ';' - RET Z - CP '<' - RET Z - CP '>' - RET Z - RET -; -; Get the next non-blank character from (DE). -; -NONBLANK: LD A,(DE) - OR A ;string ends with a null. - RET Z - CP ' ' - RET NZ - INC DE - JP NONBLANK -; -; Add (HL)=(HL)+(A) -; -ADDHL: ADD A,L - LD L,A - RET NC ;take care of any carry. - INC H - RET -; -; Convert the first name in (FCB). -; -CONVFST:LD A,0 -; -; Format a file name (convert * to '?', etc.). On return, -; (A)=0 is an unambigeous name was specified. Enter with (A) equal to -; the position within the fcb for the name (either 0 or 16). -; -CONVERT:LD HL,FCB - CALL ADDHL - PUSH HL - PUSH HL - XOR A - LD (CHGDRV),A ;initialize drive change flag. - LD HL,(INPOINT) ;set (HL) as pointer into input line. - EX DE,HL - CALL NONBLANK ;get next non-blank character. - EX DE,HL - LD (NAMEPNT),HL ;save pointer here for any error message. - EX DE,HL - POP HL - LD A,(DE) ;get first character. - OR A - JP Z,CONVRT1 - SBC A,'A'-1 ;might be a drive name, convert to binary. - LD B,A ;and save. - INC DE ;check next character for a ':'. - LD A,(DE) - CP ':' - JP Z,CONVRT2 - DEC DE ;nope, move pointer back to the start of the line. -CONVRT1:LD A,(CDRIVE) - LD (HL),A - JP CONVRT3 -CONVRT2:LD A,B - LD (CHGDRV),A ;set change in drives flag. - LD (HL),B - INC DE -; -; Convert the basic file name. -; -CONVRT3:LD B,08H -CONVRT4:CALL CHECK - JP Z,CONVRT8 - INC HL - CP '*' ;note that an '*' will fill the remaining - JP NZ,CONVRT5 ;field with '?'. - LD (HL),'?' - JP CONVRT6 -CONVRT5:LD (HL),A - INC DE -CONVRT6:DEC B - JP NZ,CONVRT4 -CONVRT7:CALL CHECK ;get next delimiter. - JP Z,GETEXT - INC DE - JP CONVRT7 -CONVRT8:INC HL ;blank fill the file name. - LD (HL),' ' - DEC B - JP NZ,CONVRT8 -; -; Get the extension and convert it. -; -GETEXT: LD B,03H - CP '.' - JP NZ,GETEXT5 - INC DE -GETEXT1:CALL CHECK - JP Z,GETEXT5 - INC HL - CP '*' - JP NZ,GETEXT2 - LD (HL),'?' - JP GETEXT3 -GETEXT2:LD (HL),A - INC DE -GETEXT3:DEC B - JP NZ,GETEXT1 -GETEXT4:CALL CHECK - JP Z,GETEXT6 - INC DE - JP GETEXT4 -GETEXT5:INC HL - LD (HL),' ' - DEC B - JP NZ,GETEXT5 -GETEXT6:LD B,3 -GETEXT7:INC HL - LD (HL),0 - DEC B - JP NZ,GETEXT7 - EX DE,HL - LD (INPOINT),HL ;save input line pointer. - POP HL -; -; Check to see if this is an ambigeous file name specification. -; Set the (A) register to non zero if it is. -; - LD BC,11 ;set name length. -GETEXT8:INC HL - LD A,(HL) - CP '?' ;any question marks? - JP NZ,GETEXT9 - INC B ;count them. -GETEXT9:DEC C - JP NZ,GETEXT8 - LD A,B - OR A - RET -; -; CP/M command table. Note commands can be either 3 or 4 characters long. -; -NUMCMDS EQU 6 ;number of commands -CMDTBL: DEFB 'DIR ' - DEFB 'ERA ' - DEFB 'TYPE' - DEFB 'SAVE' - DEFB 'REN ' - DEFB 'USER' -; -; The following six bytes must agree with those at (PATTRN2) -; or cp/m will HALT. Why? -; -PATTRN1:DEFB 0,22,0,0,0,0 ;(* serial number bytes *). -; -; Search the command table for a match with what has just -; been entered. If a match is found, then we jump to the -; proper section. Else jump to (UNKNOWN). -; On return, the (C) register is set to the command number -; that matched (or NUMCMDS+1 if no match). -; -SEARCH: LD HL,CMDTBL - LD C,0 -SEARCH1:LD A,C - CP NUMCMDS ;this commands exists. - RET NC - LD DE,FCB+1 ;check this one. - LD B,4 ;max command length. -SEARCH2:LD A,(DE) - CP (HL) - JP NZ,SEARCH3 ;not a match. - INC DE - INC HL - DEC B - JP NZ,SEARCH2 - LD A,(DE) ;allow a 3 character command to match. - CP ' ' - JP NZ,SEARCH4 - LD A,C ;set return register for this command. - RET -SEARCH3:INC HL - DEC B - JP NZ,SEARCH3 -SEARCH4:INC C - JP SEARCH1 -; -; Set the input buffer to empty and then start the command -; processor (ccp). -; -CLEARBUF: XOR A - LD (INBUFF+1),A ;second byte is actual length. -; -;************************************************************** -;* -;* -;* C C P - C o n s o l e C o m m a n d P r o c e s s o r -;* -;************************************************************** -;* -COMMAND:LD SP,CCPSTACK ;setup stack area. - PUSH BC ;note that (C) should be equal to: - LD A,C ;(uuuudddd) where 'uuuu' is the user number - RRA ;and 'dddd' is the drive number. - RRA - RRA - RRA - AND 0FH ;isolate the user number. - LD E,A - CALL GETSETUC ;and set it. - CALL RESDSK ;reset the disk system. - LD (BATCH),A ;clear batch mode flag. - POP BC - LD A,C - AND 0FH ;isolate the drive number. - LD (CDRIVE),A ;and save. - CALL DSKSEL ;...and select. - LD A,(INBUFF+1) - OR A ;anything in input buffer already? - JP NZ,CMMND2 ;yes, we just process it. -; -; Entry point to get a command line from the console. -; -CMMND1: LD SP,CCPSTACK ;set stack straight. - CALL CRLF ;start a new line on the screen. - CALL GETDSK ;get current drive. - ADD A,'a' - CALL PRINT ;print current drive. - LD A,'>' - CALL PRINT ;and add prompt. - CALL GETINP ;get line from user. -; -; Process command line here. -; -CMMND2: LD DE,TBUFF - CALL DMASET ;set standard dma address. - CALL GETDSK - LD (CDRIVE),A ;set current drive. - CALL CONVFST ;convert name typed in. - CALL NZ,SYNERR ;wild cards are not allowed. - LD A,(CHGDRV) ;if a change in drives was indicated, - OR A ;then treat this as an unknown command - JP NZ,UNKNOWN ;which gets executed. - CALL SEARCH ;else search command table for a match. -; -; Note that an unknown command returns -; with (A) pointing to the last address -; in our table which is (UNKNOWN). -; - LD HL,CMDADR ;now, look thru our address table for command (A). - LD E,A ;set (DE) to command number. - LD D,0 - ADD HL,DE - ADD HL,DE ;(HL)=(CMDADR)+2*(command number). - LD A,(HL) ;now pick out this address. - INC HL - LD H,(HL) - LD L,A - JP (HL) ;now execute it. -; -; CP/M command address table. -; -CMDADR: DEFW DIRECT,ERASE,TYPE,SAVE - DEFW RENAME,USER,UNKNOWN -; -; Halt the system. Reason for this is unknown at present. -; -HALT: LD HL,76F3H ;'DI HLT' instructions. - LD (CBASE),HL - LD HL,CBASE - JP (HL) -; -; Read error while TYPEing a file. -; -RDERROR:LD BC,RDERR - JP PLINE -RDERR: DEFB 'Read error',0 -; -; Required file was not located. -; -NONE: LD BC,NOFILE - JP PLINE -NOFILE: DEFB 'No file',0 -; -; Decode a command of the form 'A>filename number{ filename}. -; Note that a drive specifier is not allowed on the first file -; name. On return, the number is in register (A). Any error -; causes 'filename?' to be printed and the command is aborted. -; -DECODE: CALL CONVFST ;convert filename. - LD A,(CHGDRV) ;do not allow a drive to be specified. - OR A - JP NZ,SYNERR - LD HL,FCB+1 ;convert number now. - LD BC,11 ;(B)=sum register, (C)=max digit count. -DECODE1:LD A,(HL) - CP ' ' ;a space terminates the numeral. - JP Z,DECODE3 - INC HL - SUB '0' ;make binary from ascii. - CP 10 ;legal digit? - JP NC,SYNERR - LD D,A ;yes, save it in (D). - LD A,B ;compute (B)=(B)*10 and check for overflow. - AND 0E0H - JP NZ,SYNERR - LD A,B - RLCA - RLCA - RLCA ;(A)=(B)*8 - ADD A,B ;.......*9 - JP C,SYNERR - ADD A,B ;.......*10 - JP C,SYNERR - ADD A,D ;add in new digit now. -DECODE2:JP C,SYNERR - LD B,A ;and save result. - DEC C ;only look at 11 digits. - JP NZ,DECODE1 - RET -DECODE3:LD A,(HL) ;spaces must follow (why?). - CP ' ' - JP NZ,SYNERR - INC HL -DECODE4:DEC C - JP NZ,DECODE3 - LD A,B ;set (A)=the numeric value entered. - RET -; -; Move 3 bytes from (HL) to (DE). Note that there is only -; one reference to this at (A2D5h). -; -MOVE3: LD B,3 -; -; Move (B) bytes from (HL) to (DE). -; -HL2DE: LD A,(HL) - LD (DE),A - INC HL - INC DE - DEC B - JP NZ,HL2DE - RET -; -; Compute (HL)=(TBUFF)+(A)+(C) and get the byte that's here. -; -EXTRACT:LD HL,TBUFF - ADD A,C - CALL ADDHL - LD A,(HL) - RET -; -; Check drive specified. If it means a change, then the new -; drive will be selected. In any case, the drive byte of the -; fcb will be set to null (means use current drive). -; -DSELECT:XOR A ;null out first byte of fcb. - LD (FCB),A - LD A,(CHGDRV) ;a drive change indicated? - OR A - RET Z - DEC A ;yes, is it the same as the current drive? - LD HL,CDRIVE - CP (HL) - RET Z - JP DSKSEL ;no. Select it then. -; -; Check the drive selection and reset it to the previous -; drive if it was changed for the preceeding command. -; -RESETDR:LD A,(CHGDRV) ;drive change indicated? - OR A - RET Z - DEC A ;yes, was it a different drive? - LD HL,CDRIVE - CP (HL) - RET Z - LD A,(CDRIVE) ;yes, re-select our old drive. - JP DSKSEL -; -;************************************************************** -;* -;* D I R E C T O R Y C O M M A N D -;* -;************************************************************** -; -DIRECT: CALL CONVFST ;convert file name. - CALL DSELECT ;select indicated drive. - LD HL,FCB+1 ;was any file indicated? - LD A,(HL) - CP ' ' - JP NZ,DIRECT2 - LD B,11 ;no. Fill field with '?' - same as *.*. -DIRECT1:LD (HL),'?' - INC HL - DEC B - JP NZ,DIRECT1 -DIRECT2:LD E,0 ;set initial cursor position. - PUSH DE - CALL SRCHFCB ;get first file name. - CALL Z,NONE ;none found at all? -DIRECT3:JP Z,DIRECT9 ;terminate if no more names. - LD A,(RTNCODE) ;get file's position in segment (0-3). - RRCA - RRCA - RRCA - AND 60H ;(A)=position*32 - LD C,A - LD A,10 - CALL EXTRACT ;extract the tenth entry in fcb. - RLA ;check system file status bit. - JP C,DIRECT8 ;we don't list them. - POP DE - LD A,E ;bump name count. - INC E - PUSH DE - AND 03H ;at end of line? - PUSH AF - JP NZ,DIRECT4 - CALL CRLF ;yes, end this line and start another. - PUSH BC - CALL GETDSK ;start line with ('A:'). - POP BC - ADD A,'A' - CALL PRINTB - LD A,':' - CALL PRINTB - JP DIRECT5 -DIRECT4:CALL SPACE ;add seperator between file names. - LD A,':' - CALL PRINTB -DIRECT5:CALL SPACE - LD B,1 ;'extract' each file name character at a time. -DIRECT6:LD A,B - CALL EXTRACT - AND 7FH ;strip bit 7 (status bit). - CP ' ' ;are we at the end of the name? - JP NZ,DRECT65 - POP AF ;yes, don't print spaces at the end of a line. - PUSH AF - CP 3 - JP NZ,DRECT63 - LD A,9 ;first check for no extension. - CALL EXTRACT - AND 7FH - CP ' ' - JP Z,DIRECT7 ;don't print spaces. -DRECT63:LD A,' ' ;else print them. -DRECT65:CALL PRINTB - INC B ;bump to next character psoition. - LD A,B - CP 12 ;end of the name? - JP NC,DIRECT7 - CP 9 ;nope, starting extension? - JP NZ,DIRECT6 - CALL SPACE ;yes, add seperating space. - JP DIRECT6 -DIRECT7:POP AF ;get the next file name. -DIRECT8:CALL CHKCON ;first check console, quit on anything. - JP NZ,DIRECT9 - CALL SRCHNXT ;get next name. - JP DIRECT3 ;and continue with our list. -DIRECT9:POP DE ;restore the stack and return to command level. - JP GETBACK -; -;************************************************************** -;* -;* E R A S E C O M M A N D -;* -;************************************************************** -; -ERASE: CALL CONVFST ;convert file name. - CP 11 ;was '*.*' entered? - JP NZ,ERASE1 - LD BC,YESNO ;yes, ask for confirmation. - CALL PLINE - CALL GETINP - LD HL,INBUFF+1 - DEC (HL) ;must be exactly 'y'. - JP NZ,CMMND1 - INC HL - LD A,(HL) - CP 'Y' - JP NZ,CMMND1 - INC HL - LD (INPOINT),HL ;save input line pointer. -ERASE1: CALL DSELECT ;select desired disk. - LD DE,FCB - CALL DELETE ;delete the file. - INC A - CALL Z,NONE ;not there? - JP GETBACK ;return to command level now. -YESNO: DEFB 'All (y/n)?',0 -; -;************************************************************** -;* -;* T Y P E C O M M A N D -;* -;************************************************************** -; -TYPE: CALL CONVFST ;convert file name. - JP NZ,SYNERR ;wild cards not allowed. - CALL DSELECT ;select indicated drive. - CALL OPENFCB ;open the file. - JP Z,TYPE5 ;not there? - CALL CRLF ;ok, start a new line on the screen. - LD HL,NBYTES ;initialize byte counter. - LD (HL),0FFH ;set to read first sector. -TYPE1: LD HL,NBYTES -TYPE2: LD A,(HL) ;have we written the entire sector? - CP 128 - JP C,TYPE3 - PUSH HL ;yes, read in the next one. - CALL READFCB - POP HL - JP NZ,TYPE4 ;end or error? - XOR A ;ok, clear byte counter. - LD (HL),A -TYPE3: INC (HL) ;count this byte. - LD HL,TBUFF ;and get the (A)th one from the buffer (TBUFF). - CALL ADDHL - LD A,(HL) - CP CNTRLZ ;end of file mark? - JP Z,GETBACK - CALL PRINT ;no, print it. - CALL CHKCON ;check console, quit if anything ready. - JP NZ,GETBACK - JP TYPE1 -; -; Get here on an end of file or read error. -; -TYPE4: DEC A ;read error? - JP Z,GETBACK - CALL RDERROR ;yes, print message. -TYPE5: CALL RESETDR ;and reset proper drive - JP SYNERR ;now print file name with problem. -; -;************************************************************** -;* -;* S A V E C O M M A N D -;* -;************************************************************** -; -SAVE: CALL DECODE ;get numeric number that follows SAVE. - PUSH AF ;save number of pages to write. - CALL CONVFST ;convert file name. - JP NZ,SYNERR ;wild cards not allowed. - CALL DSELECT ;select specified drive. - LD DE,FCB ;now delete this file. - PUSH DE - CALL DELETE - POP DE - CALL CREATE ;and create it again. - JP Z,SAVE3 ;can't create? - XOR A ;clear record number byte. - LD (FCB+32),A - POP AF ;convert pages to sectors. - LD L,A - LD H,0 - ADD HL,HL ;(HL)=number of sectors to write. - LD DE,TBASE ;and we start from here. -SAVE1: LD A,H ;done yet? - OR L - JP Z,SAVE2 - DEC HL ;nope, count this and compute the start - PUSH HL ;of the next 128 byte sector. - LD HL,128 - ADD HL,DE - PUSH HL ;save it and set the transfer address. - CALL DMASET - LD DE,FCB ;write out this sector now. - CALL WRTREC - POP DE ;reset (DE) to the start of the last sector. - POP HL ;restore sector count. - JP NZ,SAVE3 ;write error? - JP SAVE1 -; -; Get here after writing all of the file. -; -SAVE2: LD DE,FCB ;now close the file. - CALL CLOSE - INC A ;did it close ok? - JP NZ,SAVE4 -; -; Print out error message (no space). -; -SAVE3: LD BC,NOSPACE - CALL PLINE -SAVE4: CALL STDDMA ;reset the standard dma address. - JP GETBACK -NOSPACE:DEFB 'No space',0 -; -;************************************************************** -;* -;* R E N A M E C O M M A N D -;* -;************************************************************** -; -RENAME: CALL CONVFST ;convert first file name. - JP NZ,SYNERR ;wild cards not allowed. - LD A,(CHGDRV) ;remember any change in drives specified. - PUSH AF - CALL DSELECT ;and select this drive. - CALL SRCHFCB ;is this file present? - JP NZ,RENAME6 ;yes, print error message. - LD HL,FCB ;yes, move this name into second slot. - LD DE,FCB+16 - LD B,16 - CALL HL2DE - LD HL,(INPOINT) ;get input pointer. - EX DE,HL - CALL NONBLANK ;get next non blank character. - CP '=' ;only allow an '=' or '_' seperator. - JP Z,RENAME1 - CP '_' - JP NZ,RENAME5 -RENAME1:EX DE,HL - INC HL ;ok, skip seperator. - LD (INPOINT),HL ;save input line pointer. - CALL CONVFST ;convert this second file name now. - JP NZ,RENAME5 ;again, no wild cards. - POP AF ;if a drive was specified, then it - LD B,A ;must be the same as before. - LD HL,CHGDRV - LD A,(HL) - OR A - JP Z,RENAME2 - CP B - LD (HL),B - JP NZ,RENAME5 ;they were different, error. -RENAME2:LD (HL),B ; reset as per the first file specification. - XOR A - LD (FCB),A ;clear the drive byte of the fcb. -RENAME3:CALL SRCHFCB ;and go look for second file. - JP Z,RENAME4 ;doesn't exist? - LD DE,FCB - CALL RENAM ;ok, rename the file. - JP GETBACK -; -; Process rename errors here. -; -RENAME4:CALL NONE ;file not there. - JP GETBACK -RENAME5:CALL RESETDR ;bad command format. - JP SYNERR -RENAME6:LD BC,EXISTS ;destination file already exists. - CALL PLINE - JP GETBACK -EXISTS: DEFB 'File exists',0 -; -;************************************************************** -;* -;* U S E R C O M M A N D -;* -;************************************************************** -; -USER: CALL DECODE ;get numeric value following command. - CP 16 ;legal user number? - JP NC,SYNERR - LD E,A ;yes but is there anything else? - LD A,(FCB+1) - CP ' ' - JP Z,SYNERR ;yes, that is not allowed. - CALL GETSETUC ;ok, set user code. - JP GETBACK1 -; -;************************************************************** -;* -;* T R A N S I A N T P R O G R A M C O M M A N D -;* -;************************************************************** -; -UNKNOWN:CALL VERIFY ;check for valid system (why?). - LD A,(FCB+1) ;anything to execute? - CP ' ' - JP NZ,UNKWN1 - LD A,(CHGDRV) ;nope, only a drive change? - OR A - JP Z,GETBACK1 ;neither??? - DEC A - LD (CDRIVE),A ;ok, store new drive. - CALL MOVECD ;set (TDRIVE) also. - CALL DSKSEL ;and select this drive. - JP GETBACK1 ;then return. -; -; Here a file name was typed. Prepare to execute it. -; -UNKWN1: LD DE,FCB+9 ;an extension specified? - LD A,(DE) - CP ' ' - JP NZ,SYNERR ;yes, not allowed. -UNKWN2: PUSH DE - CALL DSELECT ;select specified drive. - POP DE - LD HL,COMFILE ;set the extension to 'COM'. - CALL MOVE3 - CALL OPENFCB ;and open this file. - JP Z,UNKWN9 ;not present? -; -; Load in the program. -; - LD HL,TBASE ;store the program starting here. -UNKWN3: PUSH HL - EX DE,HL - CALL DMASET ;set transfer address. - LD DE,FCB ;and read the next record. - CALL RDREC - JP NZ,UNKWN4 ;end of file or read error? - POP HL ;nope, bump pointer for next sector. - LD DE,128 - ADD HL,DE - LD DE,CBASE ;enough room for the whole file? - LD A,L - SUB E - LD A,H - SBC A,D - JP NC,UNKWN0 ;no, it can't fit. - JP UNKWN3 -; -; Get here after finished reading. -; -UNKWN4: POP HL - DEC A ;normal end of file? - JP NZ,UNKWN0 - CALL RESETDR ;yes, reset previous drive. - CALL CONVFST ;convert the first file name that follows - LD HL,CHGDRV ;command name. - PUSH HL - LD A,(HL) ;set drive code in default fcb. - LD (FCB),A - LD A,16 ;put second name 16 bytes later. - CALL CONVERT ;convert second file name. - POP HL - LD A,(HL) ;and set the drive for this second file. - LD (FCB+16),A - XOR A ;clear record byte in fcb. - LD (FCB+32),A - LD DE,TFCB ;move it into place at(005Ch). - LD HL,FCB - LD B,33 - CALL HL2DE - LD HL,INBUFF+2 ;now move the remainder of the input -UNKWN5: LD A,(HL) ;line down to (0080h). Look for a non blank. - OR A ;or a null. - JP Z,UNKWN6 - CP ' ' - JP Z,UNKWN6 - INC HL - JP UNKWN5 -; -; Do the line move now. It ends in a null byte. -; -UNKWN6: LD B,0 ;keep a character count. - LD DE,TBUFF+1 ;data gets put here. -UNKWN7: LD A,(HL) ;move it now. - LD (DE),A - OR A - JP Z,UNKWN8 - INC B - INC HL - INC DE - JP UNKWN7 -UNKWN8: LD A,B ;now store the character count. - LD (TBUFF),A - CALL CRLF ;clean up the screen. - CALL STDDMA ;set standard transfer address. - CALL SETCDRV ;reset current drive. - CALL TBASE ;and execute the program. -; -; Transiant programs return here (or reboot). -; - LD SP,BATCH ;set stack first off. - CALL MOVECD ;move current drive into place (TDRIVE). - CALL DSKSEL ;and reselect it. - JP CMMND1 ;back to comand mode. -; -; Get here if some error occured. -; -UNKWN9: CALL RESETDR ;inproper format. - JP SYNERR -UNKWN0: LD BC,BADLOAD ;read error or won't fit. - CALL PLINE - JP GETBACK -BADLOAD:DEFB 'Bad load',0 -COMFILE:DEFB 'COM' ;command file extension. -; -; Get here to return to command level. We will reset the -; previous active drive and then either return to command -; level directly or print error message and then return. -; -GETBACK:CALL RESETDR ;reset previous drive. -GETBACK1: CALL CONVFST ;convert first name in (FCB). - LD A,(FCB+1) ;if this was just a drive change request, - SUB ' ' ;make sure it was valid. - LD HL,CHGDRV - OR (HL) - JP NZ,SYNERR - JP CMMND1 ;ok, return to command level. -; -; ccp stack area. -; - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -CCPSTACK EQU $ ;end of ccp stack area. -; -; Batch (or SUBMIT) processing information storage. -; -BATCH: DEFB 0 ;batch mode flag (0=not active). -BATCHFCB: DEFB 0,'$$$ SUB',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; File control block setup by the CCP. -; -FCB: DEFB 0,' ',0,0,0,0,0,' ',0,0,0,0,0 -RTNCODE:DEFB 0 ;status returned from bdos call. -CDRIVE: DEFB 0 ;currently active drive. -CHGDRV: DEFB 0 ;change in drives flag (0=no change). -NBYTES: DEFW 0 ;byte counter used by TYPE. -; -; Room for expansion? -; - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; Note that the following six bytes must match those at -; (PATTRN1) or cp/m will HALT. Why? -; -PATTRN2:DEFB 0,22,0,0,0,0 ;(* serial number bytes *). -; -;************************************************************** -;* -;* B D O S E N T R Y -;* -;************************************************************** -; -FBASE: JP FBASE1 -; -; Bdos error table. -; -BADSCTR:DEFW ERROR1 ;bad sector on read or write. -BADSLCT:DEFW ERROR2 ;bad disk select. -RODISK: DEFW ERROR3 ;disk is read only. -ROFILE: DEFW ERROR4 ;file is read only. -; -; Entry into bdos. (DE) or (E) are the parameters passed. The -; function number desired is in register (C). -; -FBASE1: EX DE,HL ;save the (DE) parameters. - LD (PARAMS),HL - EX DE,HL - LD A,E ;and save register (E) in particular. - LD (EPARAM),A - LD HL,0 - LD (STATUS),HL ;clear return status. - ADD HL,SP - LD (USRSTACK),HL ;save users stack pointer. - LD SP,STKAREA ;and set our own. - XOR A ;clear auto select storage space. - LD (AUTOFLAG),A - LD (AUTO),A - LD HL,GOBACK ;set return address. - PUSH HL - LD A,C ;get function number. - CP NFUNCTS ;valid function number? - RET NC - LD C,E ;keep single register function here. - LD HL,FUNCTNS ;now look thru the function table. - LD E,A - LD D,0 ;(DE)=function number. - ADD HL,DE - ADD HL,DE ;(HL)=(start of table)+2*(function number). - LD E,(HL) - INC HL - LD D,(HL) ;now (DE)=address for this function. - LD HL,(PARAMS) ;retrieve parameters. - EX DE,HL ;now (DE) has the original parameters. - JP (HL) ;execute desired function. -; -; BDOS function jump table. -; -NFUNCTS EQU 41 ;number of functions in followin table. -; -FUNCTNS:DEFW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - DEFW SETIOB,PRTSTR,RDBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - DEFW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - DEFW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - DEFW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - DEFW RTN,WTSPECL -; -; Bdos error message section. -; -ERROR1: LD HL,BADSEC ;bad sector message. - CALL PRTERR ;print it and get a 1 char responce. - CP CNTRLC ;re-boot request (control-c)? - JP Z,0 ;yes. - RET ;no, return to retry i/o function. -; -ERROR2: LD HL,BADSEL ;bad drive selected. - JP ERROR5 -; -ERROR3: LD HL,DISKRO ;disk is read only. - JP ERROR5 -; -ERROR4: LD HL,FILERO ;file is read only. -; -ERROR5: CALL PRTERR - JP 0 ;always reboot on these errors. -; -BDOSERR:DEFB 'Bdos Err On ' -BDOSDRV:DEFB ' : $' -BADSEC: DEFB 'Bad Sector$' -BADSEL: DEFB 'Select$' -FILERO: DEFB 'File ' -DISKRO: DEFB 'R/O$' -; -; Print bdos error message. -; -PRTERR: PUSH HL ;save second message pointer. - CALL OUTCRLF ;send (cr)(lf). - LD A,(ACTIVE) ;get active drive. - ADD A,'A' ;make ascii. - LD (BDOSDRV),A ;and put in message. - LD BC,BDOSERR ;and print it. - CALL PRTMESG - POP BC ;print second message line now. - CALL PRTMESG -; -; Get an input character. We will check our 1 character -; buffer first. This may be set by the console status routine. -; -GETCHAR:LD HL,CHARBUF ;check character buffer. - LD A,(HL) ;anything present already? - LD (HL),0 ;...either case clear it. - OR A - RET NZ ;yes, use it. - JP CONIN ;nope, go get a character responce. -; -; Input and echo a character. -; -GETECHO:CALL GETCHAR ;input a character. - CALL CHKCHAR ;carriage control? - RET C ;no, a regular control char so don't echo. - PUSH AF ;ok, save character now. - LD C,A - CALL OUTCON ;and echo it. - POP AF ;get character and return. - RET -; -; Check character in (A). Set the zero flag on a carriage -; control character and the carry flag on any other control -; character. -; -CHKCHAR:CP CR ;check for carriage return, line feed, backspace, - RET Z ;or a tab. - CP LF - RET Z - CP TAB - RET Z - CP BS - RET Z - CP ' ' ;other control char? Set carry flag. - RET -; -; Check the console during output. Halt on a control-s, then -; reboot on a control-c. If anything else is ready, clear the -; zero flag and return (the calling routine may want to do -; something). -; -CKCONSOL: LD A,(CHARBUF) ;check buffer. - OR A ;if anything, just return without checking. - JP NZ,CKCON2 - CALL CONST ;nothing in buffer. Check console. - AND 01H ;look at bit 0. - RET Z ;return if nothing. - CALL CONIN ;ok, get it. - CP CNTRLS ;if not control-s, return with zero cleared. - JP NZ,CKCON1 - CALL CONIN ;halt processing until another char - CP CNTRLC ;is typed. Control-c? - JP Z,0 ;yes, reboot now. - XOR A ;no, just pretend nothing was ever ready. - RET -CKCON1: LD (CHARBUF),A ;save character in buffer for later processing. -CKCON2: LD A,1 ;set (A) to non zero to mean something is ready. - RET -; -; Output (C) to the screen. If the printer flip-flop flag -; is set, we will send character to printer also. The console -; will be checked in the process. -; -OUTCHAR:LD A,(OUTFLAG) ;check output flag. - OR A ;anything and we won't generate output. - JP NZ,OUTCHR1 - PUSH BC - CALL CKCONSOL ;check console (we don't care whats there). - POP BC - PUSH BC - CALL CONOUT ;output (C) to the screen. - POP BC - PUSH BC - LD A,(PRTFLAG) ;check printer flip-flop flag. - OR A - CALL NZ,LIST ;print it also if non-zero. - POP BC -OUTCHR1:LD A,C ;update cursors position. - LD HL,CURPOS - CP DEL ;rubouts don't do anything here. - RET Z - INC (HL) ;bump line pointer. - CP ' ' ;and return if a normal character. - RET NC - DEC (HL) ;restore and check for the start of the line. - LD A,(HL) - OR A - RET Z ;ingnore control characters at the start of the line. - LD A,C - CP BS ;is it a backspace? - JP NZ,OUTCHR2 - DEC (HL) ;yes, backup pointer. - RET -OUTCHR2:CP LF ;is it a line feed? - RET NZ ;ignore anything else. - LD (HL),0 ;reset pointer to start of line. - RET -; -; Output (A) to the screen. If it is a control character -; (other than carriage control), use ^x format. -; -SHOWIT: LD A,C - CALL CHKCHAR ;check character. - JP NC,OUTCON ;not a control, use normal output. - PUSH AF - LD C,'^' ;for a control character, preceed it with '^'. - CALL OUTCHAR - POP AF - OR '@' ;and then use the letter equivelant. - LD C,A -; -; Function to output (C) to the console device and expand tabs -; if necessary. -; -OUTCON: LD A,C - CP TAB ;is it a tab? - JP NZ,OUTCHAR ;use regular output. -OUTCON1:LD C,' ' ;yes it is, use spaces instead. - CALL OUTCHAR - LD A,(CURPOS) ;go until the cursor is at a multiple of 8 - - AND 07H ;position. - JP NZ,OUTCON1 - RET -; -; Echo a backspace character. Erase the prevoius character -; on the screen. -; -BACKUP: CALL BACKUP1 ;backup the screen 1 place. - LD C,' ' ;then blank that character. - CALL CONOUT -BACKUP1:LD C,BS ;then back space once more. - JP CONOUT -; -; Signal a deleted line. Print a '#' at the end and start -; over. -; -NEWLINE:LD C,'#' - CALL OUTCHAR ;print this. - CALL OUTCRLF ;start new line. -NEWLN1: LD A,(CURPOS) ;move the cursor to the starting position. - LD HL,STARTING - CP (HL) - RET NC ;there yet? - LD C,' ' - CALL OUTCHAR ;nope, keep going. - JP NEWLN1 -; -; Output a (cr) (lf) to the console device (screen). -; -OUTCRLF:LD C,CR - CALL OUTCHAR - LD C,LF - JP OUTCHAR -; -; Print message pointed to by (BC). It will end with a '$'. -; -PRTMESG:LD A,(BC) ;check for terminating character. - CP '$' - RET Z - INC BC - PUSH BC ;otherwise, bump pointer and print it. - LD C,A - CALL OUTCON - POP BC - JP PRTMESG -; -; Function to execute a buffered read. -; -RDBUFF: LD A,(CURPOS) ;use present location as starting one. - LD (STARTING),A - LD HL,(PARAMS) ;get the maximum buffer space. - LD C,(HL) - INC HL ;point to first available space. - PUSH HL ;and save. - LD B,0 ;keep a character count. -RDBUF1: PUSH BC - PUSH HL -RDBUF2: CALL GETCHAR ;get the next input character. - AND 7FH ;strip bit 7. - POP HL ;reset registers. - POP BC - CP CR ;en of the line? - JP Z,RDBUF17 - CP LF - JP Z,RDBUF17 - CP BS ;how about a backspace? - JP NZ,RDBUF3 - LD A,B ;yes, but ignore at the beginning of the line. - OR A - JP Z,RDBUF1 - DEC B ;ok, update counter. - LD A,(CURPOS) ;if we backspace to the start of the line, - LD (OUTFLAG),A ;treat as a cancel (control-x). - JP RDBUF10 -RDBUF3: CP DEL ;user typed a rubout? - JP NZ,RDBUF4 - LD A,B ;ignore at the start of the line. - OR A - JP Z,RDBUF1 - LD A,(HL) ;ok, echo the prevoius character. - DEC B ;and reset pointers (counters). - DEC HL - JP RDBUF15 -RDBUF4: CP CNTRLE ;physical end of line? - JP NZ,RDBUF5 - PUSH BC ;yes, do it. - PUSH HL - CALL OUTCRLF - XOR A ;and update starting position. - LD (STARTING),A - JP RDBUF2 -RDBUF5: CP CNTRLP ;control-p? - JP NZ,RDBUF6 - PUSH HL ;yes, flip the print flag filp-flop byte. - LD HL,PRTFLAG - LD A,1 ;PRTFLAG=1-PRTFLAG - SUB (HL) - LD (HL),A - POP HL - JP RDBUF1 -RDBUF6: CP CNTRLX ;control-x (cancel)? - JP NZ,RDBUF8 - POP HL -RDBUF7: LD A,(STARTING) ;yes, backup the cursor to here. - LD HL,CURPOS - CP (HL) - JP NC,RDBUFF ;done yet? - DEC (HL) ;no, decrement pointer and output back up one space. - CALL BACKUP - JP RDBUF7 -RDBUF8: CP CNTRLU ;cntrol-u (cancel line)? - JP NZ,RDBUF9 - CALL NEWLINE ;start a new line. - POP HL - JP RDBUFF -RDBUF9: CP CNTRLR ;control-r? - JP NZ,RDBUF14 -RDBUF10:PUSH BC ;yes, start a new line and retype the old one. - CALL NEWLINE - POP BC - POP HL - PUSH HL - PUSH BC -RDBUF11:LD A,B ;done whole line yet? - OR A - JP Z,RDBUF12 - INC HL ;nope, get next character. - LD C,(HL) - DEC B ;count it. - PUSH BC - PUSH HL - CALL SHOWIT ;and display it. - POP HL - POP BC - JP RDBUF11 -RDBUF12:PUSH HL ;done with line. If we were displaying - LD A,(OUTFLAG) ;then update cursor position. - OR A - JP Z,RDBUF2 - LD HL,CURPOS ;because this line is shorter, we must - SUB (HL) ;back up the cursor (not the screen however) - LD (OUTFLAG),A ;some number of positions. -RDBUF13:CALL BACKUP ;note that as long as (OUTFLAG) is non - LD HL,OUTFLAG ;zero, the screen will not be changed. - DEC (HL) - JP NZ,RDBUF13 - JP RDBUF2 ;now just get the next character. -; -; Just a normal character, put this in our buffer and echo. -; -RDBUF14:INC HL - LD (HL),A ;store character. - INC B ;and count it. -RDBUF15:PUSH BC - PUSH HL - LD C,A ;echo it now. - CALL SHOWIT - POP HL - POP BC - LD A,(HL) ;was it an abort request? - CP CNTRLC ;control-c abort? - LD A,B - JP NZ,RDBUF16 - CP 1 ;only if at start of line. - JP Z,0 -RDBUF16:CP C ;nope, have we filled the buffer? - JP C,RDBUF1 -RDBUF17:POP HL ;yes end the line and return. - LD (HL),B - LD C,CR - JP OUTCHAR ;output (cr) and return. -; -; Function to get a character from the console device. -; -GETCON: CALL GETECHO ;get and echo. - JP SETSTAT ;save status and return. -; -; Function to get a character from the tape reader device. -; -GETRDR: CALL READER ;get a character from reader, set status and return. - JP SETSTAT -; -; Function to perform direct console i/o. If (C) contains (FF) -; then this is an input request. If (C) contains (FE) then -; this is a status request. Otherwise we are to output (C). -; -DIRCIO: LD A,C ;test for (FF). - INC A - JP Z,DIRC1 - INC A ;test for (FE). - JP Z,CONST - JP CONOUT ;just output (C). -DIRC1: CALL CONST ;this is an input request. - OR A - JP Z,GOBACK1 ;not ready? Just return (directly). - CALL CONIN ;yes, get character. - JP SETSTAT ;set status and return. -; -; Function to return the i/o byte. -; -GETIOB: LD A,(IOBYTE) - JP SETSTAT -; -; Function to set the i/o byte. -; -SETIOB: LD HL,IOBYTE - LD (HL),C - RET -; -; Function to print the character string pointed to by (DE) -; on the console device. The string ends with a '$'. -; -PRTSTR: EX DE,HL - LD C,L - LD B,H ;now (BC) points to it. - JP PRTMESG -; -; Function to interigate the console device. -; -GETCSTS:CALL CKCONSOL -; -; Get here to set the status and return to the cleanup -; section. Then back to the user. -; -SETSTAT:LD (STATUS),A -RTN: RET -; -; Set the status to 1 (read or write error code). -; -IOERR1: LD A,1 - JP SETSTAT -; -OUTFLAG:DEFB 0 ;output flag (non zero means no output). -STARTING: DEFB 2 ;starting position for cursor. -CURPOS: DEFB 0 ;cursor position (0=start of line). -PRTFLAG:DEFB 0 ;printer flag (control-p toggle). List if non zero. -CHARBUF:DEFB 0 ;single input character buffer. -; -; Stack area for BDOS calls. -; -USRSTACK: DEFW 0 ;save users stack pointer here. -; - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -STKAREA EQU $ ;end of stack area. -; -USERNO: DEFB 0 ;current user number. -ACTIVE: DEFB 0 ;currently active drive. -PARAMS: DEFW 0 ;save (DE) parameters here on entry. -STATUS: DEFW 0 ;status returned from bdos function. -; -; Select error occured, jump to error routine. -; -SLCTERR:LD HL,BADSLCT -; -; Jump to (HL) indirectly. -; -JUMPHL: LD E,(HL) - INC HL - LD D,(HL) ;now (DE) contain the desired address. - EX DE,HL - JP (HL) -; -; Block move. (DE) to (HL), (C) bytes total. -; -DE2HL: INC C ;is count down to zero? -DE2HL1: DEC C - RET Z ;yes, we are done. - LD A,(DE) ;no, move one more byte. - LD (HL),A - INC DE - INC HL - JP DE2HL1 ;and repeat. -; -; Select the desired drive. -; -SELECT: LD A,(ACTIVE) ;get active disk. - LD C,A - CALL SELDSK ;select it. - LD A,H ;valid drive? - OR L ;valid drive? - RET Z ;return if not. -; -; Here, the BIOS returned the address of the parameter block -; in (HL). We will extract the necessary pointers and save them. -; - LD E,(HL) ;yes, get address of translation table into (DE). - INC HL - LD D,(HL) - INC HL - LD (SCRATCH1),HL ;save pointers to scratch areas. - INC HL - INC HL - LD (SCRATCH2),HL ;ditto. - INC HL - INC HL - LD (SCRATCH3),HL ;ditto. - INC HL - INC HL - EX DE,HL ;now save the translation table address. - LD (XLATE),HL - LD HL,DIRBUF ;put the next 8 bytes here. - LD C,8 ;they consist of the directory buffer - CALL DE2HL ;pointer, parameter block pointer, - LD HL,(DISKPB) ;check and allocation vectors. - EX DE,HL - LD HL,SECTORS ;move parameter block into our ram. - LD C,15 ;it is 15 bytes long. - CALL DE2HL - LD HL,(DSKSIZE) ;check disk size. - LD A,H ;more than 256 blocks on this? - LD HL,BIGDISK - LD (HL),0FFH ;set to samll. - OR A - JP Z,SELECT1 - LD (HL),0 ;wrong, set to large. -SELECT1:LD A,0FFH ;clear the zero flag. - OR A - RET -; -; Routine to home the disk track head and clear pointers. -; -HOMEDRV:CALL HOME ;home the head. - XOR A - LD HL,(SCRATCH2) ;set our track pointer also. - LD (HL),A - INC HL - LD (HL),A - LD HL,(SCRATCH3) ;and our sector pointer. - LD (HL),A - INC HL - LD (HL),A - RET -; -; Do the actual disk read and check the error return status. -; -DOREAD: CALL READ - JP IORET -; -; Do the actual disk write and handle any bios error. -; -DOWRITE:CALL WRITE -IORET: OR A - RET Z ;return unless an error occured. - LD HL,BADSCTR ;bad read/write on this sector. - JP JUMPHL -; -; Routine to select the track and sector that the desired -; block number falls in. -; -TRKSEC: LD HL,(FILEPOS) ;get position of last accessed file - LD C,2 ;in directory and compute sector #. - CALL SHIFTR ;sector #=file-position/4. - LD (BLKNMBR),HL ;save this as the block number of interest. - LD (CKSUMTBL),HL ;what's it doing here too? -; -; if the sector number has already been set (BLKNMBR), enter -; at this point. -; -TRKSEC1:LD HL,BLKNMBR - LD C,(HL) ;move sector number into (BC). - INC HL - LD B,(HL) - LD HL,(SCRATCH3) ;get current sector number and - LD E,(HL) ;move this into (DE). - INC HL - LD D,(HL) - LD HL,(SCRATCH2) ;get current track number. - LD A,(HL) ;and this into (HL). - INC HL - LD H,(HL) - LD L,A -TRKSEC2:LD A,C ;is desired sector before current one? - SUB E - LD A,B - SBC A,D - JP NC,TRKSEC3 - PUSH HL ;yes, decrement sectors by one track. - LD HL,(SECTORS) ;get sectors per track. - LD A,E - SUB L - LD E,A - LD A,D - SBC A,H - LD D,A ;now we have backed up one full track. - POP HL - DEC HL ;adjust track counter. - JP TRKSEC2 -TRKSEC3:PUSH HL ;desired sector is after current one. - LD HL,(SECTORS) ;get sectors per track. - ADD HL,DE ;bump sector pointer to next track. - JP C,TRKSEC4 - LD A,C ;is desired sector now before current one? - SUB L - LD A,B - SBC A,H - JP C,TRKSEC4 - EX DE,HL ;not yes, increment track counter - POP HL ;and continue until it is. - INC HL - JP TRKSEC3 -; -; here we have determined the track number that contains the -; desired sector. -; -TRKSEC4:POP HL ;get track number (HL). - PUSH BC - PUSH DE - PUSH HL - EX DE,HL - LD HL,(OFFSET) ;adjust for first track offset. - ADD HL,DE - LD B,H - LD C,L - CALL SETTRK ;select this track. - POP DE ;reset current track pointer. - LD HL,(SCRATCH2) - LD (HL),E - INC HL - LD (HL),D - POP DE - LD HL,(SCRATCH3) ;reset the first sector on this track. - LD (HL),E - INC HL - LD (HL),D - POP BC - LD A,C ;now subtract the desired one. - SUB E ;to make it relative (1-# sectors/track). - LD C,A - LD A,B - SBC A,D - LD B,A - LD HL,(XLATE) ;translate this sector according to this table. - EX DE,HL - CALL SECTRN ;let the bios translate it. - LD C,L - LD B,H - JP SETSEC ;and select it. -; -; Compute block number from record number (SAVNREC) and -; extent number (SAVEXT). -; -GETBLOCK: LD HL,BLKSHFT ;get logical to physical conversion. - LD C,(HL) ;note that this is base 2 log of ratio. - LD A,(SAVNREC) ;get record number. -GETBLK1:OR A ;compute (A)=(A)/2^BLKSHFT. - RRA - DEC C - JP NZ,GETBLK1 - LD B,A ;save result in (B). - LD A,8 - SUB (HL) - LD C,A ;compute (C)=8-BLKSHFT. - LD A,(SAVEXT) -GETBLK2:DEC C ;compute (A)=SAVEXT*2^(8-BLKSHFT). - JP Z,GETBLK3 - OR A - RLA - JP GETBLK2 -GETBLK3:ADD A,B - RET -; -; Routine to extract the (BC) block byte from the fcb pointed -; to by (PARAMS). If this is a big-disk, then these are 16 bit -; block numbers, else they are 8 bit numbers. -; Number is returned in (HL). -; -EXTBLK: LD HL,(PARAMS) ;get fcb address. - LD DE,16 ;block numbers start 16 bytes into fcb. - ADD HL,DE - ADD HL,BC - LD A,(BIGDISK) ;are we using a big-disk? - OR A - JP Z,EXTBLK1 - LD L,(HL) ;no, extract an 8 bit number from the fcb. - LD H,0 - RET -EXTBLK1:ADD HL,BC ;yes, extract a 16 bit number. - LD E,(HL) - INC HL - LD D,(HL) - EX DE,HL ;return in (HL). - RET -; -; Compute block number. -; -COMBLK: CALL GETBLOCK - LD C,A - LD B,0 - CALL EXTBLK - LD (BLKNMBR),HL - RET -; -; Check for a zero block number (unused). -; -CHKBLK: LD HL,(BLKNMBR) - LD A,L ;is it zero? - OR H - RET -; -; Adjust physical block (BLKNMBR) and convert to logical -; sector (LOGSECT). This is the starting sector of this block. -; The actual sector of interest is then added to this and the -; resulting sector number is stored back in (BLKNMBR). This -; will still have to be adjusted for the track number. -; -LOGICAL:LD A,(BLKSHFT) ;get log2(physical/logical sectors). - LD HL,(BLKNMBR) ;get physical sector desired. -LOGICL1:ADD HL,HL ;compute logical sector number. - DEC A ;note logical sectors are 128 bytes long. - JP NZ,LOGICL1 - LD (LOGSECT),HL ;save logical sector. - LD A,(BLKMASK) ;get block mask. - LD C,A - LD A,(SAVNREC) ;get next sector to access. - AND C ;extract the relative position within physical block. - OR L ;and add it too logical sector. - LD L,A - LD (BLKNMBR),HL ;and store. - RET -; -; Set (HL) to point to extent byte in fcb. -; -SETEXT: LD HL,(PARAMS) - LD DE,12 ;it is the twelth byte. - ADD HL,DE - RET -; -; Set (HL) to point to record count byte in fcb and (DE) to -; next record number byte. -; -SETHLDE:LD HL,(PARAMS) - LD DE,15 ;record count byte (#15). - ADD HL,DE - EX DE,HL - LD HL,17 ;next record number (#32). - ADD HL,DE - RET -; -; Save current file data from fcb. -; -STRDATA:CALL SETHLDE - LD A,(HL) ;get and store record count byte. - LD (SAVNREC),A - EX DE,HL - LD A,(HL) ;get and store next record number byte. - LD (SAVNXT),A - CALL SETEXT ;point to extent byte. - LD A,(EXTMASK) ;get extent mask. - AND (HL) - LD (SAVEXT),A ;and save extent here. - RET -; -; Set the next record to access. If (MODE) is set to 2, then -; the last record byte (SAVNREC) has the correct number to access. -; For sequential access, (MODE) will be equal to 1. -; -SETNREC:CALL SETHLDE - LD A,(MODE) ;get sequential flag (=1). - CP 2 ;a 2 indicates that no adder is needed. - JP NZ,STNREC1 - XOR A ;clear adder (random access?). -STNREC1:LD C,A - LD A,(SAVNREC) ;get last record number. - ADD A,C ;increment record count. - LD (HL),A ;and set fcb's next record byte. - EX DE,HL - LD A,(SAVNXT) ;get next record byte from storage. - LD (HL),A ;and put this into fcb as number of records used. - RET -; -; Shift (HL) right (C) bits. -; -SHIFTR: INC C -SHIFTR1:DEC C - RET Z - LD A,H - OR A - RRA - LD H,A - LD A,L - RRA - LD L,A - JP SHIFTR1 -; -; Compute the check-sum for the directory buffer. Return -; integer sum in (A). -; -CHECKSUM: LD C,128 ;length of buffer. - LD HL,(DIRBUF) ;get its location. - XOR A ;clear summation byte. -CHKSUM1:ADD A,M ;and compute sum ignoring carries. - INC HL - DEC C - JP NZ,CHKSUM1 - RET -; -; Shift (HL) left (C) bits. -; -SHIFTL: INC C -SHIFTL1:DEC C - RET Z - ADD HL,HL ;shift left 1 bit. - JP SHIFTL1 -; -; Routine to set a bit in a 16 bit value contained in (BC). -; The bit set depends on the current drive selection. -; -SETBIT: PUSH BC ;save 16 bit word. - LD A,(ACTIVE) ;get active drive. - LD C,A - LD HL,1 - CALL SHIFTL ;shift bit 0 into place. - POP BC ;now 'or' this with the original word. - LD A,C - OR L - LD L,A ;low byte done, do high byte. - LD A,B - OR H - LD H,A - RET -; -; Extract the write protect status bit for the current drive. -; The result is returned in (A), bit 0. -; -GETWPRT:LD HL,(WRTPRT) ;get status bytes. - LD A,(ACTIVE) ;which drive is current? - LD C,A - CALL SHIFTR ;shift status such that bit 0 is the - LD A,L ;one of interest for this drive. - AND 01H ;and isolate it. - RET -; -; Function to write protect the current disk. -; -WRTPRTD:LD HL,WRTPRT ;point to status word. - LD C,(HL) ;set (BC) equal to the status. - INC HL - LD B,(HL) - CALL SETBIT ;and set this bit according to current drive. - LD (WRTPRT),HL ;then save. - LD HL,(DIRSIZE) ;now save directory size limit. - INC HL ;remember the last one. - EX DE,HL - LD HL,(SCRATCH1) ;and store it here. - LD (HL),E ;put low byte. - INC HL - LD (HL),D ;then high byte. - RET -; -; Check for a read only file. -; -CHKROFL:CALL FCB2HL ;set (HL) to file entry in directory buffer. -CKROF1: LD DE,9 ;look at bit 7 of the ninth byte. - ADD HL,DE - LD A,(HL) - RLA - RET NC ;return if ok. - LD HL,ROFILE ;else, print error message and terminate. - JP JUMPHL -; -; Check the write protect status of the active disk. -; -CHKWPRT:CALL GETWPRT - RET Z ;return if ok. - LD HL,RODISK ;else print message and terminate. - JP JUMPHL -; -; Routine to set (HL) pointing to the proper entry in the -; directory buffer. -; -FCB2HL: LD HL,(DIRBUF) ;get address of buffer. - LD A,(FCBPOS) ;relative position of file. -; -; Routine to add (A) to (HL). -; -ADDA2HL:ADD A,L - LD L,A - RET NC - INC H ;take care of any carry. - RET -; -; Routine to get the 's2' byte from the fcb supplied in -; the initial parameter specification. -; -GETS2: LD HL,(PARAMS) ;get address of fcb. - LD DE,14 ;relative position of 's2'. - ADD HL,DE - LD A,(HL) ;extract this byte. - RET -; -; Clear the 's2' byte in the fcb. -; -CLEARS2:CALL GETS2 ;this sets (HL) pointing to it. - LD (HL),0 ;now clear it. - RET -; -; Set bit 7 in the 's2' byte of the fcb. -; -SETS2B7:CALL GETS2 ;get the byte. - OR 80H ;and set bit 7. - LD (HL),A ;then store. - RET -; -; Compare (FILEPOS) with (SCRATCH1) and set flags based on -; the difference. This checks to see if there are more file -; names in the directory. We are at (FILEPOS) and there are -; (SCRATCH1) of them to check. -; -MOREFLS:LD HL,(FILEPOS) ;we are here. - EX DE,HL - LD HL,(SCRATCH1) ;and don't go past here. - LD A,E ;compute difference but don't keep. - SUB (HL) - INC HL - LD A,D - SBC A,M ;set carry if no more names. - RET -; -; Call this routine to prevent (SCRATCH1) from being greater -; than (FILEPOS). -; -CHKNMBR:CALL MOREFLS ;SCRATCH1 too big? - RET C - INC DE ;yes, reset it to (FILEPOS). - LD (HL),D - DEC HL - LD (HL),E - RET -; -; Compute (HL)=(DE)-(HL) -; -SUBHL: LD A,E ;compute difference. - SUB L - LD L,A ;store low byte. - LD A,D - SBC A,H - LD H,A ;and then high byte. - RET -; -; Set the directory checksum byte. -; -SETDIR: LD C,0FFH -; -; Routine to set or compare the directory checksum byte. If -; (C)=0ffh, then this will set the checksum byte. Else the byte -; will be checked. If the check fails (the disk has been changed), -; then this disk will be write protected. -; -CHECKDIR: LD HL,(CKSUMTBL) - EX DE,HL - LD HL,(ALLOC1) - CALL SUBHL - RET NC ;ok if (CKSUMTBL) > (ALLOC1), so return. - PUSH BC - CALL CHECKSUM ;else compute checksum. - LD HL,(CHKVECT) ;get address of checksum table. - EX DE,HL - LD HL,(CKSUMTBL) - ADD HL,DE ;set (HL) to point to byte for this drive. - POP BC - INC C ;set or check ? - JP Z,CHKDIR1 - CP (HL) ;check them. - RET Z ;return if they are the same. - CALL MOREFLS ;not the same, do we care? - RET NC - CALL WRTPRTD ;yes, mark this as write protected. - RET -CHKDIR1:LD (HL),A ;just set the byte. - RET -; -; Do a write to the directory of the current disk. -; -DIRWRITE: CALL SETDIR ;set checksum byte. - CALL DIRDMA ;set directory dma address. - LD C,1 ;tell the bios to actually write. - CALL DOWRITE ;then do the write. - JP DEFDMA -; -; Read from the directory. -; -DIRREAD:CALL DIRDMA ;set the directory dma address. - CALL DOREAD ;and read it. -; -; Routine to set the dma address to the users choice. -; -DEFDMA: LD HL,USERDMA ;reset the default dma address and return. - JP DIRDMA1 -; -; Routine to set the dma address for directory work. -; -DIRDMA: LD HL,DIRBUF -; -; Set the dma address. On entry, (HL) points to -; word containing the desired dma address. -; -DIRDMA1:LD C,(HL) - INC HL - LD B,(HL) ;setup (BC) and go to the bios to set it. - JP SETDMA -; -; Move the directory buffer into user's dma space. -; -MOVEDIR:LD HL,(DIRBUF) ;buffer is located here, and - EX DE,HL - LD HL,(USERDMA) ; put it here. - LD C,128 ;this is its length. - JP DE2HL ;move it now and return. -; -; Check (FILEPOS) and set the zero flag if it equals 0ffffh. -; -CKFILPOS: LD HL,FILEPOS - LD A,(HL) - INC HL - CP (HL) ;are both bytes the same? - RET NZ - INC A ;yes, but are they each 0ffh? - RET -; -; Set location (FILEPOS) to 0ffffh. -; -STFILPOS: LD HL,0FFFFH - LD (FILEPOS),HL - RET -; -; Move on to the next file position within the current -; directory buffer. If no more exist, set pointer to 0ffffh -; and the calling routine will check for this. Enter with (C) -; equal to 0ffh to cause the checksum byte to be set, else we -; will check this disk and set write protect if checksums are -; not the same (applies only if another directory sector must -; be read). -; -NXENTRY:LD HL,(DIRSIZE) ;get directory entry size limit. - EX DE,HL - LD HL,(FILEPOS) ;get current count. - INC HL ;go on to the next one. - LD (FILEPOS),HL - CALL SUBHL ;(HL)=(DIRSIZE)-(FILEPOS) - JP NC,NXENT1 ;is there more room left? - JP STFILPOS ;no. Set this flag and return. -NXENT1: LD A,(FILEPOS) ;get file position within directory. - AND 03H ;only look within this sector (only 4 entries fit). - LD B,5 ;convert to relative position (32 bytes each). -NXENT2: ADD A,A ;note that this is not efficient code. - DEC B ;5 'ADD A's would be better. - JP NZ,NXENT2 - LD (FCBPOS),A ;save it as position of fcb. - OR A - RET NZ ;return if we are within buffer. - PUSH BC - CALL TRKSEC ;we need the next directory sector. - CALL DIRREAD - POP BC - JP CHECKDIR -; -; Routine to to get a bit from the disk space allocation -; map. It is returned in (A), bit position 0. On entry to here, -; set (BC) to the block number on the disk to check. -; On return, (D) will contain the original bit position for -; this block number and (HL) will point to the address for it. -; -CKBITMAP: LD A,C ;determine bit number of interest. - AND 07H ;compute (D)=(E)=(C and 7)+1. - INC A - LD E,A ;save particular bit number. - LD D,A -; -; compute (BC)=(BC)/8. -; - LD A,C - RRCA ;now shift right 3 bits. - RRCA - RRCA - AND 1FH ;and clear bits 7,6,5. - LD C,A - LD A,B - ADD A,A ;now shift (B) into bits 7,6,5. - ADD A,A - ADD A,A - ADD A,A - ADD A,A - OR C ;and add in (C). - LD C,A ;ok, (C) ha been completed. - LD A,B ;is there a better way of doing this? - RRCA - RRCA - RRCA - AND 1FH - LD B,A ;and now (B) is completed. -; -; use this as an offset into the disk space allocation -; table. -; - LD HL,(ALOCVECT) - ADD HL,BC - LD A,(HL) ;now get correct byte. -CKBMAP1:RLCA ;get correct bit into position 0. - DEC E - JP NZ,CKBMAP1 - RET -; -; Set or clear the bit map such that block number (BC) will be marked -; as used. On entry, if (E)=0 then this bit will be cleared, if it equals -; 1 then it will be set (don't use anyother values). -; -STBITMAP: PUSH DE - CALL CKBITMAP ;get the byte of interest. - AND 0FEH ;clear the affected bit. - POP BC - OR C ;and now set it acording to (C). -; -; entry to restore the original bit position and then store -; in table. (A) contains the value, (D) contains the bit -; position (1-8), and (HL) points to the address within the -; space allocation table for this byte. -; -STBMAP1:RRCA ;restore original bit position. - DEC D - JP NZ,STBMAP1 - LD (HL),A ;and stor byte in table. - RET -; -; Set/clear space used bits in allocation map for this file. -; On entry, (C)=1 to set the map and (C)=0 to clear it. -; -SETFILE:CALL FCB2HL ;get address of fcb - LD DE,16 - ADD HL,DE ;get to block number bytes. - PUSH BC - LD C,17 ;check all 17 bytes (max) of table. -SETFL1: POP DE - DEC C ;done all bytes yet? - RET Z - PUSH DE - LD A,(BIGDISK) ;check disk size for 16 bit block numbers. - OR A - JP Z,SETFL2 - PUSH BC ;only 8 bit numbers. set (BC) to this one. - PUSH HL - LD C,(HL) ;get low byte from table, always - LD B,0 ;set high byte to zero. - JP SETFL3 -SETFL2: DEC C ;for 16 bit block numbers, adjust counter. - PUSH BC - LD C,(HL) ;now get both the low and high bytes. - INC HL - LD B,(HL) - PUSH HL -SETFL3: LD A,C ;block used? - OR B - JP Z,SETFL4 - LD HL,(DSKSIZE) ;is this block number within the - LD A,L ;space on the disk? - SUB C - LD A,H - SBC A,B - CALL NC,STBITMAP ;yes, set the proper bit. -SETFL4: POP HL ;point to next block number in fcb. - INC HL - POP BC - JP SETFL1 -; -; Construct the space used allocation bit map for the active -; drive. If a file name starts with '$' and it is under the -; current user number, then (STATUS) is set to minus 1. Otherwise -; it is not set at all. -; -BITMAP: LD HL,(DSKSIZE) ;compute size of allocation table. - LD C,3 - CALL SHIFTR ;(HL)=(HL)/8. - INC HL ;at lease 1 byte. - LD B,H - LD C,L ;set (BC) to the allocation table length. -; -; Initialize the bitmap for this drive. Right now, the first -; two bytes are specified by the disk parameter block. However -; a patch could be entered here if it were necessary to setup -; this table in a special mannor. For example, the bios could -; determine locations of 'bad blocks' and set them as already -; 'used' in the map. -; - LD HL,(ALOCVECT) ;now zero out the table now. -BITMAP1:LD (HL),0 - INC HL - DEC BC - LD A,B - OR C - JP NZ,BITMAP1 - LD HL,(ALLOC0) ;get initial space used by directory. - EX DE,HL - LD HL,(ALOCVECT) ;and put this into map. - LD (HL),E - INC HL - LD (HL),D -; -; End of initialization portion. -; - CALL HOMEDRV ;now home the drive. - LD HL,(SCRATCH1) - LD (HL),3 ;force next directory request to read - INC HL ;in a sector. - LD (HL),0 - CALL STFILPOS ;clear initial file position also. -BITMAP2:LD C,0FFH ;read next file name in directory - CALL NXENTRY ;and set checksum byte. - CALL CKFILPOS ;is there another file? - RET Z - CALL FCB2HL ;yes, get its address. - LD A,0E5H - CP (HL) ;empty file entry? - JP Z,BITMAP2 - LD A,(USERNO) ;no, correct user number? - CP (HL) - JP NZ,BITMAP3 - INC HL - LD A,(HL) ;yes, does name start with a '$'? - SUB '$' - JP NZ,BITMAP3 - DEC A ;yes, set atatus to minus one. - LD (STATUS),A -BITMAP3:LD C,1 ;now set this file's space as used in bit map. - CALL SETFILE - CALL CHKNMBR ;keep (SCRATCH1) in bounds. - JP BITMAP2 -; -; Set the status (STATUS) and return. -; -STSTATUS: LD A,(FNDSTAT) - JP SETSTAT -; -; Check extents in (A) and (C). Set the zero flag if they -; are the same. The number of 16k chunks of disk space that -; the directory extent covers is expressad is (EXTMASK+1). -; No registers are modified. -; -SAMEXT: PUSH BC - PUSH AF - LD A,(EXTMASK) ;get extent mask and use it to - CPL ;to compare both extent numbers. - LD B,A ;save resulting mask here. - LD A,C ;mask first extent and save in (C). - AND B - LD C,A - POP AF ;now mask second extent and compare - AND B ;with the first one. - SUB C - AND 1FH ;(* only check buts 0-4 *) - POP BC ;the zero flag is set if they are the same. - RET ;restore (BC) and return. -; -; Search for the first occurence of a file name. On entry, -; register (C) should contain the number of bytes of the fcb -; that must match. -; -FINDFST:LD A,0FFH - LD (FNDSTAT),A - LD HL,COUNTER ;save character count. - LD (HL),C - LD HL,(PARAMS) ;get filename to match. - LD (SAVEFCB),HL ;and save. - CALL STFILPOS ;clear initial file position (set to 0ffffh). - CALL HOMEDRV ;home the drive. -; -; Entry to locate the next occurence of a filename within the -; directory. The disk is not expected to have been changed. If -; it was, then it will be write protected. -; -FINDNXT:LD C,0 ;write protect the disk if changed. - CALL NXENTRY ;get next filename entry in directory. - CALL CKFILPOS ;is file position = 0ffffh? - JP Z,FNDNXT6 ;yes, exit now then. - LD HL,(SAVEFCB) ;set (DE) pointing to filename to match. - EX DE,HL - LD A,(DE) - CP 0E5H ;empty directory entry? - JP Z,FNDNXT1 ;(* are we trying to reserect erased entries? *) - PUSH DE - CALL MOREFLS ;more files in directory? - POP DE - JP NC,FNDNXT6 ;no more. Exit now. -FNDNXT1:CALL FCB2HL ;get address of this fcb in directory. - LD A,(COUNTER) ;get number of bytes (characters) to check. - LD C,A - LD B,0 ;initialize byte position counter. -FNDNXT2:LD A,C ;are we done with the compare? - OR A - JP Z,FNDNXT5 - LD A,(DE) ;no, check next byte. - CP '?' ;don't care about this character? - JP Z,FNDNXT4 - LD A,B ;get bytes position in fcb. - CP 13 ;don't care about the thirteenth byte either. - JP Z,FNDNXT4 - CP 12 ;extent byte? - LD A,(DE) - JP Z,FNDNXT3 - SUB (HL) ;otherwise compare characters. - AND 7FH - JP NZ,FINDNXT ;not the same, check next entry. - JP FNDNXT4 ;so far so good, keep checking. -FNDNXT3:PUSH BC ;check the extent byte here. - LD C,(HL) - CALL SAMEXT - POP BC - JP NZ,FINDNXT ;not the same, look some more. -; -; So far the names compare. Bump pointers to the next byte -; and continue until all (C) characters have been checked. -; -FNDNXT4:INC DE ;bump pointers. - INC HL - INC B - DEC C ;adjust character counter. - JP FNDNXT2 -FNDNXT5:LD A,(FILEPOS) ;return the position of this entry. - AND 03H - LD (STATUS),A - LD HL,FNDSTAT - LD A,(HL) - RLA - RET NC - XOR A - LD (HL),A - RET -; -; Filename was not found. Set appropriate status. -; -FNDNXT6:CALL STFILPOS ;set (FILEPOS) to 0ffffh. - LD A,0FFH ;say not located. - JP SETSTAT -; -; Erase files from the directory. Only the first byte of the -; fcb will be affected. It is set to (E5). -; -ERAFILE:CALL CHKWPRT ;is disk write protected? - LD C,12 ;only compare file names. - CALL FINDFST ;get first file name. -ERAFIL1:CALL CKFILPOS ;any found? - RET Z ;nope, we must be done. - CALL CHKROFL ;is file read only? - CALL FCB2HL ;nope, get address of fcb and - LD (HL),0E5H ;set first byte to 'empty'. - LD C,0 ;clear the space from the bit map. - CALL SETFILE - CALL DIRWRITE ;now write the directory sector back out. - CALL FINDNXT ;find the next file name. - JP ERAFIL1 ;and repeat process. -; -; Look through the space allocation map (bit map) for the -; next available block. Start searching at block number (BC-1). -; The search procedure is to look for an empty block that is -; before the starting block. If not empty, look at a later -; block number. In this way, we return the closest empty block -; on either side of the 'target' block number. This will speed -; access on random devices. For serial devices, this should be -; changed to look in the forward direction first and then start -; at the front and search some more. -; -; On return, (DE)= block number that is empty and (HL) =0 -; if no empry block was found. -; -FNDSPACE: LD D,B ;set (DE) as the block that is checked. - LD E,C -; -; Look before target block. Registers (BC) are used as the lower -; pointer and (DE) as the upper pointer. -; -FNDSPA1:LD A,C ;is block 0 specified? - OR B - JP Z,FNDSPA2 - DEC BC ;nope, check previous block. - PUSH DE - PUSH BC - CALL CKBITMAP - RRA ;is this block empty? - JP NC,FNDSPA3 ;yes. use this. -; -; Note that the above logic gets the first block that it finds -; that is empty. Thus a file could be written 'backward' making -; it very slow to access. This could be changed to look for the -; first empty block and then continue until the start of this -; empty space is located and then used that starting block. -; This should help speed up access to some files especially on -; a well used disk with lots of fairly small 'holes'. -; - POP BC ;nope, check some more. - POP DE -; -; Now look after target block. -; -FNDSPA2:LD HL,(DSKSIZE) ;is block (DE) within disk limits? - LD A,E - SUB L - LD A,D - SBC A,H - JP NC,FNDSPA4 - INC DE ;yes, move on to next one. - PUSH BC - PUSH DE - LD B,D - LD C,E - CALL CKBITMAP ;check it. - RRA ;empty? - JP NC,FNDSPA3 - POP DE ;nope, continue searching. - POP BC - JP FNDSPA1 -; -; Empty block found. Set it as used and return with (HL) -; pointing to it (true?). -; -FNDSPA3:RLA ;reset byte. - INC A ;and set bit 0. - CALL STBMAP1 ;update bit map. - POP HL ;set return registers. - POP DE - RET -; -; Free block was not found. If (BC) is not zero, then we have -; not checked all of the disk space. -; -FNDSPA4:LD A,C - OR B - JP NZ,FNDSPA1 - LD HL,0 ;set 'not found' status. - RET -; -; Move a complete fcb entry into the directory and write it. -; -FCBSET: LD C,0 - LD E,32 ;length of each entry. -; -; Move (E) bytes from the fcb pointed to by (PARAMS) into -; fcb in directory starting at relative byte (C). This updated -; directory buffer is then written to the disk. -; -UPDATE: PUSH DE - LD B,0 ;set (BC) to relative byte position. - LD HL,(PARAMS) ;get address of fcb. - ADD HL,BC ;compute starting byte. - EX DE,HL - CALL FCB2HL ;get address of fcb to update in directory. - POP BC ;set (C) to number of bytes to change. - CALL DE2HL -UPDATE1:CALL TRKSEC ;determine the track and sector affected. - JP DIRWRITE ;then write this sector out. -; -; Routine to change the name of all files on the disk with a -; specified name. The fcb contains the current name as the -; first 12 characters and the new name 16 bytes into the fcb. -; -CHGNAMES: CALL CHKWPRT ;check for a write protected disk. - LD C,12 ;match first 12 bytes of fcb only. - CALL FINDFST ;get first name. - LD HL,(PARAMS) ;get address of fcb. - LD A,(HL) ;get user number. - LD DE,16 ;move over to desired name. - ADD HL,DE - LD (HL),A ;keep same user number. -CHGNAM1:CALL CKFILPOS ;any matching file found? - RET Z ;no, we must be done. - CALL CHKROFL ;check for read only file. - LD C,16 ;start 16 bytes into fcb. - LD E,12 ;and update the first 12 bytes of directory. - CALL UPDATE - CALL FINDNXT ;get te next file name. - JP CHGNAM1 ;and continue. -; -; Update a files attributes. The procedure is to search for -; every file with the same name as shown in fcb (ignoring bit 7) -; and then to update it (which includes bit 7). No other changes -; are made. -; -SAVEATTR: LD C,12 ;match first 12 bytes. - CALL FINDFST ;look for first filename. -SAVATR1:CALL CKFILPOS ;was one found? - RET Z ;nope, we must be done. - LD C,0 ;yes, update the first 12 bytes now. - LD E,12 - CALL UPDATE ;update filename and write directory. - CALL FINDNXT ;and get the next file. - JP SAVATR1 ;then continue until done. -; -; Open a file (name specified in fcb). -; -OPENIT: LD C,15 ;compare the first 15 bytes. - CALL FINDFST ;get the first one in directory. - CALL CKFILPOS ;any at all? - RET Z -OPENIT1:CALL SETEXT ;point to extent byte within users fcb. - LD A,(HL) ;and get it. - PUSH AF ;save it and address. - PUSH HL - CALL FCB2HL ;point to fcb in directory. - EX DE,HL - LD HL,(PARAMS) ;this is the users copy. - LD C,32 ;move it into users space. - PUSH DE - CALL DE2HL - CALL SETS2B7 ;set bit 7 in 's2' byte (unmodified). - POP DE ;now get the extent byte from this fcb. - LD HL,12 - ADD HL,DE - LD C,(HL) ;into (C). - LD HL,15 ;now get the record count byte into (B). - ADD HL,DE - LD B,(HL) - POP HL ;keep the same extent as the user had originally. - POP AF - LD (HL),A - LD A,C ;is it the same as in the directory fcb? - CP (HL) - LD A,B ;if yes, then use the same record count. - JP Z,OPENIT2 - LD A,0 ;if the user specified an extent greater than - JP C,OPENIT2 ;the one in the directory, then set record count to 0. - LD A,128 ;otherwise set to maximum. -OPENIT2:LD HL,(PARAMS) ;set record count in users fcb to (A). - LD DE,15 - ADD HL,DE ;compute relative position. - LD (HL),A ;and set the record count. - RET -; -; Move two bytes from (DE) to (HL) if (and only if) (HL) -; point to a zero value (16 bit). -; Return with zero flag set it (DE) was moved. Registers (DE) -; and (HL) are not changed. However (A) is. -; -MOVEWORD: LD A,(HL) ;check for a zero word. - INC HL - OR (HL) ;both bytes zero? - DEC HL - RET NZ ;nope, just return. - LD A,(DE) ;yes, move two bytes from (DE) into - LD (HL),A ;this zero space. - INC DE - INC HL - LD A,(DE) - LD (HL),A - DEC DE ;don't disturb these registers. - DEC HL - RET -; -; Get here to close a file specified by (fcb). -; -CLOSEIT:XOR A ;clear status and file position bytes. - LD (STATUS),A - LD (FILEPOS),A - LD (FILEPOS+1),A - CALL GETWPRT ;get write protect bit for this drive. - RET NZ ;just return if it is set. - CALL GETS2 ;else get the 's2' byte. - AND 80H ;and look at bit 7 (file unmodified?). - RET NZ ;just return if set. - LD C,15 ;else look up this file in directory. - CALL FINDFST - CALL CKFILPOS ;was it found? - RET Z ;just return if not. - LD BC,16 ;set (HL) pointing to records used section. - CALL FCB2HL - ADD HL,BC - EX DE,HL - LD HL,(PARAMS) ;do the same for users specified fcb. - ADD HL,BC - LD C,16 ;this many bytes are present in this extent. -CLOSEIT1: LD A,(BIGDISK) ;8 or 16 bit record numbers? - OR A - JP Z,CLOSEIT4 - LD A,(HL) ;just 8 bit. Get one from users fcb. - OR A - LD A,(DE) ;now get one from directory fcb. - JP NZ,CLOSEIT2 - LD (HL),A ;users byte was zero. Update from directory. -CLOSEIT2: OR A - JP NZ,CLOSEIT3 - LD A,(HL) ;directories byte was zero, update from users fcb. - LD (DE),A -CLOSEIT3: CP (HL) ;if neither one of these bytes were zero, - JP NZ,CLOSEIT7 ;then close error if they are not the same. - JP CLOSEIT5 ;ok so far, get to next byte in fcbs. -CLOSEIT4: CALL MOVEWORD ;update users fcb if it is zero. - EX DE,HL - CALL MOVEWORD ;update directories fcb if it is zero. - EX DE,HL - LD A,(DE) ;if these two values are no different, - CP (HL) ;then a close error occured. - JP NZ,CLOSEIT7 - INC DE ;check second byte. - INC HL - LD A,(DE) - CP (HL) - JP NZ,CLOSEIT7 - DEC C ;remember 16 bit values. -CLOSEIT5: INC DE ;bump to next item in table. - INC HL - DEC C ;there are 16 entries only. - JP NZ,CLOSEIT1 ;continue if more to do. - LD BC,0FFECH ;backup 20 places (extent byte). - ADD HL,BC - EX DE,HL - ADD HL,BC - LD A,(DE) - CP (HL) ;directory's extent already greater than the - JP C,CLOSEIT6 ;users extent? - LD (HL),A ;no, update directory extent. - LD BC,3 ;and update the record count byte in - ADD HL,BC ;directories fcb. - EX DE,HL - ADD HL,BC - LD A,(HL) ;get from user. - LD (DE),A ;and put in directory. -CLOSEIT6: LD A,0FFH ;set 'was open and is now closed' byte. - LD (CLOSEFLG),A - JP UPDATE1 ;update the directory now. -CLOSEIT7: LD HL,STATUS ;set return status and then return. - DEC (HL) - RET -; -; Routine to get the next empty space in the directory. It -; will then be cleared for use. -; -GETEMPTY: CALL CHKWPRT ;make sure disk is not write protected. - LD HL,(PARAMS) ;save current parameters (fcb). - PUSH HL - LD HL,EMPTYFCB ;use special one for empty space. - LD (PARAMS),HL - LD C,1 ;search for first empty spot in directory. - CALL FINDFST ;(* only check first byte *) - CALL CKFILPOS ;none? - POP HL - LD (PARAMS),HL ;restore original fcb address. - RET Z ;return if no more space. - EX DE,HL - LD HL,15 ;point to number of records for this file. - ADD HL,DE - LD C,17 ;and clear all of this space. - XOR A -GETMT1: LD (HL),A - INC HL - DEC C - JP NZ,GETMT1 - LD HL,13 ;clear the 's1' byte also. - ADD HL,DE - LD (HL),A - CALL CHKNMBR ;keep (SCRATCH1) within bounds. - CALL FCBSET ;write out this fcb entry to directory. - JP SETS2B7 ;set 's2' byte bit 7 (unmodified at present). -; -; Routine to close the current extent and open the next one -; for reading. -; -GETNEXT:XOR A - LD (CLOSEFLG),A ;clear close flag. - CALL CLOSEIT ;close this extent. - CALL CKFILPOS - RET Z ;not there??? - LD HL,(PARAMS) ;get extent byte. - LD BC,12 - ADD HL,BC - LD A,(HL) ;and increment it. - INC A - AND 1FH ;keep within range 0-31. - LD (HL),A - JP Z,GTNEXT1 ;overflow? - LD B,A ;mask extent byte. - LD A,(EXTMASK) - AND B - LD HL,CLOSEFLG ;check close flag (0ffh is ok). - AND (HL) - JP Z,GTNEXT2 ;if zero, we must read in next extent. - JP GTNEXT3 ;else, it is already in memory. -GTNEXT1:LD BC,2 ;Point to the 's2' byte. - ADD HL,BC - INC (HL) ;and bump it. - LD A,(HL) ;too many extents? - AND 0FH - JP Z,GTNEXT5 ;yes, set error code. -; -; Get here to open the next extent. -; -GTNEXT2:LD C,15 ;set to check first 15 bytes of fcb. - CALL FINDFST ;find the first one. - CALL CKFILPOS ;none available? - JP NZ,GTNEXT3 - LD A,(RDWRTFLG) ;no extent present. Can we open an empty one? - INC A ;0ffh means reading (so not possible). - JP Z,GTNEXT5 ;or an error. - CALL GETEMPTY ;we are writing, get an empty entry. - CALL CKFILPOS ;none? - JP Z,GTNEXT5 ;error if true. - JP GTNEXT4 ;else we are almost done. -GTNEXT3:CALL OPENIT1 ;open this extent. -GTNEXT4:CALL STRDATA ;move in updated data (rec #, extent #, etc.) - XOR A ;clear status and return. - JP SETSTAT -; -; Error in extending the file. Too many extents were needed -; or not enough space on the disk. -; -GTNEXT5:CALL IOERR1 ;set error code, clear bit 7 of 's2' - JP SETS2B7 ;so this is not written on a close. -; -; Read a sequential file. -; -RDSEQ: LD A,1 ;set sequential access mode. - LD (MODE),A -RDSEQ1: LD A,0FFH ;don't allow reading unwritten space. - LD (RDWRTFLG),A - CALL STRDATA ;put rec# and ext# into fcb. - LD A,(SAVNREC) ;get next record to read. - LD HL,SAVNXT ;get number of records in extent. - CP (HL) ;within this extent? - JP C,RDSEQ2 - CP 128 ;no. Is this extent fully used? - JP NZ,RDSEQ3 ;no. End-of-file. - CALL GETNEXT ;yes, open the next one. - XOR A ;reset next record to read. - LD (SAVNREC),A - LD A,(STATUS) ;check on open, successful? - OR A - JP NZ,RDSEQ3 ;no, error. -RDSEQ2: CALL COMBLK ;ok. compute block number to read. - CALL CHKBLK ;check it. Within bounds? - JP Z,RDSEQ3 ;no, error. - CALL LOGICAL ;convert (BLKNMBR) to logical sector (128 byte). - CALL TRKSEC1 ;set the track and sector for this block #. - CALL DOREAD ;and read it. - JP SETNREC ;and set the next record to be accessed. -; -; Read error occured. Set status and return. -; -RDSEQ3: JP IOERR1 -; -; Write the next sequential record. -; -WTSEQ: LD A,1 ;set sequential access mode. - LD (MODE),A -WTSEQ1: LD A,0 ;allow an addition empty extent to be opened. - LD (RDWRTFLG),A - CALL CHKWPRT ;check write protect status. - LD HL,(PARAMS) - CALL CKROF1 ;check for read only file, (HL) already set to fcb. - CALL STRDATA ;put updated data into fcb. - LD A,(SAVNREC) ;get record number to write. - CP 128 ;within range? - JP NC,IOERR1 ;no, error(?). - CALL COMBLK ;compute block number. - CALL CHKBLK ;check number. - LD C,0 ;is there one to write to? - JP NZ,WTSEQ6 ;yes, go do it. - CALL GETBLOCK ;get next block number within fcb to use. - LD (RELBLOCK),A ;and save. - LD BC,0 ;start looking for space from the start - OR A ;if none allocated as yet. - JP Z,WTSEQ2 - LD C,A ;extract previous block number from fcb - DEC BC ;so we can be closest to it. - CALL EXTBLK - LD B,H - LD C,L -WTSEQ2: CALL FNDSPACE ;find the next empty block nearest number (BC). - LD A,L ;check for a zero number. - OR H - JP NZ,WTSEQ3 - LD A,2 ;no more space? - JP SETSTAT -WTSEQ3: LD (BLKNMBR),HL ;save block number to access. - EX DE,HL ;put block number into (DE). - LD HL,(PARAMS) ;now we must update the fcb for this - LD BC,16 ;newly allocated block. - ADD HL,BC - LD A,(BIGDISK) ;8 or 16 bit block numbers? - OR A - LD A,(RELBLOCK) ;(* update this entry *) - JP Z,WTSEQ4 ;zero means 16 bit ones. - CALL ADDA2HL ;(HL)=(HL)+(A) - LD (HL),E ;store new block number. - JP WTSEQ5 -WTSEQ4: LD C,A ;compute spot in this 16 bit table. - LD B,0 - ADD HL,BC - ADD HL,BC - LD (HL),E ;stuff block number (DE) there. - INC HL - LD (HL),D -WTSEQ5: LD C,2 ;set (C) to indicate writing to un-used disk space. -WTSEQ6: LD A,(STATUS) ;are we ok so far? - OR A - RET NZ - PUSH BC ;yes, save write flag for bios (register C). - CALL LOGICAL ;convert (BLKNMBR) over to loical sectors. - LD A,(MODE) ;get access mode flag (1=sequential, - DEC A ;0=random, 2=special?). - DEC A - JP NZ,WTSEQ9 -; -; Special random i/o from function #40. Maybe for M/PM, but the -; current block, if it has not been written to, will be zeroed -; out and then written (reason?). -; - POP BC - PUSH BC - LD A,C ;get write status flag (2=writing unused space). - DEC A - DEC A - JP NZ,WTSEQ9 - PUSH HL - LD HL,(DIRBUF) ;zero out the directory buffer. - LD D,A ;note that (A) is zero here. -WTSEQ7: LD (HL),A - INC HL - INC D ;do 128 bytes. - JP P,WTSEQ7 - CALL DIRDMA ;tell the bios the dma address for directory access. - LD HL,(LOGSECT) ;get sector that starts current block. - LD C,2 ;set 'writing to unused space' flag. -WTSEQ8: LD (BLKNMBR),HL ;save sector to write. - PUSH BC - CALL TRKSEC1 ;determine its track and sector numbers. - POP BC - CALL DOWRITE ;now write out 128 bytes of zeros. - LD HL,(BLKNMBR) ;get sector number. - LD C,0 ;set normal write flag. - LD A,(BLKMASK) ;determine if we have written the entire - LD B,A ;physical block. - AND L - CP B - INC HL ;prepare for the next one. - JP NZ,WTSEQ8 ;continue until (BLKMASK+1) sectors written. - POP HL ;reset next sector number. - LD (BLKNMBR),HL - CALL DEFDMA ;and reset dma address. -; -; Normal disk write. Set the desired track and sector then -; do the actual write. -; -WTSEQ9: CALL TRKSEC1 ;determine track and sector for this write. - POP BC ;get write status flag. - PUSH BC - CALL DOWRITE ;and write this out. - POP BC - LD A,(SAVNREC) ;get number of records in file. - LD HL,SAVNXT ;get last record written. - CP (HL) - JP C,WTSEQ10 - LD (HL),A ;we have to update record count. - INC (HL) - LD C,2 -; -;* This area has been patched to correct disk update problem -;* when using blocking and de-blocking in the BIOS. -; -WTSEQ10:NOP ;was 'dcr c' - NOP ;was 'dcr c' - LD HL,0 ;was 'jnz wtseq99' -; -; * End of patch. -; - PUSH AF - CALL GETS2 ;set 'extent written to' flag. - AND 7FH ;(* clear bit 7 *) - LD (HL),A - POP AF ;get record count for this extent. -WTSEQ99:CP 127 ;is it full? - JP NZ,WTSEQ12 - LD A,(MODE) ;yes, are we in sequential mode? - CP 1 - JP NZ,WTSEQ12 - CALL SETNREC ;yes, set next record number. - CALL GETNEXT ;and get next empty space in directory. - LD HL,STATUS ;ok? - LD A,(HL) - OR A - JP NZ,WTSEQ11 - DEC A ;yes, set record count to -1. - LD (SAVNREC),A -WTSEQ11:LD (HL),0 ;clear status. -WTSEQ12:JP SETNREC ;set next record to access. -; -; For random i/o, set the fcb for the desired record number -; based on the 'r0,r1,r2' bytes. These bytes in the fcb are -; used as follows: -; -; fcb+35 fcb+34 fcb+33 -; | 'r-2' | 'r-1' | 'r-0' | -; |7 0 | 7 0 | 7 0| -; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| -; | overflow | | extra | extent | record # | -; | ______________| |_extent|__number___|_____________| -; also 's2' -; -; On entry, register (C) contains 0ffh if this is a read -; and thus we can not access unwritten disk space. Otherwise, -; another extent will be opened (for writing) if required. -; -POSITION: XOR A ;set random i/o flag. - LD (MODE),A -; -; Special entry (function #40). M/PM ? -; -POSITN1:PUSH BC ;save read/write flag. - LD HL,(PARAMS) ;get address of fcb. - EX DE,HL - LD HL,33 ;now get byte 'r0'. - ADD HL,DE - LD A,(HL) - AND 7FH ;keep bits 0-6 for the record number to access. - PUSH AF - LD A,(HL) ;now get bit 7 of 'r0' and bits 0-3 of 'r1'. - RLA - INC HL - LD A,(HL) - RLA - AND 1FH ;and save this in bits 0-4 of (C). - LD C,A ;this is the extent byte. - LD A,(HL) ;now get the extra extent byte. - RRA - RRA - RRA - RRA - AND 0FH - LD B,A ;and save it in (B). - POP AF ;get record number back to (A). - INC HL ;check overflow byte 'r2'. - LD L,(HL) - INC L - DEC L - LD L,6 ;prepare for error. - JP NZ,POSITN5 ;out of disk space error. - LD HL,32 ;store record number into fcb. - ADD HL,DE - LD (HL),A - LD HL,12 ;and now check the extent byte. - ADD HL,DE - LD A,C - SUB (HL) ;same extent as before? - JP NZ,POSITN2 - LD HL,14 ;yes, check extra extent byte 's2' also. - ADD HL,DE - LD A,B - SUB (HL) - AND 7FH - JP Z,POSITN3 ;same, we are almost done then. -; -; Get here when another extent is required. -; -POSITN2:PUSH BC - PUSH DE - CALL CLOSEIT ;close current extent. - POP DE - POP BC - LD L,3 ;prepare for error. - LD A,(STATUS) - INC A - JP Z,POSITN4 ;close error. - LD HL,12 ;put desired extent into fcb now. - ADD HL,DE - LD (HL),C - LD HL,14 ;and store extra extent byte 's2'. - ADD HL,DE - LD (HL),B - CALL OPENIT ;try and get this extent. - LD A,(STATUS) ;was it there? - INC A - JP NZ,POSITN3 - POP BC ;no. can we create a new one (writing?). - PUSH BC - LD L,4 ;prepare for error. - INC C - JP Z,POSITN4 ;nope, reading unwritten space error. - CALL GETEMPTY ;yes we can, try to find space. - LD L,5 ;prepare for error. - LD A,(STATUS) - INC A - JP Z,POSITN4 ;out of space? -; -; Normal return location. Clear error code and return. -; -POSITN3:POP BC ;restore stack. - XOR A ;and clear error code byte. - JP SETSTAT -; -; Error. Set the 's2' byte to indicate this (why?). -; -POSITN4:PUSH HL - CALL GETS2 - LD (HL),0C0H - POP HL -; -; Return with error code (presently in L). -; -POSITN5:POP BC - LD A,L ;get error code. - LD (STATUS),A - JP SETS2B7 -; -; Read a random record. -; -READRAN:LD C,0FFH ;set 'read' status. - CALL POSITION ;position the file to proper record. - CALL Z,RDSEQ1 ;and read it as usual (if no errors). - RET -; -; Write to a random record. -; -WRITERAN: LD C,0 ;set 'writing' flag. - CALL POSITION ;position the file to proper record. - CALL Z,WTSEQ1 ;and write as usual (if no errors). - RET -; -; Compute the random record number. Enter with (HL) pointing -; to a fcb an (DE) contains a relative location of a record -; number. On exit, (C) contains the 'r0' byte, (B) the 'r1' -; byte, and (A) the 'r2' byte. -; -; On return, the zero flag is set if the record is within -; bounds. Otherwise, an overflow occured. -; -COMPRAND: EX DE,HL ;save fcb pointer in (DE). - ADD HL,DE ;compute relative position of record #. - LD C,(HL) ;get record number into (BC). - LD B,0 - LD HL,12 ;now get extent. - ADD HL,DE - LD A,(HL) ;compute (BC)=(record #)+(extent)*128. - RRCA ;move lower bit into bit 7. - AND 80H ;and ignore all other bits. - ADD A,C ;add to our record number. - LD C,A - LD A,0 ;take care of any carry. - ADC A,B - LD B,A - LD A,(HL) ;now get the upper bits of extent into - RRCA ;bit positions 0-3. - AND 0FH ;and ignore all others. - ADD A,B ;add this in to 'r1' byte. - LD B,A - LD HL,14 ;get the 's2' byte (extra extent). - ADD HL,DE - LD A,(HL) - ADD A,A ;and shift it left 4 bits (bits 4-7). - ADD A,A - ADD A,A - ADD A,A - PUSH AF ;save carry flag (bit 0 of flag byte). - ADD A,B ;now add extra extent into 'r1'. - LD B,A - PUSH AF ;and save carry (overflow byte 'r2'). - POP HL ;bit 0 of (L) is the overflow indicator. - LD A,L - POP HL ;and same for first carry flag. - OR L ;either one of these set? - AND 01H ;only check the carry flags. - RET -; -; Routine to setup the fcb (bytes 'r0', 'r1', 'r2') to -; reflect the last record used for a random (or other) file. -; This reads the directory and looks at all extents computing -; the largerst record number for each and keeping the maximum -; value only. Then 'r0', 'r1', and 'r2' will reflect this -; maximum record number. This is used to compute the space used -; by a random file. -; -RANSIZE:LD C,12 ;look thru directory for first entry with - CALL FINDFST ;this name. - LD HL,(PARAMS) ;zero out the 'r0, r1, r2' bytes. - LD DE,33 - ADD HL,DE - PUSH HL - LD (HL),D ;note that (D)=0. - INC HL - LD (HL),D - INC HL - LD (HL),D -RANSIZ1:CALL CKFILPOS ;is there an extent to process? - JP Z,RANSIZ3 ;no, we are done. - CALL FCB2HL ;set (HL) pointing to proper fcb in dir. - LD DE,15 ;point to last record in extent. - CALL COMPRAND ;and compute random parameters. - POP HL - PUSH HL ;now check these values against those - LD E,A ;already in fcb. - LD A,C ;the carry flag will be set if those - SUB (HL) ;in the fcb represent a larger size than - INC HL ;this extent does. - LD A,B - SBC A,M - INC HL - LD A,E - SBC A,M - JP C,RANSIZ2 - LD (HL),E ;we found a larger (in size) extent. - DEC HL ;stuff these values into fcb. - LD (HL),B - DEC HL - LD (HL),C -RANSIZ2:CALL FINDNXT ;now get the next extent. - JP RANSIZ1 ;continue til all done. -RANSIZ3:POP HL ;we are done, restore the stack and - RET ;return. -; -; Function to return the random record position of a given -; file which has been read in sequential mode up to now. -; -SETRAN: LD HL,(PARAMS) ;point to fcb. - LD DE,32 ;and to last used record. - CALL COMPRAND ;compute random position. - LD HL,33 ;now stuff these values into fcb. - ADD HL,DE - LD (HL),C ;move 'r0'. - INC HL - LD (HL),B ;and 'r1'. - INC HL - LD (HL),A ;and lastly 'r2'. - RET -; -; This routine select the drive specified in (ACTIVE) and -; update the login vector and bitmap table if this drive was -; not already active. -; -LOGINDRV: LD HL,(LOGIN) ;get the login vector. - LD A,(ACTIVE) ;get the default drive. - LD C,A - CALL SHIFTR ;position active bit for this drive - PUSH HL ;into bit 0. - EX DE,HL - CALL SELECT ;select this drive. - POP HL - CALL Z,SLCTERR ;valid drive? - LD A,L ;is this a newly activated drive? - RRA - RET C - LD HL,(LOGIN) ;yes, update the login vector. - LD C,L - LD B,H - CALL SETBIT - LD (LOGIN),HL ;and save. - JP BITMAP ;now update the bitmap. -; -; Function to set the active disk number. -; -SETDSK: LD A,(EPARAM) ;get parameter passed and see if this - LD HL,ACTIVE ;represents a change in drives. - CP (HL) - RET Z - LD (HL),A ;yes it does, log it in. - JP LOGINDRV -; -; This is the 'auto disk select' routine. The firsst byte -; of the fcb is examined for a drive specification. If non -; zero then the drive will be selected and loged in. -; -AUTOSEL:LD A,0FFH ;say 'auto-select activated'. - LD (AUTO),A - LD HL,(PARAMS) ;get drive specified. - LD A,(HL) - AND 1FH ;look at lower 5 bits. - DEC A ;adjust for (1=A, 2=B) etc. - LD (EPARAM),A ;and save for the select routine. - CP 1EH ;check for 'no change' condition. - JP NC,AUTOSL1 ;yes, don't change. - LD A,(ACTIVE) ;we must change, save currently active - LD (OLDDRV),A ;drive. - LD A,(HL) ;and save first byte of fcb also. - LD (AUTOFLAG),A ;this must be non-zero. - AND 0E0H ;whats this for (bits 6,7 are used for - LD (HL),A ;something)? - CALL SETDSK ;select and log in this drive. -AUTOSL1:LD A,(USERNO) ;move user number into fcb. - LD HL,(PARAMS) ;(* upper half of first byte *) - OR (HL) - LD (HL),A - RET ;and return (all done). -; -; Function to return the current cp/m version number. -; -GETVER: LD A,022H ;version 2.2 - JP SETSTAT -; -; Function to reset the disk system. -; -RSTDSK: LD HL,0 ;clear write protect status and log - LD (WRTPRT),HL ;in vector. - LD (LOGIN),HL - XOR A ;select drive 'A'. - LD (ACTIVE),A - LD HL,TBUFF ;setup default dma address. - LD (USERDMA),HL - CALL DEFDMA - JP LOGINDRV ;now log in drive 'A'. -; -; Function to open a specified file. -; -OPENFIL:CALL CLEARS2 ;clear 's2' byte. - CALL AUTOSEL ;select proper disk. - JP OPENIT ;and open the file. -; -; Function to close a specified file. -; -CLOSEFIL: CALL AUTOSEL ;select proper disk. - JP CLOSEIT ;and close the file. -; -; Function to return the first occurence of a specified file -; name. If the first byte of the fcb is '?' then the name will -; not be checked (get the first entry no matter what). -; -GETFST: LD C,0 ;prepare for special search. - EX DE,HL - LD A,(HL) ;is first byte a '?'? - CP '?' - JP Z,GETFST1 ;yes, just get very first entry (zero length match). - CALL SETEXT ;get the extension byte from fcb. - LD A,(HL) ;is it '?'? if yes, then we want - CP '?' ;an entry with a specific 's2' byte. - CALL NZ,CLEARS2 ;otherwise, look for a zero 's2' byte. - CALL AUTOSEL ;select proper drive. - LD C,15 ;compare bytes 0-14 in fcb (12&13 excluded). -GETFST1:CALL FINDFST ;find an entry and then move it into - JP MOVEDIR ;the users dma space. -; -; Function to return the next occurence of a file name. -; -GETNXT: LD HL,(SAVEFCB) ;restore pointers. note that no - LD (PARAMS),HL ;other dbos calls are allowed. - CALL AUTOSEL ;no error will be returned, but the - CALL FINDNXT ;results will be wrong. - JP MOVEDIR -; -; Function to delete a file by name. -; -DELFILE:CALL AUTOSEL ;select proper drive. - CALL ERAFILE ;erase the file. - JP STSTATUS ;set status and return. -; -; Function to execute a sequential read of the specified -; record number. -; -READSEQ:CALL AUTOSEL ;select proper drive then read. - JP RDSEQ -; -; Function to write the net sequential record. -; -WRTSEQ: CALL AUTOSEL ;select proper drive then write. - JP WTSEQ -; -; Create a file function. -; -FCREATE:CALL CLEARS2 ;clear the 's2' byte on all creates. - CALL AUTOSEL ;select proper drive and get the next - JP GETEMPTY ;empty directory space. -; -; Function to rename a file. -; -RENFILE:CALL AUTOSEL ;select proper drive and then switch - CALL CHGNAMES ;file names. - JP STSTATUS -; -; Function to return the login vector. -; -GETLOG: LD HL,(LOGIN) - JP GETPRM1 -; -; Function to return the current disk assignment. -; -GETCRNT:LD A,(ACTIVE) - JP SETSTAT -; -; Function to set the dma address. -; -PUTDMA: EX DE,HL - LD (USERDMA),HL ;save in our space and then get to - JP DEFDMA ;the bios with this also. -; -; Function to return the allocation vector. -; -GETALOC:LD HL,(ALOCVECT) - JP GETPRM1 -; -; Function to return the read-only status vector. -; -GETROV: LD HL,(WRTPRT) - JP GETPRM1 -; -; Function to set the file attributes (read-only, system). -; -SETATTR:CALL AUTOSEL ;select proper drive then save attributes. - CALL SAVEATTR - JP STSTATUS -; -; Function to return the address of the disk parameter block -; for the current drive. -; -GETPARM:LD HL,(DISKPB) -GETPRM1:LD (STATUS),HL - RET -; -; Function to get or set the user number. If (E) was (FF) -; then this is a request to return the current user number. -; Else set the user number from (E). -; -GETUSER:LD A,(EPARAM) ;get parameter. - CP 0FFH ;get user number? - JP NZ,SETUSER - LD A,(USERNO) ;yes, just do it. - JP SETSTAT -SETUSER:AND 1FH ;no, we should set it instead. keep low - LD (USERNO),A ;bits (0-4) only. - RET -; -; Function to read a random record from a file. -; -RDRANDOM: CALL AUTOSEL ;select proper drive and read. - JP READRAN -; -; Function to compute the file size for random files. -; -WTRANDOM: CALL AUTOSEL ;select proper drive and write. - JP WRITERAN -; -; Function to compute the size of a random file. -; -FILESIZE: CALL AUTOSEL ;select proper drive and check file length - JP RANSIZE -; -; Function #37. This allows a program to log off any drives. -; On entry, set (DE) to contain a word with bits set for those -; drives that are to be logged off. The log-in vector and the -; write protect vector will be updated. This must be a M/PM -; special function. -; -LOGOFF: LD HL,(PARAMS) ;get drives to log off. - LD A,L ;for each bit that is set, we want - CPL ;to clear that bit in (LOGIN) - LD E,A ;and (WRTPRT). - LD A,H - CPL - LD HL,(LOGIN) ;reset the login vector. - AND H - LD D,A - LD A,L - AND E - LD E,A - LD HL,(WRTPRT) - EX DE,HL - LD (LOGIN),HL ;and save. - LD A,L ;now do the write protect vector. - AND E - LD L,A - LD A,H - AND D - LD H,A - LD (WRTPRT),HL ;and save. all done. - RET -; -; Get here to return to the user. -; -GOBACK: LD A,(AUTO) ;was auto select activated? - OR A - JP Z,GOBACK1 - LD HL,(PARAMS) ;yes, but was a change made? - LD (HL),0 ;(* reset first byte of fcb *) - LD A,(AUTOFLAG) - OR A - JP Z,GOBACK1 - LD (HL),A ;yes, reset first byte properly. - LD A,(OLDDRV) ;and get the old drive and select it. - LD (EPARAM),A - CALL SETDSK -GOBACK1:LD HL,(USRSTACK) ;reset the users stack pointer. - LD SP,HL - LD HL,(STATUS) ;get return status. - LD A,L ;force version 1.4 compatability. - LD B,H - RET ;and go back to user. -; -; Function #40. This is a special entry to do random i/o. -; For the case where we are writing to unused disk space, this -; space will be zeroed out first. This must be a M/PM special -; purpose function, because why would any normal program even -; care about the previous contents of a sector about to be -; written over. -; -WTSPECL:CALL AUTOSEL ;select proper drive. - LD A,2 ;use special write mode. - LD (MODE),A - LD C,0 ;set write indicator. - CALL POSITN1 ;position the file. - CALL Z,WTSEQ1 ;and write (if no errors). - RET -; -;************************************************************** -;* -;* BDOS data storage pool. -;* -;************************************************************** -; -EMPTYFCB: DEFB 0E5H ;empty directory segment indicator. -WRTPRT: DEFW 0 ;write protect status for all 16 drives. -LOGIN: DEFW 0 ;drive active word (1 bit per drive). -USERDMA:DEFW 080H ;user's dma address (defaults to 80h). -; -; Scratch areas from parameter block. -; -SCRATCH1: DEFW 0 ;relative position within dir segment for file (0-3). -SCRATCH2: DEFW 0 ;last selected track number. -SCRATCH3: DEFW 0 ;last selected sector number. -; -; Disk storage areas from parameter block. -; -DIRBUF: DEFW 0 ;address of directory buffer to use. -DISKPB: DEFW 0 ;contains address of disk parameter block. -CHKVECT:DEFW 0 ;address of check vector. -ALOCVECT: DEFW 0 ;address of allocation vector (bit map). -; -; Parameter block returned from the bios. -; -SECTORS:DEFW 0 ;sectors per track from bios. -BLKSHFT:DEFB 0 ;block shift. -BLKMASK:DEFB 0 ;block mask. -EXTMASK:DEFB 0 ;extent mask. -DSKSIZE:DEFW 0 ;disk size from bios (number of blocks-1). -DIRSIZE:DEFW 0 ;directory size. -ALLOC0: DEFW 0 ;storage for first bytes of bit map (dir space used). -ALLOC1: DEFW 0 -OFFSET: DEFW 0 ;first usable track number. -XLATE: DEFW 0 ;sector translation table address. -; -; -CLOSEFLG: DEFB 0 ;close flag (=0ffh is extent written ok). -RDWRTFLG: DEFB 0 ;read/write flag (0ffh=read, 0=write). -FNDSTAT:DEFB 0 ;filename found status (0=found first entry). -MODE: DEFB 0 ;I/o mode select (0=random, 1=sequential, 2=special random). -EPARAM: DEFB 0 ;storage for register (E) on entry to bdos. -RELBLOCK: DEFB 0 ;relative position within fcb of block number written. -COUNTER:DEFB 0 ;byte counter for directory name searches. -SAVEFCB:DEFW 0,0 ;save space for address of fcb (for directory searches). -BIGDISK:DEFB 0 ;if =0 then disk is > 256 blocks long. -AUTO: DEFB 0 ;if non-zero, then auto select activated. -OLDDRV: DEFB 0 ;on auto select, storage for previous drive. -AUTOFLAG: DEFB 0 ;if non-zero, then auto select changed drives. -SAVNXT: DEFB 0 ;storage for next record number to access. -SAVEXT: DEFB 0 ;storage for extent number of file. -SAVNREC:DEFW 0 ;storage for number of records in file. -BLKNMBR:DEFW 0 ;block number (physical sector) used within a file or logical sect -LOGSECT:DEFW 0 ;starting logical (128 byte) sector of block (physical sector). -FCBPOS: DEFB 0 ;relative position within buffer for fcb of file of interest. -FILEPOS:DEFW 0 ;files position within directory (0 to max entries -1). -; -; Disk directory buffer checksum bytes. One for each of the -; 16 possible drives. -; -CKSUMTBL: DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; Extra space ? -; - DEFB 0,0,0,0 -; -;************************************************************** -;* -;* B I O S J U M P T A B L E -;* -;************************************************************** -; -BOOT: JP 0 ;NOTE WE USE FAKE DESTINATIONS -WBOOT: JP 0 -CONST: JP 0 -CONIN: JP 0 -CONOUT: JP 0 -LIST: JP 0 -PUNCH: JP 0 -READER: JP 0 -HOME: JP 0 -SELDSK: JP 0 -SETTRK: JP 0 -SETSEC: JP 0 -SETDMA: JP 0 -READ: JP 0 -WRITE: JP 0 -PRSTAT: JP 0 -SECTRN: JP 0 -; -;* -;****************** E N D O F C P / M ***************** -;* - diff --git a/cpm/cpm2-asm/READ.ME b/cpm/cpm2-asm/READ.ME deleted file mode 100644 index a648386..0000000 --- a/cpm/cpm2-asm/READ.ME +++ /dev/null @@ -1,9 +0,0 @@ -The two files in this ZIP file are disassembled CP/M 2.2. - - CPM22.ASM : CP/M 2.2 in 8080 mnemonics - CPM22.Z80 : CP/M 2.2 in Z80 mnemonics - -Both files claim to implement a fix that affects operation in a sector -deblocking environment. The Z80 version does not look to have been optimized -for the Z80, it just uses Z80 mnemonics. - diff --git a/cpm/pcpm/BDOS.MAC b/cpm/pcpm/BDOS.MAC deleted file mode 100644 index fa6949a..0000000 --- a/cpm/pcpm/BDOS.MAC +++ /dev/null @@ -1,4190 +0,0 @@ -.z80 - subttl Copyright Information - title Personal CP/M BDOS, Version 1.0, April 1984 -;***************************************************************** -;***************************************************************** -;** ** -;** P E R S O N A L C P / M ** -;** ** -;** B a s i c D i s k O p e r a t i n g S y s t e m ** -;** ** -;** I n t e r f a c e M o d u l e ** -;** ** -;***************************************************************** -;***************************************************************** -; -; Copyright (c) 1984 -; Digital Research -; Box 579, Pacific Grove -; California - - subttl Equates - -on equ 0ffffh -off equ 00000h - -data_low equ on ;code segment will be at lower address - ;than data segment - -standard equ on ;data not in separate segment - - org 0000H -BASE equ $ - -; bios value defined at end of module - -SSIZE equ 32 ;32 level stack - -; low memory locations - -reboot equ 0000h ;reboot system - -; -; equates for non graphic characters -; -ctlc equ 03h ;control c -ctle equ 05h ;physical eol -ctlh equ 08h ;backspace -ctlp equ 10h ;prnt toggle -ctlr equ 12h ;repeat line -ctls equ 13h ;stop/start screen -ctlu equ 15h ;line delete -ctlx equ 18h ;=ctl-u -ctlz equ 1Ah ;end of file -rubout equ 7Fh ;char delete -tab equ 09h ;tab char -cr equ 0Dh ;carriage return -lf equ 0Ah ;line feed -ctl equ 5Eh ;up arrow - - subttl PUBLICs and EXTRNs - - name ('BDOS') - - cseg - - ;used - ; by - public BDOS$CD - public BDOS$DT - public ?bdos - public ?bdosc - public ?bdosw - - ;defined in - - extrn ?flush ;bios - extrn ?discd ;bios - extrn ?mov ;bios - extrn ?auxis ;bios - extrn ?auxos ;bios - extrn ?dscrf ;bios - extrn ?bytbc ;bios - extrn ?bytba ;bios - - subttl BDOS Front End -BDOS$CD: - defb '654321' - -; enter here from the user's program with function number in c, -; and information address in d,e - - if not data_low -?bdos: - endif - - jp bdose ;past parameter block - - defw SUB$FLAG - defw OLOG - -front_size equ $-bdos$cd ;size of block to load to front of - ;data segment - -bdose: ;arrive here from user programs - ld (info),de ;info = DE - - ld A,C ;FX=BDOS FUNCTION NUMBER - ld (FX),a - - ld a,(ACTDSK) ;SELDSK=ACTDSK - ld (SELDSK),a - - ld hl,0 ;return value defaults to 0000 - ld (aret),hl - - ld (RESEL),hl ; RESEL,RELOG = FALSE - -;save user's stack pointer, set to local stack - ld (entsp),sp ;entsp = SP - - ld sp,lstack ;local stack setup - ld hl,goback ;return here after all functions - push hl ;jmp goback equivalent to ret - ld A,C - cp nfuncs - jr nc,HIGH$FX - - ld C,E ;possible output character to C - ld hl,functab -DISPATCH: - ld E,A ;DE=func, HL=.ciotab - ld D,0 - - add hl,de ;DE=functab(func) - add hl,de - ld E,(hl) - inc hl - ld D,(hl) - - ld hl,(info) ;info in DE for later xchg - ex de,hl ;dispatched - jp (hl) - subttl Imbedded copyright message - - defb 'COPYRIGHT (C) 1984, ' - defb 'DIGITAL RESEARCH ' - defb '042384' - subttl - -HIGH$FX: - cp 45 - jp z,FUNC45 - - cp 48 - jp z,FUNC48 - - cp 124 - jp z,func124 - - cp 125 - jp z,func125 - - ld hl,XFUNCTAB - sub 109 ; RETURN IF FX < 109 - ret c - - cp XNFUNCS ; RETURN IF FX >= 109 + XNFUNCS - ret nc - - jr DISPATCH - - subttl Cold & Warm Start Initialization -?bdosc: ;COLD START INITIALIZATION ROUTINE - call FUNC13 - ld C,CS$INIT$SIZE - jr WS$INIT0 - -?bdosw: ;WARM START INITIALIZATION ROUTINE - ld C,WS$INIT$SIZE -WS$INIT0: - xor A - ld hl,COLUMN - -WS$INIT1: - ld (hl),A - inc hl - dec C - jr nz,WS$INIT1 - - if data_low - ld bc,front_size ;move an image of the front of the BDOS code - ld de,bdos$dt ;segment to the front of the data segment for - ld hl,bdos$cd ;systems with data lower in RAM - ldir - endif - - ld A,'$' - ld (OUT$DELIM),a - - call SCAN$DRIVE - jp NOSELECT1 - subttl Dispatch Table for Functions -functab: - defw wbootf,func1,func2,func3 - defw punchf,listf,func6,func7 - defw func8,func9,func10,func11 -diskf equ ($-functab)/2 ;disk funcs - defw func12,func13,func14,func15 - defw func16,func17,func18,func19 - defw func20,func21,func22,func23 - defw func24,func25,func26,func27 - defw func28,func29,func30,func31 - defw func32,func33,func34,func35 - defw func36,func37,func38,func39 - defw func40 -nfuncs equ ($-functab)/2 - -XFUNCTAB: - defw FUNC109,FUNC110,FUNC111,FUNC112,FUNC113 -XNFUNCS equ ($-XFUNCTAB)/2 - subttl Error Subroutine - -ERROR: ; C = ERROR #, A = FF => RETURN & DISPLAY MODE - push af - push bc - call CPMERR - pop bc - pop af - inc A - ret z - - dec C - call z,RESET$DRIVE - call CONINF - jp WBOOTF - subttl Console Handlers - -conin: -;read console character to A - ld hl,kbchar - ld A,(hl) - ld (hl),0 - or A - ret nz - - ;no previous keyboard character ready - jp coninf ;get character externally - ;ret - -conech: ;read character with echo - call conin - call echoc - jr c,CONECH1 - -;character must be echoed before return - push af - ld C,A - call tabout - pop af - ret ;with character in A - -CONECH1: - cp CTLS - ret nz - - call CONBS - jr CONECH - -echoc: -;echo character if graphic -;cr, lf, tab, or backspace - cp cr - ret z ;carriage return? - - cp lf - ret z ;line feed? - - cp tab - ret z ;tab? - - cp ctlh - ret z ;backspace? - - cp ' ' - ret ;carry set if not graphic - -CONBRKX: - ld a,(KBCHAR) - or A - jr nz,CONB1 - -CONBRKX1: - call CONSTF - and 1 - ret - -conbrk: ;check for character ready - ld a,(KBCHAR) - or A - jr nz,CONB1 - -CONBRK1: - call CONBRKX1 - ret z ; RETURN IF CHARACTER NOT READY - -;character ready, read it - call coninf ;to A - cp ctls - jr nz,conb0 ;check stop screen function - -CONBS: -;found ctls, read next character - call coninf ;to A - cp ctlc - jp z,reboot ;ctlc implies re-boot - -;not a reboot, act as if nothing has happened - xor A - ret ;with zero in accumulator - -conb0: -;character in accum, save it - ld (kbchar),a -conb1: -;return with true set in accumulator - ld A,-1 - ret - -conout: -;compute character position/write console char from C -;compcol = true if computing column position - ld a,(compcol) - or A - jr nz,compout - -;write the character, then compute the column -;write console character from C - push bc - call CONBRK1 ;check for screen stop function - pop bc - push bc ;recall/save character - call conoutf ;externally, to console - ;may be copying to the list device - ld a,(listcp) - or A - call nz,listf ;to printer, if so - pop bc ;recall the character -compout: - ld A,C ;recall the character - ;and compute column position - ld hl,column ;A = char, HL = .column - cp rubout - ret z ;no column change if nulls - - inc (hl) ;column = column + 1 - cp ' ' - ret nc ;return if graphic - -;not graphic, reset column position - dec (hl) ;column = column - 1 - ld A,(hl) - or A - ret z ;return if at zero - -;not at zero, may be backspace or end line - ld A,C ;character back to A - cp ctlh - jr nz,notbacksp - -;backspace character - dec (hl) ;column = column - 1 - ret - -notbacksp: -;not a backspace character, eol? - cp lf - ret nz ;return if not - -;end of line, column = 0 - ld (hl),0 ;column = 0 - ret - -ctlout: -;send C character with possible preceding up-arrow - ld A,C - call echoc ;cy if not graphic (or special case) - jr nc,tabout ;skip if graphic, tab, cr, lf, or ctlh - -;send preceding up arrow - push af - ld C,ctl - call conout ;up arrow - pop af - or 40h ;becomes graphic letter - ld C,A ;ready to print - ;(drop through to tabout) - -tabout: -;expand tabs to console - ld a,(FX) - dec A - jr z,TABOUT1 - - ld a,(CONMODE) - and 10H - jp nz,CONOUTF - -TABOUT1: - ld A,C - cp tab - jr nz,conout ;direct to conout if not - -;tab encountered, move to next tab position -tab0: - ld C,' ' - call conout ;another blank - ld a,(column) - and 111b ;column mod 8 = 0 ? - jr nz,tab0 ;back for another if not - - ret - -backup: -;back-up one screen position - call pctlh - ld C,' ' - call conoutf - ;(drop through to pctlh) - -pctlh: -;send ctlh to console without affecting column count - ld C,ctlh - jp conoutf - ;ret - -crlfp: -;print #, cr, lf for ctlx, ctlu, ctlr functions -;then move to strtcol (starting column) - ld C,'#' - call conout - call crlf - -;column = 0, move to position strtcol -crlfp0: - ld a,(column) - ld hl,strtcol - cp (hl) - ret nc ;stop when column reaches strtcol - - ld C,' ' - call conout ;print blank - jr crlfp0 - -crlf: -;carriage return line feed sequence - ld C,cr - call conout - ld C,lf - jp conout - ;ret - -print: -;print message until M(BC) = '$' - ld hl,OUT$DELIM - ld a,(bc) - cp (hl) - ret z ;stop on $ - -;more to print - inc bc - push bc - ld C,A ;char to C - call tabout ;another character printed - pop bc - jr print - -read: ;read to info address (max length, current length, buffer) - ld A,1 - ld (FX),a - ld a,(column) - ld (strtcol),a ;save start for ctl-x, ctl-h - ld hl,(info) - ld C,(hl) - inc hl - push hl - xor A - ld B,A - ld (SAVE$POS),a - -;B = current buffer length, -;C = maximum buffer length, -;HL= next to fill - 1 -readnx: -;read next character, BC, HL active - push bc - push hl ;blen, cmax, HL saved -readn0: - call conin ;next char in A - pop hl - pop bc ;reactivate counters - cp cr - jp z,readen ;end of line? - - cp lf - jp z,readen ;also end of line - - cp ctlh - jr nz,noth ;backspace? - -;do we have any characters to back over? - ld a,(STRTCOL) - ld D,A - ld a,(COLUMN) - cp D - jr z,readnx - - ld (COMPCOL),a ;COL>0 -;characters remain in buffer, can we backup one - ld a,b ;check character count SCC 22 Apr 84 - or a ; SCC 22 Apr 84 - jr z,linelen ;already 0, don't decr SCC 22 Apr 84 - - dec B ;remove one character -;compcol > 0 marks repeat as length compute - jr linelen ;uses same code as repeat -noth: -;not a backspace - cp rubout - jr nz,notrub ;rubout char? - -;rubout encountered, rubout if possible - ld A,B - or A - jr z,readnx ;skip if len=0 - -;buffer has characters, resend last char - ld A,(hl) - dec B - dec hl ;A = last char -;blen=blen-1, next to fill - 1 decremented - jp rdech1 ;act like this is an echo - -notrub: -;not a rubout character, check end line - cp ctle - jr nz,note ;physical end line? - -;yes, save active counters and force eol - push bc - ld A,B - ld (SAVE$POS),a - push hl - call crlf - xor A - ld (strtcol),a ;start position = 00 - jr readn0 ;for another character - -note: -;not end of line, list toggle? - cp ctlp - jr nz,notp ;skip if not ctlp - -;list toggle - change parity - push hl ;save next to fill - 1 - ld hl,listcp ;HL=.listcp flag - ld A,1 - sub (hl) ;True-listcp - ld (hl),A ;listcp = not listcp - pop hl - jr readnx ;for another char - -notp: -;not a ctlp, line delete? - cp ctlx - jr nz,notx - - pop hl ;discard start position -;loop while column > strtcol -backx: - ld a,(strtcol) - ld hl,column - cp (hl) - jr nc,read ;start again - - dec (hl) ;column = column - 1 - call backup ;one position - jr backx - -notx: -;not control-X, control-U? - cp ctlu - jr nz,notu ;skip if not - -;delete line (ctlu) - call crlfp ;physical eol - pop hl ;discard starting position - jp read ;to start all over - -notu: -;not line delete, repeat line? - cp ctlr - jr nz,notr - - xor A - ld (SAVE$POS),a -linelen: -;repeat line, or compute line len (ctlh) -;if compcol > 0 - push bc - call crlfp ;save line length - pop bc - pop hl - push hl - push bc -;bcur, cmax active, beginning buff at HL -rep0: - ld A,B - or A - jr z,rep1 ;count len to 00 - - inc hl - ld C,(hl) ;next to print - dec B - pop de - push de - ld A,D - sub B - ld D,A - push bc - push hl ;count length down - ld a,(save$pos) - cp D - call c,CTLOUT ;character echoed - pop hl - pop bc ;recall remaining count - jr rep0 ;for the next character - -rep1: -;end of repeat, recall lengths -;original BC still remains pushed - push hl ;save next to fill - ld a,(compcol) - or A ;>0 if computing length - jp z,readn0 ;for another char if so - -;column position computed for ctlh - ld hl,column - sub (hl) ;diff > 0 - ld (compcol),a ;count down below -;move back compcol-column spaces -backsp: -;move back one more space - call backup ;one space - ld hl,compcol - dec (hl) - jr nz,backsp - - jp readn0 ;for next character - -notr: -;not a ctlr, place into buffer -rdecho: - inc hl - ld (hl),A ;character filled to mem - inc B ;blen = blen + 1 -rdech1: -;look for a random control character - push bc - push hl ;active values saved - ld C,A ;ready to print - call ctlout ;may be up-arrow C - pop hl - pop bc - ld A,(hl) ;recall char - cp ctlc ;set flags for reboot test - ld A,B ;move length to A - jr nz,notc ;skip if not a control c - - cp 1 ;control C, must be length 1 - jp z,reboot ;reboot if blen = 1 - - ;length not one, so skip reboot -notc: - ;not reboot, are we at end of buffer? - cp C - jp c,readnx ;go for another if not - -readen: -;end of read operation, store blen - pop hl - ld (hl),B ;M(current len) = B - ld C,cr - jp conout ;return carriage - ;ret - - subttl Character I/O Functions -func1: -;return console character with echo - call conech - jr sta$ret - -func2 equ tabout -;write console character with tab expansion - -func3: -;return reader character - call readerf - jr sta$ret - -;func4: equated to punchf -;write punch character - -;func5: equated to listf -;write list character -;write to list device - -func6: -;direct console i/o - read if 0FFh - ld A,C - inc A - jr z,dirinp ;0FFh => 00h, means input mode - - inc A - jp nz,CONOUTF ;DIRECT OUTPUT FUNCTION - -;0FEh => STATUS - call CONBRKX - ret z - - jp LRET$EQ$FF - -dirinp: - call CONBRKX ;status check - ret z ;skip, return 00 if not ready - -;character is ready, get it - call CONIN ;to A - jr sta$ret - -FUNC7: ;READER STATUS - call ?auxis - jr STA$RET - -FUNC8: ;PUNCH STATUS - call ?auxos - jr STA$RET - -func9: -;write line until $ encountered - ex de,hl ;was lhld info - ld C,L - ld B,H ;BC=string address - jp print ;out to console - -func10 equ read -;read a buffered console line - -func11: -;check console status - call conbrk - ;(drop through to sta$ret) - -sta$ret: -;store the A register to aret - ld (aret),a -func$ret: - ret ;jmp goback (pop stack for non cp/m functions) - -setlret1: -;set lret = 1 - ld A,1 - jr sta$ret - subttl CP/M-Plus Function -FUNC109: ;GET/SET CONSOLE MODE - -; CONMODE BITS = 7 6 5 4 3 2 1 0 -; DEFINED BITS = 4 -; -; BIT 4 = 0: Normal BDOS operation -; 1: Supress BDOS expansion of tabs, ^P and ^S handling on -; console output - - ld hl,CONMODE -TEST$SET: - ld A,D - and E - inc A - ld A,(hl) - jr z,STA$RET - - ld (hl),E - ret - -FUNC110: ;GET/SET OUTPUT DELIMITER - ld hl,OUT$DELIM - jr TEST$SET - -FUNC111: ;PRINT BLOCK TO CONSOLE - -FUNC112: ;PRINT BLOCK TO LIST -; - ex de,hl - ld E,(hl) - inc hl - ld D,(hl) - inc hl - ld C,(hl) - inc hl - ld B,(hl) - ex de,hl -;HL = ADDR OF STRING -;BC = LENGTH OF STRING -BLK$OUT: - ld A,B - or C - ret z - - push bc - push hl - ld C,(hl) - call BLK$OUT1 - pop hl - inc hl - pop bc - dec bc - jr BLK$OUT - -BLK$OUT1: - ld a,(FX) - rra - jp c,TABOUT - - jp LISTF - subttl New Personal CP/M Functions -FUNC113: ;PERFORM SCREEN FUNCTION - call ?dscrf - jp sthl$ret - -func124: ;Byte BLT copy - call ?bytbc - jr sta$ret - -func125: ;Byte BLT alter - call ?bytba - jr sta$ret - -; -; end of Basic I/O System - - subttl BDOS Disk functions - -;***************************************************************** -;***************************************************************** -;** ** -;** B a s i c D i s k O p e r a t i n g S y s t e m ** -;** ** -;***************************************************************** -;***************************************************************** - -dvers equ 28h ;Personal CP/M 1.0 - -; -; module addresses -; - -;;; literal constants - -true equ 0ffh ;constant true -false equ 000h ;constant false -enddir equ 0ffffh ;end of directory -byte equ 1 ;number of bytes for "byte" type -word equ 2 ;number of bytes for "word" type - -; -; fixed addresses in low memory -; - -tfcb equ 005ch ;default fcb location -tbuff equ 0080h ;default buffer location - subttl -; -; error message handlers -; - -rod$error: -;report read/only disk error - ld C,2 - jr GOERR - -rof$error: -;report read/only file error - ld C,3 - jr GOERR - -sel$error: - call RESET$DRIVE -;report select error - ld C,4 - -goerr: - ld H,C - ld L,0FFH - ld (ARET),hl - -GOERR1: - ld a,(ERRMODE) - inc A - call nz,ERROR - - ld A,0FFH - ld (CURDSK),a - - ld a,(FX) - cp 27 - jp z,GOBACK0 - - cp 31 - jp z,GOBACK0 - - jp GOBACK - subttl Local Subroutines for Bios Interface -MOVE: - ld B,0 ;move number of bytes in C -; -MOVEX: - call ?mov - ret - subttl Select Disk -selectdisk: - -;select the disk drive given by register D, and fill -;the base addresses curtrka - alloca, then fill -;the values of the disk parameter block - - ld C,D ;current disk# to c - ld hl,LSN$NS - ld B,0 - add hl,bc - ld (LSN$ADD),hl -;lsb of e = 0 if not yet logged - in - call seldskf ;HL filled by call -;HL = 0000 if error, otherwise disk headers - ld A,H - or L - ret z ;return with 0000 in HL and z flag - -;disk header block address in hl - ld E,(hl) - inc hl - ld D,(hl) - inc hl ;DE=.tran - ld (cdrmaxa),hl - inc hl - inc hl ;.cdrmax - ld (curtrka),hl - inc hl - inc hl ;HL=.currec - ld (curreca),hl - inc hl - inc hl ;HL=.buffa - -;DE still contains .tran - - ex de,hl - ld (tranv),hl ;.tran vector - ld hl,buffa ;DE= source for move, HL=dest - ld C,addlist - call move ;addlist filled - -;now fill the disk parameter block - - ld de,(dpbaddr) ;DE is source - ld hl,sectpt ;HL is destination - ld C,dpblist - call move ;data filled - -;now set single/double map mode - - ld hl,(maxall) ;largest allocation number - ld A,H ;00 indicates < 255 - ld hl,single - ld (hl),true ;assume a=00 - or A - jr z,retselect - -;high order of maxall not zero, use double dm - - ld (hl),false - -retselect: - - scf - ret ;select disk function ok - subttl HOME - move to track 0, sector 0 - -home: - -;move to home position, then offset to start of dir - - call homef ;move to track 00, sector 00 reference - -;lxi h,offset ;mov c,m ;inx h ;mov b,m ;call settrkf ; -;first directory position selected - - xor A ;constant zero to accumulator - ld hl,(curtrka) - ld (hl),A - inc hl - ld (hl),A ;curtrk=0000 - ld hl,(curreca) - ld (hl),A - inc hl - ld (hl),A ;currec=0000 - -;curtrk, currec both set to 0000 - - ret - subttl RDBUFF & WRBUFF - read & write disk buffers - -rdbuff: -;read buffer and check condition - ld a,1 - call readf ;current drive, track, sector, dma - jr diocomp ;check for i/o errors - -wrbuff: -;write buffer and check condition -;write type (wrtype) is in register C -;wrtype = 0 => normal write operation -;wrtype = 1 => directory write operation -;wrtype = 2 => start of new block - - call writef ;current drive, track, sector, dma - -diocomp: ;check for disk errors - - or A - ret z - - ld C,A - jp GOERR - subttl SEEK$DIR - seek the record containing the current dir entry - -seek$dir: - - ld hl,(dcnt) ;directory counter to HL - ld C,dskshf - call hlrotr ;value to HL - ld (arecord),hl ;ready for seek - ;jmp seek - ;ret - subttl SEEK - seek the track given by actual record - -seek: -;seek the track given by arecord (actual record) -;load the registers from memory - - ld hl,arecord - ld c,(hl) ;arecord - inc hl - ld b,(hl) - ld hl,(curreca) - ld e,(hl) ;currec - inc hl - ld d,(hl) - ld hl,(curtrka) - ld A,(hl) ;curtrk - inc hl - ld h,(hl) - ld l,A - -;loop while arecord < currec -seek0: - - ld A,c - sub e - ld A,b - sbc a,d - jr nc,seek1 ;skip if arecord >= currec - -;currec = currec - sectpt - - push hl - ld hl,(sectpt) - ld A,e - sub L - ld e,A - ld A,d - sbc a,H - ld d,A - pop hl - -;curtrk = curtrk - 1 - - dec hl - jr seek0 ;for another try - -seek1: -;look while arecord >= (t:=currec + sectpt) - - push hl - ld hl,(sectpt) - add hl,de ;HL = currec+sectpt - jr c,seek2 ;can be > FFFFH - - ld A,c - sub l - ld A,b - sbc a,h - jr c,seek2 ;skip if t > arecord - -;currec = t - - ex de,hl - -;curtrk = curtrk + 1 - - pop hl - inc hl - jr seek1 ;for another try - -seek2: pop hl -;arrive here with updated values in each register - - push bc - push de - push hl ;to stack for later - -;stack contains (lowest) BC=arecord, DE=currec, HL=curtrk - - ex de,hl - ld hl,(offset) - add hl,de ;HL = curtrk+offset - ld B,H - ld C,L - call settrkf ;track set up - -;note that BC - curtrk is difference to move in bios - - pop de ;recall curtrk - ld hl,(curtrka) - ld (hl),E - inc hl - ld (hl),D ;curtrk updated - -;now compute sector as arecord-currec - - pop de ;recall currec - ld hl,(curreca) - ld (hl),e - inc hl - ld (hl),d - pop bc ;BC=arecord, DE=currec - ld A,c - sub e - ld c,A - ld A,b - sbc a,d - ld b,A - ld hl,(tranv) - ex de,hl ;BC=sector#, DE=.tran - call sectran ;HL = tran(sector) - ld C,L - ld B,H ;BC = tran(sector) - jp setsecf ;sector selected - ;ret - subttl FCB constants - -;; file control block (fcb) constants - -empty equ 0E5h ;empty directory entry -lstrec equ 127 ;last record# in extent -recsiz equ 128 ;record size -fcblen equ 32 ;file control block size -dirrec equ recsiz/fcblen ;directory elts / record -dskshf equ 2 ;log2(dirrec) -dskmsk equ dirrec-1 -fcbshf equ 5 ;log2(fcblen) - - -extnum equ 12 ;extent number field -maxext equ 31 ;largest extent number -ubytes equ 13 ;unfilled bytes field -modnum equ 14 ;data module number -maxmod equ 15 ;largest module number -fwfmsk equ 80h ;file write flag is high order modnum -namlen equ 15 ;name length -reccnt equ 15 ;record count field -dskmap equ 16 ;disk map field -lstfcb equ fcblen-1 -nxtrec equ fcblen -ranrec equ nxtrec+1 ;random record field (2 bytes) - -; -; reserved file indicators -; - -rofile equ 9 ;high order of first type char -invis equ 10 ;invisible file in dir command -; equ 11 ;reserved - subttl Utility functions for file access -dm$position: -;compute disk map position for vrecord to HL - - ld hl,blkshf - ld C,(hl) ;shift count to C - ld a,(vrecord) ;current virtual record to A - -dmpos0: - - or A - rra - dec C - jr nz,dmpos0 - -;A = shr(vrecord,blkshf) = vrecord/2**(sect/block) - - ld B,A ;save it for later addition - ld A,8 - sub (hl) ;8-blkshf to accumulator - ld C,A ;extent shift count in register c - ld a,(extval) ;extent value ani extmsk - -dmpos1: -;blkshf = 3,4,5,6,7, C=5,4,3,2,1 -;shift is 4,3,2,1,0 - - dec C - jr z,dmpos2 - - or A - rla - jr dmpos1 - -dmpos2: -;arrive here with A = shl(ext and extmsk,7-blkshf) - - add a,B ;add the previous shr(vrecord,blkshf) value - -;A is one of the following values, depending upon alloc -;bks blkshf -;1k 3 v/8 + extval * 16 -;2k 4 v/16+ extval * 8 -;4k 5 v/32+ extval * 4 -;8k 6 v/64+ extval * 2 -;16k 7 v/128+extval * 1 - - ret ;with dm$position in A - subttl GETDM - return disk map value from position given by BC - -getdm: - - ld hl,(info) ;base address of file control block - ld de,dskmap - add hl,de ;HL =.diskmap - add hl,bc ;index by a single byte value - ld a,(single) ;single byte/map entry? - or A - jr z,getdmd ;get disk map single byte - - ld L,(hl) - ld H,0 - ret ;with HL=00bb - -getdmd: - - add hl,bc ;HL=.fcb(dm+i*2) - ;double precision value returned - ld E,(hl) - inc hl - ld D,(hl) - ex de,hl - ret - subttl INDEX - compute disk block number from current FCB - -index: - call dm$position ;0...15 in register A - ld C,A - ld B,0 - call getdm ;value to HL - ld (arecord),hl - ld A,L - or H - ret - subttl ATRAN - compute actual record address, assuming index called - -atran: - ld a,(blkshf) ;shift count to reg A - ld hl,(arecord) - -atran0: - - add hl,hl - dec A - jr nz,atran0 ;shl(arecord,blkshf) - - ld (arecord1),hl ;save shifted block # - ld a,(blkmsk) - ld C,A ;mask value to C - ld a,(vrecord) - and C ;masked value in A - or L - ld L,A ;to HL - ld (arecord),hl ;arecord=HL or (vrecord and blkmsk) - ret - subttl GETEXTA - get current extent field address - -getexta: - ld hl,(info) - ld de,extnum - add hl,de ;HL=.fcb(extnum) - ret - subttl GETFCBA - compute RECCNT and NXTREC addresses for GET/SETFCB - -getfcba: - ld hl,(info) - ld de,reccnt - add hl,de - ex de,hl ;DE=.fcb(reccnt) - ld hl,nxtrec-reccnt - add hl,de ;HL=.fcb(nxtrec) - ret - subttl GETFCB - set variables from currently addressed FCB - -getfcb: - call getfcba ;addresses in DE, HL - ld A,(hl) - ld (vrecord),a ;vrecord=fcb(nxtrec) - ex de,hl - ld A,(hl) - ld (rcount),a ;rcount=fcb(reccnt) - call getexta ;HL=.fcb(extnum) - ld a,(extmsk) ;extent mask to a - and (hl) ;fcb(extnum) and extmsk - ld (extval),a - ret - subttl SETFCB - place values back into current FCB - -setfcb: - call getfcba ;addresses to DE, HL - ld a,(VRECORD) - ld (hl),A - ld a,(FX) - cp 22 - jr nc,setfcb_1 - - inc (hl) - -setfcb_1: - - ex de,hl - ld a,(rcount) - ld (hl),A ;fcb(reccnt)=rcount - ret - subttl HLROTR - HL rotated right by amount C - -hlrotr: - inc C ;in case zero -hlrotr0: - dec C - ret z ;return when zero - - srl h ;SCC - operation performed was actually a - rr l ;'shift right logical' of HL - jr hlrotr0 - subttl HLROTL - HL rotated left by amount C - -hlrotl: - inc C ;may be zero -hlrotl0: - dec C - ret z ;return if zero - - add hl,hl - jr hlrotl0 - subttl - -SCAN$DRIVE: - - ld hl,(DLOG) - -SD$0: - - ld A,16 - -SD$1: - - dec A - add hl,hl - jr nc,SD$4 - - push af - push hl - ld E,A - ld a,(SCAN$FLAG) - inc A - jr z,SD$2 - - call TMPSELECT - or 1 - call COPY$ALV - call SET$DIR$BLKS - jr SD$3 - -SD$2: - - ld C,E - call ?discd - -SD$3: - - pop hl - pop af - -SD$4: - or A - jr nz,SD$1 - - ret - -SET$DLOG: - - ld de,DLOG - -set$cdisk: - - ld a,(CURDSK) - -SET$CDISK1: - - ld C,A ;ready parameter for shift - ld hl,1 ;number to shift - call hlrotl ;HL = mask to integrate - ld a,(de) - or L - ld (de),a - inc de - ld a,(de) - or H - ld (de),a - ret - -nowrite: -;return true if dir checksum difference occurred - - ld hl,(rodsk) - -TEST$VECTOR: - - ld a,(curdsk) - ld C,A - call hlrotr - ld A,L - and 1b - ret ;non zero if nowrite - -TST$LOG$FXS: - - ld hl,LOG$FXS - -TST$LOG0: - - ld a,(FX) - ld B,A - -TST$LOG1: - - ld A,(hl) - cp B - ret z - - inc hl - or A - jr nz,TST$LOG1 - - inc A - ret - -TST$RELOG: - - ld hl,RELOG - ld A,(hl) - or A - ret z - - ld (hl),0 - call CURSELECT - ld hl,0 - ld (DCNT),hl - xor A - ld (DPTR),a - ret - -CHK$EXIT$FXS: - - ld hl,GOBACK - push hl - ld hl,RW$FXS - call TST$LOG0 - jr z,CHK$MEDIA2 - - ld hl,SC$FXS - call TST$LOG0 - jp z,LRET$EQ$FF - - pop hl - ret - -SET$LSN: - - ld hl,(LSN$ADD) - ld C,(hl) - call GETEXTA - inc hl - ld (hl),C - ret - -SET$RLOG: - - ld hl,(OLOG) - call TEST$VECTOR - ret z - - ld de,RLOG - jr SET$CDISK - -CHECK$FCB: - - call GETEXTA - inc hl - ld A,(hl) - ld hl,(LSN$ADD) - cp (hl) - call nz,CHK$MEDIA1 - call GETMODNUM - and 40H - ret z - - ld hl,(INFO) - ld (hl),0 - ret - -CHK$MEDIA1: - - ld hl,(RLOG) - call TEST$VECTOR - ret z - - pop hl - pop hl - -CHK$MEDIA2: - - ld A,10 - jp STA$RET - -set$ro: -;set current disk to read only - - ld de,RODSK - ld a,(SELDSK) - call SET$CDISK1 - -;high water mark in directory goes to max - - ld hl,(dirmax) - inc hl - ex de,hl ;DE = directory max - ld hl,(cdrmaxa) ;HL = .cdrmax - ld (hl),E - inc hl - ld (hl),D ;cdrmax = dirmax - ret - -check$rodir: -;check current directory element for read/only status - - call getdptra ;address of element - -check$rofile: -;check current buff(dptr) or fcb(0) for r/o status - - ld de,rofile - add hl,de ;offset to ro bit - ld A,(hl) - rla - ret nc ;return if not set - jp rof$error - -check$write: -;check for write protected disk - - call nowrite - ret z ;ok to write if not rodsk - - jp rod$error ;read only disk error - -getdptra: -;compute the address of a directory element at -;positon dptr in the buffer - - ld hl,(buffa) - ld a,(dptr) - -addh: -;HL = HL + A - - add a,L - ld L,A - ret nc - -;overflow to H - - inc H - ret - -getmodnum: -;compute the address of the module number -;bring module number to accumulator -;(high order bit is fwf (file write flag) - - ld hl,(info) - ld de,modnum - add hl,de ;HL=.fcb(modnum) - ld A,(hl) - ret ;A=fcb(modnum) - -clrmodnum: -;clear the module number field for user open/make - - call getmodnum - ld (hl),0 ;fcb(modnum)=0 - ret - -setfwf: - - call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - -;set fwf (file write flag) to "1" - - or fwfmsk - ld (hl),A ;fcb(modnum)=fcb(modnum) or 80h - -;also returns non zero in accumulator - - ret - -compcdr: -;return cy if cdrmax > dcnt - - ld de,(dcnt) ;DE = directory counter - ld hl,(cdrmaxa) ;HL=.cdrmax - ld A,E - sub (hl) ;low(dcnt) - low(cdrmax) - inc hl ;HL = .cdrmax+1 - ld A,D - sbc a,(hl) ;hig(dcnt) - hig(cdrmax) - -;condition dcnt - cdrmax produces cy if cdrmax>dcnt - - ret - -setcdr: -;if not (cdrmax > dcnt) then cdrmax = dcnt+1 - - call compcdr - ret c ;return if cdrmax > dcnt - -;otherwise, HL = .cdrmax+1, DE = dcnt - - inc de - ld (hl),D - dec hl - ld (hl),E - ret - -subdh: -;compute HL = DE - HL - - ld A,E - sub L - ld L,A - ld A,D - sbc a,H - ld H,A - ret - -newchecksum: - - ld C,0FEH ;drop through to compute new checksum - -checksum: -;compute current checksum record and update the -;directory element if C=true, or check for = if not -;ARECORD < chksiz? - - ld de,(ARECORD) - ld hl,(chksiz) - call subdh ;DE-HL - ret nc ;skip checksum if past checksum vector size - -;ARECORD < chksiz, so continue - - push bc ;save init flag - -;COMPUTE CHECKSUM FOR CURRENT DIRECTORY BUFFER - - ld C,RECSIZ ;SIZE OF DIRECTORY BUFFER - ld hl,(BUFFA) ;CURRENT DIRECTORY BUFFER - xor A ;CLEAR CHECKSUM VALUE - -COMPUTECS0: - - add a,(hl) - inc hl - dec C ;CS=CS+BUFF(RECSIZ-C) - jr nz,COMPUTECS0 - - ld de,(checka) ;address of check sum vector - ld hl,(ARECORD) - add hl,de ;HL = .check(ARECORD) - pop bc ;recall true=0ffh or false=00 to C - inc C ;0ffh produces zero flag - jr z,initial$cs - inc C - jr z,UPDATE$CS - -;not initializing, compare - - cp (hl) ;compute$cs=check(ARECORD)? - ret z ;no message if ok - call NOWRITE - ret nz - ld A,0FFH - ld (RELOG),a - call set$rlog - -RESET$DRIVE: - - call set$dlog - jp RESET37X - -initial$cs: - - cp (hl) - ld (hl),A - ret z - ld hl,(LSN$ADD) - ld A,1 - or (hl) - -UPDATE$CS: -;initializing the checksum - - ld (hl),A - ret - -wrdir: -;write the current directory entry, set checksum - - call newchecksum ;initialize entry - call setdir ;directory dma - ld C,1 ;indicates a write directory operation - call wrbuff ;write the buffer - jr setdata ;to data dma address - ;ret - -rd$dir: -;read a directory entry into the directory buffer - - call seek$dir - call setdir ;directory dma - call rdbuff ;directory record loaded - ; jmp setdata to data dma address - ;ret - -setdata: -;set data dma address - - ld hl,dmaad - jr setdma ;to complete the call - -setdir: -;set directory dma address - - ld hl,buffa ;jmp setdma to complete call - -setdma: -;HL=.dma address to set (i.e., buffa or dmaad) - - ld C,(hl) - inc hl - ld B,(hl) ;parameter ready - jp setdmaf - -dir$to$user: -;copy the directory entry to the user buffer -;after call to search or searchn by user code - - ld de,(buffa) ;source is directory buffer - ld hl,(dmaad) ;destination is user dma address - ld C,recsiz ;copy entire record - call MOVE - ld hl,LRET - ld A,(hl) - inc A - ret z - ld a,(DCNT) - and DSKMSK - ld (hl),A - ret - -end$of$dir: -;return zero flag if at end of directory, non zero -;if not at end (end of dir if dcnt = 0ffffh) - - ld hl,(DCNT) - ld A,L - and H - inc A - ret - -set$end$dir: -;set dcnt to the end of the directory - - ld hl,enddir - ld (dcnt),hl - ret - -read$dir: -;read next directory entry, with C=true if initializing - - ld de,(dirmax) ;in preparation for subtract - ld hl,(dcnt) - inc hl - ld (dcnt),hl ;dcnt=dcnt+1 - -;continue while dirmax >= dcnt (dirmax-dcnt no cy) - - call subdh ;DE-HL - jr nc,read$dir0 - -;yes, set dcnt to end of directory - - jr set$end$dir - ;ret - -read$dir0: -;not at end of directory, seek next element -;initialization flag is in C - - ld a,(dcnt) - and dskmsk ;low(dcnt) and dskmsk - ld B,fcbshf ;to multiply by fcb size - -read$dir1: - - add a,A - dec B - jr nz,read$dir1 - -;A = (low(dcnt) and dskmsk) shl fcbshf - - ld (dptr),a ;ready for next dir operation - or A - ret nz ;return if not a new record - push bc ;save initialization flag C - call rd$dir ;read the directory record - pop bc ;recall initialization flag - call CHECKSUM - ld a,(RELOG) - or A - ret z - call CHK$EXIT$FXS - call TST$RELOG - jr RD$DIR - ;ret - -getallocbit: -;given allocation vector position BC, return with byte -;containing BC shifted so that the least significant -;bit is in the low order accumulator position. HL is -;the address of the byte for possible replacement in -;memory upon return, and D contains the number of shifts -;required to place the returned value back into position - - ld A,C - and 111b - inc A - ld E,A - ld D,A - -;d and e both contain the number of bit positions to shift - - ld H,B - ld L,C - ld C,3 - call HLROTR - ld B,H - ld C,L - - ld hl,(alloca) ;base address of allocation vector - add hl,bc - ld A,(hl) ;byte to A, hl = .alloc(BC shr 3) - -;now move the bit to the low order position of A - -rotl: rlca - dec E - jr nz,rotl - ret - -set$alloc$bit: -;BC is the bit position of ALLOC to set or reset. The -;value of the bit is in register E. - - push de - call getallocbit ;shifted val A, count in D - and 11111110b ;mask low bit to zero (may be set) - pop bc - or C ;low bit of C is masked into A - ;jmp rotr ;to rotate back into proper position - ;ret - -rotr: -;byte value from ALLOC is in register A, with shift count -;in register C (to place bit back into position), and -;target ALLOC position in registers HL, rotate and replace - - rrca - dec D - jr nz,rotr ;back into position - ld (hl),A ;back to ALLOC - ret - -COPY$ALV: -;IF Z FLAG SET, COPY 1ST ALV TO 2ND ALV -;OTHERWISE, COPY 2ND ALV TO 1ST ALV - - push af - call GET$NALBS - ld B,H - ld C,L - ld hl,(ALLOCA) - ld D,H - ld E,L - add hl,bc - pop af - jp z,MOVEX - ex de,hl - jp MOVEX - -SCANDM$AB: - - push bc - call SCANDM$A - pop bc - ;JMP SCANDM$B - -SCANDM$B: -;SET/RESET 2ND ALV - - push bc - call GET$NALBS - ex de,hl - ld hl,(ALLOCA) - pop bc - push hl - add hl,de - ld (ALLOCA),hl - call SCANDM$A - pop hl - ld (ALLOCA),hl - ret - -SCANDM$A: -;SET/RESET 1ST ALLOCATION VECTOR -;scan the disk map addressed by dptr for non-zero -;entries, the allocation vector entry corresponding -;to a non-zero entry is set to the value of C (0,1) - - call getdptra ;HL = buffa + dptr - -;HL addresses the beginning of the directory entry - - ld de,dskmap - add hl,de ;hl now addresses the disk map - push bc ;save the 0/1 bit to set - ld C,fcblen-dskmap+1 ;size of single byte disk map + 1 - -scandm0: -;loop once for each disk map entry - - pop de ;recall bit parity - dec C - ret z ;all done scanning? - - ;no, get next entry for scan - push de ;replace bit parity - ld a,(single) - or A - jr z,scandm1 - -;single byte scan operation - - push bc ;save counter - push hl ;save map address - ld C,(hl) - ld B,0 ;BC=block# - jr scandm2 - -scandm1: -;double byte scan operation - - dec C ;count for double byte - push bc ;save counter - ld C,(hl) - inc hl - ld B,(hl) ;BC=block# - push hl ;save map address - -scandm2: -;arrive here with BC=block#, E=0/1 - - ld A,C - or B ;skip if = 0000 - jr z,scanm3 - ld hl,(maxall) ;check invalid index - ld A,L - sub C - ld A,H - sbc a,B ;maxall - block# - call nc,set$alloc$bit - -;bit set to 0/1 -scanm3: - - pop hl - inc hl ;to next bit position - pop bc ;recall counter - jr scandm0 ;for another item - -GET$NALBS: ;GET # OF ALLOCATION VECTOR BYTES - - ld hl,(MAXALL) - ld C,3 - call HLROTR - inc hl - ret - -SET$DIR$BLKS: - - ld de,(DIRBLK) - ld hl,(ALLOCA) - ld A,(hl) - or E - ld (hl),A - inc hl - ld A,(hl) - or D - ld (hl),A - ret - -initialize: -;initialize the current disk -;lret = false ;set to true if $ file exists -;compute the length of the allocation vector -;number of bytes in alloc vector is (maxall/8)+1 - - call GET$NALBS - ld B,H - ld C,L ;count down BC til zero - ld hl,(alloca) ;base of allocation vector - -;fill the allocation vector with zeros -initial0: - - ld (hl),0 - inc hl ;alloc(i)=0 - dec bc ;count length down - ld A,B - or C - jr nz,initial0 - -;set the reserved space for the directory - - call SET$DIR$BLKS - -;allocation vector initialized, home disk - - call home - -;cdrmax = 3 (scans at least one directory record) - - ld hl,(cdrmaxa) - ld (hl),3 - inc hl - ld (hl),0 - -;cdrmax = 0000 - - call set$end$dir ;dcnt = enddir - -;read directory entries and check for allocated storage -initial2: - - ld C,true - call read$dir - call end$of$dir - jp z,COPY$ALV ;return if end of directory - -;not end of directory, valid entry? - - call getdptra ;HL = buffa + dptr - ld A,0F0H - and (hl) - jr nz,INITIAL2 - -;now scan the disk map for allocated blocks - - ld C,1 ;set to allocated - call SCANDM$A - call setcdr ;set cdrmax to dcnt - jr initial2 ;for another entry - -copy$dirloc: -;copy directory location to lret following -;delete, rename, ... ops - - ld a,(dirloc) - jp sta$ret - ;ret - -compext: -;compare extent# in A with that in C, return nonzero -;if they do not match - - push bc ;save C's original value - push af - ld a,(extmsk) - cpl - ld B,A - -;B has negated form of extent mask - - ld A,C - and B - ld C,A ;low bits removed from C - pop af - and B ;low bits removed from A - sub C - and maxext ;set flags - pop bc ;restore original values - ret - -SEARCH$EXTNUM: - - ld C,EXTNUM - jr SEARCH - -SEARCH$NAMLEN: - - ld C,NAMLEN - -search: -;search for directory element of length C at info - - ld A,0ffh - ld (dirloc),a ;changed if actually found - ld hl,searchl - ld (hl),C ;searchl = C - ld hl,(info) - ld (searcha),hl ;searcha = info - call set$end$dir ;dcnt = enddir - call home ;to start at the beginning -;(drop through to searchn) - -searchn: -;search for the next directory element, assuming -;a previous call on search which sets searcha and -;searchl - - ld C,false - call read$dir ;read next dir element - call end$of$dir - jr z,search$fin ;skip to end if so - - -;not end of directory, scan for match - - ld hl,(searcha) - ex de,hl ;DE=beginning of user fcb - ld a,(de) ;first character - cp empty ;keep scanning if empty - jr z,searchnext - -;not empty, may be end of logical directory - - push de ;save search address - call compcdr ;past logical end? - pop de ;recall address - jr nc,search$fin ;artificial stop - -searchnext: - - xor A - ld (USER0$SEARCH),a - call getdptra ;HL = buffa+dptr - ld a,(searchl) - ld C,A ;length of search to c - ld B,0 ;b counts up, c counts down - -searchloop: - - ld A,C - or A - jr z,endsearch - - ld a,(de) - cp '?' - jr z,searchok ;? matches all - -;scan next character if not ubytes - - ld A,B - cp ubytes - jr z,searchok - -;not the ubytes field, extent field? - - cp extnum ;may be extent field - ld a,(de) ;fcb character - jr z,searchext ;skip to search extent - - jr c,skipsys ;skip test for sys flag SCC 23 Apr 84 - - sub (hl) ; SCC 23 Apr 84 - and 3Fh ; SCC 23 Apr 84 - jr z,searchok ; SCC 23 Apr 84 - - ld a,(de) ;get FCB char again SCC 23 Apr 84 -skipsys: ; SCC 23 Apr 84 - - sub (hl) - and 7Fh ;mask-out flags/extent modulus - jr z,SEARCHOK - - ld A,(hl) - or b - jr nz,SEARCHN - - ld a,(FX) - cp 15 - jr nz,SEARCHN - - ld a,(USRCODE) - or A - jr z,SEARCHN - - ld A,0FFH - ld (USER0$SEARCH),a - jr SEARCHOK - -searchext: -;A has fcb character -;attempt an extent # match - - push bc ;save counters - ld C,(hl) ;directory character to c - call compext ;compare user/dir char - pop bc ;recall counters - jr nz,searchn ;skip if no match - -searchok: -;current character matches - - inc de - inc hl - inc B - dec C - jr searchloop - -endsearch: - - xor A - ld (DIRLOC),a - ld (LRET),a - ld hl,USER0$SEARCH - inc (hl) - ret nz - ld hl,(DCNT) - ld (SDCNT),hl - jp SEARCHN - -search$fin: -;end of directory, or empty name - - call set$end$dir ;may be artifical end - -LRET$EQ$FF: - - ld A,255 - ld B,A - inc B - jp sta$ret - -delete: -;delete the currently addressed file - - call RESELECT - call check$write ;write protected? - call SEARCH$EXTNUM ;search through file type - ret z - -DELETE00: - - jr z,DELETE1 - call CHECK$RODIR - ld hl,(INFO) - call CHK$WILD - jr nz,DELETE11 - call SEARCHN - jr DELETE00 - -DELETE1: - - call SEARCH$EXTNUM - -DELETE10: - - jp z,COPY$DIRLOC - -DELETE11: - - call GETDPTRA - ld (hl),EMPTY - ld C,0 - call SCANDM$AB - call SET$DIR$BLKS - call DELETE$SUB - call WRDIR - call SEARCHN - jr DELETE10 - -CHK$WILD: - - ld C,11 - -CHK$WILD1: - - inc hl - ld A,3FH - sub (hl) - and 7FH - ret z - dec C - jr nz,CHK$WILD1 - or A - ret - -get$block: -;given allocation vector position BC, find the zero bit -;closest to this position by searching left and right. -;if found, set the bit to one and return the bit position -;in hl. if not found (i.e., we pass 0 on the left, or -;maxall on the right), return 0000 in hl - - ld D,B - ld E,C ;copy of starting position to de - -lefttst: - - ld A,C - or B - jr z,righttst ;skip if left=0000 - -;left not at position zero, bit zero? - - dec bc - push de - push bc ;left,right pushed - call getallocbit - rra - jr nc,retblock ;return block number if zero - -;bit is one, so try the right - - pop bc - pop de ;left, right restored - -righttst: - - ld hl,(maxall) ;value of maximum allocation# - ld A,E - sub L - ld A,D - sbc a,H ;right=maxall? - jr nc,retblock0 ;return block 0000 if so - inc de - push bc - push de ;left, right pushed - ld B,D - ld C,E ;ready right for call - call getallocbit - rra - jr nc,retblock ;return block number if zero - pop de - pop bc ;restore left and right pointers - jr lefttst ;for another attempt - -retblock: - - rla - inc A ;bit back into position and set to 1 - -;d contains the number of shifts required to reposition - - call rotr ;move bit back to position and store - pop hl - pop de ;HL returned value, DE discarded - ret - -retblock0: -;cannot find an available bit, return 0000 - - ld A,C - or B - jr nz,lefttst ;also at beginning - ld hl,0000h - ret - -copy$fcb: -;copy the entire file control block - - ld C,0 - ld E,fcblen ;start at 0, to fcblen-1 - ;jmp copy$dir - -copy$dir: -;copy fcb information starting at C for E bytes -;into the currently addressed directory entry - - push de ;save length for later - ld B,0 ;double index to BC - ld hl,(info) ;HL = source for data - add hl,bc - push hl - call TEST$SUB - ld C,0FFH - call z,SET$SUB$FLAG - pop de ;DE=.fcb(C), source for copy - call getdptra ;HL=.buff(dptr), destination - pop bc ;DE=source, HL=dest, C=length - call move ;data moved - -seek$copy: -;enter from close to seek and copy current element - - call seek$dir ;to the directory element - jp wrdir ;write the directory element - ;ret - -TEST$SUB: - - inc hl - ld de,SUB$FCB - ld C,11 - -TEST$SUB1: - - ld a,(de) - cp (hl) - ret nz - inc de - inc hl - dec C - jr nz,TEST$SUB1 - xor A - ret - - -SUB$FCB: defb '$$$ SUB' - - -DELETE$SUB: - - call GETDPTRA - call TEST$SUB - ld C,0 - ret nz - ;JMP SET$SUB$FLAG - -SET$SUB$FLAG: - - ld a,(CURDSK) - or A - ret nz - ld hl,SUB$FLAG - ld (hl),C - ret - -rename: -;rename the file described by the first half of -;the currently addressed file control block. the -;new name is contained in the last half of the -;currently addressed file conrol block. the file -;name and type are changed, but the reel number -;is ignored. the user number is identical - - call check$write ;may be write protected - -;search up to the extent field - - call RESELECT - call SEARCH$EXTNUM - -;copy position 0 - - ld hl,(info) - ld A,(hl) ;HL=.fcb(0), A=fcb(0) - ld de,dskmap - add hl,de ;HL=.fcb(dskmap) - ld (hl),A ;fcb(dskmap)=fcb(0) - -;assume the same disk drive for new named file -rename0: - - jð z,COPY$DIRLOÃ ;stoð aô enä oæ dir - call DELETE$SUB - -;not end of directory, rename next element - - call check$rodir ;may be read-only file - ld C,dskmap - ld E,extnum - call copy$dir - -;element renamed, move to next - - call searchn - jr rename0 - -indicators: -;set file indicators for current fcb - - call RESELECT - call SEARCH$EXTNUM ;through file type - -indic0: - - jp z,COPY$DIRLOC ;stop at end of dir - -;not end of directory, continue to change - - ld C,0 - ld E,extnum ;copy name - call copy$dir - call searchn - jr indic0 - -open: -;search for the directory entry, copy to fcb - - call SEARCH$NAMLEN - -OPEN1: - - ret z ;return with lret=255 if end - -;not end of directory, copy fcb information -open$copy: -;(referenced below to copy fcb info) - - call getexta - ld A,(hl) - push af - push hl ;save extent# - call getdptra - ex de,hl ;DE = .buff(dptr) - ld hl,(info) ;HL=.fcb(0) - ld C,nxtrec ;length of move operation - push de ;save .buff(dptr) - call move ;from .buff(dptr) to .fcb(0) - -;note that entire fcb is copied, including indicators - - call setfwf ;sets file write flag - pop de - ld hl,extnum - add hl,de ;HL=.buff(dptr+extnum) - ld C,(hl) ;C = directory extent number - ld hl,reccnt - add hl,de ;HL=.buff(dptr+reccnt) - ld B,(hl) ;B holds directory record count - pop hl - pop af - ld (hl),A ;restore extent number - -;HL = .user extent#, B = dir rec cnt, C = dir extent# -;if user ext < dir ext then user := 128 records -;if user ext = dir ext then user := dir records -;if user ext > dir ext then user := 0 records - - ld A,C - cp (hl) - ld A,B ;ready dir reccnt - jr z,open$rcnt ;if same, user gets dir reccnt - ld A,0 - jr c,open$rcnt ;user is larger - ld A,128 ;directory is larger - -open$rcnt: ;A has record count to fill - - ld hl,(info) - ld de,reccnt - add hl,de - ld (hl),A - ret - -mergezero: -;HL = .fcb1(i), DE = .fcb2(i), -;if fcb1(i) = 0 then fcb1(i) := fcb2(i) - - ld A,(hl) - inc hl - or (hl) - dec hl - ret nz ;return if = 0000 - ld a,(de) - ld (hl),A - inc de - inc hl ;low byte copied - ld a,(de) - ld (hl),A - dec de - dec hl ;back to input form - ret - -close: -;locate the directory element and re-write it - - xor A - ld (lret),a - ld (dcnt),a - ld (dcnt+1),a - call nowrite - ret nz ;skip close if r/o disk - -;check file write flag - 0 indicates written - call getmodnum ;fcb(modnum) in A - and fwfmsk - ret nz ;return if bit remains set - - call SEARCH$NAMLEN - ret z ;return if not found - -;merge the disk map at info with that at buff(dptr) - - ld bc,dskmap - call getdptra - add hl,bc - ex de,hl ;DE is .buff(dptr+16) - ld hl,(info) - add hl,bc ;DE=.buff(dptr+16), HL=.fcb(16) - ld C,fcblen-dskmap ;length of single byte dm - -merge0: - - ld a,(single) - or A - jr z,merged ;skip to double - -;this is a single byte map -;if fcb(i) = 0 then fcb(i) = buff(i) -;if buff(i) = 0 then buff(i) = fcb(i) -;if fcb(i) <> buff(i) then error - - ld A,(hl) - or A - ld a,(de) - jr nz,fcbnzero - -;fcb(i) = 0 - - ld (hl),A ;fcb(i) = buff(i) - -fcbnzero: - - or A - jr nz,buffnzero - -;buff(i) = 0 - - ld A,(hl) - ld (de),a ;buff(i)=fcb(i) - -buffnzero: - - cp (hl) - jr nz,mergerr ;fcb(i) = buff(i)? - jr dmset ;if merge ok - -merged: -;this is a double byte merge operation - - call mergezero ;buff = fcb if buff 0000 - ex de,hl - call mergezero - ex de,hl ;fcb = buff if fcb 0000 - -;they should be identical at this point - - ld a,(de) - cp (hl) - jr nz,mergerr ;low same? - inc de - inc hl ;to high byte - ld a,(de) - cp (hl) - jr nz,mergerr ;high same? - -;merge operation ok for this pair - - dec C ;extra count for double byte - -dmset: - - inc de - inc hl ;to next byte position - dec C - jr nz,merge0 ;for more - -;end of disk map merge, check record count -;DE = .buff(dptr)+32, HL = .fcb(32) - - ld bc,-(fcblen-extnum) - add hl,bc - ex de,hl - add hl,bc - -;DE = .fcb(extnum), HL = .buff(dptr+extnum) - - ld a,(de) ;current user extent number - -;if fcb(ext) >= buff(fcb) then -;buff(ext) := fcb(ext), buff(rec) := fcb(rec) - - cp (hl) - jr c,endmerge - -;fcb extent number >= dir extent number - - ld (hl),A ;buff(ext) = fcb(ext) - -;update directory record count field - - ld bc,reccnt-extnum - add hl,bc - ex de,hl - add hl,bc - -;DE=.buff(reccnt), HL=.fcb(reccnt) - - ld A,(hl) - ld (de),a ;buff(reccnt)=fcb(reccnt) - -endmerge: - - ld A,true - ld (fcb$copied),a ;mark as copied - ld C,1 - call SCANDM$B - call SETFWF - jp seek$copy ;ok to "wrdir" here - 1.4 compat - ;ret - -mergerr: -;elements did not merge correctly - - ld hl,lret - dec (hl) ;=255 non zero flag set - ret - -make: -;create a new file by creating a directory entry -;then opening the file - - call check$write ;may be write protected - ld hl,(info) - push hl ;save fcb address, look for e5 - ld hl,efcb - ld (info),hl ;info = .empty - ld C,1 - call search ;length 1 match on empty entry - pop hl ;recall info address - ld (info),hl ;in case we return here - ret z ;return with error condition 255 if not found - ex de,hl ;DE = info address - -;clear the remainder of the fcb - - ld hl,namlen - add hl,de ;HL=.fcb(namlen) - ld C,fcblen-namlen ;number of bytes to fill - xor A ;clear accumulator to 00 for fill - -make0: - - ld (hl),A - inc hl - dec C - jr nz,make0 - ld hl,ubytes - add hl,de ;HL = .fcb(ubytes) - ld (hl),A ;fcb(ubytes) = 0 - call setcdr ;may have extended the directory - -;now copy entry to the directory - - call copy$fcb - -;and set the file write flag to "1" - - jp setfwf - ;ret - -open$reel: -;close the current extent, and open the next one -;if possible. RMF is true if in read mode - - xor A - ld (fcb$copied),a ;set true if actually copied - call close ;close current extent - -;lret remains at enddir if we cannot open the next ext - - ld a,(LRET) - inc A - ret z ;return if end - -;increment extent number - - ld hl,(info) - ld bc,extnum - add hl,bc ;HL=.fcb(extnum) - ld A,(hl) - inc A - and maxext - ld (hl),A ;fcb(extnum)=++1 - jr z,open$mod ;move to next module if zero - -;may be in the same extent group - - ld B,A - ld a,(extmsk) - and B - -;if result is zero, then not in the same group - - ld hl,fcb$copied ;true if the fcb was copied to directory - and (hl) ;produces a 00 in accumulator if not written - jr z,open$reel0 ;go to next physical extent - -;result is non zero, so we must be in same logical ext - - jr open$reel1 ;to copy fcb information - -open$mod: -;extent number overflow, go to next module - - ld bc,modnum-extnum - add hl,bc ;HL=.fcb(modnum) - inc (hl) ;fcb(modnum)=++1 - -;module number incremented, check for overflow - - ld A,(hl) - and maxmod ;mask high order bits - jr z,open$r$err ;cannot overflow to zero - -;otherwise, ok to continue with new module -open$reel0: - - call SEARCH$NAMLEN ;next extent found? - jr nz,OPEN$REEL1 - -;end of file encountered - - ld a,(rmf) - inc A ;0ffh becomes 00 if read - jr z,open$r$err ;sets lret = 1 - -;try to extend the current file - - call make - -;cannot be end of directory - - call end$of$dir - jr z,open$r$err ;with lret = 1 - - jr open$reel2 - -open$reel1: -;not end of file, open - - call open$copy - -open$reel2: - - call getfcb ;set parameters - xor A - jp sta$ret ;ret with lret = 0 - -open$r$err: -;cannot move to next extent of this file - - call setlret1 ;lret = 1 - jp setfwf ;ensure that it will not be closed - ;ret - -seqdiskread: - - call RESELECTX - -diskread: ;(may enter from seqdiskread) - - ld A,true - ld (rmf),a ;read mode flag = true (open$reel) - -;read the next record from the current fcb - - call getfcb ;sets parameters for the read - ld a,(vrecord) - ld hl,rcount - cp (hl) ;vrecord-rcount - -;skip if rcount > vrecord - - jr c,recordok - -;not enough records in the extent -;record count must be 128 to continue - - cp 128 ;vrecord = 128? - jr nz,diskeof ;skip if vrecord<>128 - - call open$reel ;go to next extent if so - xor A - ld (vrecord),a ;vrecord=00 - - -;now check for open ok - - ld a,(lret) - or A - jr nz,diskeof ;stop at eof - -recordok: -;arrive with fcb addressing a record to read - - call index - -;error 2 if reading unwritten data -;(returns 1 to be compatible with 1.4) - - jr z,diskeof - -;record has been allocated, read it - - call atran ;arecord now a disk address - call seek ;to proper track,sector - call rdbuff ;to dma address - jp setfcb ;replace parameter - ;ret - -diskeof: - - jp setlret1 ;lret = 1 - ;ret - -seqdiskwrite: - - call RESELECTX - -diskwrite: ;(may enter here from seqdiskwrite above) - - ld A,false - ld (rmf),a ;read mode flag - -;write record to currently selected file - - call check$write ;in case write protected - ld hl,(info) ;HL = .fcb(0) - call check$rofile ;may be a read-only file - call GETMODNUM - and 40H - jp nz,ROF$ERROR - call getfcb ;to set local parameters - ld a,(vrecord) - cp lstrec+1 ;vrecord-128 - -;skip if vrecord > lstrec -;vrecord = 128, cannot open next extent - jp nc,setlret1 ;lret=1 - -diskwr0: -;can write the next record, so continue - - call index - ld C,0 ;marked as normal write operation for wrbuff - jr nz,diskwr1 - -;not allocated -;the argument to getblock is the starting -;position for the disk search, and should be -;the last allocated block for this file, or -;the value 0 if no space has been allocated - - call dm$position - ld (dminx),a ;save for later - ld bc,0000h ;may use block zero - or A - jr z,nopblock ;skip if no previous block - -;previous block exists at A - - ld C,A - dec bc ;previous block # in BC - call getdm ;previous block # to HL - ld B,H - ld C,L ;BC=prev block# - -nopblock: -;BC = 0000, or previous block # - - call get$block ;block # to HL - -;arrive here with block# or zero - - ld A,L - or H - jr nz,blockok - -;cannot find a block to allocate - - ld A,2 - jp sta$ret ;lret=2 - -blockok: -;allocated block number is in HL - - ld (arecord),hl - ex de,hl ;block number to DE - ld hl,(info) - ld bc,dskmap - add hl,bc ;HL=.fcb(dskmap) - ld a,(single) - or A ;set flags for single byte dm - ld a,(dminx) ;recall dm index - jr z,allocwd ;skip if allocating word - -;allocating a byte value - - call addh - ld (hl),E ;single byte alloc - jr diskwru ;to continue - -allocwd: -;allocate a word value - - ld C,A - ld B,0 ;double(dminx) - add hl,bc - add hl,bc ;HL=.fcb(dminx*2) - ld (hl),E - inc hl - ld (hl),D ;double wd - -diskwru: -;disk write to previously unallocated block - - ld C,2 ;marked as unallocated write - -diskwr1: -;continue the write operation if no allocation error -;C = 0 if normal write, 2 if to prev unalloc block - - ld a,(lret) - or A - ret nz ;stop if non zero returned value - push bc ;save write flag - call atran ;arecord set - ld a,(FX) - cp 40 - jr nz,diskwr11 - pop bc - push bc - ld A,C - dec A - dec A - jr nz,diskwr11 ;old allocation - push hl ;arecord in hl ret from atran - ld hl,(buffa) - ld D,A ;zero buffa & fill - -fill0: - - ld (hl),A - inc hl - inc D - jp p,fill0 - call setdir - ld hl,(arecord1) - ld C,2 - -fill1: - - ld (arecord),hl - push bc - call seek - pop bc - call wrbuff ;write fill record - ld hl,(arecord) - -;restore last record - - ld C,0 ;change allocate flag - ld a,(blkmsk) - ld B,A - and L - cp B - inc hl - jr nz,fill1 ;cont until cluster is zeroed - pop hl - ld (arecord),hl - call setdata - call SEEK - jr DISKWR12 - -diskwr11: - - call seek ;to proper file position - pop bc - push bc ;restore/save write flag (C=2 if new block) - ld a,(ARECORD) - ld hl,BLKMSK - and (hl) - jr z,DISKWR13 - -DISKWR12: - - ld C,0 - -DISKWR13: - - call wrbuff ;written to disk - pop bc ;C = 2 if a new block was allocated, 0 if not - -;increment record count if rcount<=vrecord - - ld a,(vrecord) - ld hl,rcount - cp (hl) ;vrecord-rcount - jr c,diskwr2 - -;rcount <= vrecord - - ld (hl),A - inc (hl) ;rcount = vrecord+1 - ld C,2 ;mark as record count incremented - -diskwr2: -;A has vrecord, C=2 if new block or new record# - - dec C - dec C - jr nz,noupdate - push af ;save vrecord value - call getmodnum ;HL=.fcb(modnum), A=fcb(modnum) - -;reset the file write flag to mark as written fcb - - and (not fwfmsk) and 0ffh ;bit reset - ld (hl),A ;fcb(modnum) = fcb(modnum) and 7fh - pop af ;restore vrecord - -noupdate: -;check for end of extent, if found attempt to open -;next extent in preparation for next write - - cp lstrec ;vrecord=lstrec? - jr nz,diskwr3 ;skip if not - -;may be random access write, if so we are done -;change next - - ld a,(FX) - cp 22 - jr nc,DISKWR3 ;skip next extent open op - -;update current fcb before going to next extent - - call setfcb - call open$reel ;rmf=false - -;vrecord remains at lstrec causing eof if -;no more directory space is available - - ld hl,lret - ld A,(hl) - or A - jr nz,nospace - -;space available, set vrecord=255 - dec A - ld (vrecord),a ;goes to 00 next time - -nospace: - - ld (hl),0 ;lret = 00 for returned value - -diskwr3: - - jp setfcb ;replace parameters - ;ret - -rseek: -;random access seek operation, C=0ffh if read mode -;fcb is assumed to address an active file control block -;(MODNUM HAS BEEN SET TO 1010$0000b IF PREVIOUS BAD SEEK) - - push bc ;save r/w flag - ld de,(info) ;DE will hold base of fcb - ld hl,ranrec - add hl,de ;HL=.fcb(ranrec) - ld A,(hl) - and 7fh - push af ;record number - ld A,(hl) - rla ;cy=lsb of extent# - inc hl - ld A,(hl) - rla - and 11111b ;A=ext# - ld C,A ;C holds extent number, record stacked - ld A,(hl) - rra - rra - rra - rra - and 1111b ;mod# - ld B,A ;B holds module#, C holds ext# - pop af ;recall sought record # - -;check to insure that high byte of ran rec = 00 - - inc hl - ld L,(hl) ;l=high byte (must be 00) - inc L - dec L - ld L,6 ;zero flag, l=6 - -;produce error 6, seek past physical eod - - jr nz,seekerr - -;otherwise, high byte = 0, A = sought record - - ld hl,nxtrec - add hl,de ;HL = .fcb(nxtrec) - ld (hl),A ;sought rec# stored away - -;arrive here with B=mod#, C=ext#, DE=.fcb, rec stored -;the r/w flag is still stacked. compare fcb values - - ld hl,extnum - add hl,de - ld A,C ;A=seek ext# - sub (hl) - jr nz,ranclose ;tests for = extents - -;extents match, check mod# - - ld hl,modnum - add hl,de - ld A,B ;B=seek mod# - -;could be overflow at eof, producing module# -;of 90H or 10H, so compare all but fwf - - sub (hl) - and 3FH - jr z,seekok ;same? - -ranclose: - - push bc - push de ;save seek mod#,ext#, .fcb - call close ;current extent closed - pop de - pop bc ;recall parameters and fill - ld L,3 ;cannot close error #3 - ld a,(lret) - inc A - jr z,badseek - ld hl,extnum - add hl,de - ld (hl),C ;fcb(extnum)=ext# - ld hl,modnum - add hl,de - ld (hl),B ;fcb(modnum)=mod# - call open ;is the file present? - ld a,(lret) - inc A - jr nz,seekok ;open successful? - -;cannot open the file, read mode? - - pop bc ;r/w flag to c (=0ffh if read) - push bc ;everyone expects this item stacked - ld L,4 ;seek to unwritten extent #4 - inc C ;becomes 00 if read operation - jr z,badseek ;skip to error if read operation - -;write operation, make new extent - - call make - ld L,5 ;cannot create new extent #5 - ld a,(lret) - inc A - jr z,badseek ;no dir space - -;file make operation successful -seekok: - - pop bc ;discard r/w flag - xor A - jp sta$ret ;with zero set - -badseek: -;fcb no longer contains a valid fcb, mark -;with 1010$00000B IN MODNUM FIELD so that it -;appears as overflow with file write flag set - - push hl ;save error flag - call getmodnum ;HL = .modnum - ld (hl),10100000B - pop hl ;and drop through - -seekerr: - - pop bc ;discard r/w flag - ld A,L - ld (lret),a ;lret=#, nonzero - -;setfwf returns non-zero accumulator for err - - jp setfwf ;flag set, so subsequent close ok - ;ret - -randiskread: -;random disk read operation - - call RESELECTX - ld C,true ;marked as read operation - call rseek - call z,diskread ;if seek successful - ret - -randiskwrite: -;random disk write operation - - call RESELECTX - ld C,false ;marked as write operation - call rseek - call z,diskwrite ;if seek successful - ret - -compute$rr: -;compute random record position for getfilesize/setrandom - - ex de,hl - add hl,de - -;DE=.buf(dptr) or .fcb(0), HL = .f(nxtrec/reccnt) - - ld C,(hl) - ld B,0 ;BC = 0000 0000 ?rrr rrrr - ld hl,extnum - add hl,de - ld A,(hl) - rrca - and 80h ;A=e000 0000 - add a,C - ld C,A - ld A,0 - adc a,B - ld B,A - -;BC = 0000 000? errrr rrrr - - ld A,(hl) - rrca - and 0fh - add a,B - ld B,A - -;BC = 000? eeee errrr rrrr - - ld hl,modnum - add hl,de - ld A,(hl) ;A=XXX? mmmm - add a,A - add a,A - add a,A - add a,A ;cy=? A=mmmm 0000 - push af - add a,B - ld B,A - -;cy=?, BC = mmmm eeee errr rrrr - - push af ;possible second carry - pop hl ;cy = lsb of L - ld A,L ;cy = lsb of A - pop hl ;cy = lsb of L - or L ;cy/cy = lsb of A - and 1 ;A = 0000 000? possible carry-out - ret - -getfilesize: -;compute logical file size for current fcb -;zero the receiving ranrec field - - call RESELECT - ld hl,(info) - ld de,ranrec - add hl,de - push hl ;save position - ld (hl),D - inc hl - ld (hl),D - inc hl - ld (hl),D ;=00 00 00 - call SEARCH$EXTNUM - -getsize: - - jr z,SETSIZE - -;current fcb addressed by dptr - - call getdptra - ld de,reccnt ;ready for compute size - call compute$rr - -;A=0000 000? BC = mmmm eeee errr rrrr -;compare with memory, larger? - - pop hl - push hl ;recall, replace .fcb(ranrec) - ld E,A ;save cy - ld A,C - sub (hl) - inc hl ;ls byte - ld A,B - sbc a,(hl) - inc hl ;middle byte - ld A,E - sbc a,(hl) ;carry if .fcb(ranrec) > directory - jr c,getnextsize ;for another try - -;fcb is less or equal, fill from directory - - ld (hl),E - dec hl - ld (hl),B - dec hl - ld (hl),C - -getnextsize: - - call searchn - jr getsize - -setsize: - - pop hl ;discard .fcb(ranrec) - ret - -setrandom: -;set random record from the current file control block - - ld hl,(info) - ld de,nxtrec ;ready params for computesize - call compute$rr ;DE=info, A=cy, BC=mmmm eeee errr rrrr - ld hl,ranrec - add hl,de ;HL = .fcb(ranrec) - ld (hl),C - inc hl - ld (hl),B - inc hl - ld (hl),A ;to ranrec - ret - -TMPSELECT: - - ld hl,SELDSK - ld (hl),E - -CURSELECT: - - ld a,(SELDSK) - ld hl,CURDSK - cp (hl) - jr nz,SELECT - cp 0FFH - ret nz - -select: -;select disk info for subsequent input or output ops - - ld (hl),A - ld D,A - ld hl,(DLOG) - call TEST$VECTOR - ld E,A - push de - call selectdisk - pop hl ;recall dlog vector - jp nc,SEL$ERROR ;returns with CARRY SET if select ok - -;is the disk logged in? - - dec L - ret z ;return if bit is set - -;disk not logged in, set bit and initialize - - call INITIALIZE - ld hl,(LSN$ADD) - ld A,(hl) - and 1 - push af - add a,(hl) - ld (hl),A - pop af - call nz,SET$RLOG - jp SET$DLOG - ;ret - -RESELECTX: - - ld hl,CHECK$FCB - push hl - -reselect: -;check current fcb to see if reselection necessary - - ld A,true - ld (resel),a ;mark possible reselect - ld hl,(info) - ld A,(hl) ;drive select code - ld (FCBDSK),a - and 11111b ;non zero is auto drive select - dec A ;drive code normalized to 0..30, or 255 - jp m,noselect ; SCC 22 Apr 84 - - ld (SELDSK),a - -noselect: - - call CURSELECT - -;set user code - - ld a,(usrcode) ;0...15 - ld hl,(info) - ld (hl),A - -NOSELECT0: - - call TST$LOG$FXS - ret nz - call FUNC48 - -NOSELECT1: - - ld C,0FFH - jp ?discd - - subttl Individual Function Handlers -func12: -;return version number - - ld A,dvers - jp sta$ret ;lret = dvers (high = 00) - ;ret ;jmp goback -page -func13: -;reset disk system - initialize to disk 0 - - ld hl,0 - ld (rodsk),hl - ld (dlog),hl - xor A - ld (ACTDSK),a - dec A - ld (CURDSK),a - -;note that usrcode remains unchanged - - ld hl,tbuff - ld (dmaad),hl ;dmaad = tbuff - call SETDATA ;to data dma address - jr NOSELECT1 - ;ret ;jmp goback -page -FUNC14: - - call TMPSELECT - ld a,(SELDSK) - ld (ACTDSK),a - ret - -page -func15: -;open file - - call clrmodnum ;clear the module number - call reselect - call OPEN - call OPENX - ld a,(DIRLOC) - inc A - ret z - ld hl,(SDCNT) - ld A,L - and 0FCH - ld L,A - dec hl - ld (DCNT),hl - ld hl,(INFO) - ld (hl),0 - call SEARCHN - call OPEN1 - call OPENX - ret - -OPENX: - - call END$OF$DIR - ret z - pop hl - ld a,(USRCODE) - ld hl,(INFO) - cp (hl) - jr z,OPENX1 - - ld de,10 ;test file attribute t2' - add hl,de ;for sys | dir status - ld A,(hl) - and 80H - jr nz,openx2 ;system, allow open SCC 22 Apr 84 - - inc hl ;bump ptr to ext field SCC 22 Apr 84 - inc hl ; SCC 22 Apr 84 - ld (hl),a ;zero remainder of FCB SCC 22 Apr 84 - ld d,h ; SCC 22 Apr 84 - ld e,l ; SCC 22 Apr 84 - inc de ; SCC 22 Apr 84 - ld bc,19 ; SCC 22 Apr 84 - ldir ; SCC 22 Apr 84 - jp lret$eq$FF ;flag open failure SCC 22 Apr 84 - -openx2: ; SCC 22 Apr 84 - ld de,4 - add hl,de - ld A,(hl) - or 40H - ld (hl),A - -OPENX1: - - ld de,OLOG - call SET$CDISK - jp SET$LSN - ;ret ;jmp goback -page -func16: -;close file - - call reselect - call CLOSE - jp SET$LSN - ;ret ;jmp goback -page -func17: -;search for first occurence of a file - - ex de,hl - xor A - -CSEARCH: - - push af - ld A,(hl) - cp '?' - jr nz,CSEARCH1 - call CURSELECT - call NOSELECT0 - ld C,0 - jr CSEARCH2 - -CSEARCH1: - - call GETEXTA - ld A,(hl) - cp '?' - call nz,CLRMODNUM - call RESELECT - ld C,NAMLEN - -CSEARCH2: - - pop af - ld hl,DIR$TO$USER - push hl - jp z,SEARCH - jp SEARCHN -page - -func18: -;search for next occurence of a file - - ld hl,(SEARCHA) - ld (INFO),hl - or 1 - jr CSEARCH -page -FUNC19 equ DELETE -;delete a file - -FUNC20 equ SEQDISKREAD -;read a file - -FUNC21 equ SEQDISKWRITE -;write a file -page - -func22: -;make a file - - call clrmodnum - call reselect - call MAKE - jr OPENX1 - ;ret ;jmp goback - -FUNC23 equ RENAME -;rename a file - -func24: -;return the login vector - - ld hl,(dlog) - jr sthl$ret - ;ret ;jmp goback - -func25: -;return selected disk number - - ld a,(SELDSK) - jp sta$ret - ;ret ;jmp goback - -func26: -;set the subsequent dma address to info - - ex de,hl ;was lhld info - ld (dmaad),hl ;dmaad = info - jp setdata ;to data dma address - ;ret ;jmp goback - -func27: -;return the login vector address - - call CURSELECT - ld hl,(alloca) - jr sthl$ret - ;ret ;jmp goback - -func28 equ set$ro -;write protect current disk - - ;ret ;jmp goback - -func29: -;return r/o bit vector - - ld hl,(rodsk) - jr sthl$ret - ;ret ;jmp goback - -FUNC30 equ INDICATORS -;set file indicators - -func31: -;return address of disk parameter block - - call CURSELECT - ld hl,(dpbaddr) - -sthl$ret: - - ld (aret),hl - ret ;jmp goback - -func32: -;GET/SET USER CODE - - ld hl,USRCODE - -;DOES REG E = FFH? - - ld A,E - inc A - ld A,(hl) - jp z,STA$RET ; YES - RETURN USER - -;SET USER NUMBER - - ld A,E - and 0FH - ld (hl),A - ret - -FUNC33 equ RANDISKREAD -;random disk read operation - -FUNC34 equ RANDISKWRITE -;random disk write operation - -FUNC35 equ GETFILESIZE -;return file size (0-65536) - -func36 equ setrandom -;set random record - ;ret ;jmp goback - -func37: -;drive reset - - ex de,hl - -RESET37X: - - push hl - ld A,L - cpl - ld E,A - ld A,H - cpl - ld hl,(dlog) - and H - ld D,A - ld A,L - and E - ld E,A - ld hl,(rodsk) - ex de,hl - ld (dlog),hl - ld A,L - and E - ld L,A - ld A,H - and D - ld H,A - ld (rodsk),hl - ld A,0FFH - ld (CURDSK),a - ld (SCAN$FLAG),a - pop hl - jp SD$0 - -func38 equ func$ret - -func39 equ func$ret - -FUNC40 equ RANDISKWRITE - -FUNC45: -;SET BDOS ERROR MODE - - ld A,E - ld (ERRMODE),a - ret - -FUNC48: -;FLUSH BUFFERS - - call ?flush - jp DIOCOMP - subttl BDOS call termination - -GOBACK0: - - ld hl,0FFFFH - ld (ARET),hl - -goback: -;arrive here at end of processing to return to user - - ld a,(resel) - or A - jr z,retmon - -;reselection may have taken place - - ld hl,(INFO) - ld a,(FCBDSK) - ld (hl),A - -;return from the disk monitor -retmon: - - ld sp,(entsp) ;user stack restored - ld hl,(aret) - ld A,L - ld B,H ;BA = HL = aret - ret - subttl Initialized Data Areas - -efcb: - - defb empty ;0e5=available dir entry - -LOG$FXS: - - defb 15,16,17,19,22,23,30,35,0 - -RW$FXS: - - defb 20,21,33,34,40,0 - -SC$FXS: - - defb 16,18 - subttl CPMERR - console error message routine -;***************************************************************** -;***************************************************************** -;** ** -;** S I M P L E C P / M ** -;** ** -;** S t a n d a r d E r r o r R o u t i n e ** -;** ** -;***************************************************************** -;***************************************************************** - -cpmerr: ; c = error # - - ld B,0 - dec C - ld hl,errtbl - add hl,bc - add hl,bc - ld E,(hl) - inc hl - ld D,(hl) - -;stack message address, advance to new line - push de - call crlf - -;print error prefix - ld bc,dskmsg - call print - -;identify drive - ld a,(seldsk) - add a,'A' - ld C,A - call conout - -;print colon and space - ld bc,colon - call print - -;print error message tail - pop bc - jp print - -errtbl: defw permsg,rodmsg,rofmsg,selmsg - -dskmsg: defb 'CP/M Error On $' -colon: defb ': $' -permsg: defb 'Disk I/O$' -selmsg: defb 'Invalid Drive$' -rofmsg: defb 'Read/Only File$' -rodmsg: defb 'Read/Only Disk$' - -;------------------------------------------------------------------------------ - - subttl Data Segment - - if standard - dseg - endif - - public DLOG - public RODSK - public FX - public ERRMODE - public LISTCP - public KBCHAR - public SUB$FLAG - public INFO - public ARET - public ARECORD - public SELDSK - public CONMODE - public out$delim - -BDOS$DT equ $ - - if data_low -?bdos equ $+6 - defs front_size - endif - -dlog: defs WORD ;logged-in disks -rodsk: defs WORD ;read only disk vector -dmaad: defs WORD ;initial dma address - -; -; curtrka - alloca are set upon disk select -; (data must be adjacent, do not insert variables) -; (address of translate vector, not used) -; - -cdrmaxa: defs word ;pointer to cur dir max value -curtrka: defs word ;current track address -curreca: defs word ;current record address -buffa: defs word ;pointer to directory dma address -dpbaddr: defs word ;current disk parameter block address -checka: defs word ;current checksum vector address -alloca: defs word ;current allocation vector address - -addlist equ $-buffa ;address list size - -; -; sectpt - offset obtained from disk parm block at dpbaddr -; (data must be adjacent, do not insert variables) -; - -sectpt: defs word ;sectors per track -blkshf: defs byte ;block shift factor -blkmsk: defs byte ;block mask -extmsk: defs byte ;extent mask -maxall: defs word ;maximum allocation number -dirmax: defs word ;largest directory number -dirblk: defs word ;reserved allocation bits for directory -chksiz: defs word ;size of checksum vector -offset: defs word ;offset tracks at beginning - -dpblist equ $-sectpt ;size of area - -; -; local variables -; - -tranv: defs word ;address of translate vector -fcb$copied: defs byte ;set true if copy$fcb called -rmf: defs byte ;read mode flag for open$reel -dirloc: defs byte ;directory flag in rename, etc. -dminx: defs byte ;local for diskwrite -searchl: defs byte ;search length -searcha: defs word ;search address -single: defs byte ;set true if single byte allocation map -fcbdsk: defs byte ;disk named in fcb -rcount: defs byte ;record count in current fcb -extval: defs byte ;extent number and extmsk -vrecord: defs BYTE ;current virtual record -arecord: defs word ;current actual record -arecord1: defs word ;current actual block# * blkmsk - -; -; local variables for directory access -; - -dptr: defs byte ;directory pointer 0,1,2,3 -dcnt: defs word ;directory counter 0,1,...,dirmax - -entsp: defs word ;entry stack pointer - defs ssize*2 ;stack size - -lstack: - -info: defs word ;information address -aret: defs word ;address value to return -lret equ aret ;low(aret) - -; RESEL & RELOG ARE INITIALIZED AS A PAIR AT BDOS ENTRY - -resel: defs byte ;reselection flag -RELOG: defs BYTE ;RELOG DRIVE SWITCH -save$pos: defs BYTE ;SAVE BEGINNING FUNCTION 10 BUFF POS -LSN$ADD: defs WORD ;LOGIN SEQ # ADDRESS -LSN$NS: defs 16 ;LOGIN SEQUENCE #S (1 PER DRIVE) -SDCNT: defs WORD ;SAVE USER 0 DCNT FOR OPEN FX - -USER0$SEARCH: defs WORD ;USER 0 SEARCH FLAG FOR OPEN FX -CURDSK: defs BYTE ;CURRENT DISK NUMBER -ACTDSK: defs BYTE ;ACTUAL SELECTED DISK NUMBER -SELDSK: defs BYTE ;CURRENTLY SELECTED DISK NUMBER - -OUT$DELIM: defs BYTE ;FUNCTION 9 (PRINT) DELIMITER - -; The following two variables are set to zero by the -; CCP prior to passing control to a loaded transient program. - -OLOG: defs WORD ;FILE OPEN DRIVE VECTOR -RLOG: defs WORD ;MEDIA CHANGE DRIVE VECTOR -subttl Reinitialized data - -; The following variables are initialized to zero by the BDOS -; warm start initialization routine (WS$INIT) and the -; cold start initialization routine (CS$INIT) - -column: defs byte ;column position -usrcode: defs byte ;current user number -kbchar: defs byte ;initial key char = 00 -compcol: defs byte ;true if computing column position -strtcol: defs byte ;starting column position after read - -FX: defs BYTE ;CURRENT BDOS FUNCTION NUMBER -ERRMODE: defs BYTE ;BDOS ERROR MODE (NORMAL,RETURN,RET & DISPLAY) -SCAN$FLAG: defs BYTE ;SCAN$DRIVE FLAG (FF=DRIVE RESET,0=WS$INIT) -CONMODE: defs BYTE ;CONSOLE MODE (BIT 2 = RAW OUTPUT, BIT 4 = ESD) - -WS$INIT$SIZE equ $-COLUMN - - - - - -; -; The following variables are initialized to zero by the BDOS -; cold start initialization routine (CS$INIT) -; - -listcp: defs byte ;listing toggle -FX10FLG: defs BYTE ;CCP FUNCTION 10 (^C) FLAG -SUB$FLAG: defs BYTE ;SUBMIT FLAG ($$$.SUB FILE ON A) -SUBWORK: defs 20 ;CCP SUBMIT WORK AREA - -CS$INIT$SIZE equ $-COLUMN - - cseg ;this code makes the code segment begin on a - ; page boundry -LAST: - defb 0 - - org (((LAST-BASE)+255) AND 0FF00H) - 1 - defb 0 - subttl BIOS access constants - -BIOS equ $ - -bootf equ bios+3*0 ;cold boot function -wbootf equ bios+3*1 ;warm boot function -constf equ bios+3*2 ;console status function -coninf equ bios+3*3 ;console input function -conoutf equ bios+3*4 ;console output function -listf equ bios+3*5 ;list output function -punchf equ bios+3*6 ;punch output function -readerf equ bios+3*7 ;reader input function -homef equ bios+3*8 ;disk home function -seldskf equ bios+3*9 ;select disk function -settrkf equ bios+3*10 ;set track function -setsecf equ bios+3*11 ;set sector function -setdmaf equ bios+3*12 ;set dma function -readf equ bios+3*13 ;read disk function -writef equ bios+3*14 ;write disk function -liststf equ bios+3*15 ;list status function -sectran equ bios+3*16 ;sector translate - - end - \ No newline at end of file diff --git a/cpm/pcpm/CCP.MAC b/cpm/pcpm/CCP.MAC deleted file mode 100644 index 0fb47a0..0000000 --- a/cpm/pcpm/CCP.MAC +++ /dev/null @@ -1,1660 +0,0 @@ - title Console Command Processor (ccp), ver 2.0 -; assembly language version of the cp/m console command processor -; -; Personal CP/M version 1.0 May 1984 -; -; COPYRIGHT (C) 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984 -; Digital Research -; Box 579, Pacific Grove, -; California, 93950 -; -false equ 0000h -true equ not false -; -; - - cseg - -BASE equ $ -BDOSL equ BASE+800H -SUBADDR equ BDOSL+09H -ZEROADD equ BDOSL+0BH -tran equ 100h -tranm equ $ -ccploc equ $ - - -; ******************************************************** -; * base of ccp contains the following code/data * -; * ccp: jmp ccpstart (start with command) * -; * jmp ccpclear (start, clear command) * -; * ccp+6 127 (max command length) * -; * ccp+7 comlen (command length = 00) * -; * ccp+8 ' ... ' (16 blanks) * -; ******************************************************** -; * normal entry is at ccp, where the command line given * -; * at ccp+8 is executed automatically (normally a null * -; * command with comlen = 00). an initializing program * -; * can be automatically loaded by storing the command * -; * at ccp+8, with the command length at ccp+7. in this * -; * case, the ccp executes the command before prompting * -; * the console for input. note that the command is exe-* -; * cuted on both warm and cold starts. when the command* -; * line is initialized, a jump to "jmp ccpclear" dis- * -; * ables the automatic command execution. * -; ******************************************************** - - jp ccpstart ;start ccp with possible initial command - - jp ccpclear ;clear the command buffer - -maxlen: defb 127 ;max buffer length -comlen: defb 6 ;command length - -combuf: - - defb 'VCCPLD ' ;8 character fill - defb ' ' ;8 character fill - defb 'COPYRIGHT (C) 1984, DIGITAL RESEARCH ' ; 38 - defs 128-($-combuf) - ;total buffer length is 128 characters - -comaddr: defw combuf ;address of next to char to scan -staddr: defs 2 ;starting address of current fillfcb request - -diska equ 0004h ;disk address for current disk -bdos equ 0005h ;primary bdos entry point -buff equ 0080h ;default buffer -fcb equ 005ch ;default file control block - -rcharf equ 1 ;read character function -pcharf equ 2 ;print character function -pbuff equ 9 ;print buffer function -rbuff equ 10 ;read buffer function -breakf equ 11 ;break key function -liftf equ 12 ;lift head function (no operation) -initf equ 13 ;initialize bdos function -self equ 14 ;select disk function -openf equ 15 ;open file function -closef equ 16 ;close file function -searf equ 17 ;search for file function -searnf equ 18 ;search for next file function -delf equ 19 ;delete file function -dreadf equ 20 ;disk read function -dwritf equ 21 ;disk write function -makef equ 22 ;file make function -renf equ 23 ;rename file function -logf equ 24 ;return login vector -cself equ 25 ;return currently selected drive number -dmaf equ 26 ;set dma address -userf equ 32 ;set user number - -; -; special fcb flags -; - -rofile equ 9 ;read only file -sysfile equ 10 ;system file flag - -; -; special characters -; - -cr equ 13 ;carriage return -lf equ 10 ;line feed -la equ 5fh ;left arrow -eofile equ 1ah ;end of file - -; -; utility procedures -; - -printchar: - - ld E,A - ld C,pcharf - jp bdos - -printbc: -;print character, but save b,c registers - - push bc - call printchar - pop bc - ret - -crlf: - - ld A,cr - call printbc - ld A,lf - jr printbc - -blank: - - ld A,' ' - jr printbc -Šprint: -;print string starting at b,c until next 00 entry - - push bc - call crlf - pop hl ;now print the string - -prin0: - - ld A,(hl) - or A - ret z ;stop on 00 - inc hl - push hl ;ready for next - call printchar - pop hl ;character printed - jr prin0 ;for another character - -initialize: - - ld C,initf - jp bdos - -select: - - ld E,A - ld C,self - jp bdos - -openc: -;open comfcb - - xor A - ld (comrec),a ;clear next record to read - ld de,comfcb - -open: -;open the file given by d,e - - ld C,openf - -bdos$inr: - - call bdos - ld (dcnt),a - inc A - ret - -close: -;close the file given by d,e - - ld C,closef - jr bdos$inr - -search: -;search for the file given by d,e - - ld C,searf - jr bdos$inr - -searchn: -;search for the next occurrence of the file given by d,e - - ld C,searnf - jr bdos$inr - -searchcom: -;search for comfcb file - - ld de,comfcb - jr search - -delete: -;delete the file given by d,e - - ld C,delf - jp bdos - -bdos$cond: - - call bdos - or A - ret - -diskread: -;read the next record from the file given by d,e - - ld C,dreadf - jr bdos$cond - -diskreadc: -;read the comfcb file - - ld de,comfcb - jr diskread - -diskwrite: -;write the next record to the file given by d,e - - ld C,dwritf - jr bdos$cond -Šmake: -;create the file given by d,e - - ld C,makef - jr bdos$inr - -renam: -;rename the file given by d,e - - ld C,renf - jp bdos - -getuser: -;return current user code in a - - ld E,0ffh ;drop through to setuser - -setuser: - - ld (USERNO),a - ld C,userf - jp bdos ;sets user number - -saveuser: -;save user#/disk# before possible ^c or transient - - call GETUSER - ld (USERNO),a - add a,A - add a,A - add a,A - add a,A ;rot left - ld hl,cdisk - or (hl) ;4b=user, 4b=disk - ld (diska),a ;stored away in memory for later - ret - -translate: -;translate character in register a to upper case - - cp 61h - ret c ;return if below lower case a - cp 7bh - ret nc ;return if above lower case z - and 5fh - ret ;translated to upper case - -COPY$SUBFCB: - - ld hl,(SUBADDR) - inc hl - ld de,SUB$S1 - ld B,21 - or A - jr nz,COPY$SF1 - ex de,hl - -COPY$SF1: - - dec B - ret z - ld A,(hl) - ld (de),a - inc hl - inc de - jr COPY$SF1 - -readcom: -;read the next command into the command buffer -;check for submit file - - ld hl,(SUBADDR) - ld A,(hl) - or A - jr z,NOSUB - inc A - jr z,OPEN$SUB - call COPY$SUBFCB - jr READ$SUB - -OPEN$SUB: - - push hl - ld de,SUBFCB - call OPEN - pop hl - ld (hl),0 - jr z,NOSUB - inc (hl) - -READ$SUB: - - call SETDMABUFF - -;change drives to open and read the file - - ld a,(subrc) - dec A ;read last record(s) first - ld (subcr),a ;current record to read - ld de,subfcb - call diskread ;end of file if last record - jr nz,nosub -Š;disk read is ok, transfer to combuf - - ld de,comlen - ld hl,buff - ld B,128 - call move0 - -;line is transferred, close the file with a -;deleted record - - ld hl,SUBRC - dec (hl) ; ONE LESS RECORD - xor A - call COPY$SUBFCB - -;print to the 00 - - ld hl,combuf - call prin0 - call break$key - jr z,noread - call del$sub - jp ccp ;break key depressed - -nosub: -;no submit file - - call del$sub - -;translate to upper case, store zero at end - - call saveuser ;user # save in case control c - ld hl,(SUBADDR) - dec hl - ld (hl),0FFH - push hl - ld C,rbuff - ld de,maxlen - call bdos - pop hl - ld (hl),0 - -noread: -;enter here from submit file -;set the last character to zero for later scans - - ld hl,comlen - ld B,(hl) ;length is in b - -readcom0: - - inc hl - ld A,B - or A ;end of scan? - jr z,readcom1 - ld A,(hl) ;get character and translate - call translate - ld (hl),A - dec B - jr readcom0 - -readcom1: -;end of scan, h,l address end of command - - ld (hl),A ;store a zero - ld hl,combuf - ld (comaddr),hl ;ready to scan to zero - ret - -break$key: -;check for a character ready at the console - - ld C,breakf - call bdos - or A - ret z - ld C,rcharf - call bdos ;character cleared - or A - ret - -cselect: -;get the currently selected drive number to reg-a - - ld C,cself - jp bdos - -setdmabuff: -;set default buffer dma address - - ld de,buff ;(drop through) - -setdma: -;set dma address to d,e - - ld C,dmaf - jp bdos - -del$sub: -;delete the submit file, and set submit flag to false - - ld hl,(SUBADDR) - ld A,(hl) - or A - ret z ;return if no sub file - ld (hl),0 ;submit flag is set to false - ld de,subfcb - jp delete - -comerr: -;error in command string starting at position -;'staddr' and ending with first delimiter - - call crlf ;space to next line - ld hl,(staddr) ;h,l address first to print -comerr0: -;print characters until blank or zero - - ld A,(hl) - cp ' ' - jr z,comerr1 ; not blank - or A - jr z,comerr1 ; not zero, so print it - push hl - call printchar - pop hl - inc hl - jr comerr0 ; for another character - -comerr1: -;print question mark,and delete sub file - - ld A,'?' - call printchar - call crlf - call del$sub - jp ccp ;restart with next command - -; -; fcb scan and fill subroutine (entry is at fillfcb below) -;fill the comfcb, indexed by a (0 or 16) -;subroutines -; - -delim: -;look for a delimiter - - ld a,(de) - or A - ret z ;not the last element - cp ' ' - jr c,comerr ;non graphic - ret z ;treat blank as delimiter - cp '=' - ret z - cp la - ret z ;left arrow - cp '.' - ret z - cp ':' - ret z - cp ';' - ret z - cp '<' - ret z - cp '>' - ret z - ret ;delimiter not found - -deblank: -;deblank the input line - - ld a,(de) - or A - ret z ;treat end of line as blank - cp ' ' - ret nz - inc de - jr deblank - -addh: -;add a to h,l - - add a,L - ld L,A - ret nc - inc H - ret - -fillfcb0: -;equivalent to fillfcb(0) - - ld A,0 - -fillfcb: - - ld hl,comfcb - call addh - push hl - push hl ;fcb rescanned at end - xor A - ld (sdisk),a ;clear selected disk (in case a:...) - ld hl,(comaddr) - ex de,hl ;command address in d,e - call deblank ;to first non-blank character - ex de,hl - ld (staddr),hl ;in case of errors - ex de,hl - pop hl ;d,e has command, h,l has fcb address - -;look for preceding file name a: b: ... - - ld a,(de) - or A - jr z,setcur0 ;use current disk if empty command - sbc a,'A'-1 - ld B,A ;disk name held in b if : follows - inc de - ld a,(de) - cp ':' - jr z,setdsk ;set disk name if : - -setcur: -;set current disk -Š dec de ;back to first character of command - -setcur0: - - ld a,(cdisk) - ld (hl),A - jr setname - -setdsk: -;set disk to name in register b - - ld A,B - ld (sdisk),a ;mark as disk selected - ld (hl),B - inc de ;past the : - -setname: -;set the file name field - - ld B,8 ;file name length (max) - -setnam0: - - call delim - jr z,padname ;not a delimiter - inc hl - cp '*' - jr nz,setnam1 ;must be ?'s - ld (hl),'?' - jr setnam2 ;to dec count - -setnam1: - - ld (hl),A ;store character to fcb - inc de - -setnam2: - - dec B ;count down length - jr nz,setnam0 - -;end of name, truncate remainder - -trname: - - call delim - jr z,setty ;set type field if delimiter - inc de - jr trname - -padname: - - inc hl - ld (hl),' ' - dec B - jr nz,padname - -setty: -;set the type field - - ld B,3 - cp '.' - jr nz,padty ;skip the type field if no . - inc de ;past the ., to the file type field - -setty0: -;set the field from the command buffer - - call delim - jr z,padty - inc hl - cp '*' - jr nz,setty1 - ld (hl),'?' ;since * specified - jr setty2 - -setty1: -;not a *, so copy to type field - - ld (hl),A - inc de - -setty2: -;decrement count and go again - - dec B - jr nz,setty0 - -;end of type field, truncate - -trtyp: -;truncate type field - - call delim - jr z,efill - inc de - jr trtyp - -padty: -;pad the type field with blanks - - inc hl - ld (hl),' ' - dec B - jr nz,padty - -efill: -;end of the filename/filetype fill, save command address -;fill the remaining fields for the fcb - - ld B,3 - -efill0: - - inc hl - ld (hl),0 - dec B - jr nz,efill0 - ex de,hl - ld (comaddr),hl ;set new starting point - -;recover the start address of the fcb and count ?'s - - pop hl - ld bc,11 ;b=0, c=8+3 - -scnq: - - inc hl - ld A,(hl) - cp '?' - jr nz,scnq0 - -;? found, count it in b - - inc B - -scnq0: - - dec C - jr nz,scnq - -;number of ?'s in c, move to a and return with flags set -Š ld A,B - or A - ret - -intvec: -;intrinsic function names (all are four characters) - - defb 'DIR ' - defb 'ERA ' - defb 'TYPE' - defb 'SAVE' - defb 'REN ' - defb 'USER' - -intlen equ ($-intvec)/4 ;intrinsic function length - - -intrinsic: -;look for intrinsic functions (comfcb has been filled) - - ld hl,intvec - ld C,0 ;c counts intrinsics as scanned - -intrin0: - - lä A,C - cp intlen ;done with scan? - ret nc - -;no, more to scan - - ld de,comfcb+1 ;beginning of name - ld B,4 ;length of match is in b - -intrin1: - - ld a,(de) - cp (hl) ;match? - jr nz,intrin2 ;skip if no match - inc de - inc hl - dec B - jr nz,intrin1 ;loop while matching - -;complete match on name, check for blank in fcb - - ld a,(de) - cp ' ' - jr nz,intrin3 ;otherwise matched - ld A,C - ret ;with intrinsic number in a - -intrin2: -;mismatch, move to end of intrinsic - - inc hl - dec B - jr nz,intrin2 - -intrin3: -;try next intrinsic - - inc C ;to next intrinsic number - jr intrin0 ;for another round - -ccpclear: -;clear the command buffer - - xor A - ld (comlen),a - -;drop through to start ccp - -ccpstart: -;enter here from boot loader - - ld sp,stack - push bc ;save initial disk number - -;(high order 4bits=user code, low 4bits=disk#) - - ld A,C - rra - rra - rra - rra - and 0fh ;user code - ld E,A - call setuser ;user code selected - ld hl,(SUBADDR) - dec hl - ld A,(hl) - ld (hl),0 - or A - call nz,INITIALIZE - pop bc ;recall user code and disk number - ld A,C - and 0fh ;disk number in accumulator - ld (cdisk),a ;clears user code nibble - call select ;proper disk is selected, now check sub files - -;check for initial command - - ld a,(comlen) - or A - jr nz,ccp0 ;assume typed already -Šccp: -;enter here on each command or error condition - - ld sp,stack - call crlf ;print d> prompt, where d is disk name - ld a,(USERNO) - or A - jr z,CCP002 - cp 10 - jr c,CCP001 - push af - ld A,'1' - call PRINTCHAR - pop af - sub 10 - -CCP001: - - add a,30H - call PRINTCHAR - -CCP002: - - call cselect ;get current disk number - add a,'A' - call printchar - ld A,'>' - call printchar - call readcom ;command buffer filled -ccp0: -;(enter here from initialization with command full) - - call SETDMABUFF ;default dma address at buff - call cselect - ld (cdisk),a ;current disk number saved - call fillfcb0 ;command fcb filled - call nz,comerr ;the name cannot be an ambiguous reference - ld a,(sdisk) - or A - jp nz,userfunc - -;check for an intrinsic function - - call intrinsic - ld hl,jmptab ;index is in the accumulator - ld E,A - ld D,0 - add hl,de - add hl,de ;index in d,e - ld A,(hl) - inc hl - ld H,(hl) - ld L,A - jp (hl) - -;pc changes to the proper intrinsic or user function - -jmptab: - - defw direct ;directory search - defw erase ;file erase - defw type ;type file - defw save ;save memory image - defw rename ;file rename - defw user ;user number - defw userfunc ;user-defined function - -; -;utility subroutines for intrinsic handlers -; - -readerr: -;print the read error message - - ld bc,rdmsg - jp print - -rdmsg: defb 'READ ERROR',0 - - -nofile: -;print no file message - - ld bc,nofmsg - jp print - -nofmsg: defb 'NO FILE',0 - - -getnumber: -;read a number from the command line - - call fillfcb0 ;should be number - ld a,(sdisk) - or A - jp nz,comerr ;cannot be prefixed - -;convert the byte value in comfcb to binary - - ld hl,comfcb+1 - ld bc,11 ;(b=0, c=11) - -;value accumulated in b, c counts name length to zero - -conv0: - - ld A,(hl) - cp ' ' - jr z,conv1 -Š;more to scan, convert char to binary and add - - inc hl - sub '0' - cp 10 - jp nc,comerr ;valid? - ld D,A ;save value - ld A,B ;mult by 10 - and 11100000b - jp nz,comerr - ld A,B ;recover value - rlca - rlca - rlca ;*8 - add a,B - jp c,comerr - add a,B - jp c,comerr ;*8+*2 = *10 - add a,D - jp c,comerr ;+digit - ld B,A - dec C - jr nz,conv0 ;for another digit - ret - -conv1: -;end of digits, check for all blanks - - ld A,(hl) - cp ' ' - jp nz,comerr ;blanks? - inc hl - dec C - jr nz,conv1 - ld A,B ;recover value - ret - -movename: -;move 3 characters from h,l to d,e addresses - - ld B,3 - -move0: - - ld A,(hl) - ld (de),a - inc hl - inc de - dec B - jr nz,move0 - ret - -addhcf: -;buff + a + c to h,l followed by fetch - - ld hl,buff - add a,C - call addh - ld A,(hl) - ret - -setdisk: -;change disks for this command, if requested - - xor A - ld (comfcb),a ;clear disk name from fcb - ld a,(sdisk) - or A - ret z ;no action if not specified - dec A - ld hl,cdisk - cp (hl) - ret z ;already selected - jp select - -resetdisk: -;return to original disk after command - - ld a,(sdisk) - or A - ret z ;no action if not selected - dec A - ld hl,cdisk - cp (hl) - ret z ;same disk - ld a,(cdisk) - jp select - -; -;individual intrinsics follow -; - -direct: -;directory search - - call fillfcb0 ;comfcb gets file name - call setdisk ;change disk drives if requested - ld hl,comfcb+1 - ld A,(hl) ;may be empty request - cp ' ' - jr nz,dir1 ;skip fill of ??? if not blank - -;set comfcb to all ??? for current disk - - ld B,11 ;length of fill ????????.??? - -dir0: - - ld (hl),'?' - inc hl - dec B - jr nz,dir0 - -;not a blank request, must be in comfcb - -dir1: - - lä E,0 - push de ;e counts directory entries - call searchcom ;first one has been found - call z,nofile ;not found message - -dir2: - - jr z,endir - -;found, but may be system file -Š ld a,(dcnt) ;get the location of the element - rrca - rrca - rrca - and 1100000b - ld C,A - -;c contains base index into buff for dir entry - - ld A,sysfile - call addhcf ;value to a - rla - jr c,dir6 ;skip if system file - -;c holds index into buffer -;another fcb found, new line? - - pop de - ld A,E - inc E - push de - -;e=0,1,2,3,...new line if mod 4 = 0 - - and 11b - push af ;and save the test - jr nz,dirhdr0 ;header on current line - call crlf - push bc - call cselect - pop bc - -;current disk in a - - add a,'A' - call printbc - ld A,':' - call printbc - jr dirhdr1 ;skip current line hdr - -dirhdr0: - - call blank ;after last one - ld A,':' - call printbc - -dirhdr1: - - call blank - -;compute position of name in buffer - - ld B,1 ;start with first character of name - -dir3: - - ld A,B - call addhcf ;buff+a+c fetched - and 7fh ;mask flags - -;may delete trailing blanks - - cp ' ' - jr nz,dir4 ;check for blank type - pop af - push af ;may be 3rd item - cp 3 - jr nz,dirb ;place blank at end if not - ld A,9 - call addhcf ;first char of type - and 7fh - cp ' ' - jr z,dir5 - -;not a blank in the file type field - -dirb: - - ld A,' ' ;restore trailing filename chr - -dir4: - - call printbc ;char printed - inc B - ld A,B - cp 12 - jr nc,dir5 - -;check for break between names - - cp 9 - jr nz,dir3 ;for another char - -;print a blank between names - - call blank - jr dir3 - -dir5: -;end of current entry - - pop af ;discard the directory counter (mod 4) - -dir6: - - call break$key ;check for interrupt at keyboard - jr nz,endir ;abort directory search - call searchn - jr dir2 ;for another entry - -endir: -;end of directory scan - - pop de ;discard directory counter - jp retcom - -erase: - - call fillfcb0 ;cannot be all ???'s - cp 11 - jr nz,erasefile -Š;erasing all of the disk - - ld bc,ermsg - call print - - call readcom - ld hl,comlen - dec (hl) - jp nz,ccp ;bad input - inc hl - ld A,(hl) - cp 'Y' - jp nz,ccp - -;ok, erase the entire diskette - - inc hl - ld (comaddr),hl ;otherwise error at retcom - -erasefile: - - call setdisk - ld de,comfcb - call delete - inc A ;255 returned if not found - call z,nofile ;no file message if so - jp retcom - - -ermsg: defb 'ALL (Y/N)?',0 - - -type: - - call fillfcb0 - jp nz,comerr ;don't allow ?'s in file name - call setdisk - call openc ;open the file - jr z,typerr ;zero flag indicates not found - -;file opened, read 'til eof - - call crlf - ld hl,bptr - ld (hl),255 ;read first buffer - -type0: -;loop on bptr - - ld hl,bptr - ld A,(hl) - cp 128 ;end buffer - jr c,type1 - push hl ;carry if 0,1,...,127 - -;read another buffer full - - call diskreadc - pop hl ;recover address of bptr - jr nz,typeof ;hard end of file - xor A - ld (hl),A ;bptr = 0 - -type1: -;read character at bptr and print - - inc (hl) ;bptr = bptr + 1 - ld hl,buff - call addh ;h,l addresses char - ld A,(hl) - cp eofile - jp z,retcom - call printchar - call break$key - jp nz,retcom ;abort if break - jr type0 ;for another character - -typeof: -;end of file, check for errors - - dec A - jp z,retcom - call readerr - -typerr: - - call resetdisk - jp comerr - -save: - - call getnumber ; value to register a - push af ;save it for later - -;should be followed by a file to save the memory image - - call fillfcb0 - jp nz,comerr ;cannot be ambiguous - call setdisk ;may be a disk change - ld de,comfcb - push de - call delete ;existing file removed - pop de - call make ;create a new file on disk - jr z,saverr ;no directory space - xor A - ld (comrec),a ; clear next record field - pop af ;#pages to write is in a, change to #sectors -Š ld L,A - ld H,0 - add hl,hl - - ld de,tran ;h,l is sector count, d,e is load address - -save0: -;check for sector count zero - - ld A,H - or L - jr z,save1 ;may be completed - dec hl ;sector count = sector count - 1 - push hl ;save it for next time around - ld hl,128 - add hl,de - push hl ;next dma address saved - call setdma ;current dma address set - ld de,comfcb - call diskwrite - pop de - pop hl ;dma address, sector count - jr nz,saverr ;may be disk full case - jr save0 ;for another sector - -save1: -;end of dump, close the file - - ld de,comfcb - call close - inc A ; 255 becomes 00 if error - jr nz,retsave ;for another command - -saverr: -;must be full or read only disk - - ld bc,fullmsg - call print - -retsave: -;reset dma buffer - - call setdmabuff - jp retcom - - -fullmsg: defb 'NO SPACE',0 - - -rename: -;rename a file on a specific disk - - call fillfcb0 - jp nz,comerr ;must be unambiguous - ld a,(sdisk) - push af ;save for later compare - call setdisk ;disk selected - call searchcom ;is new name already there? - jr nz,renerr3 - -;file doesn't exist, move to second half of fcb - - ld hl,comfcb - ld de,comfcb+16 - ld B,16 - call move0 - -;check for = or left arrow - - ld hl,(comaddr) - ex de,hl - call deblank - cp '=' - jr z,ren1 ;ok if = - cp la - jr nz,renerr2 - -ren1: - - ex de,hl - inc hl - ld (comaddr),hl ;past delimiter - -;proper delimiter found - - call fillfcb0 - jr nz,renerr2 - -;check for drive conflict - - pop af - ld B,A ;previous drive number - ld hl,sdisk - ld A,(hl) - or A - jr z,ren2 - -;drive name was specified. same one? - - cp B - ld (hl),B - jr nz,renerr2 - -ren2: - - ld (hl),B ;store the name in case drives switched - xor A - ld (comfcb),a - call searchcom ;is old file there? - jr z,renerr1 - -;everything is ok, rename the file - - ld de,comfcb - call renam - jp retcom - -renerr1: -; no file on disk - - call nofile - jp retcom - -renerr2: -; ambigous reference/name conflict - - call resetdisk - jp comerr - -renerr3: -; file already exists - - ld bc,renmsg - call print - jp retcom - - -renmsg: defb 'FILE EXISTS',0 - -user: -;set user number - - call getnumber ; leaves the value in the accumulator - cp 16 - jp nc,comerr ; must be between 0 and 15 - ld E,A ;save for setuser call - ld a,(comfcb+1) - cp ' ' - jp z,comerr - ld A,E - call setuser ;new user number set - jp endcom - -userfunc: -;load user function and set up for execution - - ld a,(comfcb+1) - cp ' ' - jr nz,user0 - -;no file name, but may be disk switch - - ld a,(sdisk) - or A - jp z,endcom ;no disk name if 0 - dec A - ld (cdisk),a ;set user/disk - call select - jp endcom - -user0: -;file name is present - - ld de,comfcb+9 - ld a,(de) - cp ' ' - jp nz,comerr ;type ' ' - push de - call setdisk - pop de - ld hl,comtype ;.com - call movename ;file type is set to .com - call openc - jp z,userer - -;file opened properly, read it into memory - - ld hl,tran ;transient program base - -load0: - - push hl ;save dma address - - ex de,hl - call setdma - ld de,comfcb - call diskread - jr nz,load1 - -;sector loaded, set new dma address and compare - - pop hl - ld de,128 - add hl,de - ld de,tranm ;has the load overflowed? - ld A,L - sub E - ld A,H - sbc a,D - jr nc,loaderr - jr load0 ;for another sector - -load1: - - pop hl - dec A - jr nz,loaderr ;end file is 1 - call resetdisk ;back to original disk - call fillfcb0 - ld hl,sdisk - push hl - ld A,(hl) - ld (comfcb),a ;drive number set - ld A,16 - call fillfcb ;move entire fcb to memory - pop hl - ld A,(hl) - ld (comfcb+16),a - xor A - ld (comrec),a ;record number set to zero - ld de,fcb - ld hl,comfcb - ld B,33 - call move0 - -;move command line to buff - - ld hl,combuf - -bmove0: - - ld A,(hl) - or A - jr z,bmove1 - cp ' ' - jr z,bmove1 - inc hl - jr bmove0 ;for another scan - -;first blank position found - -bmove1: - - ld B,0 - ld de,buff+1 - -;ready for the move - -bmove2: - - ld A,(hl) - ld (de),a - or A - jr z,bmove3 -Š;more to move - - inc B - inc hl - inc de - jr bmove2 - -bmove3: -;b has character count - - ld A,B - ld (buff),a - call crlf - -;now go to the loaded program - - call setdmabuff ;default dma - call saveuser ;user code saved - ld hl,(ZEROADD) - ld C,4 - -ZMOVE: - - ld (hl),0 - inc hl - dec C - jr nz,ZMOVE - -;low memory diska contains user code - - call tran ;gone to the loaded program - ld sp,stack ;may come back here - ld a,(USERNO) - ld E,A - call SETUSER - ld a,(CDISK) - call select - jp ccp - -userer: -;arrive here on command error - - call resetdisk - jp comerr - -loaderr: -;cannot load the program - - ld bc,loadmsg - call print - jr retcom - - -loadmsg: defb 'BAD LOAD',0 -comtype: defb 'COM' ;for com files - - - -retcom: -;reset disk before end of command check - - call resetdisk - -endcom: -;end of intrinsic command - - call fillfcb0 ;to check for garbage at end of line - ld a,(comfcb+1) - sub ' ' - ld hl,sdisk - or (hl) - -;0 in accumulator if no disk selected, and blank fcb - - jp nz,comerr - jp ccp - -; -; data areas -; - defs 16 ;8 level stack - -stack: - -; -; 'submit' file control block -; - -subfcb: defb 1,'$$$ ' ;file name is $$$ - defb 'SUB',0 - -sub$s1: defb 0 ;file type is sub -submod: defb 0 ;module number -subrc: defs 1 ;record count filed - defs 16 ;disk map -subcr: defs 1 ;current record to read - -; -; command file control block -; -Šcomfcb: defs 32 ;fields filled in later -comrec: defs 1 ;current record to read/write -dcnt: defs 1 ;disk directory count (used for error codes) -cdisk: defs 1 ;current disk -sdisk: defs 1 ;selected disk for current operation - ;none=0, a=1, b=2 ... - -USERNO: defs 1 ;CURRENT USER NUMBER -bptr: defs 1 ;buffer pointer - - ; this is code tto make the BDOS (which follows) be on a - ; 256 byte page boundry. (make the linker happy) -last: defb 0 - org (((last-base)+255) and 0FF00h) -1 - defb 0 - - end ccploc - - \ No newline at end of file diff --git a/cpm/pcpm/ED.PLM b/cpm/pcpm/ED.PLM deleted file mode 100644 index 548cb08..0000000 --- a/cpm/pcpm/ED.PLM +++ /dev/null @@ -1,1630 +0,0 @@ -ED: -DO; - /* MODIFIED FOR .PRL OPERATION MAY, 1979 */ - /* MODIFIED FOR OPERATION WITH CP/M 2.0 AUGUST 1979 */ -DECLARE - /* JMP EDCOMMAND - 3 (TO ADDRESS LXI SP) */ - EDJMP BYTE DATA(0C3H), - EDADR ADDRESS DATA(.EDCOMMAND-3); - -DECLARE - BDISK BYTE EXTERNAL, /* BOOT DISK 0004H */ - MAXB ADDRESS EXTERNAL, /* MAX BASE 0006H */ - FCB (33) BYTE EXTERNAL, /* FCB 005CH */ - BUFF (128)BYTE EXTERNAL, /* BUFFER 0080H */ - SECTSHF LITERALLY '7', /* SHL(1,SECTSHF) = SECTSIZE */ - SECTSIZE LITERALLY '80H'; /* SECTOR SIZE */ - -MON1: PROCEDURE(F,A) EXTERNAL; - DECLARE F BYTE, A ADDRESS; - END MON1; - -MON2: PROCEDURE(F,A) BYTE EXTERNAL; - DECLARE F BYTE, A ADDRESS; - END MON2; - -BOOT: PROCEDURE EXTERNAL; - /* SYSTEM REBOOT */ - END BOOT; - - /* E D : T H E C P / M C O N T E X T E D I T O R */ - - /* COPYRIGHT (C) 1976, 1977, 1978, 1979 - DIGITAL RESEARCH - BOX 579 PACIFIC GROVE - CALIFORNIA 93950 - */ -DECLARE COPYRIGHT(*) BYTE DATA - (' COPYRIGHT (C) 1979, DIGITAL RESEARCH '); - - /* COMMAND FUNCTION - ------- -------- - A APPEND LINES OF TEXT TO BUFFER - B MOVE TO BEGINNING OR END OF TEXT - C SKIP CHARACTERS - D DELETE CHARACTERS - E END OF EDIT - F FIND STRING IN CURRENT BUFFER - H MOVE TO TOP OF FILE (HEAD) - I INSERT CHARACTERS FROM KEYBOARD - UP TO NEXT - J JUXTAPOSITION OPERATION - SEARCH FOR FIRST STRING, - INSERT SECOND STRING, DELETE UNTIL THIRD STRING - K DELETE LINES - L SKIP LINES - M MACRO DEFINITION (SEE COMMENT BELOW) - N FIND NEXT OCCURRENCE OF STRING - WITH AUTO SCAN THROUGH FILE - O RE-EDIT OLD FILE - P PAGE AND DISPLAY (MOVES UP OR DOWN 24 LINES AND - DISPLAYS 24 LINES) - Q QUIT EDIT WITHOUT UPDATING THE FILE - R READ FROM FILE .LIB UNTIL AND - INSERT INTO TEXT - S SEARCH FOR FIRST STRING, REPLACE BY SECOND STRING - T TYPE LINES - U TRANSLATE TO UPPER CASE (-U CHANGES TO NO TRANSLATE) - W WRITE LINES OF TEXT TO FILE - X TRANSFER (XFER) LINES TO TEMP FILE - Z SLEEP FOR 1/2 SECOND (USED IN MACROS TO STOP DISPLAY) - MOVE UP OR DOWN AND PRINT ONE LINE - - - IN GENERAL, THE EDITOR ACCEPTS SINGLE LETTER COMMANDS WITH OPTIONAL -INTEGER VALUES PRECEDING THE COMMAND. THE EDITOR ACCEPTS BOTH UPPER AND LOWER -CASE COMMANDS AND VALUES, AND PERFORMS TRANSLATION TO UPPER CASE UNDER THE FOL- -LOWING CONDITIONS. IF THE COMMAND IS TYPED IN UPPER CASE, THEN THE DATA WHICH -FOLLOWS IS TRANSLATED TO UPPER CASE. THUS, IF THE "I" COMMAND IS TYPED IN -UPPER CASE, THEN ALL INPUT IS AUTOMATICALLY TRANSLATED (ALTHOUGH ECHOED IN -LOWER CASE, AS TYPED). IF THE "A" COMMAND IS TYPED IN UPPER CASE, THEN ALL -INPUT IS TRANSLATED AS READ FROM THE DISK. GLOBAL TRANSLATION TO UPPER CASE -CAN BE CONTROLLED BY THE "U" COMMAND (-U TO NEGATE ITS EFFECT). IF YOU ARE -OPERATING WITH AN UPPER CASE ONLY TERMINAL, THEN OPERATION IS AUTOMATIC. -SIMILARLY, IF YOU ARE OPERATING WITH A LOWER CASE TERMINAL, AND TRANSLATION -TO UPPER CASE IS NOT SPECIFIED, THEN LOWER CASE CHARACTERS CAN BE ENTERED. - - A NUMBER OF COMMANDS CAN BE PRECEDED BY A POSITIVE OR - NEGATIVE INTEGER BETWEEN 0 AND 65535 (1 IS DEFAULT IF NO VALUE - IS SPECIFIED). THIS VALUE DETERMINES THE NUMBER OF TIMES THE - COMMAND IS APPLIED BEFORE RETURNING FOR ANOTHER COMMAND. - THE COMMANDS - C D K L T P U - CAN BE PRECEDED BY AN UNSIGNED, POSITIVE, OR NEGATIVE NUMBER, - THE COMMANDS - A F J N W Z - CAN BE PRECEDED BY AN UNSIGNED OR POSITIVE NUMBER, - THE COMMANDS - E H O Q - CANNOT BE PRECEDED BY A NUMBER. THE COMMANDS - F I J M R S - ARE ALL FOLLOWED BY ONE OR MORE STRINGS OF CHARACTERS WHICH CAN - BE OPTIONALLY SEPARATED OR TERMINATED BY EITHER OR . - THE IS GENERALLY USED TO SEPARATE THE SEARCH STRINGS - IN THE S AND J COMMANDS, AND IS USED AT THE END OF THE COMMANDS IF - ADDITIONAL COMMANDS FOLLOW. FOR EXAMPLE, THE FOLLOWING COMMAND - SEQUENCE SEARCHES FOR THE STRING 'GAMMA', SUBSTITUTES THE STRING - 'DELTA', AND THEN TYPES THE FIRST PART OF THE LINE WHERE THE - CHANGE OCCURRED, FOLLOWED BY THE REMAINDER OF THE LINE WHICH WAS - CHANGED: - SGAMMADELTA0TT - - THE CONTROL-L CHARACTER IN SEARCH AND SUBSTITUTE STRINGS IS - REPLACED ON INPUT BY CHARACTERS. THE CONTROL-I KEY - IS TAKEN AS A TAB CHARACTER. - - THE COMMAND R MUST BE FOLLOWED BY A FILE NAME (WITH ASSUMED FILE - TYPE OF 'LIB') WITH A TRAILING OR . THE COMMAND - I IS FOLLOWED BY A STRING OF SYMBOLS TO INSERT, TERMINATED BY - A OR . IF SEVERAL LINES OF TEXT ARE TO BE INSERTED, - THE I CAN BE DIRECTLY FOLLOWED BY AN OR IN WHICH - CASE THE EDITOR ACCEPTS LINES OF INPUT TO THE NEXT . - THE COMMAND 0T PRINTS THE FIRST PART OF THE CURRENT LINE, - AND THE COMMAND 0L MOVES THE REFERENCE TO THE BEGINNING OF THE - CURRENT LINE. THE COMMAND 0P PRINTS THE CURRENT PAGE ONLY, WHILE - THE COMMAND 0Z READS THE CONSOLE RATHER THAN WAITING (THIS IS USED - AGAIN WITHIN MACROS TO STOP THE DISPLAY - THE MACRO EXPANSION - STOPS UNTIL A CHARACTER IS READ. IF THE CHARACTER IS NOT A BREAK - THEN THE MACRO EXPANSION CONTINUES NORMALLY). - - NOTE THAT A POUND SIGN IS TAKEN AS THE NUMBER 65535, ALL - UNSIGNED NUMBERS ARE ASSUMED POSITIVE, AND A SINGLE - IS ASSUMED -1 - - A NUMBER OF COMMANDS CAN BE GROUPED TOGETHER AND EXECUTED - REPETITIVELY USING THE MACRO COMMAND WHICH TAKES THE FORM - - MC1C2...CN - - WHERE IS A NON-NEGATIVE INTEGER N, AND IS - OR . THE COMMANDS C1 ... CN FOLLOWING THE M ARE - EXECUTED N TIMES, STARTING AT THE CURRENT POSITION IN THE BUFFER. - IF N IS 0, 1, OR OMITTED, THE COMMANDS ARE EXECUTED UNTIL THE END - IF THE BUFFER IS ENCOUNTERED. - - THE FOLLOWING MACRO, FOR EXAMPLE, CHANGES ALL OCCURRENCES OF - THE NAME 'GAMMA' TO 'DELTA', AND PRINTS THE LINES WHICH - WERE CHANGED: - - MFGAMMA-5DIDELTA0LT - - (NOTE: AN IS THE CP/M END OF FILE MARK - CONTROL-Z) - - IF ANY KEY IS DEPRESSED DURING TYPING OR MACRO EXPANSION, THE - FUNCTION IS CONSIDERED TERMINATED, AND CONTROL RETURNS TO THE - OPERATOR. - - ERROR CONDITIONS ARE INDICATED BY PRINTING ONE OF THE CHARACTERS: - - SYMBOL ERROR CONDITION - ------ ---------------------------------------------------- - GREATER FREE MEMORY IS EXHAUSTED - ANY COMMAND CAN BE ISSUED - WHICH DOES NOT INCREASE MEMORY REQUIREMENTS. - QUESTION UNRECOGNIZED COMMAND OR ILLEGAL NUMERIC FIELD - POUND CANNOT APPLY THE COMMAND THE NUMBER OF TIMES SPECFIED - (OCCURS IF SEARCH STRING CANNOT BE FOUND) - LETTER O CANNOT OPEN .LIB IN R COMMAND - - THE ERROR CHARACTER IS ALSO ACCOMPANIED BY THE LAST CHARACTER - SCANNED WHEN THE ERROR OCCURRED. */ - -DECLARE LIT LITERALLY 'LITERALLY', - DCL LIT 'DECLARE', - PROC LIT 'PROCEDURE', - ADDR LIT 'ADDRESS', - CTLL LIT '0CH', - CTLR LIT '12H', /* REPEAT LINE IN INSERT MODE */ - CTLU LIT '15H', /* LINE DELETE IN INSERT MODE */ - CTLX LIT '18H', /* EQUIVALENT TO CTLU */ - CTLH LIT '08H', /* BACKSPACE */ - TAB LIT '09H', /* TAB CHARACTER */ - LCA LIT '110$0001B', /* LOWER CASE A */ - LCZ LIT '111$1010B', /* LOWER CASE Z */ - ENDFILE LIT '1AH'; /* CP/M END OF FILE */ - -DECLARE - MAX ADDRESS, /* .MEMORY(MAX)=0 (END) */ - MAXM ADDRESS, /* MINUS 1 */ - HMAX ADDRESS; /* = MAX/2 */ - -DECLARE - RO LITERALLY '9', /* R/O FILE INDICATOR */ - SY LITERALLY '10', /* SYSTEM FILE ATTRIBUTE */ - EX LITERALLY '12', /* EXTENT NUMBER POSITION */ - UB LITERALLY '13', /* UNFILLED BYTES */ - MD LITERALLY '14', /* MODULE NUMBER POSITION */ - NR LITERALLY '32', /* NEXT RECORD FIELD */ - FS LITERALLY '33', /* FCB SIZE */ - RFCB (FS) BYTE /* READER FILE CONTROL BLOCK */ - INITIAL(0, /* FILE NAME */ ' ', - /* FILE TYPE */ 'LIB',0,0,0), - RBP BYTE, /* READ BUFFER POINTER */ - XFCB (FS) BYTE /* XFER FILE CONTROL BLOCK */ - INITIAL(0, 'X$$$$$$$','LIB',0,0,0), - XFCBE BYTE AT(.XFCB(EX)), /* XFCB EXTENT */ - XFCBM BYTE AT(.XFCB(MD)), /* MODULE NUMBER */ - XFCBR BYTE AT(.XFCB(NR)), /* XFCB RECORD # */ - XBUFF (SECTSIZE) BYTE, /* XFER BUFFER */ - XBP BYTE, /* XFER POINTER */ - XFERON BYTE, /* TRUE IF XFER ACTIVE */ - - NBUF BYTE, /* NUMBER OF BUFFERS */ - BUFFLENGTH ADDRESS, /* NBUF * SECTSIZE */ - SFCB (FS) BYTE AT(.FCB), /* SOURCE FCB = DEFAULT FCB */ - SBUFFADR ADDRESS, /* SOURCE BUFFER ADDRESS */ - SBUFF BASED SBUFFADR (128) BYTE, /* SOURCE BUFFER */ - - DFCB (FS) BYTE, /* DEST FILE CONTROL BLOCK */ - DFUB BYTE AT(.DFCB(UB)), /* UNFILLED BYTES IN LAST RECORD */ - DBUFFADR ADDRESS, /* DESTINATION BUFFER ADDRESS */ - DBUFF BASED DBUFFADR (128) BYTE, /* DEST BUFFER */ - NSOURCE ADDRESS, /* NEXT SOURCE CHARACTER */ - NDEST ADDRESS; /* NEXT DESTINATION CHAR */ - -DECLARE SDISK BYTE, /* SOURCE FILE DISK */ - DDISK BYTE; /* DESTINATION FILE DISK */ - - /* IO SECTION */ - -READCHAR: PROCEDURE BYTE; RETURN MON2(1,0); - END READCHAR; - -DECLARE TRUE LITERALLY '1', FALSE LITERALLY '0', - FOREVER LITERALLY 'WHILE TRUE', - CR LITERALLY '13', - LF LITERALLY '10', - WHAT LITERALLY '63'; - -DECLARE - PRINTSUPPRESS BYTE; /* TRUE IF PRINT SUPPRESSED */ - -PRINTCHAR: PROCEDURE(CHAR); - DECLARE CHAR BYTE; - IF PRINTSUPPRESS THEN RETURN; - CALL MON1(2,CHAR); - END PRINTCHAR; - -DECLARE - COLUMN BYTE, /* CONSOLE COLUMN POSITION */ - SCOLUMN BYTE, /* STARTING COLUMN IN "I" MODE */ - TCOLUMN BYTE, /* TEMP DURING BACKSPACE */ - QCOLUMN BYTE; /* TEMP DURING BACKSPACE */ - -TTYCHAR: PROCEDURE(CHAR); - DECLARE CHAR BYTE; - IF CHAR >= ' ' THEN COLUMN = COLUMN + 1; - IF CHAR = LF THEN COLUMN = 0; - CALL PRINTCHAR(CHAR); - END TTYCHAR; - -BACKSPACE: PROCEDURE; - /* MOVE BACK ONE POSITION */ - IF COLUMN = 0 THEN RETURN; - CALL TTYCHAR(CTLH); /* COLUMN = COLUMN - 1 */ - CALL TTYCHAR(' ' ); /* COLUMN = COLUMN + 1 */ - CALL TTYCHAR(CTLH); /* COLUMN = COLUMN - 1 */ - COLUMN = COLUMN - 2; - END BACKSPACE; - -PRINTABS: PROCEDURE(CHAR); - DECLARE (CHAR,I,J) BYTE; - I = CHAR = TAB AND 7 - (COLUMN AND 7); - IF CHAR = TAB THEN CHAR = ' '; - DO J = 0 TO I; - CALL TTYCHAR(CHAR); - END; - END PRINTABS; - -GRAPHIC: PROCEDURE(C) BYTE; - DECLARE C BYTE; - /* RETURN TRUE IF GRAPHIC CHARACTER */ - IF C >= ' ' THEN RETURN TRUE; - RETURN C = CR OR C = LF OR C = TAB; - END GRAPHIC; - -PRINTC: PROCEDURE(C); - DECLARE C BYTE; - IF NOT GRAPHIC(C) THEN - DO; CALL PRINTABS('^'); - C = C + '@'; - END; - CALL PRINTABS(C); - END PRINTC; - -CRLF: PROCEDURE; - CALL PRINTC(CR); CALL PRINTC(LF); - END CRLF; - -PRINTM: PROCEDURE(A); - DECLARE A ADDRESS; - CALL MON1(9,A); - END PRINTM; - -PRINT: PROCEDURE(A); - DECLARE A ADDRESS; - CALL CRLF; - CALL PRINTM(A); - END PRINT; - -READ: PROCEDURE(A); - DECLARE A ADDRESS; - CALL MON1(10,A); - END READ; - -DECLARE DCNT BYTE; - - -OPEN: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - DCNT = MON2(15,FCB); - END OPEN; - -CLOSE: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - DCNT = MON2(16,FCB); - END CLOSE; - -SEARCH: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - DCNT = MON2(17,FCB); - END SEARCH; - -DELETE: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - CALL MON1(19,FCB); - END DELETE; - -DISKREAD: PROCEDURE(FCB) BYTE; - DECLARE FCB ADDRESS; - RETURN MON2(20,FCB); - END DISKREAD; - -DISKWRITE: PROCEDURE(FCB) BYTE; - DECLARE FCB ADDRESS; - RETURN MON2(21,FCB); - END DISKWRITE; - -MAKE: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - DCNT = MON2(22,FCB); - END MAKE; - -RENAME: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - CALL MON1(23,FCB); - END RENAME; - -DECLARE (MAXLEN,COMLEN) BYTE, COMBUFF(128) BYTE, - (TCBP,CBP) BYTE; - -READCOM: PROCEDURE; - MAXLEN = 128; CALL READ(.MAXLEN); - END READCOM; - -BREAK$KEY: PROCEDURE BYTE; - IF MON2(11,0) THEN - DO; /* CLEAR CHAR */ - CALL MON1(1,0); RETURN TRUE; - END; - RETURN FALSE; - END BREAK$KEY; - -CSELECT: PROCEDURE BYTE; - /* RETURN CURRENT DRIVE NUMBER */ - RETURN MON2(25,0); - END CSELECT; - -SELECT: PROCEDURE(DISK); - DECLARE DISK BYTE; - /* SET DRIVE NUMBER */ - CALL MON1(14,DISK); - END SELECT; - -SETDMA: PROCEDURE(A); - DECLARE A ADDRESS; - /* SET DMA ADDRESS */ - CALL MON1(26,A); - END SETDMA; - -REBOOT: PROCEDURE; - IF XFERON THEN CALL DELETE(.XFCB); - CALL BOOT; - END REBOOT; - -DECLARE /* LINE COUNTERS */ - BASELINE ADDRESS, /* CURRENT LINE */ - RELLINE ADDRESS, /* RELATIVE LINE IN TYPEOUT */ - LINESET BYTE; /* TRUE IF LINE #'S PRINTED */ - - /* INPUT / OUTPUT BUFFERING ROUTINES */ - -/* THE PL/M BUILT-IN PROCEDURE "MOVE" IS USED TO MOVE STORAGE, - ITS DEFINITION IS: - MOVE: PROCEDURE(COUNT,SOURCE,DEST); - DECLARE (COUNT,SOURCE,DEST) ADDRESS; - / MOVE DATA FROM SOURCE TO DEST ADDRESSES, FOR COUNT BYTES / - END MOVE; - */ - -ABORT: PROCEDURE(A); - DECLARE A ADDRESS; - CALL PRINT(A); - CALL CRLF; - CALL REBOOT; - END ABORT; - -FERR: PROCEDURE; - CALL CLOSE(.DFCB); /* ATTEMPT TO CLOSE FILE FOR LATER RECOVERY */ - CALL ABORT (.('DISK OR DIRECTORY FULL$')); - END FERR; - -SETTYPE: PROCEDURE(A); - DECLARE A ADDRESS; - CALL MOVE(3,A,.DFCB+9); - END SETTYPE; - -SETUP: PROCEDURE; - NSOURCE = BUFFLENGTH; NDEST = 0; - SFCB(EX), SFCB(MD), SFCB(NR) = 0; - /* REEL AND RECORD ZEROED */ - /* COPY NAME TO DESTINATION FCB */ - CALL MOVE(33,.FCB,.DFCB); - /* SOURCE AND DESTINATION DISKS SET */ - - /* IF SOURCE AND DESTINATION DISKS DIFFER, CHECK FOR - AN EXISTING SOURCE FILE ON THE DESTINATION DISK - THERE - COULD BE A FATAL ERROR CONDITION WHICH COULD DESTROY A - FILE IF THE USER HAPPENED TO BE ADDRESSING THE WRONG - DISK */ - IF SDISK <> DDISK THEN - DO; CALL SELECT(DDISK); - CALL SEARCH(.FCB); - IF DCNT <> 255 THEN /* SOURCE FILE PRESENT ON DEST DISK */ - CALL ABORT(.('FILE EXISTS, ERASE IT$')); - END; - CALL SELECT(SDISK); - CALL OPEN(.FCB); - IF DCNT = 255 THEN - DO; CALL MAKE(.FCB); - IF DCNT = 255 THEN CALL FERR; - CALL PRINT(.('NEW FILE$')); - CALL CRLF; - END; ELSE - IF ROL(FCB(RO),1) THEN - DO; - CALL PRINT(.('** FILE IS READ/ONLY **$')); - CALL CRLF; - END; ELSE - IF ROL(FCB(SY),1) THEN - CALL ABORT(.('"SYSTEM" FILE NOT ACCESSIBLE$')); - CALL SETTYPE(.('BAK')); - CALL DELETE(.DFCB); - IF SDISK <> DDISK THEN - DO; /* REMOVE BAK FILES FROM DESTINATION DISK */ - CALL SELECT(DDISK); - CALL DELETE(.DFCB); - END; - CALL SETTYPE(.('$$$')); - CALL DELETE(.DFCB); - CALL MAKE(.DFCB); - DFCB(32) = 0; /* NEXT RECORD IS ZERO */ - IF DCNT = 255 THEN CALL FERR; - /* THE TEMP FILE IS NOW CREATED */ - BASELINE = 1; /* START WITH LINE 1 */ - END SETUP; - -XCLEAR: PROCEDURE; - /* CLEAR THE XFER FILE PARAMETERS */ - XFERON, XFCBE, XFCBR, XBP = 0; - END XCLEAR; - -SETXDMA: PROCEDURE; - CALL SELECT(SDISK); - CALL SETDMA(.XBUFF); - END SETXDMA; - -FILLSOURCE: PROCEDURE; - DECLARE I BYTE; - ZN: PROCEDURE; - NSOURCE = 0; - END ZN; - - CALL ZN; - CALL SELECT(SDISK); - DO I = 0 TO NBUF; - CALL SETDMA(SBUFFADR+NSOURCE); - IF (DCNT := DISKREAD(.FCB)) <> 0 THEN - DO; IF DCNT > 1 THEN CALL FERR; - SBUFF(NSOURCE) = ENDFILE; - I = NBUF; - END; - ELSE - NSOURCE = NSOURCE + SECTSIZE; - END; - CALL ZN; - END FILLSOURCE; - -GETSOURCE: PROCEDURE BYTE; - DECLARE B BYTE; - IF NSOURCE >= BUFFLENGTH THEN CALL FILLSOURCE; - IF (B := SBUFF(NSOURCE)) <> ENDFILE THEN - NSOURCE = NSOURCE + 1; - RETURN B; - END GETSOURCE; - -WRITEDEST: PROCEDURE; - /* WRITE OUTPUT BUFFER UP TO (NOT INCLUDING) NDEST. - LOW 7 BITS OF NDEST ARE ZERO */ - DECLARE (I,N) BYTE; - ZN: PROCEDURE; - NDEST = 0; - END ZN; - - CALL SELECT(DDISK); - IF LOW((N := SHR(NDEST,SECTSHF) - 1)) = 255 THEN RETURN; - CALL ZN; - DO I = 0 TO N; - CALL SETDMA(DBUFFADR+NDEST); - IF DISKWRITE(.DFCB) <> 0 THEN CALL FERR; - NDEST = NDEST + SECTSIZE; - END; - CALL ZN; - END WRITEDEST; - -PUTDEST: PROCEDURE(B); - DECLARE B BYTE; - IF NDEST >= BUFFLENGTH THEN CALL WRITEDEST; - DBUFF(NDEST) = B; - NDEST = NDEST + 1; - END PUTDEST; - -PUTXFER: PROCEDURE(C); - DECLARE C BYTE; - /* WRITE C TO XFER FILE */ - IF XBP >= SECTSIZE THEN /* BUFFER OVERFLOW */ - DO; CALL SETXDMA; - IF DISKWRITE(.XFCB) <> 0 THEN CALL FERR; - XBP = 0; - END; - XBUFF(XBP) = C; XBP = XBP + 1; - END PUTXFER; - -FINIS: PROCEDURE; - MOVEUP: PROCEDURE; - CALL MOVE(16,.DFCB,.DFCB+16); - END MOVEUP; - - /* CLEAR OUTPUT */ - DFUB = 0 ; /* SET UNFILLED BYTES - USED FOR ISIS-II COMPATIBILITY */ - DO WHILE (LOW(NDEST) AND 7FH) <> 0; - DFUB = DFUB + 1; /* COUNTS UNFILLED BYTES IN LAST RECORD */ - CALL PUTDEST(ENDFILE); - END; - CALL WRITEDEST; - - CALL CLOSE(.DFCB); - IF DCNT = 255 THEN CALL FERR; - /* RENAME OLD FILE TO BAK */ - CALL SETTYPE(.('BAK')); CALL MOVEUP; - CALL SELECT(SDISK); - CALL MOVE(16,.FCB,.DFCB); - CALL RENAME(.DFCB); - CALL MOVEUP; - /* RENAME $$$ TO OLD NAME */ - CALL SETTYPE(.('$$$')); - CALL SELECT(DDISK); - CALL RENAME(.DFCB); - END FINIS; - - -DECLARE - LPP LIT '23', /* LINES PER PAGE */ - FORWARD LIT '1', - BACKWARD LIT '0', - RUBOUT LIT '07FH', - POUND LIT '23H', - MACSIZE LIT '128', /* MAX MACRO SIZE */ - SCRSIZE LIT '100', /* SCRATCH BUFFER SIZE */ - COMSIZE LIT 'ADDRESS'; /* DETERMINES MAX COMMAND NUMBER*/ - -DCL MACRO(MACSIZE) BYTE, - SCRATCH(SCRSIZE) BYTE, /* SCRATCH BUFFER FOR F,N,S */ - (WBP, WBE, WBJ) BYTE, /* END OF F STRING, S STRING, J STRING */ - (FLAG, MP, MI, XP) BYTE, - MT COMSIZE; - -DCL (START, RESTART, OVERCOUNT, OVERFLOW, RESET, BADCOM) LABEL; - -DCL INSERTING BYTE, /* TRUE IF INSERTING CHARACTERS */ - READBUFF BYTE; /* TRUE IF END OF READ BUFFER */ - -DECLARE - EOS LITERALLY '0FFH'; - - - -PRINTNMAC: PROCEDURE(CHAR); - DECLARE CHAR BYTE; - /* PRINT IF NOT IN MACRO EXPANSION */ - IF MP <> 0 THEN RETURN; - CALL PRINTC(CHAR); - END PRINTNMAC; - - - - -DECLARE TRANSLATE BYTE, /* TRUE IF TRANSLATION TO UPPER CASE */ - UPPER BYTE; /* TRUE IF GLOBALLY TRANLATING TO UC */ - -LOWERCASE: PROCEDURE(C) BYTE; - DECLARE C BYTE; - /* RETURN TRUE IF LOWER CASE ALPHABETIC */ - RETURN C >= LCA AND C <= LCZ; - END LOWERCASE; - -UCASE: PROCEDURE(C) BYTE; - DECLARE C BYTE; - /* TRANSLATE C TO UPPER CASE */ - IF LOWERCASE(C) THEN RETURN C AND 5FH; - RETURN C; - END UCASE; - -UTRAN: PROCEDURE(C) BYTE; - DECLARE C BYTE; - /* TRANSLATE TO UPPER CASE IF ALPHABETIC LOWER AND TRANSLATE */ - IF TRANSLATE THEN RETURN UCASE(C); - RETURN C; - END UTRAN; - -PRINTVALUE: PROCEDURE(V); - /* PRINT THE LINE VALUE V */ - DECLARE (D,ZERO) BYTE, - (K,V) ADDRESS; - K = 10000; - ZERO = FALSE; - DO WHILE K <> 0; - D = LOW(V/K); V = V MOD K; - K = K / 10; - IF ZERO OR D <> 0 THEN - DO; ZERO = TRUE; - CALL PRINTC('0'+D); - END; ELSE - CALL PRINTC(' '); - END; - END PRINTVALUE; - -PRINTLINE: PROCEDURE(V); - DECLARE V ADDRESS; - IF NOT LINESET THEN RETURN; - CALL PRINTVALUE(V); - CALL PRINTC(':'); - CALL PRINTC(' '); - IF INSERTING THEN CALL PRINTC(' '); ELSE - CALL PRINTC('*'); - END PRINTLINE; - - -PRINTBASE: PROCEDURE; - CALL PRINTLINE(BASELINE); - END PRINTBASE; - -PRINTNMBASE: PROCEDURE; - IF MP <> 0 THEN RETURN; - CALL PRINTBASE; - END PRINTNMBASE; - -READC: PROCEDURE BYTE; - /* MAY BE MACRO EXPANSION */ - IF MP > 0 THEN - DO; - IF BREAK$KEY THEN GO TO OVERCOUNT; - IF XP >= MP THEN - DO; /* START AGAIN */ - IF MT <> 0 THEN - DO; IF (MT:=MT-1) = 0 THEN - GO TO OVERCOUNT; - END; - XP = 0; - END; - RETURN UTRAN(MACRO((XP := XP + 1) - 1)); - END; - IF INSERTING THEN RETURN UTRAN(READCHAR); - - /* GET COMMAND LINE */ - IF READBUFF THEN - DO; READBUFF = FALSE; - IF LINESET AND COLUMN = 0 THEN - DO; - IF BACK >= MAXM THEN - CALL PRINTLINE(0); ELSE - CALL PRINTBASE; - END; ELSE - CALL PRINTC('*'); - CALL READCOM; CBP = 0; - CALL PRINTC(LF); - COLUMN = 0; - END; - IF (READBUFF := CBP = COMLEN ) THEN COMBUFF(CBP) = CR; - RETURN UTRAN(COMBUFF((CBP := CBP +1) -1)); - END READC; - -SETRDMA: PROCEDURE; - /* SET READ LIB DMA ADDRESS */ - CALL SELECT(SDISK); - CALL SETDMA(.BUFF); - END SETRDMA; - -READFILE: PROCEDURE BYTE; - IF RBP >= SECTSIZE THEN - DO; CALL SETRDMA; - IF DISKREAD(.RFCB) <> 0 THEN RETURN ENDFILE; - RBP = 0; - END; - RETURN UTRAN(BUFF((RBP := RBP + 1) - 1)); - END READFILE; - -DCL (DISTANCE, TDIST) COMSIZE, - (DIRECTION, CHAR) BYTE, - ( FRONT, BACK, FIRST, LAST) ADDR; - -SETFF: PROCEDURE; - DISTANCE = 0FFFFH; - END SETFF; - -DISTZERO: PROCEDURE BYTE; - /* RETURN TRUE IF DISTANCE IS ZERO */ - RETURN DISTANCE = 0; - END DISTZERO; - -ZERODIST: PROCEDURE; - DISTANCE = 0; - END ZERODIST; - -DISTNZERO: PROCEDURE BYTE; - /* CHECK FOR ZERO DISTANCE AND DECREMENT */ - IF NOT DISTZERO THEN - DO; DISTANCE = DISTANCE - 1; - RETURN TRUE; - END; - RETURN FALSE; - END DISTNZERO; - -SETLIMITS: PROC; - DCL (I,K,L,M) ADDR, (MIDDLE,LOOPING) BYTE; - RELLINE = 1; /* RELATIVE LINE COUNT */ - IF DIRECTION = BACKWARD THEN - DO; DISTANCE = DISTANCE+1; I = FRONT; L = 0; K = 0FFFFH; - END; ELSE - DO; I = BACK; L = MAXM; K = 1; - END; - - LOOPING = TRUE; - DO WHILE LOOPING; - DO WHILE (MIDDLE := I <> L) AND - MEMORY(M:=I+K) <> LF; - I = M; - END; - RELLINE = RELLINE - 1; - LOOPING = (DISTANCE := DISTANCE - 1) <> 0; - IF NOT MIDDLE THEN - DO; LOOPING = FALSE; - I = I - K; - END; ELSE - IF LOOPING THEN I = M; - END; - - IF DIRECTION = BACKWARD THEN - DO; FIRST = I; LAST = FRONT - 1; - END; ELSE - DO; FIRST = BACK + 1; LAST = I + 1; - END; - END SETLIMITS; - -INCFRONT: PROC; FRONT = FRONT + 1; - END INCFRONT; -INCBACK: PROCEDURE; BACK = BACK + 1; - END INCBACK; -DECFRONT: PROC; FRONT = FRONT - 1; - END DECFRONT; -DECBACK: PROC; BACK = BACK - 1; - END DECBACK; -INCBASE: PROCEDURE; - BASELINE = BASELINE + 1; - END INCBASE; - - -MEM$MOVE: PROC(MOVEFLAG); - DECLARE (MOVEFLAG,C) BYTE; - /* MOVE IF MOVEFLAG IS TRUE */ - IF DIRECTION = FORWARD THEN - DO WHILE BACK < LAST; CALL INCBACK; - IF MOVEFLAG THEN - DO; - IF (C := MEMORY(BACK)) = LF THEN CALL INCBASE; - MEMORY(FRONT) = C; CALL INCFRONT; - END; - END; ELSE - DO WHILE FRONT > FIRST; CALL DECFRONT; - IF (C := MEMORY(FRONT)) = LF THEN BASELINE = BASELINE - 1; - IF MOVEFLAG THEN - DO; MEMORY(BACK) = C; CALL DECBACK; - END; - END; - END MEM$MOVE; - -MOVER: PROC; - CALL MEM$MOVE(TRUE); - END MOVER; - -SETPTRS: PROC; - CALL MEM$MOVE(FALSE); - END SETPTRS; - -MOVELINES: PROC; - CALL SETLIMITS; - CALL MOVER; - END MOVELINES; - -SETCLIMITS: PROC; - IF DIRECTION = BACKWARD THEN - DO; LAST = BACK; - IF DISTANCE > FRONT THEN - FIRST = 1; ELSE FIRST = FRONT - DISTANCE; - END; ELSE - DO; FIRST = FRONT; - IF DISTANCE >= MAX - BACK THEN - LAST = MAXM; ELSE LAST = BACK + DISTANCE; - END; - END SETCLIMITS; - -READLINE: PROCEDURE; - DECLARE B BYTE; - /* READ ANOTHER LINE OF INPUT */ - CTRAN: PROCEDURE(B) BYTE; - DECLARE B BYTE; - /* CONDITIONALLY TRANSLATE TO UPPER CASE ON INPUT */ - IF UPPER THEN RETURN UTRAN(B); - RETURN B; - END CTRAN; - DO FOREVER; - IF FRONT >= BACK THEN GO TO OVERFLOW; - IF (B := CTRAN(GETSOURCE)) = ENDFILE THEN - DO; CALL ZERODIST; RETURN; - END; - MEMORY(FRONT) = B; - CALL INCFRONT; - IF B = LF THEN - DO; CALL INCBASE; - RETURN; - END; - END; - END READLINE; - -WRITELINE: PROCEDURE; - /* WRITE ONE LINE OUT */ - DECLARE B BYTE; - DO FOREVER; - IF BACK >= MAXM THEN /* EMPTY */ - DO; CALL ZERODIST; RETURN; - END; - CALL INCBACK; - CALL PUTDEST(B:=MEMORY(BACK)); - IF B = LF THEN - DO; CALL INCBASE; - RETURN; - END; - END; - END WRITELINE; - -WRHALF: PROCEDURE; - /* WRITE LINES UNTIL AT LEAST HALF THE BUFFER IS EMPTY */ - CALL SETFF; - DO WHILE DISTNZERO; - IF HMAX >= (MAXM - BACK) THEN CALL ZERODIST; ELSE - CALL WRITELINE; - END; - END WRHALF; - -WRITEOUT: PROCEDURE; - /* WRITE LINES DETERMINED BY 'DISTANCE', - CALLED FROM W AND E COMMANDS */ - DIRECTION = BACKWARD; FIRST = 1; LAST = BACK; - CALL MOVER; - IF DISTZERO THEN CALL WRHALF; - /* DISTANCE = 0 IF CALL WRHALF */ - DO WHILE DISTNZERO; - CALL WRITELINE; - END; - IF BACK < LAST THEN - DO; DIRECTION = FORWARD; CALL MOVER; - END; - END WRITEOUT; - -CLEARMEM: PROCEDURE; - /* CLEAR MEMORY BUFFER */ - CALL SETFF; - CALL WRITEOUT; - END CLEARMEM; - -TERMINATE: PROCEDURE; - /* CLEAR BUFFERS */ - CALL CLEARMEM; - DO WHILE (CHAR := GETSOURCE) <> ENDFILE; - CALL PUTDEST(CHAR); - END; - CALL FINIS; - END TERMINATE; - - -INSERT: PROCEDURE; - /* INSERT CHAR INTO MEMORY BUFFER */ - IF FRONT = BACK THEN GO TO OVERFLOW; - MEMORY(FRONT) = CHAR; CALL INCFRONT; - IF CHAR = LF THEN CALL INCBASE; - END INSERT; - -SCANNING: PROCEDURE BYTE; - /* READ A CHARACTER AND CHECK FOR ENDFILE OR CR */ - RETURN NOT ((CHAR := READC) = ENDFILE OR - (CHAR = CR AND NOT INSERTING)); - END SCANNING; - -COLLECT: PROCEDURE; - /* READ COMMAND BUFFER AND INSERT CHARACTERS INTO - SCRATCH 'TIL NEXT CONTROL-Z OR CR FOR FIND, NEXT, JUXT, OR - SUBSTITUTE COMMANDS - FILL AT WBE AND INCREMENT WBE SO IT - ADDRESSES NEXT EMPTY POSITION OF SCRATCH */ - SETSCR: PROCEDURE; - SCRATCH(WBE) = CHAR; - IF (WBE := WBE + 1) >= SCRSIZE THEN GO TO OVERFLOW; - END SETSCR; - DO WHILE SCANNING; - IF CHAR = CTLL THEN - DO; CHAR = CR; CALL SETSCR; - CHAR = LF; - END; - IF CHAR = 0 THEN GO TO BADCOM; - CALL SETSCR; - END; - END COLLECT; - -FIND: PROCEDURE(PA,PB) BYTE; - DECLARE (PA,PB) BYTE; - /* FIND THE STRING IN SCRATCH STARTING AT PA AND ENDING AT PB */ - DECLARE J ADDRESS, - (K, MATCH) BYTE; - J = BACK ; - MATCH = FALSE; - DO WHILE NOT MATCH AND (MAXM > J); - LAST,J = J + 1; /* START SCAN AT J */ - K = PA ; /* ATTEMPT STRING MATCH AT K */ - DO WHILE SCRATCH(K) = MEMORY(LAST) AND - NOT (MATCH := K = PB); - /* MATCHED ONE MORE CHARACTER */ - K = K + 1; LAST = LAST + 1; - END; - END; - IF MATCH THEN /* MOVE STORAGE */ - DO; LAST = LAST - 1; CALL MOVER; - END; - RETURN MATCH; - END FIND; - -SETFIND: PROCEDURE; - /* SETUP THE SEARCH STRING FOR F,N, AND S COMMANDS */ - WBE = 0; CALL COLLECT; WBP = WBE; - END SETFIND; - -CHKFOUND: PROCEDURE; - /* CHECK FOR FOUND STRING IN F AND S COMMANDS */ - IF NOT FIND(0,WBP) THEN /* NO MATCH */ GO TO OVERCOUNT; - END CHKFOUND; - - - -SETRFCB: PROCEDURE; - /* PLACE CHAR INTO READ FILE CONTROL BLOCK AND INCREMENT */ - RFCB((RBP := RBP + 1) - 1) = UCASE(CHAR); - END SETRFCB; - -PRINTREL: PROCEDURE; - CALL PRINTLINE(BASELINE+RELLINE); - END PRINTREL; - -TYPELINES: PROCEDURE; - DCL I ADDR; - DCL C BYTE; - CALL SETLIMITS; - /* DISABLE THE * PROMPT */ - INSERTING = TRUE; - IF DIRECTION = FORWARD THEN - DO; RELLINE = 0; I = FRONT; - END; ELSE - I = FIRST; - IF (C := MEMORY(I-1)) = LF AND COLUMN <> 0 THEN - CALL CRLF; - DO I = FIRST TO LAST; - IF C = LF THEN - DO; - CALL PRINTREL; - RELLINE = RELLINE + 1; - IF BREAK$KEY THEN GO TO OVERCOUNT; - END; - CALL PRINTC(C:=MEMORY(I)); - END; - END TYPELINES; - -SETLPP: PROCEDURE; - /* SET DISTANCE TO LINES PER PAGE */ - DISTANCE = LPP; - END SETLPP; - -SAVEDIST: PROCEDURE; - TDIST = DISTANCE; - END SAVEDIST; - -RESTDIST: PROCEDURE; - DISTANCE = TDIST; - END RESTDIST; - -PAGE: PROCEDURE; - DECLARE I BYTE; - CALL SAVEDIST; - CALL SETLPP; - CALL MOVELINES; - I = DIRECTION; - DIRECTION = FORWARD; - CALL SETLPP; - CALL TYPELINES; - DIRECTION = I; - IF LAST = MAXM OR FIRST = 1 THEN CALL ZERODIST; - ELSE CALL RESTDIST; - END PAGE; - -WAIT: PROCEDURE; - /* 1/2 SECOND TIME OUT */ - DECLARE I BYTE; - DO I = 0 TO 19; - IF BREAK$KEY THEN GO TO RESET; - CALL TIME(250); - END; - END WAIT; - -SETFORWARD: PROCEDURE; - DIRECTION = FORWARD; - DISTANCE = 1; - END SETFORWARD; - -APPHALF: PROCEDURE; - /* APPEND 'TIL BUFFER IS AT LEAST HALF FULL */ - CALL SETFF; /* DISTANCE = 0FFFFH */ - DO WHILE DISTNZERO; - IF FRONT >= HMAX THEN CALL ZERODIST; ELSE - CALL READLINE; - END; - END APPHALF; - -INSCRLF: PROCEDURE; - /* INSERT CR LF CHARACTERS */ - CHAR = CR; CALL INSERT; - CHAR = LF; CALL INSERT; - END INSCRLF; - -TESTCASE: PROCEDURE; - DECLARE T BYTE; - /* TEST FOR UPPER OR LOWER CASE COMMAND AND SET TRANSLATE - FLAG (USED TO DETERMINE IF CHARACTERS WHICH FOLLOW GO TO UPPER */ - TRANSLATE = TRUE; - T = LOWERCASE(CHAR); - CHAR = UTRAN(CHAR); - TRANSLATE = UPPER OR NOT T; - END TESTCASE; - -READCTRAN: PROCEDURE; - /* SET TRANSLATE TO FALSE AND READ NEXT CHARACTER */ - TRANSLATE = FALSE; - CHAR = READC; - CALL TESTCASE; - END READCTRAN; - -SINGLECOM: PROCEDURE(C) BYTE; - /* RETURN TRUE IF COMMAND IS ONLY CHARACTER, NOT IN MACRO */ - DECLARE C BYTE; - RETURN CHAR = C AND COMLEN = 1 AND MP = 0; - END SINGLECOM; - -SINGLERCOM: PROCEDURE(C) BYTE; - DECLARE C BYTE; - /* RETURN TRUE IF COMMAND IS ONLY CHARACTER, NOT IN MACRO, AND - THE OPERATOR HAS RESPONDED WITH 'Y' TO A Y/N REQUEST */ - IF SINGLECOM(C) THEN - DO; CALL CRLF; CALL PRINTCHAR(C); - CALL MON1(9,.('-(Y/N)',WHAT,'$')); - C = UCASE(READCHAR); CALL CRLF; - IF C <> 'Y' THEN GO TO START; - RETURN TRUE; - END; - RETURN FALSE; - END SINGLERCOM; - - - - - - - /* INITIALIZE THE SYSTEM */ - -EDCOMMAND: /* PAST LXI SP,STACK */ - /* I/O BUFFER REGION IS 1/8 AVAILABLE MEMORY */ - NBUF = SHR(MAX := MAXB - .MEMORY,SECTSHF+3) - 1; - /* NBUF IS NUMBER OF BUFFERS - 1 */ - BUFFLENGTH = SHL(DOUBLE(NBUF+1),SECTSHF+1); - /* NOW SET MAX AS REMAINDER OF FREE MEMORY */ - IF BUFFLENGTH + 1024 > MAX THEN - DO; CALL PRINT(.('NO MEMORY$')); - CALL BOOT; - END; - /* REMOVE BUFFER SPACE AND 00 AT END OF MEMORY VECTOR */ - MAX = MAX - BUFFLENGTH - 1; - /* RESET BUFFER LENGTH FOR I AND O */ - BUFFLENGTH = SHR(BUFFLENGTH,1); - SBUFFADR = MAXB - BUFFLENGTH; - DBUFFADR = SBUFFADR - BUFFLENGTH; - MEMORY(MAX) = 0; /* STOPS MATCH AT END OF BUFFER */ - MAXM = MAX - 1; - HMAX = SHR(MAXM,1); - /* NO TRANSLATE, WITH LINE NUMBERS */ - UPPER, PRINTSUPPRESS = FALSE; - LINESET = TRUE; - /* GET SOURCE AND DESTINATION DISKS */ - IF (FCB(1) = ' ') OR (FCB(17) <> ' ') THEN CALL FERR; - IF (SDISK := FCB(0)) = 0 THEN SDISK = CSELECT; ELSE - DO; SDISK = SDISK - 1; FCB(0) = 0; /* CLEAR DISK NAME */ - END; - IF (DDISK := FCB(16)) = 0 THEN DDISK = SDISK; ELSE - DDISK = DDISK - 1; - /* CLEAR THE XFER FILE */ - CALL XCLEAR; - -RESTART: - CALL SETUP; - MEMORY(0) = LF; - FRONT = 1; BACK = MAXM; - COLUMN = 0; - GO TO START; - -OVERCOUNT: FLAG = POUND; GO TO RESET; - -BADCOM: FLAG = WHAT; GO TO RESET; - -OVERFLOW: /* ARRIVE HERE ON OVERFLOW CONDITION (I,F,S COMMAND) */ - FLAG = '>'; - -RESET: /* ARRIVE HERE ON ERROR CONDITION */ - PRINTSUPPRESS = FALSE; - CALL PRINT(.('BREAK "$')); - CALL PRINTC(FLAG); - CALL PRINTM(.('" AT $')); - CALL PRINTC(CHAR); - CALL CRLF; - - -START: - READBUFF = TRUE; - MP = 0; - - - DO FOREVER; /* OR UNTIL THE POWER IS TURNED OFF */ - - /* ************************************************************** - SIMPLE COMMANDS (CANNOT BE PRECEDED BY DIRECTION/DISTANCE): - E END THE EDIT NORMALLY - H MOVE TO HEAD OF EDITED FILE - I INSERT CHARACTERS - O RETURN TO THE ORIGINAL FILE - R READ FROM LIBRARY FILE - Q QUIT EDIT WITHOUT CHANGES TO ORIGINAL FILE - ************************************************************** */ - - - - INSERTING = FALSE; - CALL READCTRAN; - MI = CBP; /* SAVE STARTING ADDRESS FOR COMMAND */ - IF SINGLECOM('E') THEN - DO; CALL TERMINATE; - IF SDISK <> DDISK THEN /* CHANGE DISKS */ - /* USER CODE IN HIGH NIBBLE */ - BDISK = (BDISK AND 0F0H) OR (DDISK AND 0FH); - CALL REBOOT; - END; ELSE - - - IF SINGLECOM('H') THEN /* GO TO TOP */ - DO; CALL TERMINATE; - CHAR = DDISK; DDISK = SDISK; SDISK = CHAR; - /* PING - PONG DISKS */ - GO TO RESTART; - END; ELSE - - - IF CHAR = 'I' THEN /* INSERT CHARACTERS */ - DO; - IF (INSERTING := (CBP = COMLEN) AND (MP = 0)) THEN - CALL PRINTNMBASE; - SCOLUMN = COLUMN; /* STARTING COLUMN POSITION */ - DO WHILE SCANNING; - DO WHILE CHAR <> 0; - IF CHAR=CTLU OR CHAR=CTLX OR CHAR=CTLR THEN - /* LINE DELETE OR RETYPE */ - DO; - DISTANCE = 0; DIRECTION = BACKWARD; - /* ELIMINATE OR REPEAT THE LINE */ - IF CHAR = CTLR THEN - DO; CALL CRLF; - CALL TYPELINES; - END; ELSE - /* LINE DELETE */ - DO; CALL SETLIMITS; CALL SETPTRS; - IF CHAR = CTLU THEN - DO; CALL CRLF; CALL PRINTNMBASE; - END; ELSE - /* MUST BE CTLX */ - DO WHILE COLUMN > SCOLUMN; - CALL BACKSPACE; - END; - END; - END; ELSE - IF CHAR = CTLH THEN - DO; - IF (TCOLUMN := COLUMN) > 0 THEN - CALL PRINTNMAC(' '); /* RESTORE AFT BACKSP */ - IF FRONT > 1 AND TCOLUMN > SCOLUMN THEN - DO; - IF MEMORY(FRONT-1) <> LF THEN - DO; /* CHARACTER CAN BE ELIMINATED */ - CALL DECFRONT; - PRINTSUPPRESS = TRUE; - /* BACKSPACE CHARACTER ACCEPTED */ - COLUMN = 0; - DISTANCE = 0; DIRECTION = BACKWARD; - CALL TYPELINES; - PRINTSUPPRESS = FALSE; - /* COLUMN POSITION NOW RESET */ - IF (QCOLUMN := COLUMN) < SCOLUMN THEN - QCOLUMN = SCOLUMN; - COLUMN = TCOLUMN; /* ORIGINAL VALUE */ - DO WHILE COLUMN > QCOLUMN; - CALL BACKSPACE; - END; - TCOLUMN = COLUMN; - END; - END; - CHAR = 0; - COLUMN = TCOLUMN; - END; ELSE - IF CHAR = RUBOUT THEN - DO; IF FRONT = 1 THEN GO TO RESET; - CALL DECFRONT; CALL PRINTC(CHAR:=MEMORY(FRONT)); - IF CHAR = LF THEN BASELINE=BASELINE-1; - CHAR = 0; - END; ELSE - /* NOT A SPECIAL CASE */ - DO; IF NOT GRAPHIC(CHAR) THEN - DO; CALL PRINTNMAC('^'); - CALL PRINTNMAC(CHAR + '@'); - END; - IF CHAR = CTLL THEN - CALL INSCRLF; ELSE - DO; /* COLUMN COUNT GOES UP IF GRAPHIC */ - /* COMPUTE OUTPUT COLUMN POSITION */ - IF MP = 0 THEN - DO; IF CHAR >= ' ' THEN - COLUMN = COLUMN + 1; ELSE - IF CHAR = TAB THEN - COLUMN = COLUMN + (8 - (COLUMN AND 111B)); - END; - CALL INSERT; - END; - END; - IF CHAR = LF THEN CALL PRINTNMBASE; - IF CHAR = CR THEN - CALL PRINTNMAC(CHAR:=LF); ELSE CHAR = 0; - END; - END; - IF CHAR <> ENDFILE THEN /* MUST HAVE STOPPED ON CR */ - CALL INSCRLF; - IF INSERTING AND LINESET THEN CALL CRLF; - END; ELSE - - - IF SINGLERCOM('O') THEN /* FORGET THIS EDIT */ - GO TO RESTART; ELSE - - - IF CHAR = 'R' THEN - DO; DECLARE I BYTE; - /* READ FROM LIB FILE */ - RBP = 1; CALL SETRDMA; - DO WHILE SCANNING; - IF RBP > 8 THEN GO TO OVERCOUNT; - CALL SETRFCB; - END; - CHAR = ' '; - IF (FLAG := RBP = 1) THEN /* READ FROM XFER FILE */ - DO; - CALL MOVE(8,.XFCB(1),.RFCB(1)); - CALL CLOSE(.XFCB); - END; ELSE /* LIB NAME SPECIFIED */ - DO WHILE RBP <= 8; - CALL SETRFCB; - END; - RFCB(12), RFCB(32) = 0; /* FILL REEL, AND NEXT RECORD */ - CALL OPEN(.RFCB); RBP = SECTSIZE; - IF DCNT = 255 THEN - DO; FLAG = 'O'; GO TO RESET; - END; - DO WHILE (CHAR := READFILE) <> ENDFILE; - CALL INSERT; - END; - I = 0; - IF FLAG THEN /* MAY BE XFER DATA IN BUFFER */ - DO WHILE I < XBP; - CHAR = XBUFF(I); I = I + 1; - CALL INSERT; - END; - END; ELSE - - - IF SINGLERCOM('Q') THEN - DO; CALL DELETE(.DFCB); CALL REBOOT; - END; ELSE - - - - /* MAY BE A COMMAND WHICH HAS AN OPTIONAL DIRECTION AND DISTANCE */ - DO; /* SCAN A SIGNED INTEGER VALUE (IF ANY) */ - DCL I BYTE; - - DIGIT: PROCEDURE BYTE; - RETURN (I := CHAR - '0') <= 9; - END DIGIT; - - NUMBER: PROCEDURE; - DISTANCE = 0; - DO WHILE DIGIT; - DISTANCE = SHL(DISTANCE,3) + - SHL(DISTANCE,1) + I; - CALL READCTRAN; - END; - /* RETURN WITH DISTANCE = NUMBER, CHAR = NEXT */ - END NUMBER; - - RELDISTANCE: PROCEDURE; - IF DISTANCE > BASELINE THEN - DO; DIRECTION = FORWARD; - DISTANCE = DISTANCE - BASELINE; - END; ELSE - DO; DIRECTION = BACKWARD; - DISTANCE = BASELINE - DISTANCE; - END; - END RELDISTANCE; - - CALL SETFORWARD; - - IF CHAR = '-' THEN - DO; CALL READCTRAN; DIRECTION = BACKWARD; - END; - - IF CHAR = POUND THEN - DO; CALL SETFF; CALL READCTRAN; - END; ELSE - - IF DIGIT THEN - DO; CALL NUMBER; - /* MAY BE ABSOLUTE LINE REFERENCE */ - IF CHAR = ':' THEN - DO; CHAR = 'L'; - CALL RELDISTANCE; - END; - END; ELSE - - IF CHAR = ':' THEN /* LEADING COLON */ - DO; CALL READCTRAN; /* CLEAR THE COLON */ - CALL NUMBER; - CALL RELDISTANCE; - IF DIRECTION = FORWARD THEN - DISTANCE = DISTANCE + 1; - END; - - IF DISTZERO THEN DIRECTION = BACKWARD; - /* DIRECTION AND DISTANCE ARE NOW SET */ - - - /* ************************************************************** - MAY BE A COMMAND WHICH HAS DIRECTION AND DISTANCE SPECIFIED: - B BEGINNING/BOTTOM OF BUFFER - C MOVE CHARACTER POSITIONS - D DELETE CHARACTERS - K KILL LINES - L MOVE LINE POSITION - P PAGE UP OR DOWN (LPP LINES AND PRINT) - T TYPE LINES - U UPPER CASE TRANSLATE - V VERIFY LINE NUMBERS - MOVE UP OR DOWN LINES AND PRINT LINE - ************************************************************** */ - - - IF CHAR = 'B' THEN - DO; DIRECTION = 1 - DIRECTION; - FIRST = 1; LAST = MAXM; CALL MOVER; - END; ELSE - - - IF CHAR = 'C' THEN - DO; CALL SETCLIMITS; CALL MOVER; - END; ELSE - - - IF CHAR = 'D' THEN - DO; CALL SETCLIMITS; - CALL SETPTRS; /* SETS BACK/FRONT */ - END; ELSE - - - IF CHAR = 'K' THEN - DO; CALL SETLIMITS; - CALL SETPTRS; - END; ELSE - - - IF CHAR = 'L' THEN CALL MOVELINES; ELSE - - IF CHAR = 'P' THEN /* PAGE MODE PRINT */ - DO; IF DISTZERO THEN - DO; DIRECTION = FORWARD; - CALL SETLPP; CALL TYPELINES; - END; ELSE - DO WHILE DISTNZERO; CALL PAGE; - CALL WAIT; - END; - END; ELSE - - - IF CHAR = 'T' THEN - CALL TYPELINES; ELSE - - - - IF CHAR = 'U' THEN - UPPER = DIRECTION = FORWARD; ELSE - - IF CHAR = 'V' THEN - DO; /* 0V DISPLAYS BUFFER STATE */ - IF DISTZERO THEN - DO; CALL PRINTVALUE(BACK-FRONT); - CALL PRINTC('/'); - CALL PRINTVALUE(MAXM); - CALL CRLF; - END; ELSE - LINESET = DIRECTION = FORWARD; - END; ELSE - - IF CHAR = CR THEN /* MAY BE MOVE/TYPE COMMAND */ - DO; - IF MI = 1 AND MP = 0 THEN /* FIRST COMMAND */ - DO; CALL MOVELINES; CALL SETFORWARD; CALL TYPELINES; - END; - END; ELSE - - IF DIRECTION = FORWARD OR DISTZERO THEN - DO; - - /* ************************************************************** - COMMANDS WHICH ALLOW ONLY A PRECEDING NUMBER: - A APPEND LINES - F FIND NTH OCCURRENCE - M APPLY MACRO - N SAME AS F WITH AUTOSCAN THROUGH FILE - S PERFORM N SUBSTITUTIONS - W WRITE LINES TO OUTPUT FILE - X TRANSFER (XFER) LINES TO TEMP FILE - Z SLEEP - ************************************************************** */ - - - - IF CHAR = 'A' THEN - DO; DIRECTION = FORWARD; - FIRST = FRONT; LAST = MAXM; CALL MOVER; - /* ALL STORAGE FORWARD */ - IF DISTZERO THEN CALL APPHALF; - /* DISTANCE = 0 IF APPHALF CALLED */ - DO WHILE DISTNZERO; - CALL READLINE; - END; - DIRECTION = BACKWARD; CALL MOVER; - /* POINTERS REPOSITIONED */ - END; ELSE - - - IF CHAR = 'F' THEN - DO; CALL SETFIND; /* SEARCH STRING SCANNED - AND SETUP BETWEEN 0 AND WBP-1 IN SCRATCH */ - DO WHILE DISTNZERO; CALL CHKFOUND; - END; - END; ELSE - - - IF CHAR = 'J' THEN /* JUXTAPOSITION OPERATION */ - DO; DECLARE T ADDRESS; - CALL SETFIND; CALL COLLECT; - WBJ = WBE; CALL COLLECT; - /* SEARCH FOR STRING 0 - WBP-1, INSERT STRING WBP TO WBJ-1, - AND THEN DELETE UP TO STRING WBJ TO WBE-1 */ - DO WHILE DISTNZERO; CALL CHKFOUND; - /* INSERT STRING */ MI = WBP - 1; - DO WHILE (MI := MI + 1) < WBJ; - CHAR = SCRATCH(MI); CALL INSERT; - END; - T = FRONT; /* SAVE POSITION FOR DELETE */ - IF NOT FIND(WBJ,WBE) THEN GO TO OVERCOUNT; - /* STRING FOUND, SO MOVE IT BACK */ - FIRST = FRONT - (WBE - WBJ); - DIRECTION = BACKWARD; CALL MOVER; - /* NOW REMOVE THE INTERMEDIATE STRING */ - FRONT = T; - END; - END; ELSE - - - IF CHAR = 'M' AND MP = 0 THEN /* MACRO DEFINITION */ - DO; XP = 255; - IF DISTANCE = 1 THEN CALL ZERODIST; - DO WHILE (MACRO(XP := XP + 1) := READC) <> CR; - END; - MP = XP; XP = 0; MT = DISTANCE; - END; ELSE - - - IF CHAR = 'N' THEN - DO; /* SEARCH FOR STRING WITH AUTOSCAN */ - CALL SETFIND; /* SEARCH STRING SCANNED */ - DO WHILE DISTNZERO; - /* FIND ANOTHER OCCURRENCE OF STRING */ - DO WHILE NOT FIND(0,WBP); /* NOT IN BUFFER */ - IF BREAK$KEY THEN GO TO RESET; - CALL SAVEDIST; CALL CLEARMEM; - /* MEMORY BUFFER WRITTEN */ - CALL APPHALF; - DIRECTION = BACKWARD; FIRST = 1; CALL MOVER; - CALL RESTDIST; DIRECTION = FORWARD; - /* MAY BE END OF FILE */ - IF BACK >= MAXM THEN GO TO OVERCOUNT; - END; - END; - END; ELSE - - - IF CHAR = 'S' THEN /* SUBSTITUTE COMMAND */ - DO; CALL SETFIND; - CALL COLLECT; - /* FIND STRING FROM 0 TO WBP-1, SUBSTITUTE STRING - BETWEEN WBP AND WBE-1 IN SCRATCH */ - DO WHILE DISTNZERO; - CALL CHKFOUND; - /* FRONT AND BACK NOW POSITIONED AT FOUND - STRING - REPLACE IT */ - FRONT = FRONT - (MI := WBP); /* BACKED UP */ - DO WHILE MI < WBE; - CHAR = SCRATCH(MI); - MI = MI + 1; CALL INSERT; - END; - END; - END; ELSE - - - IF CHAR = 'W' THEN - CALL WRITEOUT; ELSE - - IF CHAR = 'X' THEN /* TRANSFER LINES */ - DO; - CALL SETXDMA; - IF DISTZERO THEN /* CLEAR THE FILE */ - DO; CALL XCLEAR; - CALL DELETE(.XFCB); - END; ELSE - /* TRANSFER LINES */ - DO; DECLARE I ADDRESS; - IF NOT XFERON THEN /* CREATE XFER FILE */ - DO; CALL XCLEAR; - XFERON = TRUE; - CALL DELETE(.XFCB); /* OLD VERSION GONE */ - CALL MAKE(.XFCB); - IF DCNT = 255 THEN CALL FERR; - END; - CALL SETLIMITS; - DO I = FIRST TO LAST; - CALL PUTXFER(MEMORY(I)); - END; - END; - END; ELSE - - IF CHAR = 'Z' THEN /* SLEEP */ - DO; - IF DISTZERO THEN - DO; IF READCHAR = ENDFILE THEN GO TO RESET; - END; - DO WHILE DISTNZERO; CALL WAIT; - END; - END; ELSE - IF CHAR <> 0 THEN /* NOT BREAK LEFT OVER FROM STOP */ - /* DIRECTION FORWARD, BUT NOT ONE OF THE ABOVE */ - GO TO BADCOM; - - - END; ELSE /* DIRECTION NOT FORWARD */ - GO TO BADCOM; - END; - END; -END; - \ No newline at end of file diff --git a/cpm/pcpm/PIP.PLM b/cpm/pcpm/PIP.PLM deleted file mode 100644 index d17c817..0000000 --- a/cpm/pcpm/PIP.PLM +++ /dev/null @@ -1,1509 +0,0 @@ -PIPMOD: -DO; -/* P E R I P H E R A L I N T E R C H A N G E P R O G R A M - - COPYRIGHT (C) 1976, 1977, 1978, 1979, 1980, 1984 - DIGITAL RESEARCH - BOX 579 - PACIFIC GROVE, CA - 93950 - */ - -DECLARE - CPMVERSION LITERALLY '0028H'; /* REQUIRED FOR OPERATION */ - -DECLARE - MAXB ADDRESS EXTERNAL, /* ADDR FIELD OF JMP BDOS */ - FCB (33) BYTE EXTERNAL, /* DEFAULT FILE CONTROL BLOCK */ - BUFF(128)BYTE EXTERNAL; /* DEFAULT BUFFER */ - -DECLARE - ENDFILE LITERALLY '1AH', /* END OF FILE MARK */ - JMP LITERALLY '0C3H', /* 8080 JUMP INSTRUCTION */ - RET LITERALLY '0C9H'; /* 8080 RETURN */ - -/* THE FIRST PORTION OF THE PIP PROGRAM 'FAKES' THE PAGE ONE -(100H - 1FFH) SECTION OF PIP WHICH CONTAINS A JUMP TO PIPENTRY, AND -SPACE FOR CUSTOM I/O DRIVERS (WHICH CAN BE 'PATCHED' USING DDT) IN THE -REMAINING PAGE ONE AREA. THE PIP PROGRAM ACTUALLY STARTS AT 200H */ - -DECLARE JUMP BYTE DATA(JMP); /* JMP INSTRUCTION TO */ -/* JMP .PIPENTRY-3 WHERE THE LXI SP,STACK ACTUALLY OCCURS */ -DECLARE JADR ADDRESS DATA(.PIPENTRY-3); /* START OF PIP */ -DECLARE INPSUB(3) BYTE DATA(RET,0,0); /* INP: RET NOP NOP */ -DECLARE OUTSUB(3) BYTE DATA(RET,0,0); /* OUT: RET NOP NOP */ -DECLARE INPDATA BYTE DATA(ENDFILE); /* RETURNED DATA */ - /* NOTE: PAGE 1 AT 100H CONTAINS THE FOLLOWING - 100H: JMP PIPENTRY ;TO START THE PIP PROGRAM - 103H: RET ;INP: DEFAULTS TO EMPTY INPUT (DATA 1AH AT 109H) - 104H: NOP - 105H: NOP - 106H: RET ;OUT: DEFAULTS TO EMPTY OUTPUT - 107H: NOP - 108H: NOP - 109H: 1AH=ENDFILE ;DATA FROM INP: FUNCTION IS STORED HERE ON - ;RETURN FROM THE INP: ENTRY POINT - 10AH: - 1FFH ;SPACE RESERVED FOR SPECIAL PURPOSE - ; DRIVERS - IF INCLUDED, THEN REPLACE 103H AND 106H BY JMP'S - ; TO THE PROPER LOCATIONS WITHIN THE RESERVED AREA. - ; ALSO, RETURN DATA FROM INP: ENTRY POINT AT 109H. - ; THESE DRIVERS ARE MOST EASILY INSERTED WITH THE DDT PROGRAM - ; UNDER CP/M - */ - -DECLARE /* 16 BYTE MESSAGE */ - FREEMEMORY LITERALLY '''(INP:/OUT:SPACE)''', - /* 256 BYTE AREA FOR INP: OUT: PATCHING */ - RESERVED(*) BYTE DATA(0,0,0,0,0,0, - FREEMEMORY, FREEMEMORY, FREEMEMORY, - FREEMEMORY, FREEMEMORY, FREEMEMORY, FREEMEMORY, - FREEMEMORY, FREEMEMORY, FREEMEMORY, FREEMEMORY, - FREEMEMORY, FREEMEMORY, FREEMEMORY, FREEMEMORY); - - - - - DECLARE COPYRIGHT(*) BYTE DATA ( - ' COPYRIGHT (C) 1984, DIGITAL RESEARCH, PIP VERS 1.6'); - - DECLARE INPLOC ADDRESS DATA (.INPSUB); /* ADDRESS OF INP: DEVICE */ - DECLARE OUTLOC ADDRESS DATA (.OUTSUB); /* ADDRESS OF OUT: DEVICE */ - -OUT: PROCEDURE(B); - DECLARE B BYTE; - /* SEND B TO OUT: DEVICE */ - CALL OUTLOC; - END OUT; - -INP: PROCEDURE BYTE; - CALL INPLOC; - RETURN INPDATA; - END INP; - - -TIMEOUT: PROCEDURE; - /* WAIT FOR 50 MSEC */ - CALL TIME(250); CALL TIME(250); - END TIMEOUT; - - /* LITERAL DECLARATIONS */ - DECLARE - LIT LITERALLY 'LITERALLY', - LPP LIT '60', /* LINES PER PAGE */ - TAB LIT '09H', /* HORIZONTAL TAB */ - FF LIT '0CH', /* FORM FEED */ - LA LIT '05FH', /* LEFT ARROW */ - LB LIT '05BH', /* LEFT BRACKET */ - RB LIT '05DH', /* RIGHT BRACKET */ - XOFF LIT '13H', /* TRANSMIT BUFFER FUNCTION */ - - inpp lit '0', - aux lit '1', - LST LIT '4', - conp lit '6', /* console */ - NULP LIT '6', /* NUL: BEFORE INCREMENT */ - EOFP LIT '7', /* EOF: BEFORE INCREMENT */ - hsaux LIT 'aux', /* READER DEVICES */ - PRNT LIT '4', /* PRINTER */ - - - FSIZE LIT '33', - FRSIZE LIT '36', /* SIZE OF RANDOM FCB */ - NSIZE LIT '8', - FNSIZE LIT '11', - MDISK LIT '1', - FNAM LIT '8', - FEXT LIT '9', - FEXTL LIT '3', - ROFILE LITERALLY '9', /* READ ONLY FILE FIELD */ - SYSFILE LITERALLY '10', /* SYSTEM FILE FIELD */ - FREEL LIT '12', /* REEL NUMBER FIELD OF FCB */ - - HBUFS LIT '80', /* "HEX" BUFFER SIZE */ - - ERR LIT '0', - SPECL LIT '1', - FILE LIT '2', - PERIPH LIT '3', - DISKNAME LIT '4'; - -DECLARE - COLUMN BYTE, /* COLUMN COUNT FOR PRINTER TABS */ - LINENO BYTE, /* LINE WITHIN PAGE */ - AMBIG BYTE, /* SET FOR AMBIGUOUS FILE REFS */ - PARSET BYTE, /* TRUE IF PARAMETERS PRESENT */ - FEEDBASE BYTE, /* USED TO FEED SEARCH CHARACTERS */ - FEEDLEN BYTE, /* LENGTH OF FEED STRING */ - MATCHLEN BYTE, /* USED IN MATCHING STRINGS */ - QUITLEN BYTE, /* USED TO TERMINATE QUIT COMMAND */ - NBUF BYTE, /* NUM BUFFERS-1 IN SBUFF AND DBUFF */ - CDISK BYTE, /* CURRENT DISK */ - BUFFER LITERALLY 'BUFF', /* DEFAULT BUFFER */ - SEARFCB LITERALLY 'FCB', /* SEARCH FCB IN MULTI COPY */ - MEMSIZE LITERALLY 'MAXB', /* MEMORY SIZE */ - SBLEN ADDRESS, /* SOURCE BUFFER LENGTH */ - DBLEN ADDRESS, /* DEST BUFFER LENGTH */ - SBASE ADDRESS, /* SOURCE BUFFER BASE */ - /* THE VECTORS DBUFF AND SBUFF ARE DECLARED WITH DIMENSION - 1024, BUT ACTUALLY VARY WITH THE FREE MEMORY SIZE */ - DBUFF(1024) BYTE AT (.MEMORY), /* DESTINATION BUFFER */ - SBUFF BASED SBASE (1024) BYTE, /* SOURCE BUFFER */ - SDISK BYTE, /* SOURCE DISK */ - (SCOM, DHEX) BYTE, /* SOURCE IS 'COM' FILE IF TRUE */ - /* DEST IS 'HEX' FILE IF TRUE */ - SOURCE (FSIZE) BYTE, /* SOURCE FCB */ - SFUB BYTE AT(.SOURCE(13)), /* UNFILLED BYTES FIELD */ - DEST (FRSIZE) BYTE, /* DESTINATION FCB */ - DESTR ADDRESS AT(.DEST(33)), /* RANDOM RECORD POSITION */ - DESTO BYTE AT(.DEST(35)), /* RANDOM OVERFLOW BYTE */ - DFUB BYTE AT (.DEST(13)), /* UNFILLED BYTES FIELD */ - DDISK BYTE, /* DESTINATION DISK */ - HBUFF(HBUFS) BYTE, /* HEX FILE BUFFER */ - HSOURCE BYTE, /* NEXT HEX SOURCE CHARACTER */ - - NSOURCE ADDRESS, /* NEXT SOURCE CHARACTER */ - HARDEOF ADDRESS, /* SET TO NSOURCE ON REAL EOF */ - NDEST ADDRESS; /* NEXT DESTINATION CHARACTER */ - -DECLARE - /* SUBMIT FILE CONTROL BLOCK FOR ERROR DELETE */ - SUBFCB (*) BYTE DATA (0,'$$$ SUB',0,0,0); - - DECLARE - PDEST BYTE, /* DESTINATION DEVICE */ - PSOURCE BYTE; /* CURRENT SOURCE DEVICE */ - - DECLARE - MULTCOM BYTE, /* FALSE IF PROCESSING ONE LINE */ - PUTNUM BYTE, /* SET WHEN READY FOR NEXT LINE NUM */ - CONCNT BYTE, /* COUNTER FOR CONSOLE READY CHECK */ - CHAR BYTE, /* LAST CHARACTER SCANNED */ - TYPE BYTE, /* TYPE OF CHARACTER SCANNED */ - FLEN BYTE; /* FILE NAME LENGTH */ - -MON1: PROCEDURE(F,A) EXTERNAL; - DECLARE F BYTE, - A ADDRESS; - END MON1; - -MON2: PROCEDURE(F,A) BYTE EXTERNAL; - DECLARE F BYTE, - A ADDRESS; - END MON2; - -MON3: PROCEDURE(F,A) ADDRESS EXTERNAL; - DECLARE F BYTE, - A ADDRESS; - END MON3; - -BOOT: PROCEDURE EXTERNAL; - /* SYSTEM REBOOT */ - END BOOT; - -READRDR: PROCEDURE BYTE; - /* READ CURRENT READER DEVICE */ - RETURN MON2(3,0); - END READRDR; - -READCHAR: PROCEDURE BYTE; - /* READ CONSOLE CHARACTER */ - RETURN MON2(1,0); - END READCHAR; - -DECLARE - TRUE LITERALLY '1', - FALSE LITERALLY '0', - FOREVER LITERALLY 'WHILE TRUE', - CR LITERALLY '13', - LF LITERALLY '10', - WHAT LITERALLY '63'; - -PRINTCHAR: PROCEDURE(CHAR); - DECLARE CHAR BYTE; - CALL MON1(2,CHAR AND 7FH); - END PRINTCHAR; - -CRLF: PROCEDURE; - CALL PRINTCHAR(CR); - CALL PRINTCHAR(LF); - END CRLF; - -PRINT: PROCEDURE(A); - DECLARE A ADDRESS; - /* PRINT THE STRING STARTING AT ADDRESS A UNTIL THE - NEXT DOLLAR SIGN IS ENCOUNTERED */ - CALL CRLF; - CALL MON1(9,A); - END PRINT; - -DECLARE DCNT BYTE; - -VERSION: PROCEDURE ADDRESS; - RETURN MON3(12,0); /* VERSION NUMBER */ - END VERSION; - -INITIALIZE: PROCEDURE; - CALL MON1(13,0); - END INITIALIZE; - -SELECT: PROCEDURE(D); - DECLARE D BYTE; - CALL MON1(14,D); - END SELECT; - -OPEN: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - DCNT = MON2(15,FCB); - END OPEN; - -CLOSE: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - DCNT = MON2(16,FCB); - END CLOSE; - -SEARCH: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - DCNT = MON2(17,FCB); - END SEARCH; - -SEARCHN: PROCEDURE; - DCNT = MON2(18,0); - END SEARCHN; - -DELETE: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - CALL MON1(19,FCB); - END DELETE; - -DISKREAD: PROCEDURE(FCB) BYTE; - DECLARE FCB ADDRESS; - RETURN MON2(20,FCB); - END DISKREAD; - -DISKWRITE: PROCEDURE(FCB) BYTE; - DECLARE FCB ADDRESS; - RETURN MON2(21,FCB); - END DISKWRITE; - -MAKE: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - DCNT = MON2(22,FCB); - END MAKE; - -RENAME: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - CALL MON1(23,FCB); - END RENAME; - -DECLARE - CUSER BYTE, /* CURRENT USER NUMBER */ - SUSER BYTE; /* SOURCE USER NUMBER ('G' PARAMETER) */ - -SETIND: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - CALL MON1(30,FCB); - END SETIND; - -GETUSER: PROCEDURE BYTE; - RETURN MON2(32,0FFH); - END GETUSER; - -SETUSER: PROCEDURE(USER); - DECLARE USER BYTE; - CALL MON1(32,USER); - END SETUSER; - -SETCUSER: PROCEDURE; - CALL SETUSER(CUSER); - END SETCUSER; - -SETSUSER: PROCEDURE; - CALL SETUSER(SUSER); - END SETSUSER; - -READ$RANDOM: PROCEDURE(FCB) BYTE; - DECLARE FCB ADDRESS; - RETURN MON2(33,FCB); - END READ$RANDOM; - -WRITE$RANDOM: PROCEDURE(FCB) BYTE; - DECLARE FCB ADDRESS; - RETURN MON2(34,FCB); - END WRITE$RANDOM; - -SET$RANDOM: PROCEDURE(FCB); - DECLARE FCB ADDRESS; - /* SET RANDOM RECORD POSITION */ - CALL MON1(36,FCB); - END SET$RANDOM; - -DECLARE CBUFF(130) BYTE, /* COMMAND BUFFER */ - MAXLEN BYTE AT (.CBUFF(0)), /* MAX BUFFER LENGTH */ - COMLEN BYTE AT (.CBUFF(1)), /* CURRENT LENGTH */ - COMBUFF (128) BYTE AT (.CBUFF(2)); /* COMMAND BUFFER CONTENTS */ -DECLARE (TCBP,CBP) BYTE; /* TEMP CBP, COMMAND BUFFER POINTER */ - -READCOM: PROCEDURE; - /* READ INTO COMMAND BUFFER */ - MAXLEN = 128; - CALL MON1(10,.MAXLEN); - END READCOM; - -DECLARE MCBP BYTE; - -CONBRK: PROCEDURE BYTE; - /* CHECK CONSOLE CHARACTER READY */ - RETURN MON2(11,0); - END CONBRK; - -DECLARE /* CONTROL TOGGLE VECTOR */ - CONT(26) BYTE, /* ONE FOR EACH ALPHABETIC */ - /* 00 01 02 03 04 05 06 07 08 09 10 11 12 13 - A B C D E F G H I J K L M N - 14 15 16 17 18 19 20 21 22 23 24 25 - O P Q R S T U V W X Y Z */ - BLOCK BYTE AT(.CONT(1)), /* BLOCK MODE TRANSFER */ - DELET BYTE AT(.CONT(3)), /* DELETE CHARACTERS */ - ECHO BYTE AT(.CONT(4)), /* ECHO CONSOLE CHARACTERS */ - FORMF BYTE AT(.CONT(5)), /* FORM FILTER */ - GETU BYTE AT(.CONT(6)), /* GET FILE, USER # */ - HEXT BYTE AT(.CONT(7)), /* HEX FILE TRANSFER */ - IGNOR BYTE AT(.CONT(8)), /* IGNORE :00 RECORD ON FILE */ - LOWER BYTE AT(.CONT(11)), /* TRANSLATE TO LOWER CASE */ - NUMB BYTE AT(.CONT(13)), /* NUMBER OUTPUT LINES */ - OBJ BYTE AT(.CONT(14)), /* OBJECT FILE TRANSFER */ - PAGCNT BYTE AT(.CONT(15)), /* PAGE LENGTH */ - QUITS BYTE AT(.CONT(16)), /* QUIT COPY */ - RSYS BYTE AT(.CONT(17)), /* READ SYSTEM FILES */ - STARTS BYTE AT(.CONT(18)), /* START COPY */ - TABS BYTE AT(.CONT(19)), /* TAB SET */ - UPPER BYTE AT(.CONT(20)), /* UPPER CASE TRANSLATE */ - VERIF BYTE AT(.CONT(21)), /* VERIFY EQUAL FILES ONLY */ - WRROF BYTE AT(.CONT(22)), /* WRITE TO R/O FILE */ - ZEROP BYTE AT(.CONT(25)); /* ZERO PARITY ON INPUT */ - - SETDMA: PROCEDURE(A); - DECLARE A ADDRESS; - CALL MON1(26,A); - END SETDMA; - -DECLARE ZEROSUP BYTE, /* ZERO SUPPRESSION */ - (C3,C2,C1) BYTE; /* LINE COUNT ON PRINTER */ - - ERROR: PROCEDURE(A); - DECLARE A ADDRESS, I BYTE; - CALL SETCUSER; - CALL PRINT(A); CALL PRINTCHAR(':'); CALL PRINTCHAR(' '); - DO I = TCBP TO CBP; - IF I < COMLEN THEN CALL PRINTCHAR(COMBUFF(I)); - END; - /* ZERO THE COMLEN IN CASE THIS IS A SINGLE COMMAND */ - COMLEN = 0; - /* DELETE ANY $$$.SUB FILES IN CASE BATCH PROCESSING */ - /* DELETE SUB FILE ONLY IF PRESENT (MAY BE R/O DISK) */ - CALL SEARCH(.SUBFCB); - IF DCNT <> 255 THEN CALL DELETE(.SUBFCB); - CALL CRLF; - GO TO RETRY; - END ERROR; - - MOVE: PROCEDURE(S,D,N); - DECLARE (S,D) ADDRESS, N BYTE; - DECLARE A BASED S BYTE, B BASED D BYTE; - DO WHILE (N:=N-1) <> 255; - B = A; S = S+1; D = D+1; - END; - END MOVE; - - - FILLSOURCE: PROCEDURE; - /* FILL THE SOURCE BUFFERS */ - DECLARE (I,J) BYTE; - NSOURCE = 0; - CALL SELECT(SDISK); - CALL SETSUSER; /* SOURCE USER NUMBER SET */ - DO I = 0 TO NBUF; - /* SET DMA ADDRESS TO NEXT BUFFER POSIITION */ - CALL SETDMA(.SBUFF(NSOURCE)); - IF (J := DISKREAD(.SOURCE)) <> 0 THEN - DO; IF J <> 1 THEN - CALL ERROR(.('DISK READ ERROR$')); - /* END - OF - FILE */ - HARDEOF = NSOURCE; /* SET HARD END-OF-FILE */ - SBUFF(NSOURCE) = ENDFILE; I = NBUF; - END; ELSE - NSOURCE = NSOURCE + 128; - END; - NSOURCE = 0; - CALL SETCUSER; /* BACK TO CURRENT USER NUMBER */ - END FILLSOURCE; - - - WRITEDEST: PROCEDURE; - /* WRITE OUTPUT BUFFERS UP TO BUT NOT INCLUDING POSITION - NDEST - THE LOW ORDER 7 BITS OF NDEST ARE ZERO */ - DECLARE (I, J, N) BYTE; - DECLARE DMA ADDRESS; - DECLARE DATAOK BYTE; - IF (N := LOW(SHR(NDEST,7)) - 1) = 255 THEN RETURN ; - NDEST = 0; - CALL SELECT(DDISK); - CALL SETRANDOM(.DEST); /* SET BASE RECORD FOR VERIFY */ - DO I = 0 TO N; - /* SET DMA ADDRESS TO NEXT BUFFER */ - DMA = .DBUFF(NDEST); - CALL SETDMA(DMA); - IF DISKWRITE(.DEST) <> 0 THEN - CALL ERROR(.('DISK WRITE ERROR$')); - NDEST = NDEST + 128; - END; - IF VERIF THEN /* VERIFY DATA WRITTEN OK */ - DO; - NDEST = 0; - CALL SETDMA(.BUFF); /* FOR COMPARE */ - DO I = 0 TO N; - DATAOK = READRANDOM(.DEST) = 0; - DESTR = DESTR + 1; /* NEXT RANDOM READ */ - J = 0; - /* PERFORM COMPARISON */ - DO WHILE DATAOK AND J < 80H; - DATAOK = BUFFER(J) = DBUFF(NDEST+J); - J = J + 1; - END; - NDEST = NDEST + 128; - IF NOT DATAOK THEN - CALL ERROR(.('VERIFY ERROR$')); - END; - DATAOK = DISKWRITE(.DEST); - /* NOW READY TO CONTINUE THE WRITE OPERATION */ - END; - NDEST = 0; - END WRITEDEST; - - PUTDCHAR: PROCEDURE(B); - DECLARE B BYTE; - /* WRITE BYTE B TO THE DESTINATION DEVICE GIVEN BY PDEST */ - IF B >= ' ' THEN - DO; COLUMN = COLUMN + 1; - IF DELET > 0 THEN /* MAY BE PAST RIGHT SIDE */ - DO; IF COLUMN > DELET THEN RETURN; - END; - END; - DO CASE PDEST; - /* CASE 0 IS THE DESTINATION FILE */ - DO; - IF NDEST >= DBLEN THEN CALL WRITEDEST; - DBUFF(NDEST) = B; - NDEST = NDEST+1; - END; - /* case 1 is INP */ - CALL ERROR(.('NOT A CHARACTER SINK$')); - /* case 2 is AUX */ - do; - do while (mon2(8,0) or conbrk) = 0; /* allow break from console */ - end; - if mon2(8,0) then call mon1(4,b); - end; - /* CASE 3 IS OUT */ - CALL OUT(B); - /* CASE 4 IS PRN (TABS EXPANDED, LINES LISTED, CHANGED TO LST) */ - GO TO LSTL; - /* CASE 5 IS LST */ - LSTL: - CALL MON1(5,B); - /* CASE 6 IS CON */ - CALL MON1(2,B); - END; - END PUTDCHAR; - -PUTDESTC: PROCEDURE(B); - DECLARE (B,I) BYTE; - /* WRITE DESTINATION CHARACTER, TAB EXPANSION */ - IF B <> TAB THEN CALL PUTDCHAR(B); ELSE - IF TABS = 0 THEN CALL PUTDCHAR(B); ELSE - /* B IS TAB CHAR, TABS > 0 */ - DO; I = COLUMN; - DO WHILE I >= TABS; - I = I - TABS; - END; - I = TABS - I; - DO WHILE I > 0; - I = I - 1; - CALL PUTDCHAR(' '); - END; - END; - IF B = CR THEN COLUMN = 0; - END PUTDESTC; - -PRINT1: PROCEDURE(B); - DECLARE B BYTE; - IF (ZEROSUP := ZEROSUP AND B = 0) THEN CALL PUTDESTC(' '); ELSE - CALL PUTDESTC('0'+B); - END PRINT1; - -PRINTDIG: PROCEDURE(D); - DECLARE D BYTE; - CALL PRINT1(SHR(D,4)); CALL PRINT1(D AND 1111B); - END PRINTDIG; - -NEWLINE: PROCEDURE; - DECLARE ONE BYTE; - ONE = 1; - ZEROSUP = NUMB = 1; - C1 = DEC(C1+ONE); C2 = DEC(C2 PLUS 0); C3 = DEC(C3 PLUS 0); - CALL PRINTDIG(C3); CALL PRINTDIG(C2); CALL PRINTDIG(C1); - IF NUMB = 1 THEN /* USUALLY PRINTER OUTPUT */ - DO; CALL PUTDESTC(':'); CALL PUTDESTC(' '); - END; ELSE - CALL PUTDESTC(TAB); - END NEWLINE; - -CLEARBUFF: PROCEDURE; - /* CLEAR OUTPUT BUFFER IN BLOCK MODE TRANSMISION */ - DECLARE NA ADDRESS; - DECLARE I BYTE; - I = LOW(NDEST) AND 7FH; /* REMAINING PARTIAL BUFFER LENGTH */ - NA = NDEST AND 0FF80H; /* START OF SEGMENT NOT WRITTEN */ - CALL WRITEDEST; /* CLEARS BUFFERS */ - CALL MOVE(.DBUFF(NA),.DBUFF,I); - /* DATA MOVED TO BEGINNING OF BUFFER */ - NDEST = I; - END CLEARBUFF; - -PUTDEST: PROCEDURE(B); - DECLARE (I,B) BYTE; - /* WRITE DESTINATION CHARACTER, CHECK TABS AND LINES */ - IF FORMF THEN /* SKIP FORM FEEDS */ - DO; IF B = FF THEN RETURN; - END; - IF PUTNUM THEN /* END OF LINE OR START OF FILE */ - DO; - IF B <> FF THEN /* NOT FORM FEED */ - DO; - IF (I:=PAGCNT) <> 0 THEN /* PAGE EJECT */ - DO; IF I=1 THEN I=LPP; - IF (LINENO := LINENO + 1) >= I THEN - DO; LINENO = 0; /* NEW PAGE */ - CALL PUTDESTC(FF); - END; - END; - IF NUMB > 0 THEN - CALL NEWLINE; - PUTNUM = FALSE; - END; - END; - IF BLOCK THEN /* BLOCK MODE TRANSFER */ - DO; - IF B = XOFF AND PDEST = 0 THEN - DO; CALL CLEARBUFF; /* BUFFERS WRITTEN */ - RETURN; /* DON'T PASS THE X-OFF */ - END; - END; - IF B = FF THEN LINENO = 0; - CALL PUTDESTC(B); - IF B = LF THEN PUTNUM = TRUE; - END PUTDEST; - - -UTRAN: PROCEDURE(B) BYTE; - DECLARE B BYTE; - /* TRANSLATE ALPHA TO UPPER CASE */ - IF B >= 110$0001B AND B <= 111$1010B THEN /* LOWER CASE */ - B = B AND 101$1111B; /* TO UPPER CASE */ - RETURN B; - END UTRAN; - -LTRAN: PROCEDURE(B) BYTE; - DECLARE B BYTE; - /* TRANSLATE TO LOWER CASE ALPHA */ - IF B >= 'A' AND B <= 'Z' THEN B = B OR 10$0000B; /* TO LOWER */ - RETURN B; - END LTRAN; - -GETSOURCEC: PROCEDURE BYTE; - /* READ NEXT SOURCE CHARACTER */ - DECLARE (iob,B,CONCHK) BYTE; - - IF PSOURCE - 1 <= aux THEN /* 1 ... aux+1 */ - DO; IF (BLOCK OR HEXT) AND CONBRK THEN - DO; - IF READCHAR = ENDFILE THEN RETURN ENDFILE; - CALL PRINT(.('READER STOPPING',CR,LF,'$')); - RETURN XOFF; - END; - END; - - CONCHK = TRUE; /* CONSOLE STATUS CHECK BELOW */ - - DO CASE PSOURCE; - /* CASE 0 IS SOURCE FILE */ - DO; IF NSOURCE >= SBLEN THEN CALL FILLSOURCE; - B = SBUFF(NSOURCE); - NSOURCE = NSOURCE + 1; - END; - /* CASE 1 IS INP */ - B = INP; - /* case 2 is AUX */ - do; - do while (mon2(7,0) or conbrk) = 0; /* allow break from console */ - end; - if mon2(7,0) then b = mon2(3,0); - else b = lf; /* allow an abort to happen below */ - end; - /* CASE 3 IS OUT */ - GO TO NOTSOURCE; - /* CASE 4 IS PRN */ - GO TO NOTSOURCE; - /* CASE 5 IS LST */ - NOTSOURCE: - DO; CALL ERROR(.('NOT A CHARACTER SOURCE$')); - END; - /* CASE 6 IS CON */ - DO; CONCHK = FALSE; /* DON'T CHECK CONSOLE STATUS */ - B = MON2(1,0); - END; - END; /* OF CASES */ - IF ECHO THEN /* COPY TO CONSOLE DEVICE */ - DO; iob = pdest; PDEST = CONP; CALL PUTDEST(B); - PDEST = IOB; - END; - IF CONCHK THEN /* TEST FOR CONSOLE CHAR READY */ - DO; - IF SCOM THEN /* SOURCE IS A COM FILE */ - CONCHK = (CONCNT := CONCNT + 1) = 0; ELSE /* ASCII */ - CONCHK = B = LF; - IF CONCHK THEN - DO; IF CONBRK THEN - DO; - IF READCHAR = ENDFILE THEN RETURN ENDFILE; - CALL ERROR(.('ABORTED$')); - END; - END; - END; - IF ZEROP THEN B = B AND 7FH; - IF UPPER THEN RETURN UTRAN(B); - IF LOWER THEN RETURN LTRAN(B); - RETURN B; - END GETSOURCEC; - -GETSOURCE: PROCEDURE BYTE; - /* GET NEXT SOURCE CHARACTER */ - DECLARE CHAR BYTE; - MATCH: PROCEDURE(B) BYTE; - /* MATCH START AND QUIT STRINGS */ - DECLARE (B,C) BYTE; - IF (C:=COMBUFF(B:=(B+MATCHLEN))) = ENDFILE THEN /* END MATCH */ - DO; COMBUFF(B) = CHAR; /* SAVE CURRENT CHARACTER */ - RETURN TRUE; - END; - IF C = CHAR THEN MATCHLEN = MATCHLEN + 1; ELSE - MATCHLEN = 0; /* NO MATCH */ - RETURN FALSE; - END MATCH; - IF QUITLEN > 0 THEN - DO; IF (QUITLEN := QUITLEN - 1) = 1 THEN RETURN LF; - RETURN ENDFILE; /* TERMINATED WITH CR,LF,ENDFILE */ - END; - DO FOREVER; /* LOOKING FOR START */ - IF FEEDLEN > 0 THEN /* GET SEARCH CHARACTERS */ - DO; FEEDLEN = FEEDLEN - 1; - CHAR = COMBUFF(FEEDBASE); - FEEDBASE = FEEDBASE + 1; - RETURN CHAR; - END; - IF (CHAR := GETSOURCEC) = ENDFILE THEN RETURN ENDFILE; - IF STARTS > 0 THEN /* LOOKING FOR START STRING */ - DO; IF MATCH(STARTS) THEN - DO; FEEDBASE = STARTS; STARTS = 0; - FEEDLEN = MATCHLEN + 1; - END; /* OTHERWISE NO MATCH, SKIP CHARACTER */ - END; ELSE - IF QUITS > 0 THEN /* PASS CHARACTERS TIL MATCH */ - DO; IF MATCH(QUITS) THEN - DO; QUITS = 0; QUITLEN = 2; - /* SUBSEQUENTLY RETURN CR, LF, ENDFILE */ - RETURN CR; - END; - RETURN CHAR; - END; ELSE - RETURN CHAR; - END; /* OF DO FOREVER */ - END GETSOURCE; - -DECLARE DISK BYTE; /* SELECTED DISK */ - - GNC: PROCEDURE BYTE; - IF (CBP := CBP + 1) >= COMLEN THEN RETURN CR; - RETURN UTRAN(COMBUFF(CBP)); - END GNC; - - DEBLANK: PROCEDURE; - DO WHILE (CHAR := GNC) = ' '; - END; - END DEBLANK; - - SCAN: PROCEDURE(FCBA); - DECLARE FCBA ADDRESS, /* ADDRESS OF FCB TO FILL */ - FCB BASED FCBA (FSIZE) BYTE; /* FCB TEMPLATE */ - DECLARE (I,J,K) BYTE; /* TEMP COUNTERS */ - - /* SCAN LOOKS FOR THE NEXT DELIMITER, DEVICE NAME, OR FILE NAME. - THE VALUE OF CBP MUST BE 255 UPON ENTRY THE FIRST TIME */ - - DELIMITER: PROCEDURE(C) BYTE; - DECLARE (I,C) BYTE; - DECLARE DEL(*) BYTE DATA - (' =.:,<>',CR,LA,LB,RB); - DO I = 0 TO LAST(DEL); - IF C = DEL(I) THEN RETURN TRUE; - END; - RETURN FALSE; - END DELIMITER; - - PUTCHAR: PROCEDURE; - FCB(FLEN:=FLEN+1) = CHAR; - IF CHAR = WHAT THEN AMBIG = TRUE; /* CONTAINS AMBIGUOUS REF */ - END PUTCHAR; - - FILLQ: PROCEDURE(LEN); - /* FILL CURRENT NAME OR TYPE WITH QUESTION MARKS */ - DECLARE LEN BYTE; - CHAR = WHAT; /* QUESTION MARK */ - DO WHILE FLEN < LEN; - CALL PUTCHAR; - END; - END FILLQ; - - GETFCB: PROCEDURE(I) BYTE; - DECLARE I BYTE; - RETURN FCB(I); - END GETFCB; - - SCANPAR: PROCEDURE; - DECLARE (I,J) BYTE; - /* SCAN OPTIONAL PARAMETERS */ - PARSET = TRUE; - SUSER = CUSER; /* SOURCE USER := CURRENT USER */ - CHAR = GNC; /* SCAN PAST BRACKET */ - DO WHILE NOT(CHAR = CR OR CHAR = RB); - IF (I := CHAR - 'A') > 25 THEN /* NOT ALPHA */ - DO; IF CHAR = ' ' THEN CHAR = GNC; ELSE - CALL ERROR(.('BAD PARAMETER$')); - END; ELSE - DO; /* SCAN PARAMETER VALUE */ - IF CHAR = 'S' OR CHAR = 'Q' THEN - DO; /* START OR QUIT COMMAND */ - J = CBP + 1; /* START OF STRING */ - DO WHILE NOT ((CHAR := GNC) = ENDFILE OR CHAR = CR); - END; - CHAR=GNC; - END; ELSE - IF (J := (CHAR := GNC) - '0') > 9 THEN J = 1; - ELSE - DO WHILE (K := (CHAR := GNC) - '0') <= 9; - J = J * 10 + K; - END; - CONT(I) = J; - IF I = 6 THEN /* SET SOURCE USER */ - DO; - IF J > 31 THEN - CALL ERROR(.('INVALID USER NUMBER$')); - SUSER = J; - END; - END; - END; - CHAR = GNC; - END SCANPAR; - - CHKSET: PROCEDURE; - IF CHAR = LA THEN CHAR = '='; - END CHKSET; - - /* INITIALIZE FILE CONTROL BLOCK TO EMPTY */ - AMBIG = FALSE; TYPE = ERR; CHAR = ' '; FLEN = 0; - DO WHILE FLEN < FSIZE-1; - IF FLEN = FNSIZE THEN CHAR = 0; - CALL PUTCHAR; - END; - - /* DEBLANK COMMAND BUFFER */ - CALL DEBLANK; - - /* SAVE STARTING POSITION OF SCAN FOR DIAGNOSTICS */ - TCBP = CBP; - - /* MAY BE A SEPARATOR */ - IF DELIMITER(CHAR) THEN - DO; CALL CHKSET; - TYPE = SPECL; RETURN; - END; - - /* CHECK PERIPHERALS AND DISK FILES */ - DISK = 0; - /* CLEAR PARAMETERS */ - DO I = 0 TO 25; CONT(I) = 0; - END; - PARSET = FALSE; - FEEDLEN,MATCHLEN,QUITLEN = 0; - /* SCAN NEXT NAME */ - DO FOREVER; - FLEN = 0; - DO WHILE NOT DELIMITER(CHAR); - IF FLEN >= NSIZE THEN /* ERROR, FILE NAME TOO LONG */ - RETURN; - IF CHAR = '*' THEN CALL FILLQ(NSIZE); ELSE CALL PUTCHAR; - CHAR = GNC; - END; - - /* CHECK FOR DISK NAME OR DEVICE NAME */ - IF CHAR = ':' THEN - DO; IF DISK <> 0 THEN RETURN; /* ALREADY SET */ - IF FLEN = 1 THEN - /* MAY BE DISK NAME A ... Z */ - DO; - IF (DISK := GETFCB(1) - 'A' + 1) > 26 THEN - /* ERROR, INVALID DISK NAME */ RETURN; - CALL DEBLANK; /* MAY BE DISK NAME ONLY */ - IF DELIMITER(CHAR) THEN - DO; IF CHAR = LB THEN - CALL SCANPAR; - CBP = CBP - 1; - TYPE = DISKNAME; - RETURN; - END; - END; ELSE - - /* MAY BE A THREE CHARACTER DEVICE NAME */ - IF FLEN <> 3 THEN /* ERROR, CANNOT BE DEVICE NAME */ - RETURN; ELSE - - /* LOOK FOR DEVICE NAME */ - DO; DECLARE (I,J,K) BYTE, M LITERALLY '7', - IO(*) BYTE DATA - ('INPAUXOUTPRNLSTCONNULEOF',0); - - /* NOTE THAT ALL READER-LIKE DEVICES MUST BE - PLACED BEFORE 'AUX', AND ALL LISTING-LIKE DEVICES - MUST APPEAR BELOW LST, BUT ABOVE AUX. THE LITERAL - DECLARATIONS FOR LST AND AUX MUST INDICATE - THE POSITIONS OF THESE DEVICES IN THE LIST */ - - J = 255; - DO K = 0 TO M; - I = 0; - DO WHILE ((I:=I+1) <= 3) AND - IO(J+I) = GETFCB(I); - END; - IF I = 4 THEN /* COMPLETE MATCH */ - DO; TYPE = PERIPH; - /* SCAN PARAMETERS */ - IF GNC = LB THEN CALL SCANPAR; - CBP = CBP - 1; CHAR = K; - RETURN; - END; - /* OTHERWISE TRY NEXT DEVICE */ J = J + 3; - END; - - /* ERROR, NO DEVICE NAME MATCH */ RETURN; - END; - IF CHAR = LB THEN /* PARAMETERS FOLLOW */ - CALL SCANPAR; - END; ELSE - - /* CHAR IS NOT ':', SO FILE NAME IS SET. SCAN REMAINDER */ - DO; IF FLEN = 0 THEN /* ERROR, NO PRIMARY NAME */ - RETURN; - FLEN = FNAM; - IF CHAR = '.' THEN /* SCAN FILE TYPE */ - DO WHILE NOT DELIMITER(CHAR := GNC); - IF FLEN >= FNSIZE THEN - /* ERROR, TYPE FIELD TOO LONG */ RETURN; - IF CHAR = '*' THEN CALL FILLQ(FNSIZE); - ELSE CALL PUTCHAR; - END; - - IF CHAR = LB THEN - CALL SCANPAR; - /* RESCAN DELIMITER NEXT TIME AROUND */ - CBP = CBP - 1; - TYPE = FILE; - /* DISK IS THE SELECTED DISK (1 2 3 ... ) */ - IF DISK = 0 THEN DISK = CDISK + 1; /* DEFAULT */ - FCB(0),FCB(32) = 0; - RETURN; - END; - END; - END SCAN; - - NULLS: PROCEDURE; - /* SEND 40 NULLS TO OUTPUT DEVICE */ - DECLARE I BYTE; - DO I = 0 TO 39; CALL PUTDEST(0); - END; - END NULLS; - - - DECLARE FEXTH(FEXTL) BYTE, /* HOLDS DESTINATION FILE TYPE */ - COPYING BYTE; /* TRUE WHILE COPYING TO DEST FILE */ - - MOVEXT: PROCEDURE(A); - DECLARE A ADDRESS; - /* MOVE THREE CHARACTER EXTENT INTO DEST FCB */ - CALL MOVE(A,.DEST(FEXT),FEXTL); - END MOVEXT; - -EQUAL: PROCEDURE(A,B) BYTE; - /* COMPARE THE STRINGS AT A AND B UNTIL EITHER A MISMATCH OR - A '$' IS ENCOUNTERED IN STRING B */ - DECLARE (A,B) ADDRESS, - (SA BASED A, SB BASED B) BYTE; - DO WHILE SB <> '$'; - IF (SB AND 7FH) <> (SA AND 7FH) THEN RETURN FALSE; - A = A + 1; B = B + 1; - END; - RETURN TRUE; - END EQUAL; - -READ$EOF: PROCEDURE BYTE; - /* RETURN TRUE IF END OF FILE */ - CHAR = GETSOURCE; - IF SCOM THEN RETURN HARDEOF < NSOURCE; - RETURN CHAR = ENDFILE; - END READ$EOF; - - -HEXRECORD: PROCEDURE BYTE; - /* READ ONE RECORD INTO SBUFF AND CHECK FOR PROPER FORM - RETURNS 0 IF RECORD OK - RETURNS 1 IF END OF TAPE (:00000) - RETURNS 2 IF ERROR IN RECORD */ - - - DECLARE XOFFSET BYTE; /* TRUE IF XOFF RECVD */ - DECLARE NOERRS BYTE; /* TRUE IF NO ERRORS IN THIS RECORD */ - - PRINTERR: PROCEDURE(A); - /* PRINT ERROR MESSAGE IF NOERRS TRUE */ - DECLARE A ADDRESS; - IF NOERRS THEN - DO; NOERRS = FALSE; - CALL PRINT(A); - END; - END PRINTERR; - - CHECKXOFF: PROCEDURE; - IF XOFFSET THEN - DO; XOFFSET = FALSE; - CALL CLEARBUFF; - END; - END CHECKXOFF; - - SAVECHAR: PROCEDURE BYTE; - /* READ CHARACTER AND SAVE IN BUFFER */ - DECLARE I BYTE; - IF NOERRS THEN - DO; - DO WHILE (I := GETSOURCE) = XOFF; XOFFSET = TRUE; - END; - HBUFF(HSOURCE) = I; - IF (HSOURCE := HSOURCE + 1) >= LAST(HBUFF) THEN - CALL PRINTERR(.('RECORD TOO LONG$')); - RETURN I; - END; - RETURN ENDFILE; /* ON ERROR FLAG */ - END SAVECHAR; - - DECLARE (M, RL, CS, RT) BYTE, - LDA ADDRESS; /* LOAD ADDRESS WHICH FOLLOWS : */ - - READHEX: PROCEDURE BYTE; - DECLARE H BYTE; - IF (H := SAVECHAR) - '0' <= 9 THEN RETURN H-'0'; - IF H - 'A' > 5 THEN - CALL PRINTERR(.('INVALID DIGIT$')); - RETURN H - 'A' + 10; - END READHEX; - - READBYTE: PROCEDURE BYTE; - /* READ TWO HEX DIGITS */ - RETURN SHL(READHEX,4) OR READHEX; - END READBYTE; - - READCS: PROCEDURE BYTE; - /* READ BYTE WITH CHECKSUM */ - RETURN CS := CS + READBYTE; - END READCS; - - READADDR: PROCEDURE ADDRESS; - /* READ DOUBLE BYTE WITH CHECKSUM */ - RETURN SHL(DOUBLE(READCS),8) OR READCS; - END READADDR; - - NOERRS = TRUE; /* NO ERRORS DETECTED IN THIS RECORD */ - - /* READ NEXT RECORD */ - /* SCAN FOR THE ':' */ - HSOURCE = 0; - DO WHILE (CS := SAVECHAR) <> ':'; - HSOURCE = 0; - IF CS = ENDFILE THEN - DO; CALL PRINT(.('END OF FILE, CTL-Z',WHAT,'$')); - IF READCHAR = ENDFILE THEN RETURN 1; - ELSE HSOURCE = 0; - END; - CALL CHECKXOFF; - END; - - /* ':' FOUND */ - CS = 0; - IF (RL := READCS) = 0 THEN /* END OF TAPE */ - DO; DO WHILE (RL := SAVECHAR) <> ENDFILE; - CALL CHECKXOFF; - END; - IF NOERRS THEN RETURN 1; - RETURN 2; - END; - - /* RECORD LENGTH IS NOT ZERO */ - LDA = READADDR; /* LOAD ADDRESS */ - - /* READ WORDS UNTIL RECORD LENGTH EXHAUSTED */ - RT = READCS; /* RECORD TYPE */ - DO WHILE RL <> 0 AND NOERRS; RL = RL - 1; - M = READCS; - /* INCREMENT LA HERE FOR EXACT ADDRESS */ - END; - - /* CHECK SUM */ - IF CS + READBYTE <> 0 THEN - CALL PRINTERR(.('CHECKSUM ERROR$')); - - CALL CHECKXOFF; - IF NOERRS THEN RETURN 0; - RETURN 2; - END HEXRECORD; - -READTAPE: PROCEDURE; - /* READ HEX FILE FROM HIGH SPEED READER TO 'HEX' FILE, - CHECK EACH RECORD FOR VALID DIGITS, AND PROPER CHECKSUM */ - DECLARE (I,A) BYTE; - DO FOREVER; - DO WHILE (I := HEXRECORD) <= 1; - IF NOT (I = 1 AND IGNOR) THEN - DO A = 1 TO HSOURCE; - CALL PUTDEST(HBUFF(A-1)); - END; - CALL PUTDEST(CR); CALL PUTDEST(LF); - IF I = 1 THEN /* END OF TAPE ENCOUNTERED */ - RETURN; - END; - CALL CRLF; HBUFF(HSOURCE) = '$'; - CALL PRINT(.HBUFF); - CALL PRINT(.('CORRECT ERROR, TYPE RETURN OR CTL-Z$')); - CALL CRLF; - IF READCHAR = ENDFILE THEN RETURN; - END; - END READTAPE; - -FORMERR: PROCEDURE; - CALL ERROR(.('INVALID FORMAT$')); - END FORMERR; - -SETUPDEST: PROCEDURE; - CALL SELECT(DDISK); - DHEX = EQUAL(.DEST(FEXT),.('HEX$')); - CALL MOVE(.DEST(FEXT),.FEXTH,FEXTL); /* SAVE TYPE */ - DEST(ROFILE) = DEST(ROFILE) AND 7FH; - DEST(SYSFILE)= DEST(SYSFILE)AND 7FH; - CALL MOVEXT(.('$$$')); - CALL DELETE(.DEST); /* REMOVE OLD $$$ FILE */ - CALL MAKE(.DEST); /* CREATE A NEW ONE */ - IF DCNT = 255 THEN CALL ERROR(.('NO DIRECTORY SPACE$')); - DEST(32),NDEST = 0; - END SETUPDEST; - -SETUPSOURCE: PROCEDURE; - HARDEOF = 0FFFFH; - CALL SETSUSER; /* SOURCE USER */ - CALL SELECT(SDISK); - CALL OPEN(.SOURCE); - CALL SETCUSER; /* BACK TO CURRENT USER */ - IF (NOT RSYS) AND ROL(SOURCE(SYSFILE),1) THEN - DCNT = 255; - IF DCNT = 255 THEN CALL ERROR(.('NO FILE$')); - SOURCE(32) = 0; - /* CAUSE IMMEDIATE READ */ - SCOM = EQUAL(.SOURCE(FEXT),.('COM$')); - NSOURCE = SBLEN; - END SETUPSOURCE; - -CHECK$STRINGS: PROCEDURE; - IF STARTS > 0 THEN - CALL ERROR(.('START NOT FOUND$')); - IF QUITS > 0 THEN - CALL ERROR(.('QUIT NOT FOUND$')); - END CHECK$STRINGS; - -CLOSEDEST: PROCEDURE(DIRECT); - DECLARE DIRECT BYTE; - /* DIRECT IS TRUE IF SECTOR-BY-SECTOR COPY */ - IF DIRECT THEN - /* GET UNFILLED BYTES FROM SOURCE BUFFER */ - DFUB = SFUB; ELSE DFUB = 0; - DO WHILE (LOW(NDEST) AND 7FH) <> 0; - DFUB = DFUB + 1; - CALL PUTDEST(ENDFILE); - END; - CALL CHECK$STRINGS; - CALL WRITEDEST; - CALL SELECT(DDISK); - CALL CLOSE(.DEST); - IF DCNT = 255 THEN - CALL ERROR(.('CANNOT CLOSE DESTINATION FILE$')); - CALL MOVEXT(.FEXTH); /* RECALL ORIGINAL TYPTE */ - DEST(12) = 0; - CALL OPEN(.DEST); - IF DCNT <> 255 THEN /* FILE EXISTS */ - DO; - IF ROL(DEST(ROFILE),1) THEN /* READ ONLY */ - DO; - IF NOT WRROF THEN - DO; - CALL PRINT (.('DESTINATION IS R/O, DELETE (Y/N)?$')); - IF UTRAN(READCHAR) <> 'Y' THEN - DO; CALL PRINT(.('**NOT DELETED**$')); - CALL CRLF; - CALL MOVEXT(.('$$$')); - CALL DELETE(.DEST); - RETURN; - END; - CALL CRLF; - END; - DEST(ROFILE) = DEST(ROFILE) AND 7FH; - CALL SETIND(.DEST); - END; - CALL DELETE(.DEST); - END; - CALL MOVE(.DEST,.DEST(16),16); /* READY FOR RENAME */ - CALL MOVEXT(.('$$$')); - CALL RENAME(.DEST); - END CLOSEDEST; - -SIZE$NBUF: PROCEDURE; - /* COMPUTE NUMBER OF BUFFERS - 1 FROM DBLEN */ - NBUF = (SHR(DBLEN,7) AND 0FFH) - 1; - /* COMPUTED AS DBLEN/128-1, WHERE DBLEN <= 32K (AND THUS - NBUF RESULTS IN A VALUE <= 2**15/2**7-1 = 2**8-1 = 255) */ - END SIZE$NBUF; - -SET$DBLEN: PROCEDURE; - /* ABSORB THE SOURCE BUFFER INTO THE DEST BUFFER */ - SBASE = .MEMORY; - IF DBLEN >= 4000H THEN DBLEN = 7F80H; ELSE - DBLEN = DBLEN + SBLEN; - CALL SIZE$NBUF; - END SET$DBLEN; - -SIZE$MEMORY: PROCEDURE; - /* SET UP SOURCE AND DESTINATION BUFFERS */ - SBASE = .MEMORY + SHR(MEMSIZE - .MEMORY,1); - SBLEN, DBLEN = SHR((MEMSIZE - .MEMORY) AND 0FF00H,1); - CALL SIZE$NBUF; - END SIZE$MEMORY; - -COPYCHAR: PROCEDURE; - /* PERFORM THE ACTUAL COPY FUNCTION */ - DECLARE RESIZED BYTE; /* TRUE IF SBUFF AND DBUFF COMBINED */ - IF (RESIZED := (BLOCK AND PSOURCE <> 0)) THEN /* BLOCK MODE */ - CALL SET$DBLEN; /* ABSORB SOURCE BUFFER */ - IF HEXT OR IGNOR THEN /* HEX FILE */ - CALL READTAPE; ELSE - DO WHILE NOT READ$EOF; - CALL PUTDEST(CHAR); - END; - IF RESIZED THEN - DO; CALL CLEARBUFF; - CALL SIZE$MEMORY; - END; - END COPYCHAR; - -SIMPLECOPY: PROCEDURE; - DECLARE (FASTCOPY,I) BYTE; - REAL$EOF: PROCEDURE BYTE; - RETURN HARDEOF <> 0FFFFH; - END REALEOF; - CALL SIZE$MEMORY; - TCBP = MCBP; /* FOR ERROR TRACING */ - CALL SETUPDEST; - CALL SETUPSOURCE; - /* FILES READY FOR DIRECT COPY */ - FASTCOPY = TRUE; - /* LOOK FOR PARAMETERS */ - DO I = 0 TO 25; - IF CONT(I) <> 0 THEN - DO; - IF NOT(I=6 OR I=14 OR I=17 OR I=21 OR I=22) THEN - /* NOT OBJ OR VERIFY */ - FASTCOPY = FALSE; - END; - END; - IF FASTCOPY THEN /* COPY DIRECTLY TO DBUFF */ - DO; CALL SET$DBLEN; /* EXTEND DBUFF */ - DO WHILE NOT REAL$EOF; - CALL FILLSOURCE; - IF REAL$EOF THEN - NDEST = HARDEOF; ELSE NDEST = DBLEN; - CALL WRITEDEST; - END; - CALL SIZE$MEMORY; /* RESET TO TWO BUFFERS */ - END; ELSE - CALL COPYCHAR; - CALL CLOSEDEST(FASTCOPY); - END SIMPLECOPY; - -MULTCOPY: PROCEDURE; - DECLARE (NEXTDIR, NDCNT, NCOPIED) ADDRESS; - PRNAME: PROCEDURE; - /* PRINT CURRENT FILE NAME */ - DECLARE (I,C) BYTE; - CALL CRLF; - DO I = 1 TO FNSIZE; - IF (C := DEST(I)) <> ' ' THEN - DO; IF I = FEXT THEN CALL PRINTCHAR('.'); - CALL PRINTCHAR(C); - END; - END; - END PRNAME; - - NEXTDIR,NCOPIED = 0; - DO FOREVER; - /* FIND A MATCHING ENTRY */ - CALL SETSUSER; /* SOURCE USER */ - CALL SELECT(SDISK); - CALL SETDMA(.BUFFER); - CALL SEARCH(.SEARFCB); - NDCNT = 0; - DO WHILE (DCNT <> 255) AND NDCNT < NEXTDIR; - NDCNT = NDCNT + 1; - CALL SEARCHN; - END; - CALL SETCUSER; - /* FILE CONTROL BLOCK IN BUFFER */ - IF DCNT = 255 THEN - DO; IF NCOPIED = 0 THEN - CALL ERROR(.('NOT FOUND$')); CALL CRLF; - RETURN; - END; - NEXTDIR = NDCNT + 1; - /* GET THE FILE CONTROL BLOCK NAME TO DEST */ - CALL MOVE(.BUFFER+SHL(DCNT AND 11B,5),.DEST,16); - DEST(0) = 0; - DEST(12) = 0; - CALL MOVE(.DEST,.SOURCE,16); /* FILL BOTH FCB'S */ - IF RSYS OR NOT ROL(DEST(SYSFILE),1) THEN /* OK TO READ */ - DO; - IF (NCOPIED := NCOPIED + 1) = 1 THEN - CALL PRINT(.('COPYING -$')); - CALL PRNAME; - CALL SIMPLECOPY; - END; - END; - END MULTCOPY; - -SET$SDISK: PROCEDURE; - IF DISK > 0 THEN SDISK = DISK - 1; ELSE SDISK = CDISK; - END SET$SDISK; - -SET$DDISK: PROCEDURE; - IF PARSET THEN /* PARAMETERS PRESENT */ CALL FORMERR; - IF DISK > 0 THEN DDISK = DISK - 1; ELSE DDISK = CDISK; - END SET$DDISK; - -CHECK$DISK: PROCEDURE; - IF SUSER <> CUSER THEN /* DIFFERENT DISKS */ - RETURN; - IF DDISK = SDISK THEN CALL FORMERR; - END CHECK$DISK; - -CHECK$EOL: PROCEDURE; - CALL DEBLANK; - IF CHAR <> CR THEN CALL FORMERR; - END CHECK$EOL; - -SCANDEST: PROCEDURE(COPYFCB); - DECLARE COPYFCB ADDRESS; - CALL SET$SDISK; - CALL CHECK$EOL; - CALL MOVE(.SOURCE,COPYFCB,33); - CALL CHECK$DISK; - END SCANDEST; - -SCANEQL: PROCEDURE; - CALL SCAN(.SOURCE); - IF NOT (TYPE = SPECL AND CHAR = '=') THEN CALL FORMERR; - MCBP = CBP; /* FOR ERROR PRINTING */ - END SCANEQL; - - -PIPENTRY: - /* BUFFER AT 80H CONTAINS REMAINDER OF LINE TYPED - FOLLOWING THE COMMAND 'PIP' - IF ZERO THEN PROMPT TIL CR */ - CALL MOVE(.BUFF,.COMLEN,80H); - MULTCOM = COMLEN = 0; - - /* GET CURRENT CP/M VERSION */ - IF VERSION < CPMVERSION THEN - DO; - CALL PRINT(.('Requires Personal CP/M 1.0 or newer for operation.$')); - CALL BOOT; - END; - /* GET CURRENT USER */ - CUSER = GETUSER; - /* GET CURRENT DISK */ - CDISK = MON2(25,0); - - RETRY: - /* ENTER HERE ON ERROR EXIT FROM THE PROCEDURE 'ERROR' */ - CALL SIZE$MEMORY; - /* MAIN PROCESSING LOOP. PROCESS UNTIL CR ONLY */ - DO FOREVER; - SUSER = CUSER; - C1, C2, C3 = 0; /* LINE COUNT = 000000 */ - PUTNUM = TRUE; /* ACTS LIKE LF OCCURRED ON ASCII FILE */ - CONCNT,COLUMN = 0; /* PRINTER TABS */ - LINENO = 254; /* INCREMENTED TO 255 > PAGCNT */ - /* READ FROM CONSOLE IF NOT A ONELINER */ - IF MULTCOM THEN - DO; CALL PRINTCHAR('*'); CALL READCOM; - CALL CRLF; - END; - CBP = 255; - IF COMLEN = 0 THEN /* SINGLE CARRIAGE RETURN */ - DO; CALL SELECT(CDISK); - CALL BOOT; - END; - - /* LOOK FOR SPECIAL CASES FIRST */ - DDISK,SDISK,PSOURCE,PDEST = 0; - CALL SCAN(.DEST); - IF TYPE = PERIPH THEN GO TO SIMPLECOM; - IF TYPE = DISKNAME THEN - DO; DDISK = DISK - 1; - CALL SCANEQL; - CALL SCAN(.SOURCE); - /* MAY BE MULTI COPY */ - IF TYPE <> FILE THEN CALL FORMERR; - IF AMBIG THEN - DO; CALL SCANDEST(.SEARFCB); - CALL MULTCOPY; - END; ELSE - DO; CALL SCANDEST(.DEST); - /* FORM IS A:=B:UFN */ - CALL SIMPLECOPY; - END; - GO TO ENDCOM; - END; - - - IF TYPE <> FILE OR AMBIG THEN CALL FORMERR; - CALL SET$DDISK; - CALL SCANEQL; - CALL SCAN(.SOURCE); - IF TYPE = DISKNAME THEN - DO; - CALL SET$SDISK; CALL CHECK$DISK; - CALL MOVE(.DEST,.SOURCE,33); - CALL CHECK$EOL; - CALL SIMPLECOPY; - GO TO ENDCOM; - END; - /* MAY BE POSSIBLE TO DO A FAST DISK COPY */ - IF TYPE = FILE THEN /* FILE TO FILE */ - DO; CALL DEBLANK; IF CHAR <> CR THEN GO TO SIMPLECOM; - /* FILE TO FILE */ - CALL SET$SDISK; - CALL SIMPLECOPY; - GO TO ENDCOM; - END; - -SIMPLECOM: - CBP = 255; /* READY FOR RESCAN */ - - /* OTHERWISE PROCESS SIMPLE REQUEST */ - CALL SCAN(.DEST); - IF (TYPE < FILE) OR AMBIG THEN /* DELIMITER OR ERROR */ - CALL ERROR(.('UNRECOGNIZED DESTINATION$')); - - DHEX = FALSE; - IF TYPE = FILE THEN - DO; /* DESTINATION IS A FILE, SAVE EXTENT NAME */ - CALL SET$DDISK; - CALL SETUPDEST; - CHAR = 255; - END; ELSE - /* PERIPHERAL NAME */ - IF CHAR >= NULP OR CHAR = inpp THEN CALL ERROR(.('CANNOT WRITE$')); - - PDEST = CHAR + 1; - - /* NOW SCAN THE DELIMITER */ - CALL SCAN(.SOURCE); - IF TYPE <> SPECL OR CHAR <> '=' THEN - CALL ERROR(.('INVALID PIP FORMAT$')); - - /* OTHERWISE SCAN AND COPY UNTIL CR */ - COPYING = TRUE; - DO WHILE COPYING; - SUSER = CUSER; - CALL SCAN(.SOURCE); - /* SUSER MAY HAVE BEEN RESET */ - SCOM = FALSE; - IF TYPE = FILE AND NOT AMBIG THEN /* A SOURCE FILE */ - DO; - CALL SET$SDISK; - CALL SETUPSOURCE; - CHAR = 255; - END; ELSE - - IF TYPE <> PERIPH OR (CHAR <= LST AND CHAR > aux) THEN - CALL ERROR(.('CANNOT READ$')); - - - SCOM = SCOM OR OBJ; /* MAY BE ABSOLUTE COPY */ - PSOURCE = CHAR + 1; - IF CHAR = NULP THEN CALL NULLS; ELSE - IF CHAR = EOFP THEN CALL PUTDEST(ENDFILE); ELSE - DO; /* DISK COPY */ - IF (CHAR < hsaux AND DHEX) THEN HEXT = 1; - /* HEX FILE SET IF SOURCE IS RDR AND DEST IS HEX FILE */ - IF PDEST = PRNT THEN - DO; NUMB = 1; - IF TABS = 0 THEN TABS = 8; - IF PAGCNT = 0 THEN PAGCNT = 1; - END; - CALL COPYCHAR; - END; - - CALL CHECK$STRINGS; - /* READ ENDFILE, GO TO NEXT SOURCE */ - CALL SCAN(.SOURCE); - IF TYPE <> SPECL OR (CHAR <> ',' AND CHAR <> CR) THEN - CALL ERROR(.('INVALID SEPARATOR$')); - - COPYING = CHAR <> CR; - END; - - /* IF NECESSARY, CLOSE FILE OR PUNCH TRAILER */ - IF PDEST = aux THEN - DO; CALL PUTDEST(ENDFILE); CALL NULLS; - END; - IF PDEST = 0 THEN /* FILE HAS TO BE CLOSED AND RENAMED */ - CALL CLOSEDEST(FALSE); - - /* COMLEN SET TO 0 IF NOT PROCESSING MULTIPLE COMMANDS */ -ENDCOM: - COMLEN = MULTCOM; - - END; /* DO FOREVER */ -END; - \ No newline at end of file diff --git a/cpm/pcpm/READ.ME b/cpm/pcpm/READ.ME deleted file mode 100644 index 6a7f4d1..0000000 --- a/cpm/pcpm/READ.ME +++ /dev/null @@ -1,39 +0,0 @@ -The following list of corrections should be made to the Personal CP/M 8-bit -version 1.0 documentation. - -Programmer's Guide - - page 2-10 - BDOS function 2 - text says 'CONSOLE INPUT' - should be 'CONSOLE OUTPUT' - - page 2-45 - BDOS function 33 - 'Entry Parameters' add after Register C line: - 'Register DE: FCB Address' - - page 2-49 - BDOS function 35 - replace information about values returned in registers with: - 'Random record field of FCB set' - -System Guide - - Section 2 - References to the BDOS size being 1100h bytes are incorrect. - The BDOS code segment is 1000h bytes, and the BDOS data - segment is 00BFh bytes. With the standard distibution, - BDOSH.REL and BDOSL.REL will link these in a separate area - from the BDOS code segment. OEMs that purchase the source - can set an assembly-time switch that will make the data areas - part of the code segment so that it will all be linked as one - segment of 1100h bytes if the BDOS will execute in RAM. - - page 4-15 - BIOS function WRITE - Entry Parameters: Register C = 0: normal sector write - 1: write to directory sector - 2: write to the first sector - of a new data block - \ No newline at end of file diff --git a/cpm/pcpm/README.TOO b/cpm/pcpm/README.TOO deleted file mode 100644 index 85725eb..0000000 --- a/cpm/pcpm/README.TOO +++ /dev/null @@ -1,15 +0,0 @@ -Please note: line 2528 in BDOS.MAC is corrupted. It should read - - jp z,COPY$DIRLOC ;stop at end of dir - --------------------------- - -This zip file contains the original source for Personal CP/M 1.0. -If anybody figures out anything about this code, please drop an -email message to me at : - -gaby@gaby.de - -and I'll pass it on. - -tnx diff --git a/cpm/pcpm/STAT.PLM b/cpm/pcpm/STAT.PLM deleted file mode 100644 index 149475c..0000000 --- a/cpm/pcpm/STAT.PLM +++ /dev/null @@ -1,834 +0,0 @@ -stat: -do; -declare - cpmversion literally '20h'; /* requires 2.0 cp/m */ - /* c p / m s t a t u s c o m m a n d (s t a t) */ - -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ -/* status status status status status status */ - -/* - copyright(c) 1975, 1976, 1977, 1978, 1979, 1984 - digital research - box 579 - pacific grove, ca - 93950 - */ - -/* modified 10/30/78 to fix the space computation */ -/* modified 01/28/79 to remove despool dependencies */ -/* modified 07/26/79 to operate under cp/m 2.0 */ -/* modified 03/14/84 to remove iobyte modification for Personal CP/M */ - -declare jump byte data(0c3h), - jadr address data (.status); - /* jump to status */ - -/* function call 32 returns the address of the disk parameter -block for the currently selected disk, which consists of: - scptrk (2 by) number of sectors per track - blkshf (1 by) log2 of blocksize (2**blkshf=blksize) - blkmsk (1 by) 2**blkshf-1 - extmsk (1 by) logical/physical extents - maxall (2 by) max alloc number - dirmax (2 by) size of directory-1 - dirblk (2 by) reservation bits for directory - chksiz (2 by) size of checksum vector - offset (2 by) offset for operating system -*/ - -declare - /* fixed locations for cp/m */ - bdosa literally '0006h', /* bdos base */ - buffa literally '0080h', /* default buffer */ - fcba literally '005ch', /* default file control block */ - dolla literally '006dh', /* dollar sign position */ - parma literally '006eh', /* parameter, if sent */ - rreca literally '007dh', /* random record 7d,7e,7f */ - rreco literally '007fh', /* high byte of random overflow */ - sectorlen literally '128', /* sector length */ - memsize address at(bdosa), /* end of memory */ - rrec address at(rreca), /* random record address */ - rovf byte at(rreco), /* overflow on getfile */ - doll byte at(dolla), /* dollar parameter */ - parm byte at(parma), /* parameter */ - sizeset byte, /* true if displaying size field */ - dpba address, /* disk parameter block address */ - dpb based dpba structure - (spt address, bls byte, bms byte, exm byte, mxa address, - dmx address, dbl address, cks address, ofs address), - scptrk literally 'dpb.spt', - blkshf literally 'dpb.bls', - blkmsk literally 'dpb.bms', - extmsk literally 'dpb.exm', - maxall literally 'dpb.mxa', - dirmax literally 'dpb.dmx', - dirblk literally 'dpb.dbl', - chksiz literally 'dpb.cks', - offset literally 'dpb.ofs'; - - -boot: procedure external; - /* reboot */ - end boot; - -mon1: procedure(f,a) external; - declare f byte, a address; - end mon1; - -mon2: procedure(f,a) byte external; - declare f byte, a address; - end mon2; - -mon3: procedure(f,a) address external; - declare f byte, a address; - end mon3; - - -status: procedure; - declare copyright(*) byte data ( - ' Copyright (c) 1984, Digital Research'); - /* dummy outer procedure 'status' will start at 100h */ - /* determine status of currently selected disk */ - -declare alloca address, - /* alloca is the address of the disk allocation vector */ - alloc based alloca (1024) byte; /* allocation vector */ - -declare - true literally '1', - false literally '0', - forever literally 'while true', - cr literally '13', - lf literally '10'; - -printchar: procedure(char); - declare char byte; - call mon1(2,char); - end printchar; - -crlf: procedure; - call printchar(cr); - call printchar(lf); - end crlf; - -printb: procedure; - /* print blank character */ - call printchar(' '); - end printb; - -printx: procedure(a); - declare a address; - declare s based a byte; - do while s <> 0; - call printchar(s); - a = a + 1; - end; - end printx; - -print: procedure(a); - declare a address; - /* print the string starting at address a until the - next 0 is encountered */ - call crlf; - call printx(a); - end print; - -break: procedure byte; - return mon2(11,0); /* console ready */ - end break; - -declare dcnt byte; - -version: procedure byte; - /* returns current cp/m version # */ - return mon2(12,0); - end version; - -select: procedure(d); - declare d byte; - call mon1(14,d); - end select; - -open: procedure(fcb); - declare fcb address; - dcnt = mon2(15,fcb); - end open; - -search: procedure(fcb); - declare fcb address; - dcnt = mon2(17,fcb); - end search; - -searchn: procedure; - dcnt = mon2(18,0); - end searchn; - -cselect: procedure byte; - /* return current disk number */ - return mon2(25,0); - end cselect; - -setdma: procedure(dma); - declare dma address; - call mon1(26,dma); - end setdma; - -getalloca: procedure address; - /* get base address of alloc vector */ - return mon3(27,0); - end getalloca; - -getlogin: procedure address; - /* get the login vector */ - return mon3(24,0); - end getlogin; - -writeprot: procedure; - /* write protect the current disk */ - call mon1(28,0); - end writeprot; - -getrodisk: procedure address; - /* get the read-only disk vector */ - return mon3(29,0); - end getrodisk; - -setind: procedure; - /* set file indicators for current fcb */ - call mon1(30,fcba); - end setind; - -set$dpb: procedure; - /* set disk parameter block values */ - dpba = mon3(31,0); /* base of dpb */ - end set$dpb; - -getuser: procedure byte; - /* return current user number */ - return mon2(32,0ffh); - end getuser; - -setuser: procedure(user); - declare user byte; - call mon1(32,user); - end setuser; - -getfilesize: procedure(fcb); - declare fcb address; - call mon1(35,fcb); - end getfilesize; - -declare oldsp address, /* sp on entry */ - stack(16) address; /* this program's stack */ - -declare - fcbmax literally '512', /* max fcb count */ - fcbs literally 'memory',/* remainder of memory */ - fcb(33) byte at (fcba), /* default file control block */ - buff(128) byte at (buffa); /* default buffer */ - -declare bpb address; /* bytes per block */ - -set$bpb: procedure; - call set$dpb; /* disk parameters set */ - bpb = shl(double(1),blkshf) * sectorlen; - end set$bpb; - -select$disk: procedure(d); - declare d byte; - /* select disk and set bpb */ - call select(d); - call set$bpb; /* bytes per block */ - end select$disk; - -getalloc: procedure(i) byte; - /* return the ith bit of the alloc vector */ - declare i address; - return - rol(alloc(shr(i,3)), (i and 111b) + 1); - end getalloc; - -declare - accum(4) byte, /* accumulator */ - ibp byte; /* input buffer pointer */ - -compare: procedure(a) byte; - /* compare accumulator with four bytes addressed by a */ - declare a address; - declare (s based a) (4) byte; - declare i byte; - do i = 0 to 3; - if s(i) <> accum(i) then return false; - end; - return true; - end compare; - -scan: procedure; - /* fill accum with next input value */ - declare (i,b) byte; - setacc: procedure(b); - declare b byte; - accum(i) = b; i = i + 1; - end setacc; - /* deblank input */ - do while buff(ibp) = ' '; ibp=ibp+1; - end; - /* initialize accum length */ - i = 0; - do while i < 4; - if (b := buff(ibp)) > 1 then /* valid */ - call setacc(b); else /* blank fill */ - call setacc(' '); - if b <= 1 or b = ',' or b = ':' or - b = '*' or b = '.' or b = '>' or - b = '<' or b = '=' then buff(ibp) = 1; - else - ibp = ibp + 1; - end; - ibp = ibp + 1; - end scan; - -pdecimal: procedure(v,prec); - /* print value v with precision prec (10,100,1000) - with leading zero suppression */ - declare - v address, /* value to print */ - prec address, /* precision */ - zerosup byte, /* zero suppression flag */ - d byte; /* current decimal digit */ - zerosup = true; - do while prec <> 0; - d = v / prec ; /* get next digit */ - v = v mod prec;/* get remainder back to v */ - prec = prec / 10; /* ready for next digit */ - if prec <> 0 and zerosup and d = 0 then call printb; else - do; zerosup = false; call printchar('0'+d); - end; - end; - end pdecimal; - -add$block: procedure(ak,ab); - declare (ak, ab) address; - /* add one block to the kilobyte accumulator */ - declare kaccum based ak address; /* kilobyte accum */ - declare baccum based ab address; /* byte accum */ - baccum = baccum + bpb; - do while baccum >= 1024; - baccum = baccum - 1024; - kaccum = kaccum + 1; - end; - end add$block; - -count: procedure(mode) address; - declare mode byte; /* true if counting 0's */ - /* count kb remaining, kaccum set upon exit */ - declare - ka address, /* kb accumulator */ - ba address, /* byte accumulator */ - i address, /* local index */ - bit byte; /* always 1 if mode = false */ - ka, ba = 0; - bit = 0; - do i = 0 to maxall; - if mode then bit = getalloc(i); - if not bit then call add$block(.ka,.ba); - end; - return ka; - end count; - -abortmsg: procedure; - call print(.('** Aborted **',0)); - end abortmsg; - -userstatus: procedure; - /* display active user numbers */ - declare i byte; - declare user(32) byte; - declare ufcb(*) byte data ('????????????',0,0,0); - call print(.('Active User :',0)); - call pdecimal(getuser,10); - call print(.('Active Files:',0)); - do i = 0 to last(user); - user(i) = false; - end; - call setdma(.fcbs); - call search(.ufcb); - do while dcnt <> 255; - if (i := fcbs(shl(dcnt and 11b,5))) <> 0e5h then - user(i and 1fh) = true; - call searchn; - end; - do i = 0 to last(user); - if user(i) then call pdecimal(i,10); - end; - end userstatus; - -drivestatus: procedure; - declare - rpb address, - rpd address; - pv: procedure(v); - declare v address; - call crlf; - call pdecimal(v,10000); - call printchar(':'); - call printb; - end pv; - /* print the characteristics of the currently selected drive */ - call print(.(' ',0)); - call printchar(cselect+'A'); - call printchar(':'); - call printx(.(' Drive Characteristics',0)); - rpb = shl(double(1),blkshf); /* records/block=2**blkshf */ - if (rpd := (maxall+1) * rpb) = 0 and (rpb <> 0) then - call print(.('65536: ',0)); else - call pv(rpd); - call printx(.('128 Byte Record Capacity',0)); - call pv(count(false)); - call printx(.('Kilobyte Drive Capacity',0)); - call pv(dirmax+1); - call printx(.('32 Byte Directory Entries',0)); - call pv(shl(chksiz,2)); - call printx(.('Checked Directory Entries',0)); - call pv((extmsk+1) * 128); - call printx(.('Records/ Extent',0)); - call pv(rpb); - call printx(.('Records/ Block',0)); - call pv(scptrk); - call printx(.('Sectors/ Track',0)); - call pv(offset); - call printx(.('Reserved Tracks',0)); - call crlf; - end drivestatus; - -diskstatus: procedure; - /* display disk status */ - declare login address, d byte; - login = getlogin; /* login vector set */ - d = 0; - do while login <> 0; - if low(login) then - do; call select$disk(d); - call drivestatus; - end; - login = shr(login,1); - d = d + 1; - end; - end diskstatus; - -match: procedure(va,vl) byte; - /* return index+1 to vector at va if match */ - declare va address, - v based va (16) byte, - vl byte; - declare (i,j,match,sync) byte; - j,sync = 0; - do sync = 1 to vl; - match = true; - do i = 0 to 3; - if v(j) <> accum(i) then match=false; - j = j + 1; - end; - if match then return sync; - end; - return 0; /* no match */ - end match; - -declare devl(*) byte data - ('VAL:USR:DSK:'); - -devreq: procedure byte; - /* process device request, return true if found */ - - declare - (i,j,items) byte; - - - items = 0; - do forever; - call scan; - if (i:=match(.devl,8)) = 0 then return items<>0; - items = items+1; /* found first/next item */ - if i = 1 then /* list possible assignment */ - do; - call print(.('Temp R/O Disk: d:=R/O',0)); - call print(.('Set Indicator: d:filename.typ ', - '$R/O $R/W $SYS $DIR',0)); - call print(.('Disk Status : DSK: d:DSK:',0)); - call print(.('User Status : USR:',0)); - end; else - if i = 2 then /* list user status values */ - call userstatus; - else - if i = 3 then /* show the disk device status */ - call diskstatus; - /* end of current item, look for more */ - call scan; - if accum(0) = ' ' then return true; - if accum(0) <> ',' then - do; call print(.('Bad Delimiter',0)); - return true; - end; - end; /* of do forever */ - end devreq; - -pvalue: procedure(v); - declare (d,zero) byte, - (k,v) address; - k = 10000; - zero = false; - do while k <> 0; - d = low(v/k); v = v mod k; - k = k / 10; - if zero or k = 0 or d <> 0 then - do; zero = true; call printchar('0'+d); - end; - end; - call printchar('k'); - call crlf; - end pvalue; - -comp$alloc: procedure; - alloca = getalloca; - call printchar(cselect+'A'); - call printx(.(': ',0)); - end comp$alloc; - -prcount: procedure; - /* print the actual byte count */ - call pvalue(count(true)); - end prcount; - -pralloc: procedure; - /* print allocation for current disk */ - call print (.('Bytes Remaining On ',0)); - call comp$alloc; - call prcount; - end pralloc; - -prstatus: procedure; - /* print the status of the disk system */ - declare (login, rodisk) address; - declare d byte; - login = getlogin; /* login vector set */ - rodisk = getrodisk; /* read only disk vector set */ - d = 0; - do while login <> 0; - if low(login) then - do; call select$disk(d); - call comp$alloc; - call printx(.('R/',0)); - if low(rodisk) then - call printchar('O'); else - call printchar('W'); - call printx(.(', Space: ',0)); - call prcount; - end; - login = shr(login,1); rodisk = shr(rodisk,1); - d = d + 1; - end; - call crlf; - end prstatus; - -setdisk: procedure; - if fcb(0) <> 0 then call select$disk(fcb(0)-1); - end setdisk; - -getfile: procedure; - /* process file request */ - - declare - fnam literally '11', fext literally '12', - fmod literally '14', - frc literally '15', fln literally '15', - fdm literally '16', fdl literally '31', - ftyp literally '9', - rofile literally '9', /* read/only file */ - infile literally '10'; /* invisible file */ - declare - fcbn address, /* number of fcb's collected so far */ - finx(fcbmax) address, /* index vector used during sort */ - fcbe(fcbmax) address, /* extent counts */ - fcbb(fcbmax) address, /* byte count (mod kb) */ - fcbk(fcbmax) address, /* kilobyte count */ - fcbr(fcbmax) address, /* record count */ - bfcba address, /* index into directory buffer */ - fcbsa address, /* index into fcbs */ - bfcb based bfcba (32) byte, /* template over directory */ - fcbv based fcbsa (16) byte; /* template over fcbs entry */ - declare - i address, /* fcb counter during collection and display */ - l address, /* used during sort and display */ - k address, /* " */ - m address, /* " */ - kb byte, /* byte counter */ - lb byte, /* byte counter */ - mb byte, /* byte counter */ - (b,f) byte, /* counters */ - matched byte; /* used during fcbs search */ - - multi16: procedure; - /* utility to compute fcbs address from i */ - fcbsa = shl(i,4) + .fcbs; - end multi16; - - declare - scase byte; /* status case # */ - - declare - fstatlist(*) byte data('R/O',0,'R/W',0,'SYS',0,'DIR',0); - - setfilestatus: procedure byte; - /* eventually, scase set r/o=0,r/w=1,dat=2,sys=3 */ - declare - fstat(*) byte data('R/O R/W SYS DIR '); - if doll = ' ' then return false; - call move(4,.parm,.accum); /* $???? */ - if accum(0) = 'S' and accum(1) = ' ' then - return not (sizeset := true); - /* must be a parameter */ - if (scase := match(.fstat,4)) = 0 then - call print(.('Invalid File Indicator',0)); - return true; - end setfilestatus; - - printfn: procedure; - declare (k, lb) byte; - /* print file name */ - do k = 1 to fnam; - if (lb := fcbv(k) and 7fh) <> ' ' then - do; if k = ftyp then call printchar('.'); - call printchar(lb); - end; - end; - end printfn; - - call set$bpb; /* in case default disk */ - call setdisk; - sizeset = false; - scase = 255; - if setfilestatus then - do; if scase = 0 then return; - scase = scase - 1; - end; else - if fcb(1) = ' ' then /* no file named */ - do; call pralloc; - return; - end; - /* read the directory, collect all common file names */ - fcbn,fcb(0) = 0; - fcb(fext),fcb(fmod) = '?'; /* question mark matches all */ - call search(fcba); /* fill directory buffer */ - collect: /* label for debug */ - do while dcnt <> 255; - /* another item found, compare it for common entry */ - bfcba = shl(dcnt and 11b,5)+buffa; /* dcnt mod 4 * 32 */ - matched = false; i = 0; - do while not matched and i < fcbn; - /* compare current entry */ - call multi16; - do kb = 1 to fnam; - if bfcb(kb) <> fcbv(kb) then kb = fnam; else - /* complete match if at end */ - matched = kb = fnam; - end; - i = i + 1; - end; - checkmatched: /* label for debug */ - if matched then i = i - 1; else - do; /* copy to new position in fcbs */ - fcbn = (i := fcbn) + 1; - call multi16; - /* fcbsa set to next to fill */ - if (fcbn > fcbmax) or (fcbsa + 16) >= memsize then - do; call print(.('** Too Many Files **',0)); - i = 0; fcbn = 1; - call multi16; - end; - /* save index to element for later sort */ - finx(i) = i; - do kb = 0 to fnam; - fcbv(kb) = bfcb(kb); - end; - fcbe(i),fcbb(i),fcbk(i),fcbr(i) = 0; - end; - /* entry is at, or was placed at location i in fcbs */ - fcbe(i) = fcbe(i) + 1; /* extent incremented */ - /* record count */ - fcbr(i) = fcbr(i) + bfcb(frc) - + (bfcb(fext) and extmsk) * 128; - /* count kilobytes */ - countbytes: /* label for debug */ - lb = 1; - if maxall > 255 then lb = 2; /* double precision inx */ - do kb = fdm to fdl by lb; - mb = bfcb(kb); - if lb = 2 then /* double precision inx */ - mb = mb or bfcb(kb+1); - if mb <> 0 then /* allocated */ - call add$block(.fcbk(i),.fcbb(i)); - end; - call searchn; /* to next entry in directory */ - end; /* of do while dcnt <> 255 */ - - display: /* label for debug */ - /* now display the collected data */ - if fcbn = 0 then call print(.('File Not Found',0)); else - if scase = 255 then /* display collected data */ - do; - /* sort the file names in ascending order */ - if fcbn > 1 then /* requires at least two to sort */ - do; l = 1; - do while l > 0; /* bubble sort */ - l = 0; - do m = 0 to fcbn - 2; - i = finx(m+1); call multi16; bfcba = fcbsa; i = finx(m); - call multi16; /* sets fcbsa, basing fcbv */ - do kb = 1 to fnam; /* compare for less or equal */ - if (b:=bfcb(kb)) < (f:=fcbv(kb)) then /* switch */ - do; k = finx(m); finx(m) = finx(m + 1); - finx(m + 1) = k; l = l + 1; kb = fnam; - end; - else if b > f then kb = fnam; /* stop compare */ - end; - end; - end; - end; - if sizeset then - call print(.(' Size ',0)); else - call crlf; - call printx(.(' Recs Bytes Ext Acc',0)); - l = 0; - do while l < fcbn; - i = finx(l); /* i is the index to next in order */ - call multi16; call crlf; - /* print the file length */ - call move(16,.fcbv(0),fcba); - fcb(0) = 0; - if sizeset then - do; call getfilesize(fcba); - if rovf <> 0 then call printx(.('65536',0)); else - call pdecimal(rrec,10000); - call printb; - end; - call pdecimal(fcbr(i),10000); /* rrrrr */ - call printb; /* blank */ - call pdecimal(fcbk(i),10000); /* bbbbbk */ - call printchar('k'); call printb; - call pdecimal(fcbe(i),1000); /* eeee */ - call printb; - call printchar('R'); - call printchar('/'); - if rol(fcbv(rofile),1) then - call printchar('O'); else - call printchar('W'); - call printb; - call printchar('A'+cselect); call printchar(':'); - /* print filename.typ */ - if (mb:=rol(fcbv(infile),1)) then call printchar('('); - call printfn; - if mb then call printchar(')'); - l = l + 1; - end; - call pralloc; - end; else - setfileatt: /* label for debug */ - /* set file attributes */ - do; - l = 0; - do while l < fcbn; - if break then - do; call abortmsg; return; - end; - i = l; - call multi16; - call crlf; - call printfn; - do case scase; - /* set to r/o */ - fcbv(rofile) = fcbv(rofile) or 80h; - /* set to r/w */ - fcbv(rofile) = fcbv(rofile) and 7fh; - /* set to sys */ - fcbv(infile) = fcbv(infile) or 80h; - /* set to dir */ - fcbv(infile) = fcbv(infile) and 7fh; - end; - /* place name into default fcb location */ - call move(16,fcbsa,fcba); - fcb(0) = 0; /* in case matched user# > 0 */ - call setind; /* indicators set */ - call printx(.(' set to ',0)); - call printx(.fstatlist(shl(scase,2))); - l = l + 1; - end; - end; - end getfile; - -setdrivestatus: procedure; - /* handle possible drive status assignment */ - call scan; /* remove drive name */ - call scan; /* check for = */ - if accum(0) = '=' then - do; call scan; /* get assignment */ - if compare(.('R/O ')) then - do; call setdisk; /* a: ... */ - call writeprot; - end; else - call print(.('Invalid Disk Assignment',0)); - end; - else /* not a disk assignment */ - do; call setdisk; - if match(.devl,8) = 3 then call drive$status; else - call getfile; - end; - end setdrivestatus; - - /* save stack pointer and reset */ -oldsp = stackptr; -stackptr = .stack(length(stack)); -/* process request */ -if version < cpmversion then - call print(.('Wrong CP/M Version (Requires 2.0 or greater)',0)); - else - do; - /* size display if $S set in command */ - ibp = 1; /* initialize buffer pointer */ - if fcb(0) = 0 and fcb(1) = ' ' then /* stat only */ - call prstatus; else - do; - if fcb(0) <> 0 then - call setdrivestatus; else - do; - if not devreq then /* must be file name */ - call getfile; - end; - end; - end; - /* restore old stack before exit */ - stackptr = oldsp; - end status; -end; - \ No newline at end of file diff --git a/cpm/pcpm/XSUB.SUB b/cpm/pcpm/XSUB.SUB deleted file mode 100644 index 8d172ad..0000000 --- a/cpm/pcpm/XSUB.SUB +++ /dev/null @@ -1,10 +0,0 @@ -asm xsub0 -rmac xsub1 -link xsub1[os] -xsub -ddt xsub1.spr -ixsub0.hex -r -g0 -save 4 xsubnew.com - \ No newline at end of file diff --git a/cpm/pcpm/XSUB0.ASM b/cpm/pcpm/XSUB0.ASM deleted file mode 100644 index 280b5c1..0000000 --- a/cpm/pcpm/XSUB0.ASM +++ /dev/null @@ -1,135 +0,0 @@ -; xsub relocator version 2.2 -version equ 20h -; xsub relocator program, included with the module -; to perform the move from 200h to the destination address -; -; copyright (c) 1979, 1980 -; digital research -; box 579 -; pacific grove, ca. -; 93950 -; - org 100h - db (lxi or (b shl 3)) ;lxi b,module size - org $+2 ;skip address field - jmp start - db ' Extended Submit Vers ' - db version/16+'0','.',version mod 16+'0' -nogo: db 'Xsub Already Present$' -badver: db 'Requires CP/M Version 2.0 or later$' -; -bdos equ 0005h ;bdos entry point -print equ 9 ;bdos print function -vers equ 12 ;get version number -ccplen equ 0800h ;size of ccp -module equ 200h ;module address -; -start: -; ccp's stack used throughout - push b ;save the module's length - lda bdos+1 ;xsub already present? - cpi 06h ;low address must be 06h - jnz loaderr - lhld bdos+1 - inx h - inx h - inx h - lxi d,xsubcon - mvi c,4 -present: - ldax d - cmp m - jnz continue - inx h - inx d - dcr c - jz loaderr - jmp present -; -loaderr: -; bdos or xsub not lowest module in memory, return to ccp - mvi c,print - lxi d,nogo ;already present message - call bdos ;to print the message - pop b ;recall length - ret ;to the ccp -; -continue: - mvi c,vers - call bdos ;version number? - cpi version ;2.0 or greater - jnc versok -; -; wrong version - mvi c,print - lxi d,badver - call bdos - pop b - ret ;to ccp -; -versok: - lxi h,bdos+2;address field of jump to bdos (top memory) - mov a,m ;a has high order address of memory top - dcr a ;page directly below bdos - sui (ccplen shr 8) ;-ccp pages - pop b ;recall length of module - push b ;and save it again - sub b ;a has high order address of reloc area - mov d,a - mvi e,0 ;d,e addresses base of reloc area - push d ;save for relocation below -; - lxi h,module;ready for the move -move: mov a,b ;bc=0? - ora c - jz reloc - dcx b ;count module size down to zero - mov a,m ;get next absolute location - stax d ;place it into the reloc area - inx d - inx h - jmp move -; -reloc: ;storage moved, ready for relocation -; hl addresses beginning of the bit map for relocation - pop d ;recall base of relocation area - pop b ;recall module length - push h ;save bit map base in stack - mov h,d ;relocation bias is in d -; -rel0: mov a,b ;bc=0? - ora c - jz endrel -; -; not end of the relocation, may be into next byte of bit map - dcx b ;count length down - mov a,e - ani 111b ;0 causes fetch of next byte - jnz rel1 -; fetch bit map from stacked address - xthl - mov a,m ;next 8 bits of map - inx h - xthl ;base address goes back to stack - mov l,a ;l holds the map as we process 8 locations -rel1: mov a,l - ral ;cy set to 1 if relocation necessary - mov l,a ;back to l for next time around - jnc rel2 ;skip relocation if cy=0 -; -; current address requires relocation - ldax d - add h ;apply bias in h - stax d -rel2: inx d ;to next address - jmp rel0 ;for another byte to relocate -; -endrel: ;end of relocation - pop d ;clear stacked address -; h has the high order 8-bits of relocated module address - mvi l,0 - pchl ;go to relocated program -xsubcon: - db 'xsub' - end - \ No newline at end of file diff --git a/cpm/pcpm/XSUB1.ASM b/cpm/pcpm/XSUB1.ASM deleted file mode 100644 index 26c203b..0000000 --- a/cpm/pcpm/XSUB1.ASM +++ /dev/null @@ -1,232 +0,0 @@ -; xsub 'Extended Submit Facility' version 2.2 -; -; -; -; xsub loads below ccp, and feeds command lines to -; programs which read buffered input -; -bias equ 0000h ;bias for relocation -base equ 0ffffh ;no intercepts below here -wboot equ 0000h -bdos equ 0005h -bdosl equ bdos+1 -dbuff equ 0080h -; -cr equ 0dh ;carriage return -lf equ 0ah ;line feed -modnum equ 14 ;module number position -pbuff equ 9 ;print buffer -rbuff equ 10 ;read buffer -openf equ 15 ;open file -closef equ 16 ;close file -delf equ 19 ;delete file -dreadf equ 20 ;disk read -dmaf equ 26 ;set dma function -; -; - org 0000h+bias -; initialize jmps to include xsub module - jmp start - ds 3 -trapjmp: - jmp trap - db 'xsub' -start: - lhld wboot+1 - shld savboot - lxi h,wstart - shld wboot+1 - lhld bdosl - shld rbdos+1 ;real bdos entry - lxi h,trapjmp ;address to fill - shld bdosl ;jmp @0005 leads to trap - pop h ;ccp return address - shld ccpret - pchl ;back to ccp -; -savboot: - ds 2 ;warm boot saved and restored at end - ;of submit file -; -wstart: - lxi sp,stack - mvi c,pbuff ;print message - CALL GET$SUBADDR - lxi d,actmsg Š CNZ rbdos - lxi h,dbuff ;restore default buffer - shld udma - call rsetdma - lxi h,trapjmp - shld bdosl ;fixup low jump address - lhld ccpret ;back to ccp - pchl - -actmsg: db cr,lf,'(xsub active)$' -; -trap: ;arrive here at each bdos call - pop h ;return address - push h ;back to stack - mov a,h ;high address - cpi base shr 8 - jnc rbdos ;skip calls on bdos above here - mov a,c ;function number - cpi rbuff - jz rnbuff ;read next buffer - cpi dmaf ;set dma address? - jnz rbdos ;skip if not - xchg ;dma to hl - shld udma ;save it - xchg -rbdos: jmp 0000h ;filled in at initialization -; -setdma: - lxi d,combuf -SETDMA1: - mvi c,dmaf - JMP RBDOS -; -rsetdma: - lhld udma - xchg - JMP SETDMA1 -; -GET$SUBADDR: - LHLD RBDOS+1 - MVI L,09H - MOV E,M - INX H - MOV D,M - XCHG - MOV A,M - ORA A - RET -; -DELETE$SUB: - CALL GET$SUBADDR - MVI M,0 - MVI C,DELF - LXI D,SUBFCB -; Šfbdos: - push b - push d - call setdma - pop d - pop b - call rbdos - push psw - call rsetdma - pop psw - ret -; -cksub: ;check for sub file present - CALL GET$SUBADDR - RZ - INX H - LXI D,SUBS1 - MVI C,20 -; -MOVE: - INR C -MOVE1: - ORA C - DCR C - RZ - MOV A,M - STAX D - INX H - INX D - JMP MOVE1 -; -rnbuff: - push d ;command address - call cksub ;sub file present? - pop d - mvi c,rbuff - ORA A - jz restor ;no sub file -; - push d - lda subrc ;length of file - ora a ;zero? - jz rbdos ;skip if so - dcr a ;length - 1 - sta subcr ;next to read - mvi c,dreadf - lxi d,subfcb - call fbdos ;read record - ORA A - JZ READOK - - CALL DELETE$SUB - MVI C,0 -restor: - lhld savboot Š shld wboot+1 - jmp rbdos - -READOK: -; now print the buffer with cr,lf - - lxi h,combuf - mov e,m ;length - mvi d,0 ;high order 00 - dad d ;to last character position - inx h - mvi m,cr - inx h - mvi m,lf - inx h - mvi m,'$' - mvi c,pbuff - lxi d,combuf+1 - LDAX D - CPI 3 - CNZ rbdos ;to print it - pop h ;.max length - lxi d,combuf - ldax d ;how long? - cmp m ;cy if ok - jc movlin - mov a,m ;max length - stax d ;truncate length -movlin: - mov c,a ;length to c - inr c ;+1 - inx h ;to length of line - XCHG - CALL MOVE - CALL GET$SUBADDR - - PUSH H ;.SUBFLAG - INX H ;.FCB(S1) - INX H ;.FCB(S2) - INX H ;.FCB(RC) - DCR M - POP H - CZ DELETE$SUB - LDA COMBUF+1 ;^C? - CPI 3 - RNZ - MVI C,PBUFF - LXI D,CTLCMSG - CALL RBDOS - JMP WBOOT -; -subfcb: - db 1 ;a: - db '$$$ ' - db 'SUB' Š db 0 -SUBS1: - DB 0,0 -subrc: - ds 1 - ds 16 ;map -subcr: ds 1 -; -CTLCMSG:DB '^C$' -combuf: ds 131 -udma: dw dbuff -ccpret: ds 2 ;ccp return address - ds 24 ;12 level stack -stack: - end - \ No newline at end of file diff --git a/emu/yaze/.yazerc b/emu/yaze/.yazerc deleted file mode 100644 index 995977c..0000000 --- a/emu/yaze/.yazerc +++ /dev/null @@ -1,4 +0,0 @@ -mount a transfer -mount b disk -mount c COBOL -go diff --git a/emu/yaze/COBOL/CALL.ASM b/emu/yaze/COBOL/CALL.ASM deleted file mode 100644 index 3300152..0000000 --- a/emu/yaze/COBOL/CALL.ASM +++ /dev/null @@ -1,23 +0,0 @@ -; Program "Call" called by "Testcall"; this is assembler version; -; compare with functionally equivalent COBOL version. - - cseg - - ldax b ; read first param: A = text length -loop: - dcr a ; count down length - rm ; finished - push psw - ldax d ; next byte from second param = text - inx d - push d - mov e,a - mvi c,6 ; CP/M function code - call 5 ; call CP/M to send character - pop d - pop psw - jmp loop - -; End of demonstration program "Call" - -end diff --git a/emu/yaze/COBOL/CALL.CBL b/emu/yaze/COBOL/CALL.CBL deleted file mode 100644 index b452a83..0000000 --- a/emu/yaze/COBOL/CALL.CBL +++ /dev/null @@ -1,26 +0,0 @@ -000000****************************************************************** -000000* -000000* Program "Call" called by "Testcall"; this is COBOL version; -000000* compare with functionally equivalent assembler version. -000000* -000000****************************************************************** -000000 Working-storage section. -000000 01 temp pic 9(2) comp. -000000 01 text-buffer value space. -000000 02 tbuf-table pic x occurs 80. -000000 Linkage section. -000000 01 mess-text. -000000 02 mtex-table pic x occurs 80. -000000 01 mess-size pic 9(2) comp. -000000 Procedure division using mess-size,mess-text. -000000 l. -000000 move 0 to temp perform move-byte until temp = mess-size. -000000 display text-buffer. -000000 exit program. -000000 move-byte. -000000 add 1 to temp move mtex-table (temp) to tbuf-table (temp). -000000****************************************************************** -000000* -000000* End of demonstration program "Call" -000000* -000000****************************************************************** diff --git a/emu/yaze/COBOL/CALL.INT b/emu/yaze/COBOL/CALL.INT deleted file mode 100644 index 68c2a20..0000000 Binary files a/emu/yaze/COBOL/CALL.INT and /dev/null differ diff --git a/emu/yaze/COBOL/CALL.PRL b/emu/yaze/COBOL/CALL.PRL deleted file mode 100644 index a877d42..0000000 Binary files a/emu/yaze/COBOL/CALL.PRL and /dev/null differ diff --git a/emu/yaze/COBOL/CLI b/emu/yaze/COBOL/CLI deleted file mode 100644 index d382802..0000000 Binary files a/emu/yaze/COBOL/CLI and /dev/null differ diff --git a/emu/yaze/COBOL/CLI.CBL b/emu/yaze/COBOL/CLI.CBL deleted file mode 100644 index fc39ba3..0000000 --- a/emu/yaze/COBOL/CLI.CBL +++ /dev/null @@ -1,240 +0,0 @@ -000000 IDENTIFICATION DIVISION. -000000****************************************************************** -000000* * -000000* COPYRIGHT (C) 1982,1982 MICRO FOCUS LTD. * -000000* * -000000* MICRO FOCUS LTD. * -000000* 58, ACACIA ROAD, * -000000* ST. JOHNS WOOD, * -000000* LONDON NW8 6AG. * -000000* * -000000* TEL. 01 722 8843/4/5/6/7 * -000000* TELEX 28536 MICROF G * -000000* * -000000****************************************************************** -000000* -000000 PROGRAM-ID. COMMAND LINE INTERPRETOR. -000000 AUTHOR. MICRO FOCUS LTD. -000000 INSTALLATION. MICRO FOCUS - SWINDON. -000000 DATE-WRITTEN. 6TH DECEMBER 1982. -000000 DATE-COMPILED. 6TH DECEMBER 1982. -000000* -000000 ENVIRONMENT DIVISION. -000000 SOURCE-COMPUTER. 8080. -000000 OBJECT-COMPUTER. 8080. -000000 SPECIAL-NAMES. CONSOLE IS CRT. -000000/***************************************************************** -000000* * -000000* DATA USED BY THE CLI TO STORE THE USER'S INSTRUCTIONS. * -000000* * -000000****************************************************************** -000000* -000000 DATA DIVISION. -000000 WORKING-STORAGE SECTION. -000000* -000000 01 TEMP PIC 9(2) COMP. -000000 01 SUB1 PIC 9(2) COMP. -000000 01 SUB2 PIC 9(2) COMP. -000000 01 SUB2-SAV PIC 9(2) COMP. -000000 01 TMAX PIC 9(2) COMP. -000000 01 CHOICE PIC X. -000000* -000000 01 RTS-ROUTINES. -000000 02 POKE-CLI PIC X VALUE X"91". -000000 02 CHAIN PIC X VALUE X"84". -000000 02 GET-CHAR PIC X VALUE X"D8". -000000 02 SOUND-ALARM PIC X VALUE X"E5". -000000* -000000* DISPLAY LINES -000000* -000000 01 INIT-LINE. -000000 02 INIT-LINE-1 PIC X(68) VALUE "COBOL: A(nimate) C(ompile) D( -000000- "rive) F(orms2) Q(uit) R(un) S(witches)". -000000 02 FILLER PIC X(4). -000000 02 INIT-CHOICE PIC X. -000000* -000000 01 FILE-QUESTION-LINE. -000000 02 FQL-1 PIC X(22) VALUE "Enter name of file to ". -000000 02 VERB PIC X(8). -000000* -000000* COMMAND-LINE COMPONENTS -000000* -000000 01 SWITCH-AREA. -000000 02 FILLER PIC X VALUE "(". -000000 02 SWITCHES PIC X(40) VALUE SPACE. -000000* -000000 01 FILE-NAME PIC X(16). -000000* -000000 01 CLI-REST PIC X(80). -000000* -000000 01 WORK-AREA. -000000 02 WORK-BYTE PIC 9(2) OCCURS 80 COMP. -000000* -000000 01 OUTPUT-CLI VALUE SPACE. -000000 02 OUT-BYTE PIC 9(2) OCCURS 128 COMP. -000000* -000000 01 PROG-AREA. -000000 02 DRIVE PIC X VALUE SPACE. -000000 02 FILLER PIC X VALUE ":". -000000 02 PROG-NAME PIC X(16). -000000* -000000/***************************************************************** -000000* * -000000* MAIN ENTRY TO CLI PROGRAM. IS USED BY ORDINARY ENTRY TO * -000000* COMMAND LINE INTERPRETOR, AS WELL AS BY PROGRAMS WHICH ARE * -000000* RETURNING CONTROL TO THE CLI FOR CONTINUATION COMMANDS. * -000000* * -000000****************************************************************** -000000* -000000 PROCEDURE DIVISION. -000000 MAIN-ENTRY. -000000* -000000* TEST IF SCREEN SHOULD BE CLEARED. IF "X" ON COMMAND LINE, THEN -000000* THIS IS A SECOND OR SUBSEQUENT ENTRY, AND THE SCREEN SHOULD -000000* NOT BE CLEARED. -000000* -000000 ACCEPT WORK-AREA FROM CONSOLE. -000000 IF WORK-AREA NOT = "X" -000000 DISPLAY SPACE. -000000 CALL SOUND-ALARM. -000000* -000000 LOOP. -000000 MOVE SPACE TO INIT-CHOICE. -000000 DISPLAY INIT-LINE. -000000 DISPLAY LOW-VALUE AT 0170. -000000 CALL GET-CHAR USING CHOICE. -000000 DISPLAY SPACE. -000000 MOVE CHOICE TO INIT-CHOICE. -000000 DISPLAY INIT-LINE. -000000* -000000 IF CHOICE = "A" OR "a" -000000 MOVE "ANIMATE:" TO VERB -000000 MOVE "ANIMATE.COM" TO PROG-NAME -000000 GO TO FILE-QUESTION. -000000 IF CHOICE = "C" OR "c" -000000 MOVE "COMPILE:" TO VERB -000000 MOVE "COBOL.COM" TO PROG-NAME -000000 GO TO FILE-QUESTION. -000000 IF CHOICE = "D" OR "d" -000000 GO TO DRIVE-SET. -000000 IF CHOICE = "F" OR "f" -000000 MOVE "FORMS2.COM" TO PROG-NAME -000000 MOVE 0 TO SUB2 -000000 GO TO LOADER. -000000 IF CHOICE = "Q" OR "q" -000000 GO TO EXITING. -000000 IF CHOICE = "R" OR "r" -000000 MOVE "RUN:" TO VERB -000000 MOVE "RUN.COM" TO PROG-NAME -000000 GO TO FILE-QUESTION. -000000 IF CHOICE = "S" OR "s" -000000 GO TO SWITCH-SET. -000000 CALL SOUND-ALARM. -000000 GO TO LOOP. -000000* -000000/***************************************************************** -000000* * -000000* CODE TO HANDLE FILENAME OF PROGRAM TO BE COMPILED, ANIMATED * -000000* OR EXECUTED. * -000000* * -000000****************************************************************** -000000* -000000 FILE-QUESTION. -000000 MOVE SPACE TO FILE-NAME. -000000 DISPLAY FILE-QUESTION-LINE AT 0201. -000000 ACCEPT FILE-NAME AT 0232. -000000 IF FILE-NAME = SPACES -000000 GO TO LOOP. -000000* -000000 PERFORM CLEAR-LINES. -000000 MOVE SPACE TO CLI-REST. -000000 DISPLAY "Any further command line ?" AT 0201. -000000 ACCEPT CLI-REST AT 0301. -000000* -000000 MOVE 0 TO SUB2. -000000 IF "RUN.COM" = PROG-NAME -000000 IF SPACE NOT = SWITCHES -000000 MOVE SWITCH-AREA TO WORK-AREA -000000 MOVE 41 TO TMAX -000000 MOVE 0 TO SUB1 -000000 PERFORM TRANSFER-BUFFER -000000 ADD 1 TO SUB2 -000000 MOVE 41 TO OUT-BYTE (SUB2). -000000 MOVE FILE-NAME TO WORK-AREA. -000000 MOVE 0 TO SUB1. -000000 MOVE 16 TO TMAX. -000000 PERFORM TRANSFER-BUFFER. -000000 MOVE CLI-REST TO WORK-AREA. -000000 MOVE 0 TO SUB1. -000000 MOVE 80 TO TMAX. -000000 PERFORM TRANSFER-BUFFER. -000000 IF SUB2 > 80 -000000 GO TO CLI-OVF. -000000* -000000* COMMAND LINE NOW CREATED, CHAIN TO THE NEXT PROGRAM. THIS -000000* IS DONE BY SETTING A COMMAND LINE FOR THE RTS TO EXECUTE. -000000* -000000 LOADER. -000000 CALL POKE-CLI USING SUB2, OUTPUT-CLI. -000000 PERFORM CLEAR-LINES. -000000 DISPLAY "Loading ..." at 0201. -000000 DISPLAY LOW-VALUE AT 0301. -000000 IF DRIVE = SPACE -000000 CALL CHAIN USING PROG-NAME -000000 ELSE -000000 CALL CHAIN USING PROG-AREA. -000000* -000000/***************************************************************** -000000* * -000000* SUPPORT CLI ROUTINES, USED TO MANIPULATE THE FIELDS BEFORE * -000000* CONTROL IS TRANSFERRED TO A SUPPORT PROGRAM. * -000000* * -000000****************************************************************** -000000* -000000 SWITCH-SET. -000000 MOVE SPACE TO SWITCHES. -000000 DISPLAY "Switches:" AT 0201. -000000 ACCEPT SWITCHES AT 0211. -000000 INSPECT SWITCHES REPLACING -000000 ALL "(" BY SPACE -000000 ALL ")" BY SPACE. -000000 GO TO LOOP. -000000* -000000 DRIVE-SET. -000000 DISPLAY "Enter Drive:" AT 0201. -000000 ACCEPT DRIVE AT 0214. -000000 GO TO LOOP. -000000* -000000 EXITING. -000000 DISPLAY "Returning to CP/M" AT 0201. -000000 DISPLAY LOW-VALUE AT 0301. -000000 STOP RUN. -000000* -000000/***************************************************************** -000000* * -000000* WORK ROUTINES USED TO MANIPULATE THE SCREEN. * -000000* * -000000****************************************************************** -000000* -000000 CLI-OVF. -000000 PERFORM CLEAR-LINES. -000000 DISPLAY "Command buffer overflow" AT 0301. -000000 GO TO LOOP. -000000* -000000 CLEAR-LINES. -000000 MOVE SPACE TO WORK-AREA. -000000 DISPLAY WORK-AREA AT 0201. -000000 DISPLAY WORK-AREA AT 0301. -000000* -000000 TRANSFER-BUFFER. -000000 ADD 1 TO SUB1. -000000 ADD 1 TO SUB2. -000000 MOVE WORK-BYTE (SUB1) TO TEMP. -000000 IF TEMP NOT = 32 -000000 MOVE SUB2 TO SUB2-SAV -000000 MOVE TEMP TO OUT-BYTE (SUB2). -000000 IF SUB1 < TMAX -000000 GO TO TRANSFER-BUFFER. -000000 MOVE SUB2-SAV TO SUB2. -000000 ADD 1 TO SUB2. -000000* diff --git a/emu/yaze/COBOL/CLI.COM b/emu/yaze/COBOL/CLI.COM deleted file mode 100644 index 08e83e6..0000000 Binary files a/emu/yaze/COBOL/CLI.COM and /dev/null differ diff --git a/emu/yaze/COBOL/COBOL b/emu/yaze/COBOL/COBOL deleted file mode 100644 index c0d5fcc..0000000 Binary files a/emu/yaze/COBOL/COBOL and /dev/null differ diff --git a/emu/yaze/COBOL/COBOL.COM b/emu/yaze/COBOL/COBOL.COM deleted file mode 100644 index f9e131b..0000000 Binary files a/emu/yaze/COBOL/COBOL.COM and /dev/null differ diff --git a/emu/yaze/COBOL/COBOL.ERR b/emu/yaze/COBOL/COBOL.ERR deleted file mode 100644 index 890d40e..0000000 --- a/emu/yaze/COBOL/COBOL.ERR +++ /dev/null @@ -1,160 +0,0 @@ -Compiler error; consult Technical Support -Illegal format : Data-name -Illegal format : Literal, or invalid use of ALL -Illegal format : Character -Data-name not unique -Too many data or procedure names declared -Illegal character in column 7 or continuation error -Nested COPY statement or unknown COPY file specified -'.' missing -Statement starts in wrong area of source line -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -'.' missing -DIVISION missing -SECTION missing -IDENTIFICATION missing -PROGRAM-ID missing -AUTHOR missing -INSTALLATION missing -DATE-WRITTEN missing -SECURITY missing -ENVIRONMENT missing -CONFIGURATION missing -SOURCE-COMPUTER missing -OBJECT-COMPUTER/SPECIAL-NAMES clause error -OBJECT-COMPUTER missing -Compiler error; consult Technical Support -SPECIAL-NAMES missing -SWITCH clause error or system name/mnemonic name error -DECIMAL-POINT clause error -CONSOLE clause error -Illegal currency symbol -'.' missing -DIVISION missing -SECTION missing -INPUT-OUTPUT missing -FILE-CONTROL missing -ASSIGN missing -SEQUENTIAL or RELATIVE or INDEXED missing -ACCESS missing on indexed/relative file -SEQUENTIAL or DYNAMIC missing or > 64 alternate keys -Illegal ORGANIZATION/ACCESS/KEY combination -Unrecognized phrase in SELECT clause -RERUN clause syntax error -SAME AREA clause syntax error -Missing or illegal file-name -DATA DIVISION missing -PROCEDURE DIVISION missing or unknown statement -Program collating sequence not defined -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -'.' missing -DIVISION missing -SECTION missing -File-name not specified in SELECT stmt or invalid CD name -RECORD SIZE integer missing or line sequential rec > 1024 bytes -Illegal level no (01-49),01 level reqd,or level hierarachy wrong -FD, CD or SD qualification syntax error -WORKING-STORAGE missing -PROCEDURE DIVISION missing or unknown statement -Data description qualifier or '.' missing -Incompatible PICTURE clause and qualifiers -BLANK illegal with non-numeric data-item -PICTURE clause too long -VALUE with non-elementary item,wrong data-type or value truncated -VALUE in error or illegal for PICTURE type -Non-elementary item has FILLER/SYNC/JUST/BLANK clause -Preceding item at this level has > 8192 bytes or 0 bytes -REDEFINES of unequal fields or different levels -Data storage exceeds 64K bytes -Compiler error; consult Technical Support -Data description qualifier inappropriate or repeated -REDEFINES data-name not declared -USAGE must be COMP,DISPLAY or INDEX -SIGN must be LEADING or TRAILING -SYNCHRONIZED must be LEFT or RIGHT -JUSTIFIED must be RIGHT -BLANK must be ZERO -OCCURS must be numeric, non-zero, unsigned or DEPENDING -VALUE must be literal, numeric literal or figurative constant -PICTURE string has illegal precedence or illegal char -INDEXED data-name missing or already declared -Numeric-edited PICTURE string is too large -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Unrecognized verb -IF....ELSE mismatch -Operand has wrong data-type, is not declared or '.' missing -Procedure not unique -Procedure name same as data-name -Name required -Wrong combination of data-types -Conditional statement not allowed in this context -Malformed subscript -ACCEPT/DISPLAY wrong or Communications syntax incorrect -Illegal syntax used with I-O verb -Invalid arithmetic statement -Invalid arithmetic expression -Compiler error; consult Technical Support -Invalid conditional expression -IF stmts nested too deep, or too many AFTERs in PERFORM stmt -Incorrect structure of PROCEDURE DIVISION -Reserved word missing or incorrectly used -Too many subscripts in one statement (internal buffer overflow) -Too many operands in one statement -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Inter-segment procedure name duplication -Unterminated condition at end of source -Operand has wrong data-type or not declared -Procedure name undeclared -INDEX data-name declared twice -Bad cursor control : illegal AT clause -KEY declaration missing or illegal -STATUS declaration missing -Bad STATUS record -Undefined inter-segment reference or error in ALTERed para -PROCEDURE DIVISION in error -USING parameter not declared in LINKAGE SECTION -USING parameter not level 01 or 77 -USING parameter used twice in parameter list -FD missing -Compiler error; consult Technical Support -Incorrect structure of PROCEDURE DIVISION -Compiler error; consult Technical Support -Compiler error; consult Technical Support -Too many operands in one statement diff --git a/emu/yaze/COBOL/COBOL.I51 b/emu/yaze/COBOL/COBOL.I51 deleted file mode 100644 index c7bf8fb..0000000 Binary files a/emu/yaze/COBOL/COBOL.I51 and /dev/null differ diff --git a/emu/yaze/COBOL/COBOL.I52 b/emu/yaze/COBOL/COBOL.I52 deleted file mode 100644 index 07953e3..0000000 Binary files a/emu/yaze/COBOL/COBOL.I52 and /dev/null differ diff --git a/emu/yaze/COBOL/COBOL.I53 b/emu/yaze/COBOL/COBOL.I53 deleted file mode 100644 index 2506bd7..0000000 Binary files a/emu/yaze/COBOL/COBOL.I53 and /dev/null differ diff --git a/emu/yaze/COBOL/COBOL.I56 b/emu/yaze/COBOL/COBOL.I56 deleted file mode 100644 index 4f1be47..0000000 Binary files a/emu/yaze/COBOL/COBOL.I56 and /dev/null differ diff --git a/emu/yaze/COBOL/COBOL.I59 b/emu/yaze/COBOL/COBOL.I59 deleted file mode 100644 index 2566943..0000000 Binary files a/emu/yaze/COBOL/COBOL.I59 and /dev/null differ diff --git a/emu/yaze/COBOL/COBOL.ISR b/emu/yaze/COBOL/COBOL.ISR deleted file mode 100644 index 6ad3a50..0000000 Binary files a/emu/yaze/COBOL/COBOL.ISR and /dev/null differ diff --git a/emu/yaze/COBOL/CONFIG b/emu/yaze/COBOL/CONFIG deleted file mode 100644 index ea03942..0000000 Binary files a/emu/yaze/COBOL/CONFIG and /dev/null differ diff --git a/emu/yaze/COBOL/IXSIO.INT b/emu/yaze/COBOL/IXSIO.INT deleted file mode 100644 index 38fc577..0000000 Binary files a/emu/yaze/COBOL/IXSIO.INT and /dev/null differ diff --git a/emu/yaze/COBOL/PI.CBL b/emu/yaze/COBOL/PI.CBL deleted file mode 100644 index 4a952fb..0000000 --- a/emu/yaze/COBOL/PI.CBL +++ /dev/null @@ -1,83 +0,0 @@ - IDENTIFICATION DIVISION. - PROGRAM-ID. PI-CALC. - AUTHOR. PF/TR. - * - ENVIRONMENT DIVISION. - CONFIGURATION SECTION. - OBJECT-COMPUTER. MDS-800. - SPECIAL-NAMES. CONSOLE IS CRT. - * - DATA DIVISION. - WORKING-STORAGE SECTION. - * - 01 SCREEN PIC X(1920). - * - 01 DI-1 REDEFINES SCREEN. - 02 FILLER PIC X(160). - 02 DI-TX1 PIC X(160). - 02 DI-TX2 PIC X(13). - 02 DI-TERM PIC X(15). - 02 FILLER PIC X(136). - 02 DI-TX3 PIC X(6). - 02 DI-PI PIC X(15). - 02 FILLER PIC X(1415). - * - 01 DI-2 REDEFINES SCREEN. - 02 FILLER PIC X(333). - 02 DI-TERM2 PIC X(15). - 02 FILLER PIC X(142). - 02 DI-PI2 PIC X(15). - 02 FILLER PIC X(1415). - * - 01 WORK-AREA. - 02 PI PIC S9V9(14). - 02 TERM PIC S9V9(14). - 02 W PIC S9V9(14). - 02 N PIC 9999. - 02 N1 PIC 9999. - 02 N2 PIC 9999. - 02 ED PIC -9.9(12). - * - 01 CONSTANTS. - 02 TX1 PIC X(17) VALUE "CALCULATION OF PI". - 02 TX2 PIC X(12) VALUE "NEXT TERM IS". - 02 TX3 PIC X(5) VALUE "PI IS". - * - PROCEDURE DIVISION. - LA-START. - DISPLAY SPACE. - MOVE SPACE TO SCREEN. - MOVE TX1 TO DI-TX1. - MOVE TX2 TO DI-TX2. - MOVE TX3 TO DI-TX3. - MOVE 0.5 TO ED. - MOVE ED TO DI-TERM. - MOVE 3 TO ED. - MOVE ED TO DI-PI. - DISPLAY DI-1. - MOVE 0.5 TO PI. - MOVE 0.5 TO TERM. - MOVE 3 TO N. - LOOP. - MOVE N TO N2. - SUBTRACT 2 FROM N2. - MULTIPLY N2 BY N2. - MULTIPLY N2 BY TERM. - MOVE N TO N1. - SUBTRACT 1 FROM N1. - MULTIPLY N BY N1. - MULTIPLY 4 BY N1. - DIVIDE N1 INTO TERM. - IF TERM < 0.0000000000001 THEN GO TO HALT. - ADD TERM TO PI. - MOVE PI TO W. - MULTIPLY 6 BY W. - MOVE W TO ED. - MOVE ED TO DI-PI2. - MOVE TERM TO ED. - MOVE ED TO DI-TERM2. - DISPLAY DI-2. - ADD 2 TO N. - IF N < 100 GO TO LOOP. - HALT. - STOP RUN. diff --git a/emu/yaze/COBOL/RUN.COM b/emu/yaze/COBOL/RUN.COM deleted file mode 100644 index 5a7d240..0000000 Binary files a/emu/yaze/COBOL/RUN.COM and /dev/null differ diff --git a/emu/yaze/COBOL/STOCK1.CBL b/emu/yaze/COBOL/STOCK1.CBL deleted file mode 100644 index 3a73fd3..0000000 --- a/emu/yaze/COBOL/STOCK1.CBL +++ /dev/null @@ -1,59 +0,0 @@ -000010 IDENTIFICATION DIVISION. -000020 PROGRAM-ID. STOCK-FILE-SET-UP. -000030 AUTHOR. MICRO FOCUS LTD. -000040 ENVIRONMENT DIVISION. -000050 CONFIGURATION SECTION. -000060 SOURCE-COMPUTER. MDS-800. -000070 OBJECT-COMPUTER. MDS-800. -000075 SPECIAL-NAMES. CONSOLE IS CRT. -000080 INPUT-OUTPUT SECTION. -000090 FILE-CONTROL. -000100 SELECT STOCK-FILE ASSIGN "STOCK.IT" -000110 ORGANIZATION INDEXED -000120 ACCESS DYNAMIC -000130 RECORD KEY STOCK-CODE. -000140 DATA DIVISION. -000150 FILE SECTION. -000160 FD STOCK-FILE; RECORD 32. -000170 01 STOCK-ITEM. -000180 02 STOCK-CODE PIC X(4). -000190 02 PRODUCT-DESC PIC X(24). -000200 02 UNIT-SIZE PIC 9(4). -000210 WORKING-STORAGE SECTION. -000220 01 SCREEN-HEADINGS. -000230 02 ASK-CODE PIC X(21) VALUE "STOCK CODE < >". -000240 02 FILLER PIC X(59). -000250 02 ASK-DESC PIC X(16) VALUE "DESCRIPTION <". -000260 02 SI-DESC PIC X(25) VALUE " >". -000270 02 FILLER PIC X(39). -000280 02 ASK-SIZE PIC X(21) VALUE "UNIT SIZE < >". -000290 01 ENTER-IT REDEFINES SCREEN-HEADINGS. -000300 02 FILLER PIC X(16). -000310 02 CRT-STOCK-CODE PIC X(4). -000320 02 FILLER PIC X(76). -000330 02 CRT-PROD-DESC PIC X(24). -000340 02 FILLER PIC X(56). -000350 02 CRT-UNIT-SIZE PIC 9(4). -000360 02 FILLER PIC X. -000370 PROCEDURE DIVISION. -000380 SR1. -000390 DISPLAY SPACE. -000400 OPEN I-O STOCK-FILE. -000410 DISPLAY SCREEN-HEADINGS. -000420 NORMAL-INPUT. -000430 MOVE SPACE TO ENTER-IT. -000440 DISPLAY ENTER-IT. -000450 CORRECT-ERROR. -000460 ACCEPT ENTER-IT. -000470 IF CRT-STOCK-CODE = SPACE GO TO END-IT. -000480 IF CRT-UNIT-SIZE NOT NUMERIC GO TO CORRECT-ERROR. -000490 MOVE CRT-PROD-DESC TO PRODUCT-DESC. -000500 MOVE CRT-UNIT-SIZE TO UNIT-SIZE. -000510 MOVE CRT-STOCK-CODE TO STOCK-CODE. -000520 WRITE STOCK-ITEM; INVALID GO TO CORRECT-ERROR. -000530 GO TO NORMAL-INPUT. -000540 END-IT. -000550 CLOSE STOCK-FILE. -000560 DISPLAY SPACE. -000570 DISPLAY "END OF PROGRAM". -000580 STOP RUN. diff --git a/emu/yaze/COBOL/STOCK2.CBL b/emu/yaze/COBOL/STOCK2.CBL deleted file mode 100644 index 46c1097..0000000 --- a/emu/yaze/COBOL/STOCK2.CBL +++ /dev/null @@ -1,119 +0,0 @@ - IDENTIFICATION DIVISION. - PROGRAM-ID. GOODS-IN. - AUTHOR. MICRO FOCUS LTD. - ENVIRONMENT DIVISION. - CONFIGURATION SECTION. - SOURCE-COMPUTER. MDS-800. - OBJECT-COMPUTER. MDS-800. - SPECIAL-NAMES. CONSOLE IS CRT. - INPUT-OUTPUT SECTION. - FILE-CONTROL. - SELECT STOCK-FILE ASSIGN "STOCK.IT" - ORGANIZATION INDEXED - ACCESS DYNAMIC - RECORD KEY STOCK-CODE. - SELECT TRANS-FILE - ASSIGN "STOCK.TRS" - ORGANIZATION SEQUENTIAL. - / - DATA DIVISION. - FILE SECTION. - FD STOCK-FILE; RECORD 32. - 01 STOCK-ITEM. - 02 STOCK-CODE PIC X(4). - 02 STOCK-DESCRIPT PIC X(24). - 02 UNIT-SIZE PIC 9(4). - FD TRANS-FILE; RECORD 30. - 01 TRANS-RECORD. - 02 TRAN-NO PIC 9(4). - 02 TF-STOCK-CODE PIC X(4). - 02 TF-QUANTITY PIC 9(8). - 02 TF-ORDER-NO PIC X(6). - 02 TF-DATE PIC X(8). - WORKING-STORAGE SECTION. - 01 STOCK-INWARD-FORM. - 02 PRG-TITLE PIC X(20) VALUE " GOODS INWARD". - 02 FILLER PIC X(140). - 02 CODE-HDNG PIC X(23) VALUE "STOCK CODE < >". - 02 FILLER PIC X(57). - 02 ORDER-NO-HDNG PIC X(23) VALUE "ORDER NO < >". - 02 FILLER PIC X(57). - 02 DATE-HDNG PIC X(24) VALUE "DELIVERY DATE MM/DD/YY". - 02 FILLER PIC X(56). - 02 UNITS-HDNG PIC X(23) VALUE "NO OF UNITS < >". - 01 STOCK-RECEIPT REDEFINES STOCK-INWARD-FORM. - 02 FILLER PIC X(178). - 02 SR-STOCK-CODE PIC X(4). - 02 FILLER PIC X(74). - 02 SR-ORDER-NO PIC X(6). - 02 FILLER PIC X(73). - 02 SR-DATE. - 04 SR-MM PIC 99. - 04 FILLER PIC X. - 04 SR-DD PIC 99. - 04 FILLER PIC X. - 04 SR-YY PIC 99. - 02 FILLER PIC X(75). - 02 SR-NO-OF-UNITS PIC 9(4). - 01 CONFIRM-MSG REDEFINES STOCK-INWARD-FORM. - 02 FILLER PIC X(184). - 02 CM-STOCK-DESCRIPT PIC X(24). - 02 FILLER PIC X(352). - 02 UNIT-SIZE-HDNG PIC X(18). - 02 CM-UNIT-SIZE PIC 9(4). - 02 FILLER PIC X(58). - 02 QUANTITY-HDNG PIC X(14). - 02 CM-QUANTITY PIC 9(8). - 02 FILLER PIC X(58). - 02 OK-HDNG PIC X(3). - 02 CM-Y-OR-N PIC X. - / - PROCEDURE DIVISION. - START-PROC. - OPEN I-O STOCK-FILE. - OPEN OUTPUT TRANS-FILE. - DISPLAY SPACE. - MOVE 0 TO TRAN-NO. - DISPLAY STOCK-INWARD-FORM. - GET-INPUT. - ACCEPT STOCK-RECEIPT. - IF SR-STOCK-CODE = SPACE GO TO END-IT. - IF SR-NO-OF-UNITS NOT NUMERIC GO TO INVALID-ENTRY. - MOVE SR-STOCK-CODE TO STOCK-CODE. - READ STOCK-FILE; INVALID GO TO INVALID-CODE. - *VALID ENTRY, CALCULATE AND DISPLAY TOTAL QUANTITY IN TO CONFIRM - MOVE STOCK-DESCRIPT TO CM-STOCK-DESCRIPT. - MOVE "UNIT SIZE" TO UNIT-SIZE-HDNG. - MOVE UNIT-SIZE TO CM-UNIT-SIZE. - MOVE "QUANTITY IN" TO QUANTITY-HDNG. - MOVE UNIT-SIZE TO TF-QUANTITY. - MULTIPLY SR-NO-OF-UNITS BY TF-QUANTITY. - MOVE TF-QUANTITY TO CM-QUANTITY. - MOVE "OK?" TO OK-HDNG. - DISPLAY CONFIRM-MSG. - ACCEPT CM-Y-OR-N AT 1004. - IF CM-Y-OR-N = "Y" PERFORM WRITE-TRANS. - *CLEAR INPUT DATA ON SCREEN - MOVE SPACE TO CONFIRM-MSG. - MOVE "MM/DD/YY" TO SR-DATE. - DISPLAY STOCK-RECEIPT. - DISPLAY CONFIRM-MSG. - GO TO GET-INPUT. - WRITE-TRANS. - ADD 1 TO TRAN-NO. - MOVE STOCK-CODE TO TF-STOCK-CODE. - MOVE SR-ORDER-NO TO TF-ORDER-NO. - MOVE GET-INPUT TO TF-DATE. - WRITE TRANS-RECORD. - INVALID-ENTRY. - DISPLAY "NON-NUMERIC NO OF UNITS" AT 0325. - GO TO GET-INPUT. - INVALID-CODE. - DISPLAY "INVALID CODE " AT 0325. - GO TO GET-INPUT. - END-IT. - CLOSE STOCK-FILE. - CLOSE TRANS-FILE. - DISPLAY SPACE. - DISPLAY "END OF PROGRAM". - STOP RUN. diff --git a/emu/yaze/COBOL/TESTCALL.CBL b/emu/yaze/COBOL/TESTCALL.CBL deleted file mode 100644 index ddc74b8..0000000 --- a/emu/yaze/COBOL/TESTCALL.CBL +++ /dev/null @@ -1,19 +0,0 @@ -000000****************************************************************** -000000* -000000* Program "Testcall" to demonstrate L/II COBOL calling mechanism -000000* -000000****************************************************************** -000000 Working-storage section. -000000 01 progname pic x(4). -000000 01 message-size pic 9(2) comp value 60. -000000 01 message-text pic x(60) value -000000 "This message is sent via a called program to the screen.". -000000 Procedure division. -000000 move "call" to progname. -000000 call progname using message-size,message-text -000000 overflow display "call overflowed". -000000****************************************************************** -000000* -000000* End of demonstration program "Testcall" -000000* -000000****************************************************************** diff --git a/emu/yaze/COBOL/TESTCALL.INT b/emu/yaze/COBOL/TESTCALL.INT deleted file mode 100644 index 83e25e3..0000000 Binary files a/emu/yaze/COBOL/TESTCALL.INT and /dev/null differ diff --git a/emu/yaze/disk b/emu/yaze/disk deleted file mode 100644 index eb25f82..0000000 Binary files a/emu/yaze/disk and /dev/null differ diff --git a/emu/yaze/transfer/DDT.COM b/emu/yaze/transfer/DDT.COM deleted file mode 100644 index 70e4ebf..0000000 Binary files a/emu/yaze/transfer/DDT.COM and /dev/null differ diff --git a/emu/yaze/transfer/DUMP.COM b/emu/yaze/transfer/DUMP.COM deleted file mode 100644 index 03a77c3..0000000 Binary files a/emu/yaze/transfer/DUMP.COM and /dev/null differ diff --git a/emu/yaze/transfer/PIP.COM b/emu/yaze/transfer/PIP.COM deleted file mode 100644 index 4b2ce4b..0000000 Binary files a/emu/yaze/transfer/PIP.COM and /dev/null differ diff --git a/emu/yaze/transfer/STAT.COM b/emu/yaze/transfer/STAT.COM deleted file mode 100644 index 1de359f..0000000 Binary files a/emu/yaze/transfer/STAT.COM and /dev/null differ diff --git a/emu/yaze/transfer/SUBMIT.COM b/emu/yaze/transfer/SUBMIT.COM deleted file mode 100644 index 2e78882..0000000 Binary files a/emu/yaze/transfer/SUBMIT.COM and /dev/null differ diff --git a/emu/yaze/transfer/SYS.COM b/emu/yaze/transfer/SYS.COM deleted file mode 100644 index b56e650..0000000 Binary files a/emu/yaze/transfer/SYS.COM and /dev/null differ diff --git a/emu/yaze/yaze.sh b/emu/yaze/yaze.sh deleted file mode 100755 index 665be95..0000000 --- a/emu/yaze/yaze.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -yaze -v \ No newline at end of file diff --git a/emu/yaze/yaze_test.sh b/emu/yaze/yaze_test.sh deleted file mode 100755 index 0bf8838..0000000 --- a/emu/yaze/yaze_test.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -cd /usr/local/src/yaze-1.14/ -yaze -v \ No newline at end of file diff --git a/emu/z80pack-1.9/cpmsim/cpm2 b/emu/z80pack-1.9/cpmsim/cpm2 deleted file mode 100755 index a394240..0000000 --- a/emu/z80pack-1.9/cpmsim/cpm2 +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -rm -f disks/drive[ab].cpm -ln disks/library/cpm2-1.dsk disks/drivea.cpm -ln disks/library/cpm2-2.dsk disks/driveb.cpm -cpmsim diff --git a/emu/z80pack-1.9/cpmsim/cpm3 b/emu/z80pack-1.9/cpmsim/cpm3 deleted file mode 100755 index 7ffc0c3..0000000 --- a/emu/z80pack-1.9/cpmsim/cpm3 +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -rm -f disks/drive[ab].cpm -ln disks/library/cpm3-1.dsk disks/drivea.cpm -ln disks/library/cpm3-2.dsk disks/driveb.cpm -cpmsim diff --git a/emu/z80pack-1.9/cpmsim/disks/drivea.cpm b/emu/z80pack-1.9/cpmsim/disks/drivea.cpm deleted file mode 100644 index 290f30b..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/drivea.cpm and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/driveb.cpm b/emu/z80pack-1.9/cpmsim/disks/driveb.cpm deleted file mode 100644 index f7ad273..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/driveb.cpm and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/drivei.cpm b/emu/z80pack-1.9/cpmsim/disks/drivei.cpm deleted file mode 100644 index b8c067d..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/drivei.cpm and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/library/cpm2-1.dsk b/emu/z80pack-1.9/cpmsim/disks/library/cpm2-1.dsk deleted file mode 100644 index 290f30b..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/library/cpm2-1.dsk and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/library/cpm2-2.dsk b/emu/z80pack-1.9/cpmsim/disks/library/cpm2-2.dsk deleted file mode 100644 index f7ad273..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/library/cpm2-2.dsk and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/library/cpm3-1.dsk b/emu/z80pack-1.9/cpmsim/disks/library/cpm3-1.dsk deleted file mode 100644 index aac653d..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/library/cpm3-1.dsk and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/library/cpm3-2.dsk b/emu/z80pack-1.9/cpmsim/disks/library/cpm3-2.dsk deleted file mode 100644 index 8a23d92..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/library/cpm3-2.dsk and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/library/hd-tools.dsk b/emu/z80pack-1.9/cpmsim/disks/library/hd-tools.dsk deleted file mode 100644 index b8c067d..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/library/hd-tools.dsk and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/library/mpm-1.dsk b/emu/z80pack-1.9/cpmsim/disks/library/mpm-1.dsk deleted file mode 100644 index 6a6a8e6..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/library/mpm-1.dsk and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/disks/library/mpm-2.dsk b/emu/z80pack-1.9/cpmsim/disks/library/mpm-2.dsk deleted file mode 100644 index af98507..0000000 Binary files a/emu/z80pack-1.9/cpmsim/disks/library/mpm-2.dsk and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/mpm b/emu/z80pack-1.9/cpmsim/mpm deleted file mode 100755 index 9735291..0000000 --- a/emu/z80pack-1.9/cpmsim/mpm +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -rm -f disks/drive[ab].cpm -ln disks/library/mpm-1.dsk disks/drivea.cpm -ln disks/library/mpm-2.dsk disks/driveb.cpm -cpmsim -h diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/Makefile b/emu/z80pack-1.9/cpmsim/srccpm2/Makefile deleted file mode 100644 index 057f4f1..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm2/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -CFLAGS= -O -s - -all: format putsys bin2hex send receive bios.bin boot.bin - @echo "done" - -format: format.c - cc $(CFLAGS) -o format format.c - cp format .. - -putsys: putsys.c - cc $(CFLAGS) -o putsys putsys.c - -bin2hex: bin2hex.c - cc $(CFLAGS) -o bin2hex bin2hex.c - cp bin2hex .. - -send: send.c - cc $(CFLAGS) -o send send.c - cp send .. - -receive: receive.c - cc $(CFLAGS) -o receive receive.c - cp receive .. - -bios.bin: bios.asm - z80asm -vl -sn -x bios.asm - -boot.bin: boot.asm - z80asm -vl -sn boot.asm - -clean: - rm -f *.lis bios.bin boot.bin format putsys bin2hex receive send diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/bin2hex.c b/emu/z80pack-1.9/cpmsim/srccpm2/bin2hex.c deleted file mode 100644 index e0ba19c..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm2/bin2hex.c +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void help(char *name) -{ - printf("%s - BINARY to Intel HEX file convertor version 1.00\n"\ - "(c)BCL Vysoke Myto 2001 (benedikt@lphard.cz)\n\n",name); - printf("Usage: %s [-option] binfile hexfile\n"\ - " -l Bytes to read from binary file\n"\ - " -i Binary file starting offset\n"\ - " -o Output file offset (where HEX data starts)\n"\ - " -t Exclude EOF record\n"\ - " -a Append to end of existing HEX file\n"\ - " -q Quiet mode (no statistics are printed)\n", name); -} - -int main(int argc,char *argv[])/*Main routine*/ -{ - char *ifile = NULL; - char *ofile = NULL; - char c; - FILE *inp, *outp; - int ch,csum; - int ofsa = 0; - int cnt = 0; - struct stat statbuf; - long int foffset = 0; - long int fsize = 0; - long int fsub; - long int fpoint = 0; - long int adrs = 0; - unsigned char quiet = 0; - unsigned char eofrec = 0; - unsigned char append = 0; - - opterr = 0; //print error message if unknown option - - while ((c = getopt (argc, argv, "l:i:o:taqv")) != -1) - switch (c) { - case 'l': - fsize = atol(optarg); - break; - case 'i': - foffset = atol(optarg); - break; - case 'o': - adrs = atol(optarg); - break; - case 't': - eofrec = 1; - break; - case 'a': - append = 1; - break; - case 'q': - quiet = 1; - break; - case 'v': - printf("%s - BINARY to Intel HEX file convertor version 1.00\n"\ - "(c)BCL Vysoke Myto 2001 (benedikt@lphard.cz)\n",argv[0]); - return 0; - case '?': - help (argv[0]); - return 1; - } - - if ((argc - optind) != 2) { - printf("ERROR: Missing input/output file.\n"); - help(argv[0]); - return 1; - } - ifile = argv[optind]; - ofile = argv[optind+1]; - - /*Open file check*/ - if((inp = fopen(ifile, "rb")) == NULL){ - printf("ERROR: Cannot open input file.\n"); - return 1; - } - fseek (inp, foffset, SEEK_SET); - - if (append == 0) { - if((outp = fopen(ofile, "wt")) == NULL){ - printf("ERROR: Cannot open output file.\n"); - return 1; - } - } else { - if((outp = fopen(ofile, "at")) == NULL){ - printf("ERROR: Cannot re-open output file.\n"); - return 1; - } - fseek (outp, 0, SEEK_END); - } - - fstat(fileno(inp), &statbuf); - if (quiet == 0) printf("Input file size=%ld\n",statbuf.st_size); - if (foffset > statbuf.st_size) { - printf("ERROR: Input offset > input file length\n"); - } - if ((fsize == 0) || (fsize > (statbuf.st_size - foffset))) - fsize = statbuf.st_size - foffset; - -// fprintf(outp,":020000020000FC\n");/*Start Header*/ - fsub = fsize - fpoint; - if (fsub > 0x20) { - fprintf(outp,":20%04X00",adrs);/*Hex line Header*/ - csum = 0x20 + (adrs>>8) + (adrs & 0xFF); - adrs += 0x20; - } - else { - fprintf(outp, ":%02X%04X00", fsub,adrs);/*Hex line Header*/ - csum = fsub + (adrs>>8) + (adrs & 0xFF); - adrs += fsub; - } - while (fsub > 0){ - ch = fgetc(inp); - fprintf(outp,"%02X",ch);/*Put data*/ - cnt++; fpoint++; - fsub = fsize - fpoint; - csum = ch + csum; - if((fsub == 0)||(cnt == 0x20)){ - cnt = 0; csum = 0xFF & (~csum + 1); - fprintf(outp,"%02X\n",csum);/*Put checksum*/ - if(fsub == 0) break; - if(adrs > 0xFFFF){ - ofsa = 0x1000 + ofsa; - adrs = 0; - fprintf(outp,":02000002%04X",ofsa);/*Change offset address*/ - csum = 0x02 + 0x02 + (ofsa>>8) + (ofsa & 0xFF); - csum = 0xFF & (~csum + 1); - fprintf(outp,"%02X\n", csum); - } - adrs = 0xFFFF & adrs; - if (fsub > 0x20) { - fprintf(outp,":20%04X00",adrs);/*Next Hex line Header*/ - csum = 0x20 + (adrs>>8) + (adrs & 0xFF); - adrs += 0x20; - } - else { - if(fsub > 0){ - fprintf(outp, ":%02X%04X00", fsub,adrs);/*Next Hex line Header*/ - csum = fsub + (adrs>>8) + (adrs & 0xFF); - adrs += fsub; - } - } - } - } - if (eofrec == 0) fprintf(outp,":00000001FF\n");/*End footer*/ - fflush (outp); - - fstat(fileno(outp), &statbuf); - if (quiet == 0) printf("Output file size=%ld\n",statbuf.st_size); - - fclose(inp); - fclose(outp); - return 0; -} diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/bios.asm b/emu/z80pack-1.9/cpmsim/srccpm2/bios.asm deleted file mode 100644 index 2ef7bfa..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm2/bios.asm +++ /dev/null @@ -1,375 +0,0 @@ -; CBIOS for Z80-Simulator -; -; Copyright (C) 1988-2006 by Udo Munk -; -MSIZE EQU 64 ;cp/m version memory size in kilobytes -; -; "bias" is address offset from 3400H for memory systems -; than 16K (referred to as "b" throughout the text). -; -BIAS EQU (MSIZE-20)*1024 -CCP EQU 3400H+BIAS ;base of ccp -BDOS EQU CCP+806H ;base of bdos -BIOS EQU CCP+1600H ;base of bios -CDISK EQU 0004H ;current disk number 0=A,...,15=P -IOBYTE EQU 0003H ;intel i/o byte -; -; I/O ports -; -CONSTA EQU 0 ;console status port -CONDAT EQU 1 ;console data port -PRTSTA EQU 2 ;printer status port -PRTDAT EQU 3 ;printer data port -AUXDAT EQU 5 ;auxiliary data port -FDCD EQU 10 ;fdc-port: # of drive -FDCT EQU 11 ;fdc-port: # of track -FDCS EQU 12 ;fdc-port: # of sector -FDCOP EQU 13 ;fdc-port: command -FDCST EQU 14 ;fdc-port: status -DMAL EQU 15 ;dma-port: dma address low -DMAH EQU 16 ;dma-port: dma address high -; - ORG BIOS ;origin of this program -NSECTS EQU (BIOS-CCP)/128 ;warm start sector count -; -; jump vector for individual subroutines -; - JP BOOT ;cold start -WBOOTE: JP WBOOT ;warm start - JP CONST ;console status - JP CONIN ;console character in - JP CONOUT ;console character out - JP LIST ;list character out - JP PUNCH ;punch character out - JP READER ;reader character out - JP HOME ;move head to home position - JP SELDSK ;select disk - JP SETTRK ;set track number - JP SETSEC ;set sector number - JP SETDMA ;set dma address - JP READ ;read disk - JP WRITE ;write disk - JP LISTST ;return list status - JP SECTRAN ;sector translate -; -; fixed data tables for four-drive standard -; IBM-compatible 8" disks -; -; disk parameter header for disk 00 -DPBASE: DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK00,ALL00 -; disk parameter header for disk 01 - DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK01,ALL01 -; disk parameter header for disk 02 - DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK02,ALL02 -; disk parameter header for disk 03 - DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK03,ALL03 -; -; sector translate vector for the IBM 8" disks -; -TRANS: DEFB 1,7,13,19 ;sectors 1,2,3,4 - DEFB 25,5,11,17 ;sectors 5,6,7,8 - DEFB 23,3,9,15 ;sectors 9,10,11,12 - DEFB 21,2,8,14 ;sectors 13,14,15,16 - DEFB 20,26,6,12 ;sectors 17,18,19,20 - DEFB 18,24,4,10 ;sectors 21,22,23,24 - DEFB 16,22 ;sectors 25,26 -; -; disk parameter block, common to all IBM 8" disks -; -DPBLK: DEFW 26 ;sectors per track - DEFB 3 ;block shift factor - DEFB 7 ;block mask - DEFB 0 ;extent mask - DEFW 242 ;disk size-1 - DEFW 63 ;directory max - DEFB 192 ;alloc 0 - DEFB 0 ;alloc 1 - DEFW 16 ;check size - DEFW 2 ;track offset -; -; fixed data tables for 4MB harddisk -; -; disk parameter header -HDBASE: DEFW HDTRA,0000H - DEFW 0000H,0000H - DEFW DIRBF,HDBLK - DEFW CHKHD,ALLHD -; -; sector translate vector for the hardisk -; -HDTRA: DEFB 1,2,3,4,5,6,7,8,9,10 - DEFB 11,12,13,14,15,16,17,18,19,20 - DEFB 21,22,23,24,25,26,27,28,29,30 - DEFB 31,32,33,34,35,36,37,38,39,40 - DEFB 41,42,43,44,45,46,47,48,49,50 - DEFB 51,52,53,54,55,56,57,58,59,60 - DEFB 61,62,63,64,65,66,67,68,69,70 - DEFB 71,72,73,74,75,76,77,78,79,80 - DEFB 81,82,83,84,85,86,87,88,89,90 - DEFB 91,92,93,94,95,96,97,98,99,100 - DEFB 101,102,103,104,105,106,107,108,109,110 - DEFB 111,112,113,114,115,116,117,118,119,120 - DEFB 121,122,123,124,125,126,127,128 -; -; disk parameter block for harddisk -; -HDBLK: DEFW 128 ;sectors per track - DEFB 4 ;block shift factor - DEFB 15 ;block mask - DEFB 0 ;extent mask - DEFW 2039 ;disk size-1 - DEFW 1023 ;directory max - DEFB 255 ;alloc 0 - DEFB 255 ;alloc 1 - DEFW 0 ;check size - DEFW 0 ;track offset -; -; signon message -; -SIGNON: DEFM '64K CP/M Vers. 2.2 (CBIOS V1.1 for Z80SIM, ' - DEFM 'Copyright 1988-2006 by Udo Munk)' - DEFB 13,10,0 -; -; end of fixed tables -; -; individual subroutines to perform each function -; simplest case is to just perform parameter initialization -; -BOOT: LD SP,80H ;use space below buffer for stack - LD HL,SIGNON ;print message -BOOTL: LD A,(HL) - OR A - JP Z,BOOTC - LD C,A - CALL CONOUT - INC HL - JP BOOTL -BOOTC: XOR A ;zero in the accum - LD (IOBYTE),A ;clear the iobyte - LD (CDISK),A ;select disk zero - JP GOCPM ;initialize and go to cp/m -; -; simplest case is to read the disk until all sectors loaded -; -WBOOT: LD SP,80H ;use space below buffer for stack - LD C,0 ;select disk 0 - CALL SELDSK - CALL HOME ;go to track 00 -; - LD B,NSECTS ;b counts # of sectors to load - LD C,0 ;c has the current track number - LD D,2 ;d has the next sector to read -; note that we begin by reading track 0, sector 2 since sector 1 -; contains the cold start loader, which is skipped in a warm start - LD HL,CCP ;base of cp/m (initial load point) -LOAD1: ;load one more sector - PUSH BC ;save sector count, current track - PUSH DE ;save next sector to read - PUSH HL ;save dma address - LD C,D ;get sector address to register c - CALL SETSEC ;set sector address from register c - POP BC ;recall dma address to b,c - PUSH BC ;replace on stack for later recall - CALL SETDMA ;set dma address from b,c -; drive set to 0, track set, sector set, dma address set - CALL READ - CP 00H ;any errors? - JP NZ,WBOOT ;retry the entire boot if an error occurs -; no error, move to next sector - POP HL ;recall dma address - LD DE,128 ;dma=dma+128 - ADD HL,DE ;new dma address is in h,l - POP DE ;recall sector address - POP BC ;recall number of sectors remaining, and current trk - DEC B ;sectors=sectors-1 - JP Z,GOCPM ;transfer to cp/m if all have been loaded -; more sectors remain to load, check for track change - INC D - LD A,D ;sector=27?, if so, change tracks - CP 27 - JP C,LOAD1 ;carry generated if sector<27 -; end of current track, go to next track - LD D,1 ;begin with first sector of next track - INC C ;track=track+1 -; save register state, and change tracks - CALL SETTRK ;track address set from register c - JP LOAD1 ;for another sector -; end of load operation, set parameters and go to cp/m -GOCPM: - LD A,0C3H ;c3 is a jmp instruction - LD (0),A ;for jmp to wboot - LD HL,WBOOTE ;wboot entry point - LD (1),HL ;set address field for jmp at 0 -; - LD (5),A ;for jmp to bdos - LD HL,BDOS ;bdos entry point - LD (6),HL ;address field of jump at 5 to bdos -; - LD BC,80H ;default dma address is 80h - CALL SETDMA -; - EI ;enable the interrupt system - LD A,(CDISK) ;get current disk number - LD C,A ;send to the ccp - JP CCP ;go to cp/m for further processing -; -; -; simple i/o handlers -; -; console status, return 0ffh if character ready, 00h if not -; -CONST: IN A,(CONSTA) ;get console status - RET -; -; console character into register a -; -CONIN: IN A,(CONDAT) ;get character from console - RET -; -; console character output from register c -; -CONOUT: LD A,C ;get to accumulator - OUT (CONDAT),A ;send character to console - RET -; -; list character from register c -; -LIST: LD A,C ;character to register a - OUT (PRTDAT),A - RET -; -; return list status (0 if not ready, 0xff if ready) -; -LISTST: IN A,(PRTSTA) - RET -; -; punch character from register c -; -PUNCH: LD A,C ;character to register a - OUT (AUXDAT),A - RET -; -; read character into register a from reader device -; -READER: IN A,(AUXDAT) - RET -; -; -; i/o drivers for the disk follow -; -; move to the track 00 position of current drive -; translate this call into a settrk call with parameter 00 -; -HOME: LD C,0 ;select track 0 - JP SETTRK ;we will move to 00 on first read/write -; -; select disk given by register C -; -SELDSK: LD HL,0000H ;error return code - LD A,C - CP 4 ;must be between 0 and 3 - JR NC,SELHD ;no carry if 4,5,... -; disk number is in the proper range -; compute proper disk parameter header address - OUT (FDCD),A ;selekt disk drive - LD L,A ;L=disk number 0,1,2,3 - ADD HL,HL ;*2 - ADD HL,HL ;*4 - ADD HL,HL ;*8 - ADD HL,HL ;*16 (size of each header) - LD DE,DPBASE - ADD HL,DE ;HL=.dpbase(diskno*16) - RET -SELHD: CP 8 ;select the harddisk? - RET NZ ;no, error - OUT (FDCD),A ;select disk drive - LD HL,HDBASE ;HL=hdbase for harddisk - RET -; -; set track given by register c -; -SETTRK: LD A,C - OUT (FDCT),A - RET -; -; set sector given by register c -; -SETSEC: LD A,C - OUT (FDCS),A - RET -; -; translate the sector given by BC using the -; translate table given by DE -; -SECTRAN: - EX DE,HL ;HL=.trans - ADD HL,BC ;HL=.trans(sector) - LD L,(HL) ;L = trans(sector) - LD H,0 ;HL= trans(sector) - RET ;with value in HL -; -; set dma address given by registers b and c -; -SETDMA: LD A,C ;low order address - OUT (DMAL),A - LD A,B ;high order address - OUT (DMAH),A ;in dma - RET -; -; perform read operation -; -READ: XOR A ;read command -> A - JP WAITIO ;to perform the actual i/o -; -; perform a write operation -; -WRITE: LD A,1 ;write command -> A -; -; enter here from read and write to perform the actual i/o -; operation. return a 00h in register a if the operation completes -; properly, and 01h if an error occurs during the read or write -; -; in this case, we have saved the disk number in 'diskno' (0-3) -; the track number in 'track' (0-76) -; the sector number in 'sector' (1-26) -; the dma address in 'dmaad' (0-65535) -; -WAITIO: OUT (FDCOP),A ;start i/o operation - IN A,(FDCST) ;status of i/o operation -> A - RET -; -; the remainder of the CBIOS is reserved uninitialized -; data area, and does not need to be a part of the -; system memory image (the space must be available, -; however, between "begdat" and "enddat"). -; -; scratch ram area for BDOS use -; -BEGDAT EQU $ ;beginning of data area -DIRBF: DEFS 128 ;scratch directory area -ALL00: DEFS 31 ;allocation vector 0 -ALL01: DEFS 31 ;allocation vector 1 -ALL02: DEFS 31 ;allocation vector 2 -ALL03: DEFS 31 ;allocation vector 3 -ALLHD: DEFS 255 ;allocation vector harddisk -CHK00: DEFS 16 ;check vector 0 -CHK01: DEFS 16 ;check vector 1 -CHK02: DEFS 16 ;check vector 2 -CHK03: DEFS 16 ;check vector 3 -CHKHD: DEFS 0 ;check vector harddisk -; -ENDDAT EQU $ ;end of data area -DATSIZ EQU $-BEGDAT ;size of data area - END ;of BIOS diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/boot.asm b/emu/z80pack-1.9/cpmsim/srccpm2/boot.asm deleted file mode 100644 index 50b6a6b..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm2/boot.asm +++ /dev/null @@ -1,74 +0,0 @@ -; CP/M 2.2 boot-loader for Z80-Simulator -; -; Copyright (C) 1988 by Udo Munk -; - ORG 0 ; mem base of boot -; -MSIZE EQU 64 ; mem size in kbytes -; -BIAS EQU (MSIZE-20)*1024 ; offset from 20k system -CCP EQU 3400H+BIAS ; base of the ccp -BIOS EQU CCP+1600H ; base of the bios -BIOSL EQU 0300H ; length of the bios -BOOT EQU BIOS -SIZE EQU BIOS+BIOSL-CCP ; size of cp/m system -SECTS EQU SIZE/128 ; # of sectors to load -; -; I/O ports -; -DRIVE EQU 10 ; fdc-port: # of drive -TRACK EQU 11 ; fdc-port: # of track -SECTOR EQU 12 ; fdc-port: # of sector -FDCOP EQU 13 ; fdc-port: command -FDCST EQU 14 ; fdc-port: status -DMAL EQU 15 ; dma-port: dma address low -DMAH EQU 16 ; dma-port: dma address high -; -; begin the load operation -; -COLD: LD BC,2 ; b=track 0, c=sector 2 - LD D,SECTS ; d=# sectors to load - LD HL,CCP ; base transfer address - LD A,0 ; select drive A - OUT (DRIVE),A -; -; load the next sector -; -LSECT: LD A,B ; set track - OUT (TRACK),A - LD A,C ; set sector - OUT (SECTOR),A - LD A,L ; set dma address low - OUT (DMAL),A - LD A,H ; set dma adress high - OUT (DMAH),A - XOR A ; read sector - OUT (FDCOP),A - IN A,(FDCST) ; get status of fdc - CP 0 ; read successful ? - JP Z,CONT ; yes, continue - HALT ; no, halt cpu -CONT: - ; go to next sector if load is incomplete - DEC D ; sects=sects-1 - JP Z,BOOT ; head for the bios -; -; more sectors to load -; -; we aren't using a stack, so use as scratch register -; to hold the load address increment -; - LD SP,128 ; 128 bytes per sector - ADD HL,SP ; = + 128 -; - INC C ; sector = sector + 1 - LD A,C - CP 27 ; last sector of track ? - JP C,LSECT ; no, go read another -; -; end of track, increment to next track -; - LD C,1 ; sector = 1 - INC B ; track = track + 1 - JP LSECT ; for another group - END ; of boot loader diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/cpm.bin b/emu/z80pack-1.9/cpmsim/srccpm2/cpm.bin deleted file mode 100644 index e18110d..0000000 Binary files a/emu/z80pack-1.9/cpmsim/srccpm2/cpm.bin and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/format.c b/emu/z80pack-1.9/cpmsim/srccpm2/format.c deleted file mode 100644 index d118e89..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm2/format.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * CP/M 2.2 Formats a simulated Disk Drive - * - * Copyright (C) 1988-2006 by Udo Munk - * - * History: - * 29-APR-88 Development on TARGON/35 with AT&T Unix System V.3 - * 11-MAR-93 comments in english - * 01-OCT-06 modified to compile on modern POSIX OS's - * 18-NOV-06 added a second harddisk - */ - -#include -#include -#include -#include -#include - -#define TRACK 77 -#define SECTOR 26 -#define HDTRACK 255 -#define HDSECTOR 128 - -/* - * This program is able to format the following disk formats: - * - * drive A: 8" IBM SS,SD - * drive B: 8" IBM SS,SD - * drive C: 8" IBM SS,SD - * drive D: 8" IBM SS,SD - * drive I: 4MB harddisk - * drive J: 4MB harddisk - */ -int main(int argc, char *argv[]) -{ - register int i; - int fd; - char drive; - static unsigned char sector[128]; - static char fn[] = "disks/drive?.cpm"; - static char usage[] = "usage: format a | b | c | d | i | j"; - - if (argc != 2) { - puts(usage); - exit(1); - } - i = *argv[1]; - if (argc != 2 || - (i != 'a' && i != 'b' && i != 'c' && i != 'd' && i != 'i' - && i != 'j')) { - puts(usage); - exit(1); - } - fn[11] = drive = (char) i; - memset((char *) sector, 0xe5, 128); - if ((fd = creat(fn, 0644)) == -1) { - perror("disk file"); - exit(1); - } - if (drive != 'i' && drive != 'j') { - for (i = 0; i < TRACK * SECTOR; i++) - write(fd, (char *) sector, 128); - } else { - for (i = 0; i < HDTRACK * HDSECTOR; i++) - write(fd, (char *) sector, 128); - } - close(fd); - return(0); -} diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/putsys.c b/emu/z80pack-1.9/cpmsim/srccpm2/putsys.c deleted file mode 100644 index a9df513..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm2/putsys.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Write the CP/M systemfiles to system tracks of drive A - * - * Copyright (C) 1988-2006 by Udo Munk - * - * History: - * 29-APR-88 Development on TARGON/35 with AT&T Unix System V.3 - * 11-MAR-93 comments in english and ported to COHERENT 4.0 - * 02-OCT-06 modified to compile on modern POSIX OS's - */ - -#include -#include -#include -#include -#include - -/* - * This program writes the CP/M 2.2 OS from the following files - * onto the system tracks of the boot disk (drivea.cpm): - * - * boot loader boot.bin (Mostek binary format) - * CCP cpm.bin (binary format) - * BDOS cpm.bin (binary format) - * BIOS bios.bin (Mostek binary format) - */ -int main(void) -{ - unsigned char header[3]; - unsigned char sector[128]; - register int i; - int fd, drivea, readed; - - /* open drive A for writing */ - if ((drivea = open("../disks/drivea.cpm", O_WRONLY)) == -1) { - perror("file ../disks/drivea.cpm"); - exit(1); - } - /* open boot loader (boot.bin) for reading */ - if ((fd = open("boot.bin", O_RDONLY)) == -1) { - perror("file boot.bin"); - exit(1); - } - /* read and check 3 byte header */ - if ((readed = read(fd, (char *) header, 3)) != 3) { - perror("file boot.bin"); - exit(1); - } - if (header[0] != 0xff || header[1] != 0 || header[2] != 0) { - puts("start adress of boot.bin <> 0"); - exit(0); - } - /* read boot loader */ - memset((char *) sector, 0, 128); - read(fd, (char *) sector, 128); - close(fd); - /* and write it to disk in drive A */ - write(drivea, (char *) sector, 128); - /* open CP/M system file (cpm.bin) for reading */ - if ((fd = open("cpm.bin", O_RDONLY)) == -1) { - perror("file cpm.bin"); - exit(1); - } - /* position to CCP in cpm.bin, needed if created with SAVE or similar */ - lseek(fd, (long) 17 * 128, 0); - /* read CCP and BDOS from cpm.bin and write them to disk in drive A */ - for (i = 0; i < 44; i++) { - if ((readed = read(fd, (char *) sector, 128)) != 128) { - perror("file cpm.bin"); - exit(1); - } - write(drivea, (char *) sector, 128); - } - close(fd); - /* open BIOS (bios.bin) for reading */ - if ((fd = open("bios.bin", O_RDONLY)) == -1) { - perror("file bios.bin"); - exit(1); - } - /* read and check 3 byte header */ - if ((readed = read(fd, (char *) header, 3)) != 3) { - perror("file bios.bin"); - exit(1); - } - if (header[0] != 0xff) { - puts("unknown format of bios.bin"); - exit(0); - } - /* read BIOS from bios.bin and write it to disk in drive A */ - i = 0; - while ((readed = read(fd, (char *) sector, 128)) == 128) { - write(drivea, (char *) sector, 128); - i++; - if (i == 6) { - puts("6 sectors written, can't write any more!"); - goto stop; - } - } - if (readed > 0) { - write(drivea, (char *) sector, 128); - } -stop: - close(fd); - close(drivea); - return(0); -} diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/receive.c b/emu/z80pack-1.9/cpmsim/srccpm2/receive.c deleted file mode 100644 index 96dcbba..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm2/receive.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Receive a file out of the named pipe "auxout" from CP/M simulation - * - * Copyright (C) 1988-2006 by Udo Munk - * - * History: - * 05-OKT-88 Development on TARGON/35 with AT&T Unix System V.3 - * 11-MAR-93 comments in english and ported to COHERENT 4.0 - * 01-OCT-06 modified to compile on modern POSIX OS's - */ - -#include -#include -#include -#include -#include - -int fdin, fdout; - -int main(int argc, char *argv[]) -{ - char c; - void int_handler(void); - - if (argc != 2) { - puts("usage: receive filname &"); - exit(1); - } - if ((fdin = open("auxout", O_RDONLY)) == -1) { - perror("pipe auxout"); - exit(1); - } - if ((fdout = creat(argv[1], 0644)) == -1) { - perror(argv[1]); - exit(1); - } - - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - signal(SIGHUP, int_handler); - - for (;;) { - if (read(fdin, &c, 1) == 1) - if (c != '\r') - write(fdout, &c, 1); - } - - return(0); -} - -void int_handler(void) -{ - close(fdin); - close(fdout); - exit(0); -} diff --git a/emu/z80pack-1.9/cpmsim/srccpm2/send.c b/emu/z80pack-1.9/cpmsim/srccpm2/send.c deleted file mode 100644 index e110f6c..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm2/send.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Sends a file through named pipe "auxin" to the CP/M simulation - * - * Copyright (C) 1988-2006 by Udo Munk - * - * History: - * 05-OKT-88 Development on TARGON/35 with AT&T Unix System V.3 - * 11-MAR-93 comments in english and ported to COHERENT 4.0 - * 01-OCT-06 modified to compile on modern POSIX OS's - */ - -#include -#include -#include -#include - -void sendbuf(int); - -char buf[BUFSIZ]; -char cr = '\r'; -int fdout, fdin; - -int main(int argc,char *argv[]) -{ - register int readed; - - if (argc != 2) { - puts("usage: send filname &"); - exit(1); - } - if ((fdin = open(argv[1], O_RDONLY)) == -1) { - perror(argv[1]); - exit(1); - } - if ((fdout = open("auxin", O_WRONLY)) == -1) { - perror("pipe auxin"); - exit(1); - } - while ((readed = read(fdin, buf, BUFSIZ)) == BUFSIZ) - sendbuf(BUFSIZ); - if (readed) - sendbuf(readed); - close(fdin); - close(fdout); - return(0); -} - -void sendbuf(int size) -{ - register char *s = buf; - - while (s - buf < size) { - if (*s == '\n') - write(fdout, (char *) &cr, 1); - write(fdout, s++, 1); - } -} diff --git a/emu/z80pack-1.9/cpmsim/srccpm3/Makefile b/emu/z80pack-1.9/cpmsim/srccpm3/Makefile deleted file mode 100644 index 337d0f2..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm3/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -CFLAGS= -O -s - -all: putsys boot.bin - echo done - -putsys: putsys.c - cc $(CFLAGS) -o putsys putsys.c - -boot.bin: boot.asm - z80asm -vl -sn -fb boot.asm - -clean: - rm -f *.lis putsys boot.bin diff --git a/emu/z80pack-1.9/cpmsim/srccpm3/bios3.mac b/emu/z80pack-1.9/cpmsim/srccpm3/bios3.mac deleted file mode 100644 index c9c6d8b..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm3/bios3.mac +++ /dev/null @@ -1,582 +0,0 @@ -; CP/M 3 BIOS for Z80-Simulator -; -; Copyright (C) 1989-2006 by Udo Munk -; - .Z80 -; -; bdos functions -; -WARM EQU 0 -BDOS EQU 5 -PRINT EQU 9 -OPEN EQU 15 -READS EQU 20 -DMA EQU 26 -MULTI EQU 44 -; -; i/o ports -; -CONSTA EQU 0 ;console status port -CONDAT EQU 1 ;console data port -PRTSTA EQU 2 ;printer status port -PRTDAT EQU 3 ;printer data port -AUXSTA EQU 4 ;auxilary status port -AUXDAT EQU 5 ;auxilary data port -FDCD EQU 10 ;fdc-port: # of drive -FDCT EQU 11 ;fdc-port: # of track -FDCS EQU 12 ;fdc-port: # of sector -FDCOP EQU 13 ;fdc-port: command -FDCST EQU 14 ;fdc-port: status -DMAL EQU 15 ;dma-port: dma address low -DMAH EQU 16 ;dma-port: dma address high -MMUINI EQU 20 ;initialize mmu -MMUSEL EQU 21 ;bank select mmu -CLKCMD EQU 25 ;clock command -CLKDAT EQU 26 ;clock data -; -; clock commands -; -GETSEC EQU 0 ;get seconds -GETMIN EQU 1 ;get minutes -GETHOU EQU 2 ;get hours -GETDAL EQU 3 ;get days low -GETDAH EQU 4 ;get days high -; -; character device mode byte fields -; -mb$input EQU 00000001B ;device may do input -mb$output EQU 00000010B ;device may do output -mb$in$out EQU mb$input+mb$output ;device may do both -baud$none EQU 0 -; -; external references in scb -; - EXTRN @civec, @covec, @aovec, @aivec, @lovec, @bnkbf - EXTRN @crdma, @crdsk, @fx, @resel, @vinfo, @usrcd - EXTRN @ermde, @date, @hour, @min, @sec, @mxtpa -; - CSEG -; -; cp/m 3 jump vector for individual subroutines -; - JP BOOT ;perform cold start initialization -WBOOTE: JP WBOOT ;perform warm start initialization - JP CONST ;check for console input char ready - JP CONIN ;read console character in - JP CONOUT ;write console character out - JP LIST ;write list character out - JP AUXOUT ;write auxiliary output char - JP AUXIN ;read auxiliary input char - JP HOME ;move head to track 0 on selcted disk - JP SELDSK ;select disk drive - JP SETTRK ;set track number - JP SETSEC ;set sector number - JP SETDMA ;set dma address - JP READ ;read specified sector - JP WRITE ;write specified sector - JP LISTST ;return list status - JP SECTRAN ;translate logical to physical sector - JP CONOST ;return output status of console - JP AUXIST ;return input status of aux. port - JP AUXOST ;return output status of aux. port - JP DEVTBL ;return address of character i/o table - JP DEVINI ;initialize character i/o devices - JP DRVTBL ;return address of disk drive table - JP MULTIO ;set number of sectors to read/write - JP FLUSH ;flush deblocking buffers - JP MOVE ;memory to memory move - JP TIME ;time set/get signal - JP SELMEM ;select bank of memory - JP SETBNK ;specify bank for dma operation - JP XMOVE ;set bank for memory dma transfer - JP 0 ;reserved for system implementor - JP 0 ;reserved for future use - JP 0 ;reserved for future use -; -; drive table -; -DRIVES: DW DPH0 - DW DPH1 - DW DPH2 - DW DPH3 - DW 0 - DW 0 - DW 0 - DW 0 - DW DPH8 - DW DPH9 - DW 0 - DW 0 - DW 0 - DW 0 - DW 0 - DW 0 -; -; fixed data tables for IBM-compatible 8" disks -; -; disk parameter header -; -DPH0: DEFW TRANS ;sector translation table - DB 0,0,0,0,0,0,0,0,0 ;bdos scratch area - DB 0 ;media flag - DEFW DPB0 ;disk parameter block - DEFW 0FFFEH ;checksum vector - DEFW 0FFFEH ;allocation vector - DEFW 0FFFEH ;directory buffer control block - DEFW 0FFFFH ;dtabcb not used - DEFW 0FFFEH ;hashing - DEFB 0 ;hash bank -DPH1: DEFW TRANS ;sector translation table - DB 0,0,0,0,0,0,0,0,0 ;bdos scratch area - DB 0 ;media flag - DEFW DPB0 ;disk parameter block - DEFW 0FFFEH ;checksum vector - DEFW 0FFFEH ;allocation vector - DEFW 0FFFEH ;directory buffer control block - DEFW 0FFFFH ;dtabcb not used - DEFW 0FFFEH ;hashing - DEFB 0 ;hash bank -DPH2: DEFW TRANS ;sector translation table - DB 0,0,0,0,0,0,0,0,0 ;bdos scratch area - DB 0 ;media flag - DEFW DPB0 ;disk parameter block - DEFW 0FFFEH ;checksum vector - DEFW 0FFFEH ;allocation vector - DEFW 0FFFEH ;directory buffer control block - DEFW 0FFFFH ;dtabcb not used - DEFW 0FFFEH ;hashing - DEFB 0 ;hash bank -DPH3: DEFW TRANS ;sector translation table - DB 0,0,0,0,0,0,0,0,0 ;bdos scratch area - DB 0 ;media flag - DEFW DPB0 ;disk parameter block - DEFW 0FFFEH ;checksum vector - DEFW 0FFFEH ;allocation vector - DEFW 0FFFEH ;directory buffer control block - DEFW 0FFFFH ;dtabcb not used - DEFW 0FFFEH ;hashing - DEFB 0 ;hash bank -; -; sector translate vector for the IBM 8" disk -; -TRANS: DEFB 1,7,13,19 ;sectors 1,2,3,4 - DEFB 25,5,11,17 ;sectors 5,6,7,8 - DEFB 23,3,9,15 ;sectors 9,10,11,12 - DEFB 21,2,8,14 ;sectors 13,14,15,16 - DEFB 20,26,6,12 ;sectors 17,18,19,20 - DEFB 18,24,4,10 ;sectors 21,22,23,24 - DEFB 16,22 ;sectors 25,26 -; -; disk parameter block for the IBM 8" disk -; -DPB0: DEFW 26 ;sectors per track - DEFB 3 ;block shift factor - DEFB 7 ;block mask - DEFB 0 ;extent mask - DEFW 242 ;disk size-1 - DEFW 63 ;directory max - DEFB 192 ;alloc 0 - DEFB 0 ;alloc 1 - DEFW 16 ;check size - DEFW 2 ;track offset - DEFB 0,0 ;physical sector size and shift -; -; fixed data tables for 4mb harddisks -; -; disk parameter header -; -DPH8: DEFW HDTRA ;sector translation table - DB 0,0,0,0,0,0,0,0,0 ;bdos scratch area - DB 0 ;media flag - DEFW DPB1 ;disk parameter block - DEFW 0FFFEH ;checksum vector - DEFW 0FFFEH ;allocation vector - DEFW 0FFFEH ;directory buffer control block - DEFW 0FFFFH ;dtabcb not used - DEFW 0FFFEH ;hashing - DEFB 0 ;hash bank -DPH9: DEFW HDTRA ;sector translation table - DB 0,0,0,0,0,0,0,0,0 ;bdos scratch area - DB 0 ;media flag - DEFW DPB1 ;disk parameter block - DEFW 0FFFEH ;checksum vector - DEFW 0FFFEH ;allocation vector - DEFW 0FFFEH ;directory buffer control block - DEFW 0FFFFH ;dtabcb not used - DEFW 0FFFEH ;hashing - DEFB 0 ;hash bank -; -; sector translate vector for 4mb harddisk -; -HDTRA: DEFB 1,2,3,4,5,6,7,8,9,10 - DEFB 11,12,13,14,15,16,17,18,19,20 - DEFB 21,22,23,24,25,26,27,28,29,30 - DEFB 31,32,33,34,35,36,37,38,39,40 - DEFB 41,42,43,44,45,46,47,48,49,50 - DEFB 51,52,53,54,55,56,57,58,59,60 - DEFB 61,62,63,64,65,66,67,68,69,70 - DEFB 71,72,73,74,75,76,77,78,79,80 - DEFB 81,82,83,84,85,86,87,88,89,90 - DEFB 91,92,93,94,95,96,97,98,99,100 - DEFB 101,102,103,104,105,106,107,108,109,110 - DEFB 111,112,113,114,115,116,117,118,119,120 - DEFB 121,122,123,124,125,126,127,128 -; -; disk parameter block for 4mb harddisk -; -DPB1: DEFW 128 ;sectors per track - DEFB 4 ;block shift factor - DEFB 15 ;block mask - DEFB 0 ;extent mask - DEFW 2039 ;disk size-1 - DEFW 1023 ;directory max - DEFB 255 ;alloc 0 - DEFB 255 ;alloc 1 - DEFW 0 ;check size - DEFW 0 ;track offset - DEFB 0,0 ;physical sector size and shift -; -; character device table -; -CHRTBL: DEFB 'CRT ' - DEFB mb$in$out - DEFB baud$none - DEFB 'LPT ' - DEFB mb$output - DEFB baud$none - DEFB 'PTP ' - DEFB mb$output - DEFB baud$none - DEFB 'PTR ' - DEFB mb$input - DEFB baud$none - DEFB 0 -; -; signon message -; -SIGNON: DEFB 13,10 - DEFM 'BANKED BIOS3 V1.4 for Z80SIM, ' - DEFM 'Copyright 1989-2006 by Udo Munk' - DEFB 13,10 - DEFB 0 -; -; small stack -; - DS 8 -STACK: -; -; fcb for loading ccp -; -CCPFCB: DEFB 1,'CCP COM',0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -CCPREC: DEFB 0,0,0 -; - DSEG -; -; bios error messages -; -CCPOER: DEFB 13,10,'BIOS ERROR: cannot open CCP.COM',13,10,'$' -CCPIOE: DEFB 13,10,'BIOS ERROR: reading CCP.COM',13,10,'$' -; - CSEG -; -DRIVE: DEFB 0 ;drive to select -BANK: DEFB 0 ;bank to select for dma -; -; end of fixed tables -; -; individual subroutines to perform each function -; - DSEG -; -BOOT: LD B,1 ;indicate cold boot -; - LD HL,8000H - LD (@civec),HL ;CONSOLE:=CON for input - LD (@covec),HL ;CONSOLE:=CON for output - LD HL,4000H - LD (@lovec),HL ;LST:=LPT - LD HL,2000H - LD (@aovec),HL ;AUXOUT:=PTP - LD HL,1000H - LD (@aivec),HL ;AUXIN:=PTR -; - LD A,3 ;initialize 3 memory banks - OUT (MMUINI),A - JP WBOOT1 -; - CSEG -; -WBOOT: LD B,0 ;indicate warm boot -WBOOT1: LD SP,STACK -; -; initialize low memory jumps in bank 1 -; - LD A,1 - CALL SELMEM -; - LD A,0C3H ;jmp instruction - LD (WARM),A - LD HL,WBOOTE ;warm boot enty point - LD (WARM+1),HL - LD (BDOS),A - LD HL,(@mxtpa) ;bdos entry point - LD (BDOS+1),HL -; -; print message on cold boot -; - LD A,B - OR A - JP Z,LDCCP - LD HL,SIGNON ;print message -WBOOT2: LD A,(HL) - OR A - JP Z,LDCCP - LD C,A - CALL CONOUT - INC HL - JP WBOOT2 -; -; load ccp.com into tpa -; -LDCCP: XOR A ;initialize fcb - LD (CCPFCB+15),A - LD HL,0 - LD (CCPREC),HL - LD DE,CCPFCB ;open file ccp.com - LD C,OPEN - CALL BDOS - LD DE,CCPOER - INC A - JP Z,CCPERR ;print error if file not found - LD DE,0100H ;setup DMA to tpa - LD C,DMA - CALL BDOS - LD DE,128 ;read up to 16KB - LD C,MULTI - CALL BDOS - LD DE,CCPFCB ;read the ccp into memory - LD C,READS - CALL BDOS - LD DE,CCPIOE - INC A - JP NZ,0100H ;start ccp -CCPERR: LD C,PRINT ;print error message - CALL BDOS - HALT -; -; character i/o drivers -; -DEVTBL: LD HL,CHRTBL - RET -; -; character device initialization -; -DEVINI: RET -; -; console in status, return 0ffh if character ready, 00h if not -; -CONST: IN A,(CONSTA) - RET -; -; console character input from register a -; -CONIN: IN A,(CONDAT) - RET -; -; console out status, return 0ffh if ready, 00h if not -CONOST: LD A,0FFH ;console out always ready - RET -; -; console character output from register c -; -CONOUT: LD A,C ;get to accumulator - OUT (CONDAT),A ;send character to console - RET -; -; list out status, return 0ffh if ready, 00h if not -; -LISTST: LD A,0FFH ;list out always ready - RET -; -; list character output from register C -; -LIST: LD A,C - OUT (PRTDAT),A - RET -; -; auxilary input status, 0ffh if ready, 00h if not -; -AUXIST: XOR A ;never ready, hardware not available yet - RET -; -; auxilary output status, 0ffh if ready, 00h if not -; -AUXOST: XOR A ;never ready, hadware not available yet - RET -; -; auxilary input -; -AUXIN: IN A,(AUXDAT) - RET -; -; auxilary output from register c -; -AUXOUT: LD A,C - OUT (AUXDAT),A - RET -; -; -; i/o drivers for the disks -; -DRVTBL: LD HL,DRIVES - RET -; - DSEG -; -; move to the track 00 position of current drive -; translate this call into a settrk call with parameter 00 -; -HOME: LD C,0 ;select track 0 - JP SETTRK ;we will move to 00 on first read/write -; -; select disk given by register C -; -SELDSK: LD HL,0000H ;error return code - LD A,C - LD (DRIVE),A - CP 4 ;disk drive 1-4? - JP C,SEL1 ;go - CP 8 ;harddisk 1? - JP Z,SEL1 ;go - CP 9 ;harddisk 2? - RET NZ ;no, error -; disk number is in the proper range -; return proper disk parameter header address -SEL1: LD L,C - LD H,0 - ADD HL,HL ;drive index in hl - LD BC,DRIVES - ADD HL,BC ;get pointer to dph - LD A,(HL) - INC HL - LD H,(HL) - LD L,A - LD A,(DRIVE) - OUT (FDCD),A ;selekt disk drive - RET -; -; set track given by register c -; -SETTRK: LD A,C - OUT (FDCT),A - RET -; -; set sector given by register c -; -SETSEC: LD A,C - OUT (FDCS),A - RET -; -; translate the sector given by bc using the -; translate table given by de -; -SECTRAN: - EX DE,HL ;hl=.trans - ADD HL,BC ;hl=.trans(sector) - LD L,(HL) ;l = trans(sector) - LD H,0 ;hl= trans(sector) - RET ;with value in HL -; -; set dma address given by registers b and c -; -SETDMA: LD A,C ;low order address - OUT (DMAL),A - LD A,B ;high order address - OUT (DMAH),A - RET -; - CSEG -; -; perform read operation -; -READ: LD A,(BANK) ;switch to saved bank - OUT (MMUSEL),A - XOR A ;read command -> A - JP WAITIO ;to perform the actual i/o -; -; perform write operation -; -WRITE: LD A,(BANK) ;switch to saved bank - OUT (MMUSEL),A - LD A,1 ;write command -> A -; -; enter here from read and write to perform the actual i/o -; operation. return 00h in register a if the operation completes -; properly, and 01h if an error occurs during the read or write -; -WAITIO: OUT (FDCOP),A ;start i/o operation - XOR A ;reselect bank 0 - OUT (MMUSEL),A - IN A,(FDCST) ;status of i/o operation -> A - RET -; -; nothing to do -; -MULTIO: XOR A - RET -; -; nothing to do -; -FLUSH: XOR A - RET -; -; memory move -; -MOVE: EX DE,HL - LDIR - EX DE,HL - RET -; -; select memory bank -SELMEM: OUT (MMUSEL),A - RET -; -; specify memory bank for dma operation -SETBNK: LD (BANK),A - RET -; -; xmove not implemented yet, hardware missing -; -XMOVE: RET -; -; get/set time -; -TIME: - LD A,C - CP 0FFH - RET Z ;we cannot set the UNIX time from here - LD A,GETSEC ;get seconds - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (@sec),A - LD A,GETMIN ;get minutes - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (@min),A - LD A,GETHOU ;get hours - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (@hour),A - LD A,GETDAL ;get day - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (@date),A - LD A,GETDAH - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (@date+1),A - RET -; -ENDDAT EQU $ ;end - END ;of BIOS diff --git a/emu/z80pack-1.9/cpmsim/srccpm3/boot.asm b/emu/z80pack-1.9/cpmsim/srccpm3/boot.asm deleted file mode 100644 index 43241be..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm3/boot.asm +++ /dev/null @@ -1,67 +0,0 @@ -; CP/M 3 boot-loader for Z80-Simulator -; -; Copyright (C) 1989-2006 by Udo Munk -; - ORG 0 ; mem base of boot -; -BOOT EQU 0100H ; cpmldr runs at 0100H -SECTS EQU 51 ; # of sectors to load (26 * 2 - 1) -; -; I/O ports -; -DRIVE EQU 10 ; fdc-port: # of drive -TRACK EQU 11 ; fdc-port: # of track -SECTOR EQU 12 ; fdc-port: # of sector -FDCOP EQU 13 ; fdc-port: command -FDCST EQU 14 ; fdc-port: status -DMAL EQU 15 ; dma-port: dma address low -DMAH EQU 16 ; dma-port: dma address high -; -; begin the load operation -; -COLD: LD BC,2 ; b=track 0, c=sector 2 - LD D,SECTS ; d=# sectors to load - LD HL,BOOT ; base transfer address - LD A,0 ; select drive A - OUT (DRIVE),A -; -; load the next sector -; -LSECT: LD A,B ; set track - OUT (TRACK),A - LD A,C ; set sector - OUT (SECTOR),A - LD A,L ; set dma address low - OUT (DMAL),A - LD A,H ; set dma adress high - OUT (DMAH),A - XOR A ; read sector - OUT (FDCOP),A - IN A,(FDCST) ; get status of fdc - CP 0 ; read successful ? - JP Z,CONT ; yes, continue - HALT ; no, halt cpu -CONT: - ; go to next sector if load is incomplete - DEC D ; sects=sects-1 - JP Z,BOOT ; head for the bios -; -; more sectors to load -; -; we aren't using a stack, so use as scratch register -; to hold the load address increment -; - LD SP,128 ; 128 bytes per sector - ADD HL,SP ; = + 128 -; - INC C ; sector = sector + 1 - LD A,C - CP 27 ; last sector of track ? - JP C,LSECT ; no, go read another -; -; end of track, increment to next track -; - LD C,1 ; sector = 1 - INC B ; track = track + 1 - JP LSECT ; for another group - END ; of boot loader diff --git a/emu/z80pack-1.9/cpmsim/srccpm3/cpmldr.bin b/emu/z80pack-1.9/cpmsim/srccpm3/cpmldr.bin deleted file mode 100644 index 8def05a..0000000 Binary files a/emu/z80pack-1.9/cpmsim/srccpm3/cpmldr.bin and /dev/null differ diff --git a/emu/z80pack-1.9/cpmsim/srccpm3/ldrbios3.mac b/emu/z80pack-1.9/cpmsim/srccpm3/ldrbios3.mac deleted file mode 100644 index 1ae671d..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm3/ldrbios3.mac +++ /dev/null @@ -1,212 +0,0 @@ -; CP/M 3 LDRBIOS for Z80-Simulator -; -; Copyright (C) 1989-2006 by Udo Munk -; - .Z80 -; -; I/O ports -; -CONSTA EQU 0 ;console status port -CONDAT EQU 1 ;console data port -FDCD EQU 10 ;fdc-port: # of drive -FDCT EQU 11 ;fdc-port: # of track -FDCS EQU 12 ;fdc-port: # of sector -FDCOP EQU 13 ;fdc-port: command -FDCST EQU 14 ;fdc-port: status -DMAL EQU 15 ;dma-port: dma address low -DMAH EQU 16 ;dma-port: dma address high -; - CSEG -; -; jump vector for individual subroutines -; * needs to be implemented -; - JP BOOT ; * perform cold start initialization - JP WBOOT ; perform warm start initialization - JP CONST ; check for console input char ready - JP CONIN ; read console character in - JP CONOUT ; * write console character out - JP LIST ; write list character out - JP AUXOUT ; write auxiliary output char - JP AUXIN ; read auxiliary input char - JP HOME ; * move head to track 0 on selcted disk - JP SELDSK ; * select disk drive - JP SETTRK ; * set track number - JP SETSEC ; * set sector number - JP SETDMA ; * set dma address - JP READ ; * read specified sector - JP WRITE ; write specified sector - JP LISTST ; return list status - JP SECTRAN ; * translate logical to physical sector - JP CONOST ; return output status of console - JP AUXIST ; return input status of aux. port - JP AUXOST ; return output status of aux. port - JP DEVTBL ; return address of character i/o table - JP DEVINI ; initialize character i/o devices - JP DRVTBL ; return address of disk drive table - JP MULTIO ; set number of sectors to read/write - JP FLUSH ; flush deblocking buffers - JP MOVE ; * memory to memory move - JP TIME ; time set/get signal - JP SELMEM ; select bank of memory - JP SETBNK ; specify bank for dma operation - JP XMOVE ; set bank for memory dma transfer - JP 0 ; reserved for system implementor - JP 0 ; reserved for future use - JP 0 ; reserved for future use -; -; fixed data tables for a IBM-compatible 8" disk -; -; disk parameter header -; -DPH0: DEFW TRANS ;sector translation table - DB 0,0,0,0,0,0,0,0,0 ;bdos scratch area - DB 0 ;media flag - DEFW DPB0 ;disk parameter block - DEFW 0FFFEH ;checksum vector - DEFW 0FFFEH ;allocation vector - DEFW 0FFFEH ;directory buffer control block - DEFW 0FFFFH ;dtabcb not used - DEFW 0FFFFH ;hashing not used - DEFB 0 ;hash bank -; -; sector translate vector for the IBM 8" disk -; -TRANS: DEFB 1,7,13,19 ;sectors 1,2,3,4 - DEFB 25,5,11,17 ;sectors 5,6,7,8 - DEFB 23,3,9,15 ;sectors 9,10,11,12 - DEFB 21,2,8,14 ;sectors 13,14,15,16 - DEFB 20,26,6,12 ;sectors 17,18,19,20 - DEFB 18,24,4,10 ;sectors 21,22,23,24 - DEFB 16,22 ;sectors 25,26 -; -; disk parameter block for the IBM 8" disk -; -DPB0: DEFW 26 ;sectors per track - DEFB 3 ;block shift factor - DEFB 7 ;block mask - DEFB 0 ;extent mask - DEFW 242 ;disk size-1 - DEFW 63 ;directory max - DEFB 192 ;alloc 0 - DEFB 0 ;alloc 1 - DEFW 16 ;check size - DEFW 2 ;track offset - DEFB 0,0 ;physical sector size and shift -; -; signon message -; -SIGNON: DEFB 13,10 - DEFM 'LDRBIOS3 V1.1 for Z80SIM, ' - DEFM 'Copyright 1989-2006 by Udo Munk' - DEFB 13,10,0 -; -; end of fixed tables -; -; individual subroutines to perform each function -; -BOOT: LD HL,SIGNON ;print message -BOOTL: LD A,(HL) - OR A - JP Z,WBOOT - LD C,A - CALL CONOUT - INC HL - JP BOOTL -; -; those are not implemented in loader bios -; -WBOOT: -CONST: -CONIN: -LIST: -AUXOUT: -AUXIN: -WRITE: -LISTST: -CONOST: -AUXIST: -AUXOST: -DEVTBL: -DEVINI: -DRVTBL: -MULTIO: -FLUSH: -TIME: -SELMEM: -SETBNK: -XMOVE: RET -; -; console character output from register c -; -CONOUT: LD A,C ;get to accumulator - OUT (CONDAT),A ;send character to console - RET -; -; -; i/o drivers for the disk follow -; -; move to the track 00 position of current drive -; translate this call into a settrk call with parameter 00 -; -HOME: LD C,0 ;select track 0 - JP SETTRK ;we will move to 00 on first read/write -; -; select disk given by register C -; -SELDSK: LD HL,0000H ;error return code - LD A,C - CP 0 ;we boot from drive 0 only - RET NZ ;return error -; disk number is in the proper range -; return proper disk parameter header address - OUT (FDCD),A ;selekt disk drive - LD HL,DPH0 - RET -; -; set track given by register c -; -SETTRK: LD A,C - OUT (FDCT),A - RET -; -; set sector given by register c -; -SETSEC: LD A,C - OUT (FDCS),A - RET -; -; translate the sector given by BC using the -; translate table given by DE -; -SECTRAN: - EX DE,HL ;hl=.trans - ADD HL,BC ;hl=.trans(sector) - LD L,(HL) ;l = trans(sector) - LD H,0 ;hl= trans(sector) - RET ;with value in hl -; -; set dma address given by registers b and c -; -SETDMA: LD A,C ;low order address - OUT (DMAL),A - LD A,B ;high order address - OUT (DMAH),A ;in dma - RET -; -; perform read operation -; -READ: XOR A ;read command -> a - OUT (FDCOP),A ;start i/o operation - IN A,(FDCST) ;status of i/o operation -> a - RET -; -; memory move -; -MOVE: EX DE,HL - LDIR - EX DE,HL - RET -; -ENDDAT EQU $ ;end - END ;of bios diff --git a/emu/z80pack-1.9/cpmsim/srccpm3/putsys.c b/emu/z80pack-1.9/cpmsim/srccpm3/putsys.c deleted file mode 100644 index 7589932..0000000 --- a/emu/z80pack-1.9/cpmsim/srccpm3/putsys.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Write the CP/M 3 systemfiles to system tracks of drive A - * - * Copyright (C) 1988-2006 by Udo Munk - * - * History: - * 29-APR-88 Development on TARGON/35 with AT&T Unix System V.3 - * 11-MAR-93 comments in english and ported to COHERENT 4.0 - * 02-OCT-06 modified to compile on modern POSIX OS's - */ - -#include -#include -#include -#include -#include - -/* - * This program writes the CP/M 3 OS from the following files - * onto the system tracks of the boot disk (drivea.cpm): - * - * boot loader boot.bin - * cpmldr cpmldr.bin - */ -int main(void) -{ - unsigned char sector[128]; - register int i; - int fd, drivea, readed; - - /* open drive A for writing */ - if ((drivea = open("../disks/drivea.cpm", O_WRONLY)) == -1) { - perror("file ../disks/drivea.cpm"); - exit(1); - } - /* open boot loader (boot.bin) for reading */ - if ((fd = open("boot.bin", O_RDONLY)) == -1) { - perror("file boot.bin"); - exit(1); - } - /* read boot loader */ - memset((char *) sector, 0, 128); - read(fd, (char *) sector, 128); - close(fd); - /* and write it to disk in drive A */ - write(drivea, (char *) sector, 128); - /* open CP/M 3 cpmldr file (cpmldr.bin) for reading */ - if ((fd = open("cpmldr.bin", O_RDONLY)) == -1) { - perror("file cpmldr.bin"); - exit(1); - } - /* read from cpmldr.bin and write to disk in drive A */ - while ((readed = read(fd, (char *) sector, 128)) == 128) - write(drivea, (char *) sector, 128); - write(drivea, (char *) sector, 128); - close(fd); - close(drivea); - return(0); -} diff --git a/emu/z80pack-1.9/cpmsim/srcmpm/bnkxios.mac b/emu/z80pack-1.9/cpmsim/srcmpm/bnkxios.mac deleted file mode 100644 index 325ec3c..0000000 --- a/emu/z80pack-1.9/cpmsim/srcmpm/bnkxios.mac +++ /dev/null @@ -1,503 +0,0 @@ -; MP/M 2 XIOS for Z80-Simulator -; -; Copyright (C) 1989-2006 by Udo Munk -; - .Z80 - CSEG -; -; i/o ports -; -CONSTA EQU 0 ;console status port -CONDAT EQU 1 ;console data port -PRTSTA EQU 2 ;printer status port -PRTDAT EQU 3 ;printer data port -AUXSTA EQU 4 ;auxilary status port -AUXDAT EQU 5 ;auxilary data port -FDCD EQU 10 ;fdc-port: # of drive -FDCT EQU 11 ;fdc-port: # of track -FDCS EQU 12 ;fdc-port: # of sector -FDCOP EQU 13 ;fdc-port: command -FDCST EQU 14 ;fdc-port: status -DMAL EQU 15 ;dma-port: dma address low -DMAH EQU 16 ;dma-port: dma address high -MMUINI EQU 20 ;initialize mmu -MMUSEL EQU 21 ;bank select mmu -CLKCMD EQU 25 ;clock command -CLKDAT EQU 26 ;clock data -TIMER EQU 27 ;interrupt timer -; -; clock commands -; -GETSEC EQU 0 ;get seconds -GETMIN EQU 1 ;get minutes -GETHOU EQU 2 ;get hours -GETDAL EQU 3 ;get days low -GETDAH EQU 4 ;get days high -; -BDOS EQU 5 ;bdos calls -SETTD EQU 104 ;bdos set time and date -; -POLL EQU 131 ;xdos poll function -PLCI0 EQU 0 ;poll console in #0 -FLAGSET EQU 133 ;xdos flag set function -SYSDATA EQU 154 ;xdos syste data address -; -; jump vector for individual subroutines -; - JP COMMONBASE ;commonbase - JP WARMSTART ;warm start - JP CONST ;console status - JP CONIN ;console character in - JP CONOUT ;console character out - JP LIST ;list character out - JP PUNCH ;not used by MP/M 2 - JP READER ;not used by MP/M 2 - JP HOME ;move head to home - JP SELDSK ;select disk - JP SETTRK ;set track numer - JP SETSEC ;set sector number - JP SETDMA ;set dma address - JP READ ;read disk - JP WRITE ;write disk - JP LISTST ;not used by MP/M 2 - JP SECTRAN ;sector translate - JP SELMEMORY ;select memory - JP POLLDEVICE ;poll device - JP STARTCLOCK ;start clock - JP STOPCLOCK ;stop clock - JP EXITREGION ;exit region - JP MAXCONSOLE ;maximum console number - JP SYSTEMINIT ;system initialization - JP IDLE ;idle prozedure -; -COMMONBASE: - JP COLDSTART -SWTUSER: - JP $-$ -SWTSYS: JP $-$ -PDISP: JP $-$ -XDOS: JP $-$ -SYSDAT: DEFW $-$ -; -COLDSTART: -WARMSTART: - LD C,0 - JP XDOS ;system reset, terminate prozess -; -; MP/M II V2.0 Console Bios -; -CONST: - CALL PTBLJMP ;compute and jump to handler - DW PTSTI0 -; -CONIN: - CALL PTBLJMP ;compute and jump to handle - DW PTIN0 -; -CONOUT: - CALL PTBLJMP ;compute and jump to handler - DW PTOUT0 -; -PTSTI0: IN A,(CONSTA) ;console 0 input - RET -; -PTIN0: LD C,POLL ;poll console 0 status in - LD E,PLCI0 - CALL XDOS ;poll console 0 - IN A,(CONDAT) ;read character - AND 7FH ;strip parity - RET -; -PTOUT0: LD A,C ;console 0 output - OUT (CONDAT),A - RET -; -PTBLJMP: ;compute and jump to handler - LD A,D - ADD A,A ;double table index for adress offset - POP HL ;return adress of jump table - LD E,A - LD D,0 - ADD HL,DE ;table index * 2 + table base - LD E,(HL) ;get handler address - INC HL - LD D,(HL) - EX DE,HL - JP (HL) ;jump to computed handler -; -LIST: - LD A,C - OUT (PRTDAT),A - RET -; -; not used by MP/M 2 -PUNCH: -READER: -LISTST: - RET -; -; MP/M II V2.0 Xios -; -; select/protect memory -; BC = address of memory descriptor -SELMEMORY: - LD HL,3 ;offset memory bank in memory descriptor - ADD HL,BC - LD A,(HL) ;get bank - OUT (MMUSEL),A ;and select it - RET -; -; poll character devices -; -POLLDEVICE: - JP PTSTI0 ;poll console 0 status in -; -; start clock -; -STARTCLOCK: - LD A,0FFH - LD (TICKN),A - RET -; -; stop clock -; -STOPCLOCK: - XOR A - LD (TICKN),A - RET -; -; exit region: -; enable interrupt if not preempted or in dispatcher -; -EXITREGION: - LD A,(PREEMP) - OR A - RET NZ - EI - RET -; -; maximum console number -; -MAXCONSOLE: - LD A,1 - RET -; -; system initialization -; C MP/M debugger restart # -; DE MP/M entry point for debugger -; HL BIOS jump table address -; -SYSTEMINIT: -; - ;doesn't work - PUSH HL - LD C,SYSDATA ;get system data page address - CALL XDOS - CALL SETTOD ;set tod from hardware clock - POP HL -; - LD A,8 ;initialize banked memory - OUT (MMUINI),A - LD B,A -; -SYS1: DEC B - LD A,B - OUT (MMUSEL),A ;select every bank and initialize - LD A,0C3H ;jp instruction - LD (0),A - LD (38H),A - LD (1),HL - PUSH HL - LD HL,INTHND - LD (39H),HL - POP HL - JP NZ,SYS1 -; - LD HL,SIGNON ;print message -SYS2: LD A,(HL) - OR A - JP Z,SYS3 - OUT (CONDAT),A - INC HL - JP SYS2 -; -SYS3: IM 1 - LD A,1 ;enable 20ms interrupt timer - OUT (TIMER),A - EI - RET -; -; set mp/m tod from hardware clock -; hl = tod address -; -SETTOD: LD A,GETDAL - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (HL),A - INC HL - LD A,GETDAH - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (HL),A - INC HL - LD A,GETHOU - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (HL),A - INC HL - LD A,GETMIN - OUT (CLKCMD),A - IN A,(CLKDAT) - LD (HL),A - RET -; -; idle -; -IDLE: EI - HALT - RET -; -; interrupt handler -; -INTHND: LD (SVDHL),HL ;save registers - POP HL - LD (SVDRET),HL - PUSH AF - LD HL,0 - ADD HL,SP - LD (SVDSP),HL - LD SP,INTSTK - PUSH DE - PUSH BC - LD A,0FFH ;set preempted flag - LD (PREEMP),A - LD A,(TICKN) - OR A ;test tick, indicates delayed process - JP Z,INTHND1 - LD C,FLAGSET ;set flag #1 each tick - LD E,1 - CALL XDOS -INTHND1: - LD HL,CNT50 ;decrement tick counter - DEC (HL) - JP NZ,INTDONE - LD (HL),50 ;set flag #2 each second - LD C,FLAGSET - LD E,2 - CALL XDOS -INTDONE: - XOR A ;clear preempted flag - LD (PREEMP),A - POP BC ;restore registers - POP DE - LD HL,(SVDSP) - LD SP,HL - POP AF - LD HL,(SVDRET) - PUSH HL - LD HL,(PDISP+1) ;dispatch processes - PUSH HL - LD HL,(SVDHL) - RETI -; -; i/o drivers for disks -; -; move to the track 00 position of current drive -; translate this call into a settrk call with parameter 00 -; -HOME: LD C,0 ;select track 0 - JP SETTRK ;we will move to 00 on first read/write -; -; select disk given by register C -; -SELDSK: LD HL,0000H ;error return code - LD A,C - CP 4 ;must be between 0 and 3 - JR NC,SELHD ;no carry if 4,5,... -; disk number is in the proper range -; compute proper disk parameter header address - OUT (FDCD),A ;selekt disk drive - LD L,A ;L=disk number 0,1,2,3 - ADD HL,HL ;*2 - ADD HL,HL ;*4 - ADD HL,HL ;*8 - ADD HL,HL ;*16 (size of each header) - LD DE,DPBASE - ADD HL,DE ;HL=.dpbase(diskno*16) - RET -SELHD: CP 8 ;select the harddisk? - RET NZ ;no, error - OUT (FDCD),A ;select disk drive - LD HL,HDBASE ;HL=hdbase for harddisk - RET -; -; set track given by register c -; -SETTRK: LD A,C - OUT (FDCT),A - RET -; -; set sector given by register c -; -SETSEC: LD A,C - OUT (FDCS),A - RET -; -; translate the sector given by BC using the -; translate table given by DE -; -SECTRAN: - EX DE,HL ;HL=.trans - ADD HL,BC ;HL=.trans(sector) - LD L,(HL) ;L = trans(sector) - LD H,0 ;HL= trans(sector) - RET ;with value in HL -; -; set dma address given by registers b and c -; -SETDMA: LD A,C ;low order address - OUT (DMAL),A - LD A,B ;high order address - OUT (DMAH),A ;in dma - RET -; -; perform read operation -; -READ: XOR A ;read command -> A - JP WAITIO ;to perform the actual i/o -; -; perform a write operation -; -WRITE: LD A,1 ;write command -> A -; -; enter here from read and write to perform the actual i/o -; operation. return a 00h in register a if the operation completes -; properly, and 01h if an error occurs during the read or write -; -; in this case, we have saved the disk number in 'diskno' (0-3) -; the track number in 'track' (0-76) -; the sector number in 'sector' (1-26) -; the dma address in 'dmaad' (0-65535) -; -WAITIO: OUT (FDCOP),A ;start i/o operation - IN A,(FDCST) ;status of i/o operation -> A - RET -; -; XIOS data segment -; -SIGNON: DEFB 13,10 - DEFM 'MP/M 2 XIOS V1.1 for Z80SIM, ' - DEFM 'Copyright 1989-2006 by Udo Munk' - DEFB 13,10,0 -; -TICKN: DEFB 0 ;flag for tick -PREEMP: DEFB 0 ;preempted flag -TOD: DEFS 4 ;time of day -SVDHL: DEFS 2 ;save hl during interrupt -SVDRET: DEFS 2 ;save return address during interrupt -SVDSP: DEFS 2 ;save sp during interrupt -CNT50: DEFB 50 ;50 ticks a 20ms = 1 second - ;interrupt stack - DEFW 0C7C7H,0C7C7H,0C7C7H,0C7C7H - DEFW 0C7C7H,0C7C7H,0C7C7H,0C7C7H - DEFW 0C7C7H,0C7C7H,0C7C7H,0C7C7H - DEFW 0C7C7H,0C7C7H,0C7C7H,0C7C7H -INTSTK: -; -; fixed data tables for four-drive standard -; IBM-compatible 8" disks -; -; disk parameter header for disk 00 -DPBASE: DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK00,ALL00 -; disk parameter header for disk 01 - DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK01,ALL01 -; disk parameter header for disk 02 - DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK02,ALL02 -; disk parameter header for disk 03 - DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK03,ALL03 -; -; sector translate vector for the IBM 8" disks -; -TRANS: DEFB 1,7,13,19 ;sectors 1,2,3,4 - DEFB 25,5,11,17 ;sectors 5,6,7,8 - DEFB 23,3,9,15 ;sectors 9,10,11,12 - DEFB 21,2,8,14 ;sectors 13,14,15,16 - DEFB 20,26,6,12 ;sectors 17,18,19,20 - DEFB 18,24,4,10 ;sectors 21,22,23,24 - DEFB 16,22 ;sectors 25,26 -; -; disk parameter block, common to all IBM 8" disks -; -DPBLK: DEFW 26 ;sectors per track - DEFB 3 ;block shift factor - DEFB 7 ;block mask - DEFB 0 ;extent mask - DEFW 242 ;disk size-1 - DEFW 63 ;directory max - DEFB 192 ;alloc 0 - DEFB 0 ;alloc 1 - DEFW 16 ;check size - DEFW 2 ;track offset -; -; fixed data tables for 4MB harddisk -; -; disk parameter header -HDBASE: DEFW HDTRA,0000H - DEFW 0000H,0000H - DEFW DIRBF,HDBLK - DEFW CHKHD,ALLHD -; -; sector translate vector for the hardisk -; -HDTRA: DEFB 1,2,3,4,5,6,7,8,9,10 - DEFB 11,12,13,14,15,16,17,18,19,20 - DEFB 21,22,23,24,25,26,27,28,29,30 - DEFB 31,32,33,34,35,36,37,38,39,40 - DEFB 41,42,43,44,45,46,47,48,49,50 - DEFB 51,52,53,54,55,56,57,58,59,60 - DEFB 61,62,63,64,65,66,67,68,69,70 - DEFB 71,72,73,74,75,76,77,78,79,80 - DEFB 81,82,83,84,85,86,87,88,89,90 - DEFB 91,92,93,94,95,96,97,98,99,100 - DEFB 101,102,103,104,105,106,107,108,109,110 - DEFB 111,112,113,114,115,116,117,118,119,120 - DEFB 121,122,123,124,125,126,127,128 -; -; disk parameter block for harddisk -; -HDBLK: DEFW 128 ;sectors per track - DEFB 4 ;block shift factor - DEFB 15 ;block mask - DEFB 0 ;extent mask - DEFW 2039 ;disk size-1 - DEFW 1023 ;directory max - DEFB 255 ;alloc 0 - DEFB 255 ;alloc 1 - DEFW 0 ;check size - DEFW 0 ;track offset -; -DIRBF: DEFS 128 ;scratch directory area -ALL00: DEFS 31 ;allocation vector 0 -ALL01: DEFS 31 ;allocation vector 1 -ALL02: DEFS 31 ;allocation vector 2 -ALL03: DEFS 31 ;allocation vector 3 -ALLHD: DEFS 255 ;allocation vector harddisk -CHK00: DEFS 16 ;check vector 0 -CHK01: DEFS 16 ;check vector 1 -CHK02: DEFS 16 ;check vector 2 -CHK03: DEFS 16 ;check vector 3 -CHKHD: DEFS 0 ;check vector harddisk -; - END diff --git a/emu/z80pack-1.9/cpmsim/srcmpm/ldrbios.mac b/emu/z80pack-1.9/cpmsim/srcmpm/ldrbios.mac deleted file mode 100644 index 495a4d6..0000000 --- a/emu/z80pack-1.9/cpmsim/srcmpm/ldrbios.mac +++ /dev/null @@ -1,177 +0,0 @@ -; MP/M 2 LDRBIOS for Z80-Simulator -; -; Copyright (C) 1989-2006 by Udo Munk -; - ORG 1700H -; -; I/O ports -; -CONSTA EQU 0 ;console status port -CONDAT EQU 1 ;console data port -FDCD EQU 10 ;fdc-port: # of drive -FDCT EQU 11 ;fdc-port: # of track -FDCS EQU 12 ;fdc-port: # of sector -FDCOP EQU 13 ;fdc-port: command -FDCST EQU 14 ;fdc-port: status -DMAL EQU 15 ;dma-port: dma address low -DMAH EQU 16 ;dma-port: dma address high -; -; jump vector for individual subroutines -; - JP BOOT ;perform cold start initialization - JP WBOOT ;perform warm start initialization - JP CONST ;check for console input char ready - JP CONIN ;read console character in - JP CONOUT ;write console character out - JP LIST ;write list character out - JP AUXOUT ;write auxiliary output char - JP AUXIN ;read auxiliary input char - JP HOME ;move head to track 0 on selcted disk - JP SELDSK ;select disk drive - JP SETTRK ;set track number - JP SETSEC ;set sector number - JP SETDMA ;set dma address - JP READ ;read specified sector - JP WRITE ;write specified sector - JP LISTST ;return list status - JP SECTRAN ;translate logical to physical sector -; -; fixed data tables for a IBM-compatible 8" disk -; -; disk parameter header -; -DPH: DEFW TRANS,0000H - DEFW 0000H,0000H - DEFW DIRBF,DPBLK - DEFW CHK00,ALL00 -; -; sector translate vector for the IBM 8" disk -; -TRANS: DEFB 1,7,13,19 ;sectors 1,2,3,4 - DEFB 25,5,11,17 ;sectors 5,6,7,8 - DEFB 23,3,9,15 ;sectors 9,10,11,12 - DEFB 21,2,8,14 ;sectors 13,14,15,16 - DEFB 20,26,6,12 ;sectors 17,18,19,20 - DEFB 18,24,4,10 ;sectors 21,22,23,24 - DEFB 16,22 ;sectors 25,26 -; -; disk parameter block for the IBM 8" disk -; -DPBLK: DEFW 26 ;sectors per track - DEFB 3 ;block shift factor - DEFB 7 ;block mask - DEFB 0 ;extent mask - DEFW 242 ;disk size-1 - DEFW 63 ;directory max - DEFB 192 ;alloc 0 - DEFB 0 ;alloc 1 - DEFW 16 ;check size - DEFW 2 ;track offset -; -; signon message -; -SIGNON: DEFB 13,10 - DEFM 'LDRBIOS V1.0 for Z80SIM, ' - DEFM 'Copyright 1989-2006 by Udo Munk' - DEFB 13,10,0 -; -; end of fixed tables -; -; individual subroutines to perform each function -; -BOOT: LD HL,SIGNON ;print message -BOOTL: LD A,(HL) - OR A - JP Z,WBOOT - LD C,A - CALL CONOUT - INC HL - JP BOOTL -; -; those are not implemented in loader bios -; -WBOOT: -CONST: -CONIN: -LIST: -AUXOUT: -AUXIN: -WRITE: -LISTST: - RET -; -; console character output from register c -; -CONOUT: LD A,C ;get to accumulator - OUT (CONDAT),A ;send character to console - RET -; -; -; i/o drivers for the disk follow -; -; move to the track 00 position of current drive -; translate this call into a settrk call with parameter 00 -; -HOME: LD C,0 ;select track 0 - JP SETTRK ;we will move to 00 on first read/write -; -; select disk given by register C -; -SELDSK: PUSH BC - CALL BOOT ;signon message - POP BC - LD HL,0000H ;error return code - LD A,C - CP 0 ;we boot from drive 0 only - RET NZ ;return error -; disk number is in the proper range -; return proper disk parameter header address - OUT (FDCD),A ;selekt disk drive - LD HL,DPH - RET -; -; set track given by register c -; -SETTRK: LD A,C - OUT (FDCT),A - RET -; -; set sector given by register c -; -SETSEC: LD A,C - OUT (FDCS),A - RET -; -; translate the sector given by BC using the -; translate table given by DE -; -SECTRAN: - EX DE,HL ;hl=.trans - ADD HL,BC ;hl=.trans(sector) - LD L,(HL) ;l = trans(sector) - LD H,0 ;hl= trans(sector) - RET ;with value in hl -; -; set dma address given by registers b and c -; -SETDMA: LD A,C ;low order address - OUT (DMAL),A - LD A,B ;high order address - OUT (DMAH),A ;in dma - RET -; -; perform read operation -; -READ: XOR A ;read command -> a - OUT (FDCOP),A ;start i/o operation - IN A,(FDCST) ;status of i/o operation -> a - RET -; -BEGDAT EQU $ -DIRBF: DEFS 128 ;scratch directory area -ALL00: DEFS 31 ;allocation vector -CHK00: DEFS 16 ;check vector -; -ENDDAT EQU $ ;end -DATSIZ EQU $-BEGDAT ;size of data area - END ;of bios diff --git a/emu/z80pack-1.9/cpmsim/srcsim/Makefile b/emu/z80pack-1.9/cpmsim/srcsim/Makefile deleted file mode 100644 index 5cd9216..0000000 --- a/emu/z80pack-1.9/cpmsim/srcsim/Makefile +++ /dev/null @@ -1,74 +0,0 @@ -CFLAGS= -O -c -Wall -LFLAGS= -s - -OBJ = sim0.o \ - sim1.o \ - sim2.o \ - sim3.o \ - sim4.o \ - sim5.o \ - sim6.o \ - sim7.o \ - simctl.o \ - simint.o \ - iosim.o \ - simfun.o \ - simglb.o - -all: ../auxin ../auxout ../cpmsim - @echo "done." - -../auxin: - test -f ../auxin || mknod ../auxin p - -../auxout: - test -f ../auxout || mknod ../auxout p - -../cpmsim : $(OBJ) - cc $(OBJ) $(LFLAGS) -o ../cpmsim - -sim0.c: - lnsrc - -sim0.o : sim0.c sim.h simglb.h - cc $(CFLAGS) sim0.c - -sim1.o : sim1.c sim.h simglb.h - cc $(CFLAGS) sim1.c - -sim2.o : sim2.c sim.h simglb.h - cc $(CFLAGS) sim2.c - -sim3.o : sim3.c sim.h simglb.h - cc $(CFLAGS) sim3.c - -sim4.o : sim4.c sim.h simglb.h - cc $(CFLAGS) sim4.c - -sim5.o : sim5.c sim.h simglb.h - cc $(CFLAGS) sim5.c - -sim6.o : sim6.c sim.h simglb.h - cc $(CFLAGS) sim6.c - -sim7.o : sim7.c sim.h simglb.h - cc $(CFLAGS) sim7.c - -simctl.o : simctl.c sim.h simglb.h - cc $(CFLAGS) simctl.c - -simint.o : simint.c sim.h simglb.h - cc $(CFLAGS) simint.c - -iosim.o : iosim.c sim.h simglb.h - cc $(CFLAGS) iosim.c - -simfun.o : simfun.c sim.h - cc $(CFLAGS) simfun.c - -simglb.o : simglb.c sim.h - cc $(CFLAGS) simglb.c - -clean: - rm -f *.o - ulnsrc diff --git a/emu/z80pack-1.9/cpmsim/srcsim/iosim.c b/emu/z80pack-1.9/cpmsim/srcsim/iosim.c deleted file mode 100644 index 154d375..0000000 --- a/emu/z80pack-1.9/cpmsim/srcsim/iosim.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * This modul contains a complex I/O-simulation for running - * CP/M 2, CP/M 3, MP/M... - * Please note this this doesn't emulate any hardware which - * ever existed, we've got all virtual circuits in here! - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 19-MAY-89 Additions for CP/M 3.0 und MP/M - * 23-DEC-90 Ported to COHERENT 3.0 - * 10-JUN-92 Some optimization done - * 25-JUN-92 Flush output of stdout only at every OUT to port 0 - * 25-JUN-92 Comments in english and ported to COHERENT 4.0 - * 05-OCT-06 modified to compile on modern POSIX OS's - * 18-NOV-06 added a second harddisk - */ - -/* - * This module contains the I/O handlers for a simulation - * of the hardware required for a CP/M system. - * - * Used I/O ports: - * - * 0 - console status - * 1 - console data - * - * 2 - printer status - * 3 - printer data - * - * 4 - auxilary status - * 5 - auxilary data - * - * 10 - FDC drive - * 11 - FDC track - * 12 - FDC sector - * 13 - FDC command - * 14 - FDC status - * - * 15 - DMA destination address low - * 16 - DMA destination address high - * - * 20 - MMU initialization - * 21 - MMU bank select - * - * 25 - clock command - * 26 - clock data - * 27 - 20ms timer causing INT, only usable in IM 1 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "sim.h" -#include "simglb.h" - -/* - * Structure to describe a emulated floppy disk drive: - * pointer to filename - * pointer to file descriptor - * number of tracks - * number of sectors - */ -struct dskdef { - char *fn; - int *fd; - unsigned int tracks; - unsigned int sectors; -}; - -static BYTE drive; /* current drive A..P (0..15) */ -static BYTE track; /* current track (0..255) */ -static BYTE sector; /* current sektor (0..255) */ -static BYTE status; /* status of last I/O operation on FDC */ -static BYTE dmadl; /* current DMA adresse destination low */ -static BYTE dmadh; /* current DMA adresse destination high */ -static BYTE clkcmd; /* clock command */ -static BYTE timer; /* 20ms timer */ -static int drivea; /* fd for file "drivea.cpm" */ -static int driveb; /* fd for file "driveb.cpm" */ -static int drivec; /* fd for file "drivec.cpm" */ -static int drived; /* fd for file "drived.cpm" */ -static int drivee; /* fd for file "drivee.cpm" */ -static int drivef; /* fd for file "drivef.cpm" */ -static int driveg; /* fd for file "driveg.cpm" */ -static int driveh; /* fd for file "driveh.cpm" */ -static int drivei; /* fd for file "drivei.cpm" */ -static int drivej; /* fd for file "drivej.cpm" */ -static int drivek; /* fd for file "drivek.cpm" */ -static int drivel; /* fd for file "drivel.cpm" */ -static int drivem; /* fd for file "drivem.cpm" */ -static int driven; /* fd for file "driven.cpm" */ -static int driveo; /* fd for file "driveo.cpm" */ -static int drivep; /* fd for file "drivep.cpm" */ -static int printer; /* fd for file "printer.cpm" */ -static int auxin; /* fd for pipe "auxin" */ -static int auxout; /* fd for pipe "auxout" */ -static int aux_in_eof; /* status of pipe "auxin" (<>0 means EOF) */ -static int pid_rec; /* PID of the receiving process for auxiliary */ -static char last_char; /* buffer for 1 character (console status) */ - -static struct dskdef disks[16] = { - { "disks/drivea.cpm", &drivea, 77, 26 }, - { "disks/driveb.cpm", &driveb, 77, 26 }, - { "disks/drivec.cpm", &drivec, 77, 26 }, - { "disks/drived.cpm", &drived, 77, 26 }, - { "disks/drivee.cpm", &drivee, -1, -1 }, - { "disks/drivef.cpm", &drivef, -1, -1 }, - { "disks/driveg.cpm", &driveg, -1, -1 }, - { "disks/driveh.cpm", &driveh, -1, -1 }, - { "disks/drivei.cpm", &drivei, 255, 128 }, - { "disks/drivej.cpm", &drivej, 255, 128 }, - { "disks/drivek.cpm", &drivek, -1, -1 }, - { "disks/drivel.cpm", &drivel, -1, -1 }, - { "disks/drivem.cpm", &drivem, -1, -1 }, - { "disks/driven.cpm", &driven, -1, -1 }, - { "disks/driveo.cpm", &driveo, -1, -1 }, - { "disks/drivep.cpm", &drivep, -1, -1 } -}; - -/* - * MMU: - * === - * - * +--------+ - * 16KB | common | - * +--------+ - * +--------+ +--------+ .......... +--------+ - * | | | | | | - * 48KB | | | | .......... | | - * | bank 0 | | bank 1 | | bank n | - * +--------+ +--------+ .......... +--------+ - */ -#define MAXSEG 16 /* max. number of memory banks */ -#define SEGSIZ 49152 /* size of one bank = 48KBytes */ -static char *mmu[MAXSEG]; /* MMU with pointers to the banks */ -static int selbnk; /* current bank */ -static int maxbnk; /* number of initialized banks */ - -/* - * Forward declaration of the I/O handlers for all used ports - */ -static BYTE io_trap(void); -static BYTE cond_in(void), cond_out(BYTE), cons_in(void), cons_out(BYTE); -static BYTE prtd_in(void), prtd_out(BYTE), prts_in(void), prts_out(BYTE); -static BYTE auxd_in(void), auxd_out(BYTE), auxs_in(void), auxs_out(BYTE); -static BYTE fdcd_in(void), fdcd_out(BYTE); -static BYTE fdct_in(void), fdct_out(BYTE); -static BYTE fdcs_in(void), fdcs_out(BYTE); -static BYTE fdco_in(void), fdco_out(BYTE); -static BYTE fdcx_in(void), fdcx_out(BYTE); -static BYTE dmal_in(void), dmal_out(BYTE); -static BYTE dmah_in(void), dmah_out(BYTE); -static BYTE mmui_in(void), mmui_out(BYTE), mmus_in(void), mmus_out(BYTE); -static BYTE clkc_in(void), clkc_out(BYTE), clkd_in(void), clkd_out(BYTE); -static BYTE time_in(void), time_out(BYTE); -static void int_timer(int); - -static int to_bcd(int), get_date(struct tm *); - -/* - * This array contains two function pointer for every - * active port, one for input and one for output. - */ -static BYTE (*port[256][2]) () = { - { cons_in, cons_out }, /* port 0 */ - { cond_in, cond_out }, /* port 1 */ - { prts_in, prts_out }, /* port 2 */ - { prtd_in, prtd_out }, /* port 3 */ - { auxs_in, auxs_out }, /* port 4 */ - { auxd_in, auxd_out }, /* port 5 */ - { io_trap, io_trap }, /* port 6 */ - { io_trap, io_trap }, /* port 7 */ - { io_trap, io_trap }, /* port 8 */ - { io_trap, io_trap }, /* port 9 */ - { fdcd_in, fdcd_out }, /* port 10 */ - { fdct_in, fdct_out }, /* port 11 */ - { fdcs_in, fdcs_out }, /* port 12 */ - { fdco_in, fdco_out }, /* port 13 */ - { fdcx_in, fdcx_out }, /* port 14 */ - { dmal_in, dmal_out }, /* port 15 */ - { dmah_in, dmah_out }, /* port 16 */ - { io_trap, io_trap }, /* port 17 */ - { io_trap, io_trap }, /* port 18 */ - { io_trap, io_trap }, /* port 19 */ - { mmui_in, mmui_out }, /* port 20 */ - { mmus_in, mmus_out }, /* port 21 */ - { io_trap, io_trap }, /* port 22 */ - { io_trap, io_trap }, /* port 23 */ - { io_trap, io_trap }, /* port 24 */ - { clkc_in, clkc_out }, /* port 25 */ - { clkd_in, clkd_out }, /* port 26 */ - { time_in, time_out } /* port 27 */ -}; - -/* - * This function initializes the I/O handlers: - * 1. Initialize all unused ports with the I/O trap handler. - * 2. Initialize the MMU with NULL pointers. - * 3. Open the files which emulates the disk drives. The file - * for drive A must be opened, or CP/M can't be booted. - * Errors for opening one of the other 15 drives results - * in a NULL pointer for fd in the dskdef structure, - * so that this drive can't be used. - * 4. Create and open the file "printer.cpm" for emulation - * of a printer. - * 5. Fork the process for receiving from the serial port. - * 6. Open the named pipes "auxin" and "auxout" for simulation - * of a serial port. - */ -void init_io(void) -{ - register int i; - - for (i = 28; i <= 255; i++) { - port[i][0] = io_trap; - port[i][1] = io_trap; - } - for (i = 0; i < MAXSEG; i++) - mmu[i] = NULL; - if ((*disks[0].fd = open(disks[0].fn, O_RDWR)) == -1) { - perror("file disks/drivea.cpm"); - exit(1); - } - for (i = 1; i <= 15; i++) - if ((*disks[i].fd = open(disks[i].fn, O_RDWR)) == -1) - disks[i].fd = NULL; - if ((printer = creat("printer.cpm", 0644)) == -1) { - perror("file printer.cpm"); - exit(1); - } - pid_rec = fork(); - switch (pid_rec) { - case -1: - puts("can't fork"); - exit(1); - case 0: - execlp("./receive", "receive", "auxiliary.cpm", (char *) NULL); - puts("can't exec receive process"); - exit(1); - } - if ((auxin = open("auxin", O_RDONLY | O_NDELAY)) == -1) { - perror("pipe auxin"); - exit(1); - } - if ((auxout = open("auxout", O_WRONLY)) == -1) { - perror("pipe auxout"); - exit(1); - } -} - -/* - * This function stops the I/O handlers: - * - * 1. The files emulating the disk drives are closed. - * 2. The file "printer.com" emulating a printer is closed. - * 3. The named pipes "auxin" and "auxout" are closed. - * 4. The receiving process for the serial port is stopped. - */ -void exit_io(void) -{ - register int i; - - for (i = 0; i <= 15; i++) - if (disks[i].fd != NULL) - close(*disks[i].fd); - close(printer); - close(auxin); - close(auxout); - kill(pid_rec, SIGHUP); -} - -/* - * This function is called for every IN opcode from the - * CPU emulation. It calls the right handler for the - * port, from which input is wanted. - */ -BYTE io_in(BYTE adr) -{ - return((*port[adr][0]) ()); -} - -/* - * This function is called for every OUT opcode from the - * CPU emulation. It calls the right handler for the port, - * to which output is wanted. - */ -BYTE io_out(BYTE adr, BYTE data) -{ - (*port[adr][1]) (data); - return((BYTE) 0); -} - -/* - * I/O trap handler - */ -static BYTE io_trap(void) -{ - if (i_flag) { - cpu_error = IOTRAP; - cpu_state = STOPPED; - } - return((BYTE) 0); -} - -/* - * I/O handler for read console status: - * 0xff : input available - * 0x00 : no input available - */ -static BYTE cons_in(void) -{ - register int flags, readed; - - if (last_char) - return((BYTE) 0xff); - if (cntl_c) - return((BYTE) 0xff); - if (cntl_bs) - return((BYTE) 0xff); - else { - flags = fcntl(0, F_GETFL, 0); - fcntl(0, F_SETFL, flags | O_NDELAY); - readed = read(0, &last_char, 1); - fcntl(0, F_SETFL, flags); - if (readed == 1) - return((BYTE) 0xff); - } - return((BYTE) 0); -} - -/* - * I/O handler for write console status: - * no reaction - */ -static BYTE cons_out(BYTE data) -{ - data = data; - return((BYTE) 0); -} - -/* - * I/O handler for read console data: - * read one character from the terminal without echo - * and character transformations - */ -static BYTE cond_in(void) -{ - char c; - - aborted: - if (last_char) { - c = last_char; - last_char = '\0'; - } else if (cntl_c) { - cntl_c--; - c = 0x03; - } else if (cntl_bs) { - cntl_bs--; - c = 0x1c; - } else if (read(0, &c, 1) != 1) { - goto aborted; - } - return((BYTE) c); -} - -/* - * I/O handler for write console data: - * the output is written to the terminal - */ -static BYTE cond_out(BYTE data) -{ - while ((write(fileno(stdout), (char *) &data, 1)) != 1) - ; - fflush(stdout); - return((BYTE) 0); -} - -/* - * I/O handler for read printer status: - * the printer is ready all the time - */ -static BYTE prts_in(void) -{ - return((BYTE) 0xff); -} - -/* - * I/O handler for write printer status: - * no reaction - */ -static BYTE prts_out(BYTE data) -{ - data = data; - return((BYTE) 0); -} - -/* - * I/O handler for read printer data: - * always read a 0 from the printer - */ -static BYTE prtd_in(void) -{ - return((BYTE) 0); -} - -/* - * I/O handler for write printer data: - * the output is written to file "printer.cpm" - */ -static BYTE prtd_out(BYTE data) -{ - if (data != '\r') - while ((write(printer, (char *) &data, 1)) != 1) - ; - return((BYTE) 0); -} - -/* - * I/O handler for read aux status: - * return EOF status of the aux device - */ -static BYTE auxs_in(void) -{ - return((BYTE) aux_in_eof); -} - -/* - * I/O handler for write aux status: - * change EOF status of the aux device - */ -static BYTE auxs_out(BYTE data) -{ - aux_in_eof = data; - return((BYTE) 0); -} - -/* - * I/O handler for read aux data: - * read next byte from pipe "auxin" - */ -static BYTE auxd_in(void) -{ - char c; - - if (read(auxin, &c, 1) == 1) - return((BYTE) c); - else { - aux_in_eof = 0xff; - return((BYTE) 0x1a); /* CP/M EOF */ - } -} - -/* - * I/O handler for write aux data: - * write output to pipe "auxout" - */ -static BYTE auxd_out(BYTE data) -{ - if (data != '\r') - write(auxout, (char *) &data, 1); - return((BYTE) 0); -} - -/* - * I/O handler for read FDC drive: - * return the current drive - */ -static BYTE fdcd_in(void) -{ - return((BYTE) drive); -} - -/* - * I/O handler for write FDC drive: - * set the current drive - */ -static BYTE fdcd_out(BYTE data) -{ - drive = data; - return((BYTE) 0); -} - -/* - * I/O handler for read FDC track: - * return the current track - */ -static BYTE fdct_in(void) -{ - return((BYTE) track); -} - -/* - * I/O handler for write FDC track: - * set the current track - */ -static BYTE fdct_out(BYTE data) -{ - track = data; - return((BYTE) 0); -} - -/* - * I/O handler for read FDC sector - * return the current sector - */ -static BYTE fdcs_in(void) -{ - return((BYTE) sector); -} - -/* - * I/O handler for write FDC sector: - * set the current sector - */ -static BYTE fdcs_out(BYTE data) -{ - sector = data; - return((BYTE) 0); -} - -/* - * I/O handler for read FDC command: - * always returns 0 - */ -static BYTE fdco_in(void) -{ - return((BYTE) 0); -} - -/* - * I/O handler for write FDC command: - * transfer one sector in the wanted direction, - * 0 = read, 1 = write - * - * The status byte of the FDC is set as follows: - * 0 - ok - * 1 - illegal drive - * 2 - illegal track - * 3 - illegal sector - * 4 - seek error - * 5 - read error - * 6 - write error - * 7 - illegal command to FDC - */ -static BYTE fdco_out(BYTE data) -{ - register long pos; - if (disks[drive].fd == NULL) { - status = 1; - return((BYTE) 0); - } - if (track > disks[drive].tracks) { - status = 2; - return((BYTE) 0); - } - if (sector > disks[drive].sectors) { - status = 3; - return((BYTE) 0); - } - pos = (((long)track) * ((long)disks[drive].sectors) + sector - 1) << 7; - if (lseek(*disks[drive].fd, pos, 0) == -1L) { - status = 4; - return((BYTE) 0); - } - switch (data) { - case 0: /* read */ - if (read(*disks[drive].fd, (char *) ram + (dmadh << 8) + - dmadl, 128) != 128) - status = 5; - else - status = 0; - break; - case 1: /* write */ - if (write(*disks[drive].fd, (char *) ram + (dmadh << 8) + - dmadl, 128) != 128) - status = 6; - else - status = 0; - break; - default: /* illegal command */ - status = 7; - break; - } - return((BYTE) 0); -} - -/* - * I/O handler for read FDC status: - * returns status of last FDC operation, - * 0 = ok, else some error - */ -static BYTE fdcx_in(void) -{ - return((BYTE) status); -} - -/* - * I/O handler for write FDC status: - * no reaction - */ -static BYTE fdcx_out(BYTE data) -{ - data = data; - return((BYTE) 0); -} - -/* - * I/O handler for read lower byte of DMA address: - * return lower byte of current DMA address - */ -static BYTE dmal_in(void) -{ - return((BYTE) dmadl); -} - -/* - * I/O handler for write lower byte of DMA address: - * set lower byte of DMA address - */ -static BYTE dmal_out(BYTE data) -{ - dmadl = data; - return((BYTE) 0); -} - -/* - * I/O handler for read higher byte of DMA address: - * return higher byte of current DMA address - */ -static BYTE dmah_in(void) -{ - return((BYTE) dmadh); -} - -/* - * I/O handler for write higher byte of DMA address: - * set higher byte of the DMA address - */ -static BYTE dmah_out(BYTE data) -{ - dmadh = data; - return((BYTE) 0); -} - -/* - * I/O handler for read MMU initialization: - * return number of initialized MMU banks - */ -static BYTE mmui_in(void) -{ - return((BYTE) maxbnk); -} - -/* - * I/O handler for write MMU initialization: - * for the FIRST call the memory for the wanted number of banks - * is allocated and pointers to the memory is stored in the MMU array - */ -static BYTE mmui_out(BYTE data) -{ - register int i; - - if (mmu[0] != NULL) - return((BYTE) 0); - if (data > MAXSEG) { - printf("Try to init %d banks, available %d banks\n", - data, MAXSEG); - exit(1); - } - for (i = 0; i < data; i++) { - if ((mmu[i] = malloc(SEGSIZ)) == NULL) { - printf("can't allocate memory for bank %d\n", i+1); - exit(1); - } - } - maxbnk = data; - return((BYTE) 0); -} - -/* - * I/O handler for read MMU bank select: - * return current selected MMU bank - */ -static BYTE mmus_in(void) -{ - return((BYTE) selbnk); -} - -/* - * I/O handler for write MMU bank select: - * if the current selected bank is not equal the wanted bank, - * the current bank is saved. Then the memory of the wanted - * bank is copied into the CPU address space and this bank is - * set to be the current one now. - */ -static BYTE mmus_out(BYTE data) -{ - if (data > maxbnk) { - printf("Try to select unallocated bank %d\n", data); - exit(1); - } - if (data == selbnk) - return((BYTE) 0); - memcpy(mmu[selbnk], (char *) ram, SEGSIZ); - memcpy((char *) ram, mmu[data], SEGSIZ); - selbnk = data; - return((BYTE) 0); -} - -/* - * I/O handler for read clock command: - * return last clock command - */ -static BYTE clkc_in(void) -{ - return(clkcmd); -} - -/* - * I/O handler for write clock command: - * set the wanted clock command - */ -static BYTE clkc_out(BYTE data) -{ - clkcmd = data; - return((BYTE) 0); -} - -/* - * I/O handler for read clock data: - * dependent from the last clock command the following - * informations are given from the system clock: - * 0 - seconds in BCD - * 1 - minutes in BCD - * 2 - hours in BCD - * 3 - low byte number of days since 1.1.1978 - * 4 - high byte number of days since 1.1.1978 - * for every other clock command a 0 is returned - */ -static BYTE clkd_in(void) -{ - register struct tm *t; - register int val; - time_t Time; - - time(&Time); - t = localtime(&Time); - switch(clkcmd) { - case 0: /* seconds in BCD */ - val = to_bcd(t->tm_sec); - break; - case 1: /* minutes in BCD */ - val = to_bcd(t->tm_min); - break; - case 2: /* hours in BCD */ - val = to_bcd(t->tm_hour); - break; - case 3: /* low byte days */ - val = get_date(t) & 255; - break; - case 4: /* high byte days */ - val = get_date(t) >> 8; - break; - default: - val = 0; - break; - } - return((BYTE) val); -} - -/* - * I/O handler for write clock data: - * under UNIX the system clock only can be set by the - * super user, so we do nothing here - */ -static BYTE clkd_out(BYTE data) -{ - data = data; - return((BYTE) 0); -} - -/* - * Convert an integer to BCD - */ -static int to_bcd(int val) -{ - register int i = 0; - - while (val >= 10) { - i += val / 10; - i <<= 4; - val %= 10; - } - i += val; - return (i); -} - -/* - * Calculate number of days since 1.1.1978 - * The Y2K bug here is intentional, CP/M 3 has a Y2K bug fix - */ -static int get_date(struct tm *t) -{ - register int i; - register int val = 0; - - for (i = 1978; i < 1900 + t->tm_year; i++) { - val += 365; - if (i % 4 == 0) - val++; - } - val += t->tm_yday + 1; - return(val); -} - -/* - * I/O handler for write timer - */ -static BYTE time_out(BYTE data) -{ - static struct itimerval tim; - static struct sigaction newact; - - if (data == 1) { - timer = 1; - newact.sa_handler = int_timer; - sigaction(SIGALRM, &newact, NULL); - tim.it_value.tv_sec = 0; - tim.it_value.tv_usec = 20000; - tim.it_interval.tv_sec = 0; - tim.it_interval.tv_usec = 20000; - setitimer(ITIMER_REAL, &tim, NULL); - } else { - timer = 0; - newact.sa_handler = SIG_IGN; - sigaction(SIGALRM, &newact, NULL); - tim.it_value.tv_sec = 0; - tim.it_value.tv_usec = 0; - setitimer(ITIMER_REAL, &tim, NULL); - } - return((BYTE) 0); -} - -/* - * I/O handler for read timer - */ -static BYTE time_in(void) -{ - return(timer); -} - -/* - * timer interrupt causes maskerable CPU interrupt - */ -static void int_timer(int sig) -{ - int_type = INT_INT; -} diff --git a/emu/z80pack-1.9/cpmsim/srcsim/lnsrc b/emu/z80pack-1.9/cpmsim/srcsim/lnsrc deleted file mode 100755 index 682dfe4..0000000 --- a/emu/z80pack-1.9/cpmsim/srcsim/lnsrc +++ /dev/null @@ -1,14 +0,0 @@ -# use this to link the common parts of Z80 simulation - -ln ../../z80sim/sim0.c sim0.c -ln ../../z80sim/sim1.c sim1.c -ln ../../z80sim/sim2.c sim2.c -ln ../../z80sim/sim3.c sim3.c -ln ../../z80sim/sim4.c sim4.c -ln ../../z80sim/sim5.c sim5.c -ln ../../z80sim/sim6.c sim6.c -ln ../../z80sim/sim7.c sim7.c -ln ../../z80sim/simfun.c simfun.c -ln ../../z80sim/simint.c simint.c -ln ../../z80sim/simglb.c simglb.c -ln ../../z80sim/simglb.h simglb.h diff --git a/emu/z80pack-1.9/cpmsim/srcsim/sim.h b/emu/z80pack-1.9/cpmsim/srcsim/sim.h deleted file mode 100644 index 48bcbb5..0000000 --- a/emu/z80pack-1.9/cpmsim/srcsim/sim.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Develoment on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 23-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 02-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * The following defines may be activated, commented or modified - * by user for her/his own purpose. - */ -#define WANT_INT /* interrupt for MP/M */ -/*#define WANT_SPC*/ /* CP/M doesn't work with SP over-/underrun */ -/*#define WANT_PCC*/ /* CP/M doesn't work with PC overrun */ -/*#define CNTL_C*/ /* don't abort simulation with cntl-c */ -#define CNTL_BS /* emergency exit with cntl-\ :-) */ -/*#define CNTL_Z*/ /* don't suspend simulation with cntl-z */ -#define WANT_TIM /* run length measurement needed to adjust CPU speed */ -/*#define HISIZE 1000*//* no history */ -/*#define SBSIZE 10*/ /* no breakpoints */ - -/* - * The following lines of this file should not be modified by user - */ -#define COPYR "Copyright (C) 1987-2006 by Udo Munk" -#define RELEASE "1.9" - -#define LENCMD 80 /* length of command buffers etc */ - -#define S_FLAG 128 /* bit definitions of CPU flags */ -#define Z_FLAG 64 -#define N2_FLAG 32 -#define H_FLAG 16 -#define N1_FLAG 8 -#define P_FLAG 4 -#define N_FLAG 2 -#define C_FLAG 1 - - /* operation of simulated CPU */ -#define SINGLE_STEP 0 /* single step */ -#define CONTIN_RUN 1 /* continual run */ -#define STOPPED 0 /* stop CPU because of error */ - - /* causes of error */ -#define NONE 0 /* no error */ -#define OPHALT 1 /* HALT op-code trap */ -#define IOTRAP 2 /* IN/OUT trap */ -#define OPTRAP1 3 /* illegal 1 byte op-code trap */ -#define OPTRAP2 4 /* illegal 2 byte op-code trap */ -#define OPTRAP4 5 /* illegal 4 byte op-code trap */ -#define USERINT 6 /* user interrupt */ - - /* type of CPU interrupt */ -#define INT_NONE 0 -#define INT_NMI 1 /* non maskable interrupt */ -#define INT_INT 2 /* maskable interrupt */ - -typedef unsigned short WORD; /* 16 bit unsigned */ -typedef unsigned char BYTE; /* 8 bit unsigned */ - -#ifdef HISIZE -struct history { /* structure of a history entry */ - WORD h_adr; /* address of execution */ - WORD h_af; /* register AF */ - WORD h_bc; /* register BC */ - WORD h_de; /* register DE */ - WORD h_hl; /* register HL */ - WORD h_ix; /* register IX */ - WORD h_iy; /* register IY */ - WORD h_sp; /* register SP */ -}; -#endif - -#ifdef SBSIZE -struct softbreak { /* structure of a breakpoint */ - WORD sb_adr; /* address of breakpoint */ - BYTE sb_oldopc; /* op-code at address of breakpoint */ - int sb_passcount; /* pass counter of breakpoint */ - int sb_pass; /* no. of pass to break */ -}; -#endif - -#ifndef isxdigit -#define isxdigit(c) ((c<='f'&&c>='a')||(c<='F'&&c>='A')||(c<='9'&&c>='0')) -#endif diff --git a/emu/z80pack-1.9/cpmsim/srcsim/simctl.c b/emu/z80pack-1.9/cpmsim/srcsim/simctl.c deleted file mode 100644 index d5d12b4..0000000 --- a/emu/z80pack-1.9/cpmsim/srcsim/simctl.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 14-MAR-89 new option -l - * 23-DEC-90 Ported to COHERENT 3.0 - * 06-OCT-06 modified to compile on modern POSIX OS's - */ - -#include -#include -#include -#include -#include "sim.h" -#include "simglb.h" - -extern void cpu(void); - -struct termios old_term, new_term; - -/* - * This function gets the CP/M boot sector from first track/sector - * of disk drive A (file drivea.cpm) into memory started at 0. - * Then the Z80 CPU emulation is started and the system should boot. - */ -void mon(void) -{ - register int fd; - - if (!l_flag) { - if ((fd = open("disks/drivea.cpm", O_RDONLY)) == -1) { - perror("file disks/drivea.cpm"); - return; - } - if (read(fd, (char *) ram, 128) != 128) { - perror("file disks/drivea.cpm"); - return; - } - close(fd); - } - - tcgetattr(0, &old_term); - new_term = old_term; - new_term.c_lflag &= ~(ICANON | ECHO); - new_term.c_iflag &= ~(IXON | IXANY | IXOFF); - new_term.c_iflag &= ~(IGNCR | ICRNL | INLCR); - new_term.c_cc[VMIN] = 1; -#ifndef CNTL_Z - new_term.c_cc[VSUSP] = 0; -#endif - tcsetattr(0, TCSADRAIN, &new_term); - - cpu_state = CONTIN_RUN; - cpu_error = NONE; - cpu(); - - tcsetattr(0, TCSADRAIN, &old_term); - - switch (cpu_error) { - case NONE: - break; - case OPHALT: - printf("\nHALT Op-Code reached at %04x\n", - (unsigned int)(PC - ram - 1)); - break; - case IOTRAP: - printf("\nI/O Trap at %04x\n", (unsigned int)(PC - ram)); - break; - case OPTRAP1: - printf("\nOp-code trap at %04x %02x\n", - (unsigned int)(PC - 1 - ram), *(PC - 1)); - break; - case OPTRAP2: - printf("\nOp-code trap at %04x %02x %02x\n", - (unsigned int)(PC - 2 - ram), *(PC - 2), *(PC - 1)); - break; - case OPTRAP4: - printf("\nOp-code trap at %04x %02x %02x %02x %02x\n", - (unsigned int)(PC - 4 - ram), *(PC - 4), *(PC - 3), - *(PC - 2), *(PC - 1)); - break; - case USERINT: - puts("\nUser Interrupt"); - break; - default: - printf("\nUnknown error %d\n", cpu_error); - break; - } -} diff --git a/emu/z80pack-1.9/cpmsim/srcsim/ulnsrc b/emu/z80pack-1.9/cpmsim/srcsim/ulnsrc deleted file mode 100755 index fcbc250..0000000 --- a/emu/z80pack-1.9/cpmsim/srcsim/ulnsrc +++ /dev/null @@ -1,6 +0,0 @@ -# use this to unlink the common parts of Z80 simulation - -rm sim[0-7].c -rm simfun.c -rm simint.c -rm simglb.[hc] diff --git a/emu/z80pack-1.9/doc/COPYING b/emu/z80pack-1.9/doc/COPYING deleted file mode 100644 index 71b3b85..0000000 --- a/emu/z80pack-1.9/doc/COPYING +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 1987-2006 Udo Munk - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/emu/z80pack-1.9/doc/README-asm.txt b/emu/z80pack-1.9/doc/README-asm.txt deleted file mode 100644 index 705e13e..0000000 --- a/emu/z80pack-1.9/doc/README-asm.txt +++ /dev/null @@ -1,85 +0,0 @@ -Usage: - -z80asm -ofile -f[b|m|h] -l[file] -s[n|a] -x -v -dsymbol ... file ... - -A maximum of 512 source files is allowed. If the filename of a source -doesn't have an extension the default extension ".asm" will be -concated. Source file names may have a path, the maximum length of -a full qualified filename is 2048 characters. -For relative paths the extension must be used, because all characters -after a "." would be used as extension! - -Option o: -To override the default name of the output file. Without this option -the name of the output file becomes the name of the input file, -but with the extension ".bin". The output file may have a path, -the maximum length is limited to 2048 characters. - -Option f: -Format of the output file: - - -fb -> binary file - -fm -> binary file with Mostek header - -fh -> Intel hex - -Option l: -Without this option no list file will be generated. With -l a list -file with the name of the source file but extension ".lis" will be -generated. An optional file name with path (2048 characters maximum) -may be added to this option. - -Option s: -This option writes the unsorted symbol table (-s), sorted by name (-sn) -or sorted by address (-sa) into the list file. This option only works -together with option -l. - -Option x: -Don't output data in pass 2 into object file for DEFS. This only works -if unallocated data isn't followed by any code or initialized data! -Usefull for CP/M BIOS's, where unallocated data doesn't need to be -part of the system image, if the complete image won't fit on the system -tracks. - -Option v: -Verbose operation of the assembler. - -Option d: -This option predefines symbols with a value of 0. -The number of this option is not limited in the command line. - -Pseudo Operations: - -Definition of symbols and allocation of memory: - - ORG - set program address - EQU - define constant symbol - DEFL - define variable symbol - DEFB - write bytes in memory - DEFW - write words (16 bits) in memory - DEFM <'string'> - write character string in memory - DEFS - reserve space in memory - - -Conditional assembly: - -IFDEF - assemble if symbol defined -IFNDEF - assemble if symbol not defined -IFEQ - assemble if equal -IFNEQ - assemble if not equal -ELSE - else for all conditionals -ENDIF - end of conditional assembly - - -Manipulation of list file: - -PAGE - number of lines/page -EJECT - skip to new page -LIST - listing on -NOLIST - listing off -TITLE <'string'> - define title for page header - - -Others: - -INCLUDE - include another source file -PRINT <'string'> - print string to stdout in pass one diff --git a/emu/z80pack-1.9/doc/README-cpm2.txt b/emu/z80pack-1.9/doc/README-cpm2.txt deleted file mode 100644 index 6b8cb5b..0000000 --- a/emu/z80pack-1.9/doc/README-cpm2.txt +++ /dev/null @@ -1,54 +0,0 @@ - Quickstart to run CP/M and MP/M on the Z80-CPU simulation - -1. Change to directory ~/z80pack/cpmsim/srcsim - make - make clean -This compiles the CPU and hardware emulation needed to run CP/M and MP/M. - -2. Change to directory ~/z80pack/cpmsim/srccpm2 - make - make clean -This compiles support programs (see below), installs named pipes and so on. - -3. Make backup copies of your distribution disks! - cd ~/z80pack/cpmsim/disks/library - cp *.dsk ../backups - -4. Change to directory ~/z80pack/cpmsim - cpm2 - run CP/M 2.2 - cpm3 - run CP/M 3.0 - mpm - this boots CP/M 2, run command mpm to boot MP/M 2 - -Usage of the support programs: - -format: to create an empty disk image for the CP/M simulation. - input: format - output: in directory disks files drivea.cpm, driveb.cpm, - drivec.cpm, drived.cpm, drivei.cpm and drivej.cpm - -bin2hex:converts binary files to Intel hex. - -receive:This is a process spawned by cpmsim. It reads from the named - pipe auxout and writes all input from the pipe to the file, - which is given as first argument. cpmsim spawns this process - with the output filename auxiliary.cpm. Inside the simulator - this pipe is connected to I/O-port 5, which is assigned - to the CP/M device PUN:. So everything you write from CP/M - to device PUN: goes into the file auxiliary.cpm on the - UNIX host. - -send: This process is to send a file from the UNIX host to the - simulator. Type send &, and then run cpmsim. - The process writes all data from file into the named pipe - auxin, which is also connected to I/O-port 5, which is - assigned to the CP/M device RDR:. You may use this to - transfer a file from the UNIX host to the simulator. - Under CP/M type pip file=RDR: to read the data send from - the process on the UNIX host. - -If you use PIP to transfer files between the UNIX host and the -simulator, you can only use ASCII files, because pip uses cntl-z -for EOF! To transfer a binary file from the UNIX host to the -simulator convert it to Intel hex format with bin2hex. This -can be converted back to a binary file under CP/M with the LOAD -command. diff --git a/emu/z80pack-1.9/doc/z80-documented.pdf b/emu/z80pack-1.9/doc/z80-documented.pdf deleted file mode 100644 index 3db25eb..0000000 Binary files a/emu/z80pack-1.9/doc/z80-documented.pdf and /dev/null differ diff --git a/emu/z80pack-1.9/z80asm/Makefile b/emu/z80pack-1.9/z80asm/Makefile deleted file mode 100644 index 106e3b1..0000000 --- a/emu/z80pack-1.9/z80asm/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -CFLAGS = -c -O -LFLAGS = -s - -OBJ = z80amain.o \ - z80atab.o \ - z80anum.o \ - z80aout.o \ - z80arfun.o \ - z80apfun.o \ - z80aopc.o \ - z80aglb.o - -z80asm : $(OBJ) - cc $(OBJ) $(LFLAGS) -o z80asm - -z80amain.o : z80amain.c z80a.h z80aglb.h - cc $(CFLAGS) z80amain.c - -z80atab.o : z80atab.c z80a.h z80aglb.h - cc $(CFLAGS) z80atab.c - -z80anum.o : z80anum.c z80a.h z80aglb.h - cc $(CFLAGS) z80anum.c - -z80aout.o : z80aout.c z80a.h z80aglb.h - cc $(CFLAGS) z80aout.c - -z80arfun.o : z80arfun.c z80a.h z80aglb.h - cc $(CFLAGS) z80arfun.c - -z80apfun.o : z80apfun.c z80a.h z80aglb.h - cc $(CFLAGS) z80apfun.c - -z80aopc.o : z80aopc.c z80a.h - cc $(CFLAGS) z80aopc.c - -z80aglb.o : z80aglb.c z80a.h - cc $(CFLAGS) z80aglb.c - -clean: - rm -f core *.o z80asm diff --git a/emu/z80pack-1.9/z80asm/z80a.h b/emu/z80pack-1.9/z80asm/z80a.h deleted file mode 100644 index 48c46fa..0000000 --- a/emu/z80pack-1.9/z80asm/z80a.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 21-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * OS dependant definitions - */ -#define LENFN 2048 /* max. filename length */ -#define READA "r" /* file open mode read ascii */ -#define WRITEA "w" /* file open mode write ascii */ -#define WRITEB "w" /* file open mode write binary */ - -/* - * various constants - */ -#define REL "1.3" -#define COPYR "Copyright (C) 1987-2006 by Udo Munk" -#define SRCEXT ".asm" /* filenamen extension source */ -#define OBJEXT ".bin" /* filenamen extension object */ -#define LSTEXT ".lis" /* filenamen extension listing */ -#define OUTBIN 1 /* format of object: binary */ -#define OUTMOS 2 /* Mostek binaer */ -#define OUTHEX 3 /* Intel hex */ -#define OUTDEF OUTMOS /* default object format */ -#define COMMENT ';' /* inline comment character */ -#define LINCOM '*' /* comment line if in columne 1 */ -#define LABSEP ':' /* label separator */ -#define STRSEP '\'' /* string separator */ -#define ENDFILE "END" /* end of source */ -#define MAXFN 512 /* max. no. source files */ -#define MAXLINE 128 /* max. line length source */ -#define PLENGTH 65 /* default lines/page in listing */ -#define SYMSIZE 8 /* max. symbol length */ -#define INCNEST 5 /* max. INCLUDE nesting depth */ -#define IFNEST 5 /* max IF.. nesting depth */ -#define HASHSIZE 500 /* max. entries in symbol hash array */ -#define OPCARRAY 256 /* size of object buffer */ -#define SYMINC 100 /* start size of sorted symbol array */ - -/* - * structure opcode table - */ -struct opc { - char *op_name; /* opcode name */ - int (*op_fun) (); /* function pointer code generation */ - int op_c1; /* first base opcode*/ - int op_c2; /* second base opcode */ -}; - -/* - * structure operand table - */ -struct ope { - char *ope_name; /* operand name */ - int ope_sym; /* symbol value operand */ -}; - -/* - * structure symbol table entries - */ -struct sym { - char *sym_name; /* symbol name */ - int sym_wert; /* symbol value */ - struct sym *sym_next; /* next entry */ -}; - -/* - * structure nested INCLUDE's - */ -struct inc { - unsigned inc_line; /* line counter for listing */ - char *inc_fn; /* filename */ - FILE *inc_fp; /* file pointer */ -}; - -/* - * definition of operand symbols - * definitions for registers A, B, C, D, H, L and (HL) - * are defined as the bits used in operands and may not - * be changed! - */ -#define REGB 0 /* register B */ -#define REGC 1 /* register C */ -#define REGD 2 /* register D */ -#define REGE 3 /* register E */ -#define REGH 4 /* register H */ -#define REGL 5 /* register L */ -#define REGIHL 6 /* register indirect HL */ -#define REGA 7 /* register A */ -#define REGI 8 /* register I */ -#define REGR 9 /* register R */ -#define REGAF 10 /* register pair AF */ -#define REGBC 11 /* register pair BC */ -#define REGDE 12 /* register pair DE */ -#define REGHL 13 /* register pair HL */ -#define REGIX 14 /* register IX */ -#define REGIY 15 /* register IY */ -#define REGSP 16 /* register SP */ -#define REGIBC 17 /* register indirect BC */ -#define REGIDE 18 /* register indirect DE */ -#define REGIIX 19 /* register indirect IX */ -#define REGIIY 20 /* register indirect IY */ -#define REGISP 21 /* register indirect SP */ -#define FLGNC 30 /* flag no carry */ -#define FLGNZ 31 /* flag not zerro */ -#define FLGZ 32 /* flag zerro */ -#define FLGM 33 /* flag minus */ -#define FLGP 34 /* flag plus */ -#define FLGPE 35 /* flag parrity even */ -#define FLGPO 36 /* flag parrity odd */ -#define NOOPERA 98 /* no operand */ -#define NOREG 99 /* operand isn't register */ - -/* - * definitions of error numbers for error messages in listfile - */ -#define E_ILLOPC 0 /* illegal opcode */ -#define E_ILLOPE 1 /* illegal operand */ -#define E_MISOPE 2 /* missing operand */ -#define E_MULSYM 3 /* multiple defined symbol */ -#define E_UNDSYM 4 /* undefined symbol */ -#define E_VALOUT 5 /* value out of bounds */ -#define E_MISPAR 6 /* missing parren */ -#define E_MISHYP 7 /* missing string separator */ -#define E_MEMOVR 8 /* memory override (ORG) */ -#define E_MISIFF 9 /* missing IF at ELSE or ENDIF */ -#define E_IFNEST 10 /* to many IF's nested */ -#define E_MISEIF 11 /* missing ENDIF */ -#define E_INCNEST 12 /* to many INCLUDE's nested */ - -/* - * definition fatal errors - */ -#define F_OUTMEM 0 /* out of memory */ -#define F_USAGE 1 /* usage: .... */ -#define F_HALT 2 /* assembly halted */ -#define F_FOPEN 3 /* can't open file */ -#define F_INTERN 4 /* internal error */ diff --git a/emu/z80pack-1.9/z80asm/z80aglb.c b/emu/z80pack-1.9/z80asm/z80aglb.c deleted file mode 100644 index 1021feb..0000000 --- a/emu/z80pack-1.9/z80asm/z80aglb.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 21-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * this module contains all global variables other - * than CPU specific tables - */ - -#include -#include "z80a.h" - -char *infiles[MAXFN], /* source filenames */ - objfn[LENFN + 1], /* object filename */ - lstfn[LENFN + 1], /* listing filename */ - *srcfn, /* filename of current processed source file */ - line[MAXLINE], /* buffer for one line souce */ - tmp[MAXLINE], /* temporary buffer */ - label[SYMSIZE+1], /* buffer for label */ - opcode[MAXLINE], /* buffer for opcode */ - operand[MAXLINE], /* buffer for operand */ - ops[OPCARRAY], /* buffer for generated object code */ - title[MAXLINE]; /* buffer for titel of souce */ - -int list_flag, /* flag for option -l */ - sym_flag, /* flag for option -s */ - ver_flag, /* flag for option -v */ - dump_flag, /* flag for option -x */ - pc, /* programm counter */ - pass, /* processed pass */ - iflevel, /* IF nesting level */ - gencode = 1, /* flag for conditional object code */ - errors, /* error counter */ - errnum, /* error number in pass 2 */ - sd_flag, /* list flag for PSEUDO opcodes */ - /* = 0: address from , data from */ - /* = 1: address from , data from */ - /* = 2: no address, data from */ - /* = 3: address from , no data */ - /* = 4: suppress whole line */ - sd_val, /* output value for PSEUDO opcodes */ - prg_adr, /* start address of programm */ - prg_flag, /* flag for prg_adr valid */ - out_form = OUTDEF, /* format of object file */ - symsize; /* size of symarray */ - -FILE *srcfp, /* file pointer for current source */ - *objfp, /* file pointer for object code */ - *lstfp, /* file pointer for listing */ - *errfp; /* file pointer for error output */ - -unsigned - c_line, /* current line no. in current source */ - s_line, /* line no. counter for listing */ - p_line, /* no. printed lines on page */ - ppl = PLENGTH, /* page length */ - page; /* no. of pages for listing */ - -struct sym - *symtab[HASHSIZE], /* symbol table */ - **symarray; /* sorted symbol table */ diff --git a/emu/z80pack-1.9/z80asm/z80aglb.h b/emu/z80pack-1.9/z80asm/z80aglb.h deleted file mode 100644 index 7f92cbe..0000000 --- a/emu/z80pack-1.9/z80asm/z80aglb.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 21-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * global variable declarations - */ - -extern char *infiles[], - objfn[], - lstfn[], - *srcfn, - line[], - tmp[], - label[], - opcode[], - operand[], - ops[], - title[]; - -extern int list_flag, - sym_flag, - ver_flag, - dump_flag, - pc, - pass, - iflevel, - gencode, - errors, - errnum, - sd_flag, - sd_val, - prg_adr, - prg_flag, - out_form, - symsize, - no_opcodes, - no_operands; - -extern FILE *srcfp, - *objfp, - *lstfp, - *errfp; - -extern unsigned c_line, - s_line, - p_line, - ppl, - page; - -extern struct sym *symtab[], - **symarray; - -extern struct opc opctab[]; - -extern struct ope opetab[]; diff --git a/emu/z80pack-1.9/z80asm/z80amain.c b/emu/z80pack-1.9/z80asm/z80amain.c deleted file mode 100644 index 7ea3230..0000000 --- a/emu/z80pack-1.9/z80asm/z80amain.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 21-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * main module, handles the options and runs 2 passes over the sources - */ - -#include -#include -#include -#include "z80a.h" -#include "z80aglb.h" - -void init(void), options(int, char *[]); -void usage(void), fatal(int, char *); -void pass1(void), p1_file(char *); -void pass2(void), p2_file(char *); -void open_o_files(char *), get_fn(char *, char *, char *); -char *get_label(char *, char *); -char *get_opcode(char *, char *); -char *get_arg(char *, char *); - -extern void asmerr(int); -extern void lst_line(int, int); -extern void lst_sym(void); -extern void lst_sort_sym(int); -extern void obj_header(void); -extern void obj_end(void); -extern void obj_writeb(int); -extern struct opc *search_op(char *); -extern int put_sym(char *, int); -extern void put_label(void); -extern int copy_sym(void); -extern void n_sort_sym(int); -extern void a_sort_sym(int); - -static char *errmsg[] = { /* error messages for fatal() */ - "out of memory: %s", /* 0 */ - "usage: z80asm -ofile -f[b|m|h] -l[file] -s[n|a] {-x} -v -dsymbol ... file ...", - "Assembly halted", /* 2 */ - "can't open file %s", /* 3 */ - "internal error: %s" /* 4 */ -}; - -main(int argc, char *argv[]) -{ - int len; - - init(); - options(argc, argv); - printf("Z80 - Assembler Release %s, %s\n", REL, COPYR); - pass1(); - pass2(); - if (list_flag) { - switch (sym_flag) { - case 0: /* no symbol table */ - break; - case 1: /* unsorted symbol table */ - lst_sym(); - break; - case 2: /* symbol table sorted by name */ - len = copy_sym(); - n_sort_sym(len); - lst_sort_sym(len); - break; - case 3: /* symbol table sorted by address */ - len = copy_sym(); - a_sort_sym(len); - lst_sort_sym(len); - break; - default: - break; - } - fclose(lstfp); - } - return(errors); -} - -/* - * initialization - */ -void init(void) -{ - errfp = stdout; -} - -/* - * process options - */ -void options(int argc, char *argv[]) -{ - register char *s, *t; - register int i; - - while (--argc > 0 && (*++argv)[0] == '-') - for (s = argv[0]+1; *s != '\0'; s++) - switch (*s) { - case 'o': - case 'O': - if (*++s == '\0') { - puts("name missing in option -o"); - usage(); - } - get_fn(objfn, s, OBJEXT); - s += (strlen(s) - 1); - break; - case 'l': - case 'L': - if (*(s + 1) != '\0') { - get_fn(lstfn, ++s, LSTEXT); - s += (strlen(s) - 1); - } - list_flag = 1; - break; - case 's': - case 'S': - if (*(s + 1) == '\0') - sym_flag = 1; - else if ((*(s + 1) == 'n') || (*(s + 1) == 'N')) - sym_flag = 2; - else if ((*(s + 1) == 'a') || (*(s + 1) == 'A')) - sym_flag = 3; - else { - printf("unknown option -%s\n", s); - usage(); - } - s += (strlen(s) - 1); - break; - case 'x': - case 'X': - dump_flag = 1; - break; - case 'f': - case 'F': - if ((*(s + 1) == 'b') || (*(s + 1) == 'B')) - out_form = OUTBIN; - else if ((*(s + 1) == 'm') || (*(s + 1) == 'M')) - out_form = OUTMOS; - else if ((*(s + 1) == 'h') || (*(s + 1) == 'H')) - out_form = OUTHEX; - else { - printf("unknown option -%s\n", s); - usage(); - } - s += (strlen(s) - 1); - break; - case 'd': - case 'D': - if (*++s == '\0') { - puts("name missing in option -d"); - usage(); - } - t = tmp; - while (*s) - *t++ = islower(*s) ? toupper(*s++) - : *s++; - s--; - *t = '\0'; - if (put_sym(tmp, 0)) - fatal(F_OUTMEM, "symbols"); - break; - case 'v': - case 'V': - ver_flag = 1; - break; - default : - printf("unknown option %c\n", *s); - usage(); - } - i = 0; - while ((argc--) && (i < MAXFN)) { - if ((infiles[i] = malloc(LENFN + 1)) == NULL) - fatal(F_OUTMEM, "filenames"); - get_fn(infiles[i], *argv++, SRCEXT); - i++; - } - if (i == 0) { - printf("no input file given\n"); - usage(); - } -} - -/* - * error in options, print usage - */ -void usage(void) -{ - fatal(F_USAGE, NULL); -} - -/* - * print error messages and abort - */ -void fatal(int i, char *arg) -{ - printf(errmsg[i], arg); - putchar('\n'); - exit(1); -} - -/* - * Pass 1: - * - process all source files - */ -void pass1(void) -{ - register int fi; - - pass = 1; - pc = 0; - fi = 0; - if (!ver_flag) - puts("Pass 1"); - open_o_files(infiles[fi]); - while (infiles[fi] != NULL) { - if (!ver_flag) - printf(" Read %s\n", infiles[fi]); - p1_file(infiles[fi]); - fi++; - } - if (errors) { - fclose(objfp); - unlink(objfn); - printf("%d error(s)\n", errors); - fatal(F_HALT, NULL); - } -} - -/* - * Pass 1: - * - process one source file - * - * Input: name of source file - */ -void p1_file(char *fn) -{ - c_line = 0; - srcfn = fn; - if ((srcfp = fopen(fn, READA)) == NULL) - fatal(F_FOPEN, fn); - while (p1_line()) - ; - fclose(srcfp); - if (iflevel) - asmerr(E_MISEIF); -} - -/* - * Pass 1: - * - process one line of source - * - * Output: 1 line processed - * 0 EOF - */ -int p1_line(void) -{ - register char *p; - register int i; - register struct opc *op; - - if ((p = fgets(line, MAXLINE, srcfp)) == NULL) - return(0); - c_line++; - p = get_label(label, p); - p = get_opcode(opcode, p); - p = get_arg(operand, p); - if (strcmp(opcode, ENDFILE) == 0) - return(0); - if (*opcode) { - if ((op = search_op(opcode)) != NULL) { - i = (*op->op_fun)(op->op_c1, op->op_c2); - if (gencode) - pc += i; - } else - asmerr(E_ILLOPC); - } else - if (*label) - put_label(); - return(1); -} - -/* - * Pass 2: - * - process all source files - */ -void pass2(void) -{ - register int fi; - - pass = 2; - pc = 0; - fi = 0; - if (!ver_flag) - puts("Pass 2"); - obj_header(); - while (infiles[fi] != NULL) { - if (!ver_flag) - printf(" Read %s\n", infiles[fi]); - p2_file(infiles[fi]); - fi++; - } - obj_end(); - fclose(objfp); - printf("%d error(s)\n", errors); -} - -/* - * Pass 2: - * - process one source file - * - * Input: name of source file - */ -void p2_file(char *fn) -{ - c_line = 0; - srcfn = fn; - if ((srcfp = fopen(fn, READA)) == NULL) - fatal(F_FOPEN, fn); - while (p2_line()) - ; - fclose(srcfp); -} - -/* - * Pass 2: - * - process one line of source - * - * Output: 1 line processed - * 0 EOF - */ -int p2_line(void) -{ - register char *p; - register int op_count; - register struct opc *op; - - if ((p = fgets(line, MAXLINE, srcfp)) == NULL) - return(0); - c_line++; - s_line++; - p = get_label(label, p); - p = get_opcode(opcode, p); - p = get_arg(operand, p); - if (strcmp(opcode, ENDFILE) == 0) { - lst_line(pc, 0); - return(0); - } - if (*opcode) { - op = search_op(opcode); - op_count = (*op->op_fun)(op->op_c1, op->op_c2); - if (gencode) { - lst_line(pc, op_count); - obj_writeb(op_count); - pc += op_count; - } else { - sd_flag = 2; - lst_line(0, 0); - } - } else { - sd_flag = 2; - lst_line(0, 0); - } - return(1); -} - -/* - * open output files: - * input is filename of source file - * list and object filenames are build from source filename if - * not given by options - */ -void open_o_files(char *source) -{ - register char *p; - - if (*objfn == '\0') - strcpy(objfn, source); - if ((p = strrchr(objfn, '.')) != NULL) - strcpy(p, OBJEXT); - else - strcat(objfn, OBJEXT); - - if (out_form == OUTHEX) - objfp = fopen(objfn, WRITEA); - else - objfp = fopen(objfn, WRITEB); - if (objfp == NULL) - fatal(F_FOPEN, objfn); - if (list_flag) { - if (*lstfn == '\0') - strcpy(lstfn, source); - if ((p = strrchr(lstfn, '.')) != NULL) - strcpy(p, LSTEXT); - else - strcat(lstfn, LSTEXT); - if ((lstfp = fopen(lstfn, WRITEA)) == NULL) - fatal(F_FOPEN, lstfn); - errfp = lstfp; - } -} - -/* - * create a filename in "dest" from "src" and "ext" - */ -void get_fn(char *dest, char *src, char *ext) -{ - register int i; - register char *sp, *dp; - - i = 0; - sp = src; - dp = dest; - while ((i++ < LENFN) && (*sp != '\0')) - *dp++ = *sp++; - *dp = '\0'; - if ((strrchr(dest,'.') == NULL) && - (strlen(dest) <= (LENFN - strlen(ext)))) - strcat(dest, ext); -} - -/* - * get labels, constants and variables from source line - * convert names to upper case and truncate length of name - */ -char *get_label(char *s, char *l) -{ - register int i; - - i = 0; - if (*l == LINCOM) - goto comment; - while (!isspace(*l) && *l != COMMENT && *l != LABSEP && i < SYMSIZE) { - *s++ = islower(*l) ? toupper(*l++) : *l++; - i++; - } -comment: - *s = '\0'; - return(l); -} - -/* - * get opcode into s from source line l - * converts to uper case - */ -char *get_opcode(char *s, char *l) -{ - if (*l == LINCOM) - goto comment; - while (!isspace(*l) && *l != COMMENT && *l != LABSEP) - l++; - if (*l == LABSEP) - l++; - while (*l == ' ' || *l == '\t') - l++; - while (!isspace(*l) && *l != COMMENT) - *s++ = islower(*l) ? toupper(*l++) : *l++; -comment: - *s = '\0'; - return(l); -} - -/* - * get operand into s from source line l - * converts to upper case - * strings inside of 's are copied without changes - */ -char *get_arg(char *s, char *l) -{ - if (*l == LINCOM) - goto comment; - while (*l == ' ' || *l == '\t') - l++; - while (*l != '\n' && *l != COMMENT) { - if (isspace(*l)) { - l++; - continue; - } - if (*l != STRSEP) { - *s++ = islower(*l) ? toupper(*l) : *l; - l++; - continue; - } - *s++ = *l++; - if (*(s - 2) == 'F') /* EX AF,AF' !!!!! */ - continue; - while (*l != STRSEP) { - if (*l == '\n' || *l == '\0' || *l == COMMENT) - goto comment; - *s++ = *l++; - } - *s++ = *l++; - } -comment: - *s = '\0'; - return(l); -} diff --git a/emu/z80pack-1.9/z80asm/z80anum.c b/emu/z80pack-1.9/z80asm/z80anum.c deleted file mode 100644 index d836915..0000000 --- a/emu/z80pack-1.9/z80asm/z80anum.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 21-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * modul with numercial computation and conversion - */ - -#include -#include -#include -#include "z80a.h" -#include "z80aglb.h" - -#ifndef isxdigit -#define isxdigit(c) (isdigit(c) || (c>='a' && c<='f') || (c>='A' && c<='F')) -#endif - -/* - * definitions of operator symbols for expression parser - */ -#define OPEDEC 1 /* decimal number */ -#define OPEHEX 2 /* hexadecimal number */ -#define OPEOCT 3 /* octal number */ -#define OPEBIN 4 /* binary number */ -#define OPESUB 5 /* arithmetical - */ -#define OPEADD 6 /* arithmetical + */ -#define OPEMUL 7 /* arithmetical * */ -#define OPEDIV 8 /* arithmetical / */ -#define OPEMOD 9 /* arithmetical modulo */ -#define OPESHL 10 /* logical shift left */ -#define OPESHR 11 /* logical shift right */ -#define OPELOR 12 /* logical OR */ -#define OPELAN 13 /* logical AND */ -#define OPEXOR 14 /* logical XOR */ -#define OPECOM 15 /* logical complement */ -#define OPESYM 99 /* symbol */ - -extern struct sym *get_sym(char *); -extern void asmerr(int); - -/* - * recursive expression parser - * - * Input: pointer to argument rest string - * - * Output: computed value - */ -int eval(char *s) -{ - register char *p; - register int val; - char word[MAXLINE]; - struct sym *sp; - - val = 0; - while (*s) { - p = word; - if (*s == '(') { - s++; - while (*s != ')') { - if (*s == '\0') { - asmerr(E_MISPAR); - goto eval_break; - } - *p++ = *s++; - } - *p = '\0'; - s++; - val = eval(word); - continue; - } - if (*s == STRSEP) { - s++; - while (*s != STRSEP) { - if (*s == '\n' || *s == '\0') { - asmerr(E_MISHYP); - goto hyp_error; - } - *p++ = *s++; - } - s++; -hyp_error: - *p = '\0'; - val = strval(word); - continue; - } - if (isari(*s)) - *p++ = *s++; - else - while (!isspace(*s) && !isari(*s) && (*s != '\0')) - *p++ = *s++; - *p = '\0'; - switch (get_type(word)) { - case OPESYM: /* symbol */ - if (strcmp(word, "$") == 0) { - val = pc; - break; - } - if (strlen(word) > SYMSIZE) - word[SYMSIZE] = '\0'; - if ((sp = get_sym(word)) != NULL) - val = sp->sym_wert; - else - asmerr(E_UNDSYM); - break; - case OPEDEC: /* decimal number */ - val = atoi(word); - break; - case OPEHEX: /* hexadecimal number */ - val = axtoi(word); - break; - case OPEBIN: /* binary number */ - val = abtoi(word); - break; - case OPEOCT: /* octal number */ - val = aotoi(word); - break; - case OPESUB: /* arithmetical - */ - val -= eval(s); - goto eval_break; - case OPEADD: /* arithmetical + */ - val += eval(s); - goto eval_break; - case OPEMUL: /* arithmetical * */ - val *= eval(s); - goto eval_break; - case OPEDIV: /* arithmetical / */ - val /= eval(s); - goto eval_break; - case OPEMOD: /* arithmetical modulo */ - val %= eval(s); - goto eval_break; - case OPESHL: /* logical shift left */ - val <<= eval(s); - goto eval_break; - case OPESHR: /* logical shift right */ - val >>= eval(s); - goto eval_break; - case OPELOR: /* logical OR */ - val |= eval(s); - goto eval_break; - case OPELAN: /* logical AND */ - val &= eval(s); - goto eval_break; - case OPEXOR: /* logical XOR */ - val ^= eval(s); - goto eval_break; - case OPECOM: /* logical complement */ - val = ~(eval(s)); - goto eval_break; - } - } - eval_break: - return(val); -} - -/* - * get typ of operand - * - * Input: pointer to string with operand - * - * Output: operand typ - */ -int get_type(char *s) -{ - if (isdigit(*s)) { /* numerical operand */ - if (isdigit(*(s + strlen(s) - 1))) /* decimal number */ - return(OPEDEC); - else if (*(s + strlen(s) - 1) == 'H') /* hexadecimal number */ - return(OPEHEX); - else if (*(s + strlen(s) - 1) == 'B') /* binary number */ - return(OPEBIN); - else if (*(s + strlen(s) - 1) == 'O') /* octal number */ - return(OPEOCT); - } else if (*s == '-') /* arithmetical operand - */ - return(OPESUB); - else if (*s == '+') /* arithmetical operand + */ - return(OPEADD); - else if (*s == '*') /* arithmetical operand * */ - return(OPEMUL); - else if (*s == '/') /* arithmetical operand / */ - return(OPEDIV); - else if (*s == '%') /* arithmetical modulo */ - return(OPEMOD); - else if (*s == '<') /* logical shift left */ - return(OPESHL); - else if (*s == '>') /* logical shift rigth */ - return(OPESHR); - else if (*s == '|') /* logical OR */ - return(OPELOR); - else if (*s == '&') /* logical AND */ - return(OPELAN); - else if (*s == '^') /* logical XOR */ - return(OPEXOR); - else if (*s == '~') /* logical complement */ - return(OPECOM); - return(OPESYM); /* operand is symbol */ -} - -/* - * check a character for arithmetical operators - * +, -, *, /, %, <, >, |, &, ~ and ^ - */ -int isari(int c) -{ - return((c) == '+' || (c) == '-' || (c) == '*' || - (c) == '/' || (c) == '%' || (c) == '<' || - (c) == '>' || (c) == '|' || (c) == '&' || - (c) == '~' || (c) == '^'); -} - -/* - * conversion of string with hexadecimal number to integer - * format: nnnnH or 0nnnnH if 1st digit > 9 - */ -int axtoi(char *str) -{ - register int num; - - num = 0; - while (isxdigit(*str)) { - num *= 16; - num += *str - ((*str <= '9') ? '0' : '7'); - str++; - } - return(num); -} - -/* - * conversion of string with octal number to integer - * format: nnnnO - */ -int aotoi(char *str) -{ - register int num; - - num = 0; - while ('0' <= *str && *str <= '7') { - num *= 8; - num += (*str++) - '0'; - } - return(num); -} - -/* - * conversion of string with binary number to integer - * format: nnnnnnnnnnnnnnnnB - */ -int abtoi(char *str) -{ - register int num; - - num = 0; - while ('0' <= *str && *str <= '1') { - num *= 2; - num += (*str++) - '0'; - } - return(num); -} - -/* - * convert ASCII string to integer - */ -int strval(char *str) -{ - register int num; - - num = 0; - while (*str) { - num <<= 8; - num += (int) *str++; - } - return(num); -} - -/* - * check value for range -256 < value < 256 - * Output: value if in range, otherwise 0 and error message - */ -int chk_v1(int i) -{ - if (i >= -255 && i <= 255) - return(i); - else { - asmerr(E_VALOUT); - return(0); - } -} - -/* - * check value for range -128 < value < 128 - * Output: value if in range, otherwise 0 and error message - */ -int chk_v2(int i) -{ - if (i >= -127 && i <= 127) - return(i); - else { - asmerr(E_VALOUT); - return(0); - } -} diff --git a/emu/z80pack-1.9/z80asm/z80aopc.c b/emu/z80pack-1.9/z80asm/z80aopc.c deleted file mode 100644 index fcc8613..0000000 --- a/emu/z80pack-1.9/z80asm/z80aopc.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 21-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * opcode tables - */ - -#include -#include "z80a.h" - -extern int op_1b(), op_2b(), op_pupo(), op_ex(), op_ld(); -extern int op_call(), op_ret(), op_jp(), op_jr(), op_djnz(), op_rst(); -extern int op_add(), op_adc(), op_sub(), op_sbc(), op_cp(); -extern int op_inc(), op_dec(), op_or(), op_xor(), op_and(); -extern int op_rl(), op_rr(), op_sla(), op_sra(), op_srl(), op_rlc(), op_rrc(); -extern int op_out(), op_in(), op_im(); -extern int op_set(), op_res(), op_bit(); -extern int op_org(), op_dl(), op_equ(); -extern int op_ds(), op_db(), op_dw(), op_dm(); -extern int op_misc(); -extern int op_cond(); -extern int op_glob(); - -/* - * opcode table: - * includes entries for all opcodes and pseudo ops other than END - * must be sorted in ascending order! - */ -struct opc opctab[] = { - { "ADC", op_adc, 0, 0 }, - { "ADD", op_add, 0, 0 }, - { "AND", op_and, 0, 0 }, - { "BIT", op_bit, 0, 0 }, - { "CALL", op_call, 0, 0 }, - { "CCF", op_1b, 0x3f, 0 }, - { "CP", op_cp, 0, 0 }, - { "CPD", op_2b, 0xed, 0xa9 }, - { "CPDR", op_2b, 0xed, 0xb9 }, - { "CPI", op_2b, 0xed, 0xa1 }, - { "CPIR", op_2b, 0xed, 0xb1 }, - { "CPL", op_1b, 0x2f, 0 }, - { "DAA", op_1b, 0x27, 0 }, - { "DEC", op_dec, 0, 0 }, - { "DEFB", op_db, 0, 0 }, - { "DEFL", op_dl, 0, 0 }, - { "DEFM", op_dm, 0, 0 }, - { "DEFS", op_ds, 0, 0 }, - { "DEFW", op_dw, 0, 0 }, - { "DI", op_1b, 0xf3, 0 }, - { "DJNZ", op_djnz, 0, 0 }, - { "EI", op_1b, 0xfb, 0 }, - { "EJECT", op_misc, 1, 0 }, - { "ELSE", op_cond, 98, 0 }, - { "ENDIF", op_cond, 99, 0 }, - { "EQU", op_equ, 0, 0 }, - { "EX", op_ex, 0, 0 }, - { "EXTRN", op_glob, 1, 0 }, - { "EXX", op_1b, 0xd9, 0 }, - { "HALT", op_1b, 0x76, 0 }, - { "IFDEF", op_cond, 1, 0 }, - { "IFEQ", op_cond, 3, 0 }, - { "IFNDEF", op_cond, 2, 0 }, - { "IFNEQ", op_cond, 4, 0 }, - { "IM", op_im, 0, 0 }, - { "IN", op_in, 0, 0 }, - { "INC", op_inc, 0, 0 }, - { "INCLUDE", op_misc, 6, 0 }, - { "IND", op_2b, 0xed, 0xaa }, - { "INDR", op_2b, 0xed, 0xba }, - { "INI", op_2b, 0xed, 0xa2 }, - { "INIR", op_2b, 0xed, 0xb2 }, - { "JP", op_jp, 0, 0 }, - { "JR", op_jr, 0, 0 }, - { "LD", op_ld, 0, 0 }, - { "LDD", op_2b, 0xed, 0xa8 }, - { "LDDR", op_2b, 0xed, 0xb8 }, - { "LDI", op_2b, 0xed, 0xa0 }, - { "LDIR", op_2b, 0xed, 0xb0 }, - { "LIST", op_misc, 2, 0 }, - { "NEG", op_2b, 0xed, 0x44 }, - { "NOLIST", op_misc, 3, 0 }, - { "NOP", op_1b, 0, 0 }, - { "OR", op_or, 0, 0 }, - { "ORG", op_org, 0, 0 }, - { "OTDR", op_2b, 0xed, 0xbb }, - { "OTIR", op_2b, 0xed, 0xb3 }, - { "OUT", op_out, 0, 0 }, - { "OUTD", op_2b, 0xed, 0xab }, - { "OUTI", op_2b, 0xed, 0xa3 }, - { "PAGE", op_misc, 4, 0 }, - { "POP", op_pupo, 1, 0 }, - { "PRINT", op_misc, 5, 0 }, - { "PUBLIC", op_glob, 2, 0 }, - { "PUSH", op_pupo, 2, 0 }, - { "RES", op_res, 0, 0 }, - { "RET", op_ret, 0, 0 }, - { "RETI", op_2b, 0xed, 0x4d }, - { "RETN", op_2b, 0xed, 0x45 }, - { "RL", op_rl, 0, 0 }, - { "RLA", op_1b, 0x17, 0 }, - { "RLC", op_rlc, 0, 0 }, - { "RLCA", op_1b, 0x07, 0 }, - { "RLD", op_2b, 0xed, 0x6f }, - { "RR", op_rr, 0, 0 }, - { "RRA", op_1b, 0x1f, 0 }, - { "RRC", op_rrc, 0, 0 }, - { "RRCA", op_1b, 0x0f, 0 }, - { "RRD", op_2b, 0xed, 0x67 }, - { "RST", op_rst, 0, 0 }, - { "SBC", op_sbc, 0, 0 }, - { "SCF", op_1b, 0x37, 0 }, - { "SET", op_set, 0, 0 }, - { "SLA", op_sla, 0, 0 }, - { "SRA", op_sra, 0, 0 }, - { "SRL", op_srl, 0, 0 }, - { "SUB", op_sub, 0, 0 }, - { "TITLE", op_misc, 7, 0 }, - { "XOR", op_xor, 0, 0 } -}; - -/* - * compute no. of table entries for search_op() - */ -int no_opcodes = sizeof(opctab) / sizeof(struct opc); - -/* - * table with reserverd operand words: registers and flags - * must be sorted in ascending order! - */ -struct ope opetab[] = { - { "(BC)", REGIBC }, - { "(DE)", REGIDE }, - { "(HL)", REGIHL }, - { "(IX)", REGIIX }, - { "(IY)", REGIIY }, - { "(SP)", REGISP }, - { "A", REGA }, - { "AF", REGAF }, - { "B", REGB }, - { "BC", REGBC }, - { "C", REGC }, - { "D", REGD }, - { "DE", REGDE }, - { "E", REGE }, - { "H", REGH }, - { "HL", REGHL }, - { "I", REGI }, - { "IX", REGIX }, - { "IY", REGIY }, - { "L", REGL }, - { "M", FLGM }, - { "NC", FLGNC }, - { "NZ", FLGNZ }, - { "P", FLGP }, - { "PE", FLGPE }, - { "PO", FLGPO }, - { "R", REGR }, - { "SP", REGSP }, - { "Z", FLGZ } -}; - -/* - * compute no. of table entries - */ -int no_operands = sizeof(opetab) / sizeof(struct ope); diff --git a/emu/z80pack-1.9/z80asm/z80aout.c b/emu/z80pack-1.9/z80asm/z80aout.c deleted file mode 100644 index 869bcac..0000000 --- a/emu/z80pack-1.9/z80asm/z80aout.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 21-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * module for output functions to list, object and error files - */ - -#include -#include -#include "z80a.h" -#include "z80aglb.h" - -void flush_hex(void); -int chksum(void); -void btoh(unsigned char, char **); - -extern void fatal(int, char *); - -static char *errmsg[] = { /* error messages for asmerr() */ - "illegal opcode", /* 0 */ - "illegal operand", /* 1 */ - "missing operand", /* 2 */ - "multiply defined symbol", /* 3 */ - "undefined symbol", /* 4 */ - "value out of range", /* 5 */ - "missing )", /* 6 */ - "missing string separator", /* 7 */ - "memory override", /* 8 */ - "missing IF", /* 9 */ - "IF nesting to deep", /* 10 */ - "missing ENDIF", /* 11 */ - "INCLUDE nesting to deep" /* 12 */ -}; - -#define MAXHEX 32 /* max no bytes/hex record */ - -static unsigned short hex_adr; /* current address in hex record */ -static int hex_cnt; /* current no bytes in hex buffer */ - -static unsigned char hex_buf[MAXHEX]; /* buffer for one hex record */ -static char hex_out[MAXHEX*2+11]; /* ASCII buffer for one hex record */ - -/* - * print error message to listfile and increase error counter - */ -void asmerr(int i) -{ - if (pass == 1) { - fprintf(errfp, "Error in file: %s Line: %d\n", srcfn, c_line); - fprintf(errfp, errmsg[i]); - fprintf(errfp, "\n\n"); - } else - errnum = i; - errors++; -} - -/* - * begin new page in listfile - */ -void lst_header(void) -{ - fprintf(lstfp, "\fZ80-Assembler\t\tRelease %s\t\t\t\tPage %d\n", REL, - ++page); - fprintf(lstfp, "Source file: %s\n", srcfn); - fprintf(lstfp, "Title: %s\n", title); - p_line = 3; -} - -/* - * print header for source lines - */ -void lst_attl(void) -{ - fprintf(lstfp, "\nLOC OBJECT CODE LINE STMT SOURCE CODE\n"); - p_line += 2; -} - -/* - * print one line into listfile, if -l option set - */ -void lst_line(int val, int opanz) -{ - register int i; - - if (!list_flag || sd_flag == 4) { - sd_flag = 0; - return; - } - if ((p_line >= ppl) || (c_line == 1)) { - lst_header(); - lst_attl(); - } - switch (sd_flag) { - case 0: - fprintf(lstfp, "%04x ", val & 0xffff); - break; - case 1: - fprintf(lstfp, "%04x ", sd_val & 0xffff); - break; - case 2: - fprintf(lstfp, " "); - break; - case 3: - fprintf(lstfp, "%04x ", sd_val & 0xffff); - goto no_data; - default: - fatal(F_INTERN, "illegal listflag for function lst_line"); - break; - } - if (opanz >= 1) fprintf(lstfp, "%02x ", ops[0] & 0xff); - else fprintf(lstfp, " "); - if (opanz >= 2) fprintf(lstfp, "%02x ", ops[1] & 0xff); - else fprintf(lstfp, " "); - if (opanz >= 3) fprintf(lstfp, "%02x ", ops[2] & 0xff); - else fprintf(lstfp, " "); - if (opanz >= 4) fprintf(lstfp, "%02x ", ops[3] & 0xff); - else fprintf(lstfp, " "); - no_data: - fprintf(lstfp, "%6d %6d %s", c_line, s_line, line); - if (errnum) { - fprintf(errfp, "=> %s", errmsg[errnum]); - putc('\n', errfp); - errnum = 0; - p_line++; - } - sd_flag = 0; - p_line++; - if (opanz > 4 && sd_flag == 0) { - opanz -= 4; - i = 4; - sd_val = val; - while (opanz > 0) { - if (p_line >= ppl) { - lst_header(); - lst_attl(); - } - s_line++; - sd_val += 4; - fprintf(lstfp, "%04x ", sd_val & 0xffff); - if (opanz-- > 0) fprintf(lstfp, "%02x ", - ops[i++] & 0xff); - else fprintf(lstfp, " "); - if (opanz-- > 0) fprintf(lstfp, "%02x ", - ops[i++] & 0xff); - else fprintf(lstfp, " "); - if (opanz-- > 0) fprintf(lstfp, "%02x ", - ops[i++] & 0xff); - else fprintf(lstfp, " "); - if (opanz-- > 0) fprintf(lstfp, "%02x ", - ops[i++] & 0xff); - else fprintf(lstfp, " "); - fprintf(lstfp, "%6d %6d\n", c_line, s_line); - p_line++; - } - } -} - -/* - * print symbol table into listfile unsorted - */ -void lst_sym(void) -{ - register int i, j; - register struct sym *np; - - p_line = j = 0; - strcpy(title,"Symboltable"); - for (i = 0; i < HASHSIZE; i++) { - if (symtab[i] != NULL) { - for (np = symtab[i]; np != NULL; np = np->sym_next) { - if (p_line == 0) { - lst_header(); - fputs("\n", lstfp); - p_line += 1; - } - fprintf(lstfp, "%-8s %04x\t", np->sym_name, - np->sym_wert & 0xffff); - if (++j == 4) { - fprintf(lstfp, "\n"); - if (p_line++ >= ppl) - p_line = 0; - j = 0; - } - } - } - } -} - -/* - * print sorted symbol table into listfile - */ -void lst_sort_sym(int len) -{ - register int i, j; - - p_line = i = j = 0; - strcpy(title, "Symboltable"); - while (i < len) { - if (p_line == 0) { - lst_header(); - fputs("\n", lstfp); - p_line += 1; - } - fprintf(lstfp, "%-8s %04x\t", symarray[i]->sym_name, - symarray[i]->sym_wert & 0xffff); - if (++j == 4) { - fprintf(lstfp, "\n"); - if (p_line++ >= ppl) - p_line = 0; - j = 0; - } - i++; - } -} - -/* - * write header record into object file - */ -void obj_header(void) -{ - switch (out_form) { - case OUTBIN: - break; - case OUTMOS: - putc(0xff, objfp); - putc(prg_adr & 0xff, objfp); - putc(prg_adr >> 8, objfp); - break; - case OUTHEX: - hex_adr = prg_adr; - break; - } -} - -/* - * write end record into object file - */ -void obj_end(void) -{ - switch (out_form) { - case OUTBIN: - break; - case OUTMOS: - break; - case OUTHEX: - flush_hex(); - fprintf(objfp, ":0000000000\n"); - break; - } -} - -/* - * write opcodes in ops[] into object file - */ -void obj_writeb(int opanz) -{ - register int i; - - switch (out_form) { - case OUTBIN: - fwrite(ops, 1, opanz, objfp); - break; - case OUTMOS: - fwrite(ops, 1, opanz, objfp); - break; - case OUTHEX: - for (i = 0; opanz; opanz--) { - if (hex_cnt >= MAXHEX) - flush_hex(); - hex_buf[hex_cnt++] = ops[i++]; - } - break; - } -} - -/* - * write bytes 0xff into object file - */ -void obj_fill(int count) -{ - switch (out_form) { - case OUTBIN: - while (count--) - putc(0xff, objfp); - break; - case OUTMOS: - while (count--) - putc(0xff, objfp); - break; - case OUTHEX: - flush_hex(); - hex_adr += count; - break; - } -} - -/* - * create a hex record in ASCII and write into object file - */ -void flush_hex(void) -{ - char *p; - register int i; - - if (!hex_cnt) - return; - p = hex_out; - *p++ = ':'; - btoh((unsigned char) hex_cnt, &p); - btoh((unsigned char) (hex_adr >> 8), &p); - btoh((unsigned char) (hex_adr & 0xff), &p); - *p++ = '0'; - *p++ = '0'; - for (i = 0; i < hex_cnt; i++) - btoh(hex_buf[i], &p); - btoh((unsigned char) chksum(), &p); - *p++ = '\n'; - *p = '\0'; - fwrite(hex_out, 1, strlen(hex_out), objfp); - hex_adr += hex_cnt; - hex_cnt = 0; -} - -/* - * convert unsigned char into ASCII hex and copy to string at p - * increase p by 2 - */ -void btoh(unsigned char byte, char **p) -{ - register unsigned char c; - - c = byte >> 4; - *(*p)++ = (c < 10) ? (c + '0') : (c - 10 + 'A'); - c = byte & 0xf; - *(*p)++ = (c < 10) ? (c + '0') : (c - 10 + 'A'); -} - -/* - * computer checksum for Intel hex record - */ -int chksum(void) -{ - register int i, j, sum; - - sum = hex_cnt; - sum += hex_adr >> 8; - sum += hex_adr & 0xff; - for (i = 0; i < hex_cnt; i++) { - j = hex_buf[i]; - sum += j & 0xff; - } - return (0x100 - (sum & 0xff)); -} diff --git a/emu/z80pack-1.9/z80asm/z80apfun.c b/emu/z80pack-1.9/z80asm/z80apfun.c deleted file mode 100644 index 912db5d..0000000 --- a/emu/z80pack-1.9/z80asm/z80apfun.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 22-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * processing of all PSEUDO ops - */ - -#include -#include -#include -#include "z80a.h" -#include "z80aglb.h" - -extern void fatal(int, char *); -extern void p1_file(char *); -extern void p2_file(char *); -extern int eval(char *); -extern void asmerr(int); -extern void lst_header(void); -extern void lst_attl(void); -extern void lst_line(int, int); -extern void obj_fill(int); -extern struct sym *get_sym(char *); -extern int put_sym(char *, int); -extern void put_label(void); - -/* - * ORG - */ -int op_org(void) -{ - register int i; - - if (!gencode) - return(0); - i = eval(operand); - if (i < pc) { - asmerr(E_MEMOVR); - return(0); - } - if (pass == 1) { /* PASS 1 */ - if (!prg_flag) { - prg_adr = i; - prg_flag++; - } - } else { /* PASS 2 */ - if (++prg_flag > 2) - obj_fill(i - pc); - sd_flag = 2; - } - pc = i; - return(0); -} - -/* - * EQU - */ -int op_equ(void) -{ - if (!gencode) - return(0); - if (pass == 1) { /* Pass 1 */ - if (get_sym(label) == NULL) { - sd_val = eval(operand); - if (put_sym(label, sd_val)) - fatal(F_OUTMEM, "symbols"); - } else - asmerr(E_MULSYM); - } else { /* Pass 2 */ - sd_flag = 1; - sd_val = eval(operand); - } - return(0); -} - -/* - * DEFL - */ -int op_dl(void) -{ - if (!gencode) - return(0); - sd_flag = 1; - sd_val = eval(operand); - if (put_sym(label, sd_val)) - fatal(F_OUTMEM, "symbols"); - return(0); -} - -/* - * DEFS - */ -int op_ds(void) -{ - register int val; - - if (!gencode) - return(0); - if (pass == 1) - if (*label) - put_label(); - sd_val = pc; - sd_flag = 3; - val = eval(operand); - if ((pass == 2) && !dump_flag) - obj_fill(val); - pc += val; - return(0); -} - -/* - * DEFB - */ -int op_db(void) -{ - register int i; - register char *p; - register char *s; - - if (!gencode) - return(0); - i = 0; - p = operand; - if (pass == 1) - if (*label) - put_label(); - while (*p) { - if (*p == STRSEP) { - p++; - while (*p != STRSEP) { - if (*p == '\n' || *p == '\0') { - asmerr(E_MISHYP); - goto hyp_error; - } - ops[i++] = *p++; - if (i >= OPCARRAY) - fatal(F_INTERN, "Op-Code buffer overflow"); - } - p++; - } else { - s = tmp; - while (*p != ',' && *p != '\0') - *s++ = *p++; - *s = '\0'; - ops[i++] = eval(tmp); - if (i >= OPCARRAY) - fatal(F_INTERN, "Op-Code buffer overflow"); - } - if (*p == ',') - p++; - } -hyp_error: - return(i); -} - -/* - * DEFM - */ -int op_dm(void) -{ - register int i; - register char *p; - - if (!gencode) - return(0); - i = 0; - p = operand; - if (pass == 1) - if (*label) - put_label(); - if (*p != STRSEP) { - asmerr(E_MISHYP); - return(0); - } - p++; - while (*p != STRSEP) { - if (*p == '\n' || *p == '\0') { - asmerr(E_MISHYP); - break; - } - ops[i++] = *p++; - if (i >= OPCARRAY) - fatal(F_INTERN, "Op-Code buffer overflow"); - } - return(i); -} - -/* - * DEFW - */ -int op_dw(void) -{ - register int i, len, temp; - register char *p; - register char *s; - - if (!gencode) - return(0); - p = operand; - i = len = 0; - if (pass == 1) - if (*label) - put_label(); - while (*p) { - s = tmp; - while (*p != ',' && *p != '\0') - *s++ = *p++; - *s = '\0'; - if (pass == 2) { - temp = eval(tmp); - ops[i++] = temp & 0xff; - ops[i++] = temp >> 8; - if (i >= OPCARRAY) - fatal(F_INTERN, "Op-Code buffer overflow"); - } - len += 2; - if (*p == ',') - p++; - } - return(len); -} - -/* - * EJECT, LIST, NOLIST, PAGE, PRINT, TITLE, INCLUDE - */ -int op_misc(int op_code, int dummy) -{ - register char *p, *d; - static char fn[LENFN]; - static int incnest; - static struct inc incl[INCNEST]; - - if (!gencode) - return(0); - sd_flag = 2; - switch(op_code) { - case 1: /* EJECT */ - if (pass == 2) - p_line = ppl; - break; - case 2: /* LIST */ - if (pass == 2) - list_flag = 1; - break; - case 3: /* NOLIST */ - if (pass == 2) - list_flag = 0; - break; - case 4: /* PAGE */ - if (pass == 2) - ppl = eval(operand); - break; - case 5: /* PRINT */ - if (pass == 1) { - p = operand; - while (*p) { - if (*p != STRSEP) - putchar(*p++); - else - p++; - } - putchar('\n'); - } - break; - case 6: /* INCLUDE */ - if (incnest >= INCNEST) { - asmerr(E_INCNEST); - break; - } - incl[incnest].inc_line = c_line; - incl[incnest].inc_fn = srcfn; - incl[incnest].inc_fp = srcfp; - incnest++; - p = line; - d = fn; - while(isspace(*p)) /* ignore white space until INCLUDE */ - p++; - while(!isspace(*p)) /* ignore INCLUDE */ - p++; - while(isspace(*p)) /* ignore white space until filename */ - p++; - while(!isspace(*p) && *p != COMMENT) /* get filename */ - *d++ = *p++; - *d = '\0'; - if (pass == 1) { /* PASS 1 */ - if (!ver_flag) - printf(" Include %s\n", fn); - p1_file(fn); - } else { /* PASS 2 */ - sd_flag = 2; - lst_line(0, 0); - if (!ver_flag) - printf(" Include %s\n", fn); - p2_file(fn); - } - incnest--; - c_line = incl[incnest].inc_line; - srcfn = incl[incnest].inc_fn; - srcfp = incl[incnest].inc_fp; - printf(" Resume %s\n", srcfn); - if (list_flag && (pass == 2)) { - lst_header(); - lst_attl(); - } - sd_flag = 4; - break; - case 7: /* TITLE */ - if (pass == 2) { - p = line; - d = title; - while (isspace(*p)) /* ignore white space until TITLE */ - p++; - while (!isspace(*p)) /* ignore TITLE */ - p++; - while (isspace(*p)) /* ignore white space until text */ - p++; - if (*p == STRSEP) - p++; - while (*p != '\n' && *p != STRSEP && *p != COMMENT) - *d++ = *p++; - *d = '\0'; - } - break; - default: - fatal(F_INTERN, "illegal opcode for function op_misc"); - break; - } - return(0); -} - -/* - * IFDEF, IFNDEF, IFEQ, IFNEQ, ELSE, ENDIF - */ -int op_cond(int op_code, int dummy) -{ - register char *p, *p1, *p2; - static int condnest[IFNEST]; - - switch(op_code) { - case 1: /* IFDEF */ - if (iflevel >= IFNEST) { - asmerr(E_IFNEST); - break; - } - condnest[iflevel++] = gencode; - if (gencode) - if (get_sym(operand) == NULL) - gencode = 0; - break; - case 2: /* IFNDEF */ - if (iflevel >= IFNEST) { - asmerr(E_IFNEST); - break; - } - condnest[iflevel++] = gencode; - if (gencode) - if (get_sym(operand) != NULL) - gencode = 0; - break; - case 3: /* IFEQ */ - if (iflevel >= IFNEST) { - asmerr(E_IFNEST); - break; - } - condnest[iflevel++] = gencode; - p = operand; - if (!*p || !(p1 = strchr(operand, ','))) { - asmerr(E_MISOPE); - break; - } - if (gencode) { - p2 = tmp; - while (*p != ',') - *p2++ = *p++; - *p2 = '\0'; - if (eval(tmp) != eval(++p1)) - gencode = 0; - } - break; - case 4: /* IFNEQ */ - if (iflevel >= IFNEST) { - asmerr(E_IFNEST); - break; - } - condnest[iflevel++] = gencode; - p = operand; - if (!*p || !(p1 = strchr(operand, ','))) { - asmerr(E_MISOPE); - break; - } - if (gencode) { - p2 = tmp; - while (*p != ',') - *p2++ = *p++; - *p2 = '\0'; - if (eval(tmp) == eval(++p1)) - gencode = 0; - } - break; - case 98: /* ELSE */ - if (!iflevel) - asmerr(E_MISIFF); - else - if ((iflevel == 0) || (condnest[iflevel - 1] == 1)) - gencode = !gencode; - break; - case 99: /* ENDIF */ - if (!iflevel) - asmerr(E_MISIFF); - else - gencode = condnest[--iflevel]; - break; - default: - fatal(F_INTERN, "illegal opcode for function op_cond"); - break; - } - sd_flag = 2; - return(0); -} - -/* - * EXTRN and PUBLIC - */ -int op_glob(int op_code, int dummy) -{ - if (!gencode) - return(0); - sd_flag = 2; - switch(op_code) { - case 1: /* EXTRN */ - break; - case 2: /* PUBLIC */ - break; - default: - fatal(F_INTERN, "illegal opcode for function op_glob"); - break; - } - return(0); -} diff --git a/emu/z80pack-1.9/z80asm/z80arfun.c b/emu/z80pack-1.9/z80asm/z80arfun.c deleted file mode 100644 index 02ab38d..0000000 --- a/emu/z80pack-1.9/z80asm/z80arfun.c +++ /dev/null @@ -1,3274 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 22-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * processing of all real Z80 opcodes - */ - -#include -#include -#include "z80a.h" -#include "z80aglb.h" - -char *get_second(char *); - -extern int eval(char *); -extern int chk_v1(int); -extern int chk_v2(int); -extern void asmerr(int); -extern int get_reg(char *); -extern void put_label(void); - -/* - * process 1byte opcodes without arguments - */ -int op_1b(int b1, int dummy) -{ - if (pass == 1) { /* Pass 1 */ - if (*label) - put_label(); - } else /* Pass 2 */ - ops[0] = b1; - return(1); -} - -/* - * process 2byte opcodes without arguments - */ -int op_2b(int b1, int b2) -{ - if (pass == 1) { /* Pass 1 */ - if (*label) - put_label(); - } else { /* Pass 2 */ - ops[0] = b1; - ops[1] = b2; - } - return(2); -} - -/* - * IM - */ -int op_im(void) -{ - if (pass == 1) - if (*label) - put_label(); - if (pass == 2) { - ops[0] = 0xed; - switch(eval(operand)) { - case 0: - ops[1] = 0x46; - break; - case 1: - ops[1] = 0x56; - break; - case 2: - ops[1] = 0x5e; - break; - default: - ops[1] = 0; - asmerr(E_ILLOPE); - break; - } - } - return(2); -} - -/* - * PUSH and POP - */ -int op_pupo(int op_code, int dummy) -{ - register int len; - - if (pass == 1) - if (*label) - put_label(); - switch (get_reg(operand)) { - case REGAF: - if (pass == 2) { - if (op_code == 1) - ops[0] = 0xf1; /* POP AF */ - else - ops[0] = 0xf5; /* PUSH AF */ - } - len = 1; - break; - case REGBC: - if (pass == 2) { - if (op_code == 1) - ops[0] = 0xc1; /* POP BC */ - else - ops[0] = 0xc5; /* PUSH BC */ - } - len = 1; - break; - case REGDE: - if (pass == 2) { - if (op_code == 1) - ops[0] = 0xd1; /* POP DE */ - else - ops[0] = 0xd5; /* PUSH DE */ - } - len = 1; - break; - case REGHL: - if (pass == 2) { - if (op_code == 1) - ops[0] = 0xe1; /* POP HL */ - else - ops[0] = 0xe5; /* PUSH HL */ - } - len = 1; - break; - case REGIX: - if (pass == 2) { - if (op_code == 1) { - ops[0] = 0xdd; /* POP IX */ - ops[1] = 0xe1; - } else { - ops[0] = 0xdd; /* PUSH IX */ - ops[1] = 0xe5; - } - } - len = 2; - break; - case REGIY: - if (pass == 2) { - if (op_code == 1) { - ops[0] = 0xfd; /* POP IY */ - ops[1] = 0xe1; - } else { - ops[0] = 0xfd; /* PUSH IY */ - ops[1] = 0xe5; - } - } - len = 2; - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * EX - */ -int op_ex(void) -{ - register int len; - - if (pass == 1) - if (*label) - put_label(); - if (strncmp(operand, "DE,HL", 5) == 0) { - ops[0] = 0xeb; - len = 1; - } else if (strncmp(operand, "AF,AF'", 7) == 0) { - ops[0] = 0x08; - len = 1; - } else if (strncmp(operand, "(SP),HL", 7) == 0) { - ops[0] = 0xe3; - len = 1; - } else if (strncmp(operand, "(SP),IX", 7) == 0) { - ops[0] = 0xdd; - ops[1] = 0xe3; - len = 2; - } else if (strncmp(operand, "(SP),IY", 7) == 0) { - ops[0] = 0xfd; - ops[1] = 0xe3; - len = 2; - } else { - ops[0] = 0; - len = 1; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * CALL - */ -int op_call(void) -{ - register char *p1, *p2; - register int i; - - if (pass == 1) { /* PASS 1 */ - if (*label) - put_label(); - } else { /* PASS 2 */ - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - switch (get_reg(tmp)) { - case REGC: /* CALL C,nn */ - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xdc; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case FLGNC: /* CALL NC,nn */ - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xd4; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case FLGZ: /* CALL Z,nn */ - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xcc; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case FLGNZ: /* CALL NZ,nn */ - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xc4; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case FLGPE: /* CALL PE,nn */ - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xec; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case FLGPO: /* CALL PO,nn */ - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xe4; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case FLGM: /* CALL M,nn */ - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xfc; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case FLGP: /* CALL P,nn */ - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xf4; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case NOREG: /* CALL nn */ - i = eval(operand); - ops[0] = 0xcd; - ops[1] = i & 0xff; - ops[2] = i >> 8; - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - ops[1] = 0; - ops[2] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - ops[2] = 0; - asmerr(E_ILLOPE); - } - } - return(3); -} - -/* - * RST - */ -int op_rst(void) -{ - register int op; - - if (pass == 1) { /* PASS 1 */ - if (*label) - put_label(); - } else { /* PASS 2 */ - op = eval(operand); - if ((op / 8 > 7) || (op % 8 != 0)) { - ops[0] = 0; - asmerr(E_VALOUT); - } else - ops[0] = 0xc7 + op; - } - return(1); -} - -/* - * RET - */ -int op_ret(void) -{ - if (pass == 1) { /* PASS 1 */ - if (*label) - put_label(); - } else { /* PASS 2 */ - switch (get_reg(operand)) { - case NOOPERA: /* RET */ - ops[0] = 0xc9; - break; - case REGC: /* RET C */ - ops[0] = 0xd8; - break; - case FLGNC: /* RET NC */ - ops[0] = 0xd0; - break; - case FLGZ: /* RET Z */ - ops[0] = 0xc8; - break; - case FLGNZ: /* RET NZ */ - ops[0] = 0xc0; - break; - case FLGPE: /* RET PE */ - ops[0] = 0xe8; - break; - case FLGPO: /* RET PO */ - ops[0] = 0xe0; - break; - case FLGM: /* RET M */ - ops[0] = 0xf8; - break; - case FLGP: /* RET P */ - ops[0] = 0xf0; - break; - default: /* invalid operand */ - ops[0] = 0; - asmerr(E_ILLOPE); - } - } - return(1); -} - -/* - * JP - */ -int op_jp(void) -{ - register char *p1, *p2; - register int i, len; - - if (pass == 1) - if (*label) - put_label(); - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - switch (get_reg(tmp)) { - case REGC: /* JP C,nn */ - len = 3; - if (pass == 2) { - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xda; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case FLGNC: /* JP NC,nn */ - len = 3; - if (pass == 2) { - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xd2; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case FLGZ: /* JP Z,nn */ - len = 3; - if (pass == 2) { - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xca; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case FLGNZ: /* JP NZ,nn */ - len = 3; - if (pass == 2) { - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xc2; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case FLGPE: /* JP PE,nn */ - len = 3; - if (pass == 2) { - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xea; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case FLGPO: /* JP PO,nn */ - len = 3; - if (pass == 2) { - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xe2; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case FLGM: /* JP M,nn */ - len = 3; - if (pass == 2) { - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xfa; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case FLGP: /* JP P,nn */ - len = 3; - if (pass == 2) { - i = eval(strchr(operand, ',') + 1); - ops[0] = 0xf2; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case REGIHL: /* JP (HL) */ - ops[0] = 0xe9; - len = 1; - break; - case REGIIX: /* JP (IX) */ - ops[0] = 0xdd; - ops[1] = 0xe9; - len = 2; - break; - case REGIIY: /* JP (IY) */ - ops[0] = 0xfd; - ops[1] = 0xe9; - len = 2; - break; - case NOREG: /* JP nn */ - len = 3; - if (pass == 2) { - i = eval(operand); - ops[0] = 0xc3; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - len = 1; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - len = 1; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * JR - */ -int op_jr(void) -{ - register char *p1, *p2; - - if (pass == 1) { /* PASS 1 */ - if (*label) - put_label(); - } else { /* PASS 2 */ - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - switch (get_reg(tmp)) { - case REGC: /* JR C,n */ - ops[0] = 0x38; - ops[1] = chk_v2(eval(strchr(operand, ',') + 1) - pc - 2); - break; - case FLGNC: /* JR NC,n */ - ops[0] = 0x30; - ops[1] = chk_v2(eval(strchr(operand, ',') + 1) - pc - 2); - break; - case FLGZ: /* JR Z,n */ - ops[0] = 0x28; - ops[1] = chk_v2(eval(strchr(operand, ',') + 1) - pc - 2); - break; - case FLGNZ: /* JR NZ,n */ - ops[0] = 0x20; - ops[1] = chk_v2(eval(strchr(operand, ',') + 1) - pc - 2); - break; - case NOREG: /* JR n */ - ops[0] = 0x18; - ops[1] = chk_v2(eval(operand) - pc - 2); - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_ILLOPE); - } - } - return(2); -} - -/* - * DJNZ - */ -int op_djnz(void) -{ - if (pass == 1) { /* PASS 1 */ - if (*label) - put_label(); - } else { /* PASS 2 */ - ops[0] = 0x10; - ops[1] = chk_v2(eval(operand) - pc - 2); - } - return(2); -} - -/* - * LD - */ -int op_ld(void) -{ - register int len; - register char *p1, *p2; - - if (pass == 1) - if (*label) - put_label(); - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - switch (get_reg(tmp)) { - case REGA: /* LD A,? */ - len = lda(); - break; - case REGB: /* LD B,? */ - len = ldb(); - break; - case REGC: /* LD C,? */ - len = ldc(); - break; - case REGD: /* LD D,? */ - len = ldd(); - break; - case REGE: /* LD E,? */ - len = lde(); - break; - case REGH: /* LD H,? */ - len = ldh(); - break; - case REGL: /* LD L,? */ - len = ldl(); - break; - case REGI: /* LD I,A */ - if (get_reg(get_second(operand)) == REGA) { - len = 2; - ops[0] = 0xed; - ops[1] = 0x47; - break; - } - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - break; - case REGR: /* LD R,A */ - if (get_reg(get_second(operand)) == REGA) { - len = 2; - ops[0] = 0xed; - ops[1] = 0x4f; - break; - } - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - break; - case REGBC: /* LD BC,? */ - len = ldbc(); - break; - case REGDE: /* LD DE,? */ - len = ldde(); - break; - case REGHL: /* LD HL,? */ - len = ldhl(); - break; - case REGIX: /* LD IX,? */ - len = ldix(); - break; - case REGIY: /* LD IY,? */ - len = ldiy(); - break; - case REGSP: /* LD SP,? */ - len = ldsp(); - break; - case REGIHL: /* LD (HL),? */ - len = ldihl(); - break; - case REGIBC: /* LD (BC),A */ - if (get_reg(get_second(operand)) == REGA) { - len = 1; - ops[0] = 0x02; - break; - } - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - break; - case REGIDE: /* LD (DE),A */ - if (get_reg(get_second(operand)) == REGA) { - len = 1; - ops[0] = 0x12; - break; - } - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: - if (strncmp(operand, "(IX+", 4) == 0) - len = ldiix(); /* LD (IX+d),? */ - else if (strncmp(operand, "(IY+", 4) == 0) - len = ldiiy(); /* LD (IY+d),? */ - else if (*operand == '(') - len = ldinn(); /* LD (nn),? */ - else { /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - } - return(len); -} - -/* - * LD A,? - */ -int lda(void) -{ - register int op; - register int i, len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD A,A */ - case REGB: /* LD A,B */ - case REGC: /* LD A,C */ - case REGD: /* LD A,D */ - case REGE: /* LD A,E */ - case REGH: /* LD A,H */ - case REGL: /* LD A,L */ - case REGIHL: /* LD A,(HL) */ - len = 1; - ops[0] = 0x78 + op; - break; - case REGI: /* LD A,I */ - len = 2; - ops[0] = 0xed; - ops[1] = 0x57; - break; - case REGR: /* LD A,R */ - len = 2; - ops[0] = 0xed; - ops[1] = 0x5f; - break; - case REGIBC: /* LD A,(BC) */ - len = 1; - ops[0] = 0x0a; - break; - case REGIDE: /* LD A,(DE) */ - len = 1; - ops[0] = 0x1a; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { /* LD A,(IX+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x7e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - if (strncmp(p, "(IY+", 4) == 0) { /* LD A,(IY+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x7e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - if (*p == '(' && *(p + strlen(p) - 1) == ')') { - len = 3; /* LD A,(nn) */ - if (pass == 2) { - i = calc_val(p + 1); - ops[0] = 0x3a; - ops[1] = i & 255; - ops[2] = i >> 8; - } - break; - } - len = 2; /* LD A,n */ - if (pass == 2) { - ops[0] = 0x3e; - ops[1] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD B,? - */ -int ldb(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD B,A */ - case REGB: /* LD B,B */ - case REGC: /* LD B,C */ - case REGD: /* LD B,D */ - case REGE: /* LD B,E */ - case REGH: /* LD B,H */ - case REGL: /* LD B,L */ - case REGIHL: /* LD B,(HL) */ - len = 1; - ops[0] = 0x40 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { /* LD B,(IX+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x46; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - if (strncmp(p, "(IY+", 4) == 0) { /* LD B,(IY+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x46; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - len = 2; /* LD B,n */ - if (pass == 2) { - ops[0] = 0x06; - ops[1] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD C,? - */ -int ldc(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD C,A */ - case REGB: /* LD C,B */ - case REGC: /* LD C,C */ - case REGD: /* LD C,D */ - case REGE: /* LD C,E */ - case REGH: /* LD C,H */ - case REGL: /* LD C,L */ - case REGIHL: /* LD C,(HL) */ - len = 1; - ops[0] = 0x48 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { /* LD C,(IX+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x4e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - if (strncmp(p, "(IY+", 4) == 0) { /* LD C,(IY+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x4e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - len = 2; /* LD C,n */ - if (pass == 2) { - ops[0] = 0x0e; - ops[1] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD D,? - */ -int ldd(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD D,A */ - case REGB: /* LD D,B */ - case REGC: /* LD D,C */ - case REGD: /* LD D,D */ - case REGE: /* LD D,E */ - case REGH: /* LD D,H */ - case REGL: /* LD D,L */ - case REGIHL: /* LD D,(HL) */ - len = 1; - ops[0] = 0x50 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { /* LD D,(IX+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x56; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - if (strncmp(p, "(IY+", 4) == 0) { /* LD D,(IY+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x56; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - len = 2; /* LD D,n */ - if (pass == 2) { - ops[0] = 0x16; - ops[1] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD E,? - */ -int lde(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD E,A */ - case REGB: /* LD E,B */ - case REGC: /* LD E,C */ - case REGD: /* LD E,D */ - case REGE: /* LD E,E */ - case REGH: /* LD E,H */ - case REGL: /* LD E,L */ - case REGIHL: /* LD E,(HL) */ - len = 1; - ops[0] = 0x58 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { /* LD E,(IX+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x5e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - if (strncmp(p, "(IY+", 4) == 0) { /* LD E,(IY+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x5e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - len = 2; /* LD E,n */ - if (pass == 2) { - ops[0] = 0x1e; - ops[1] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD H,? - */ -int ldh(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD H,A */ - case REGB: /* LD H,B */ - case REGC: /* LD H,C */ - case REGD: /* LD H,D */ - case REGE: /* LD H,E */ - case REGH: /* LD H,H */ - case REGL: /* LD H,L */ - case REGIHL: /* LD H,(HL) */ - len = 1; - ops[0] = 0x60 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { /* LD H,(IX+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x66; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - if (strncmp(p, "(IY+", 4) == 0) { /* LD H,(IY+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x66; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - len = 2; /* LD H,n */ - if (pass == 2) { - ops[0] = 0x26; - ops[1] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD L,? - */ -int ldl(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD L,A */ - case REGB: /* LD L,B */ - case REGC: /* LD L,C */ - case REGD: /* LD L,D */ - case REGE: /* LD L,E */ - case REGH: /* LD L,H */ - case REGL: /* LD L,L */ - case REGIHL: /* LD L,(HL) */ - len = 1; - ops[0] = 0x68 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { /* LD L,(IX+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x6e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - if (strncmp(p, "(IY+", 4) == 0) { /* LD L,(IY+d) */ - len = 3; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x6e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - break; - } - len = 2; /* LD L,n */ - if (pass == 2) { - ops[0] = 0x2e; - ops[1] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD BC,? - */ -int ldbc(void) -{ - register int i, len; - register char *p; - - p = get_second(operand); - switch (get_reg(p)) { - case NOREG: /* operand isn't register */ - if (*p == '(' && *(p + strlen(p) - 1) == ')') { - len = 4; /* LD BC,(nn) */ - if (pass == 2) { - i = calc_val(p + 1); - ops[0] = 0xed; - ops[1] = 0x4b; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - } - len = 3; /* LD BC,nn */ - if (pass == 2) { - i = eval(p); - ops[0] = 0x01; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD DE,? - */ -int ldde(void) -{ - register int i, len; - register char *p; - - p = get_second(operand); - switch (get_reg(p)) { - case NOREG: /* operand isn't register */ - if (*p == '(' && *(p + strlen(p) - 1) == ')') { - len = 4; /* LD DE,(nn) */ - if (pass == 2) { - i = calc_val(p + 1); - ops[0] = 0xed; - ops[1] = 0x5b; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - } - len = 3; /* LD DE,nn */ - if (pass == 2) { - i = eval(p); - ops[0] = 0x11; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD HL,? - */ -int ldhl(void) -{ - register int i, len; - register char *p; - - p = get_second(operand); - switch (get_reg(p)) { - case NOREG: /* operand isn't register */ - if (*p == '(' && *(p + strlen(p) - 1) == ')') { - len = 3; /* LD HL,(nn) */ - if (pass == 2) { - i = calc_val(p + 1); - ops[0] = 0x2a; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - } - len = 3; /* LD HL,nn */ - if (pass == 2) { - i = eval(p); - ops[0] = 0x21; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD IX,? - */ -int ldix(void) -{ - register int i, len; - register char *p; - - p = get_second(operand); - switch (get_reg(p)) { - case NOREG: /* operand isn't register */ - if (*p == '(' && *(p + strlen(p) - 1) == ')') { - len = 4; /* LD IX,(nn) */ - if (pass == 2) { - i = calc_val(p + 1); - ops[0] = 0xdd; - ops[1] = 0x2a; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - } - len = 4; /* LD IX,nn */ - if (pass == 2) { - i = eval(p); - ops[0] = 0xdd; - ops[1] = 0x21; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD IY,? - */ -int ldiy(void) -{ - register int i, len; - register char *p; - - p = get_second(operand); - switch (get_reg(p)) { - case NOREG: /* operand isn't register */ - if (*p == '(' && *(p + strlen(p) - 1) == ')') { - len = 4; /* LD IY,(nn) */ - if (pass == 2) { - i = calc_val(p + 1); - ops[0] = 0xfd; - ops[1] = 0x2a; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - } - len = 4; /* LD IY,nn */ - if (pass == 2) { - i = eval(p); - ops[0] = 0xfd; - ops[1] = 0x21; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD SP,? - */ -int ldsp(void) -{ - register int i, len; - register char *p; - - p = get_second(operand); - switch (get_reg(p)) { - case REGHL: /* LD SP,HL */ - len = 1; - ops[0] = 0xf9; - break; - case REGIX: /* LD SP,IX */ - len = 2; - ops[0] = 0xdd; - ops[1] = 0xf9; - break; - case REGIY: /* LD SP,IY */ - len = 2; - ops[0] = 0xfd; - ops[1] = 0xf9; - break; - case NOREG: /* operand isn't register */ - if (*p == '(' && *(p + strlen(p) - 1) == ')') { - len = 4; /* LD SP,(nn) */ - if (pass == 2) { - i = calc_val(p + 1); - ops[0] = 0xed; - ops[1] = 0x7b; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - } - len = 3; /* LD SP,nn */ - if (pass == 2) { - i = eval(p); - ops[0] = 0x31; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD (HL),? - */ -int ldihl(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD (HL),A */ - case REGB: /* LD (HL),B */ - case REGC: /* LD (HL),C */ - case REGD: /* LD (HL),D */ - case REGE: /* LD (HL),E */ - case REGH: /* LD (HL),H */ - case REGL: /* LD (HL),L */ - len = 1; - ops[0] = 0x70 + op; - break; - case NOREG: /* operand isn't register */ - len = 2; /* LD (HL),n */ - if (pass == 2) { - ops[0] = 0x36; - ops[1] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD (IX+d),? - */ -int ldiix(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD (IX+d),A */ - case REGB: /* LD (IX+d),B */ - case REGC: /* LD (IX+d),C */ - case REGD: /* LD (IX+d),D */ - case REGE: /* LD (IX+d),E */ - case REGH: /* LD (IX+d),H */ - case REGL: /* LD (IX+d),L */ - len = 3; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x70 + op; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - break; - case NOREG: /* LD (IX+d),n */ - len = 4; - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x36; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD (IY+d),? - */ -int ldiiy(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* LD (IY+d),A */ - case REGB: /* LD (IY+d),B */ - case REGC: /* LD (IY+d),C */ - case REGD: /* LD (IY+d),D */ - case REGE: /* LD (IY+d),E */ - case REGH: /* LD (IY+d),H */ - case REGL: /* LD (IY+d),L */ - len = 3; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x70 + op; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - break; - case NOREG: /* LD (IY+d),n */ - len = 4; - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x36; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = chk_v1(eval(p)); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * LD (nn),? - */ -int ldinn(void) -{ - register int i, len; - register char *p; - - p = get_second(operand); - switch (get_reg(p)) { - case REGA: /* LD (nn),A */ - len = 3; - if (pass == 2) { - i = calc_val(operand + 1); - ops[0] = 0x32; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case REGBC: /* LD (nn),BC */ - len = 4; - if (pass == 2) { - i = calc_val(operand + 1); - ops[0] = 0xed; - ops[1] = 0x43; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - case REGDE: /* LD (nn),DE */ - len = 4; - if (pass == 2) { - i = calc_val(operand + 1); - ops[0] = 0xed; - ops[1] = 0x53; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - case REGHL: /* LD (nn),HL */ - len = 3; - if (pass == 2) { - i = calc_val(operand + 1); - ops[0] = 0x22; - ops[1] = i & 0xff; - ops[2] = i >> 8; - } - break; - case REGSP: /* LD (nn),SP */ - len = 4; - if (pass == 2) { - i = calc_val(operand + 1); - ops[0] = 0xed; - ops[1] = 0x73; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - case REGIX: /* LD (nn),IX */ - len = 4; - if (pass == 2) { - i = calc_val(operand + 1); - ops[0] = 0xdd; - ops[1] = 0x22; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - case REGIY: /* LD (nn),IY */ - len = 4; - if (pass == 2) { - i = calc_val(operand + 1); - ops[0] = 0xfd; - ops[1] = 0x22; - ops[2] = i & 0xff; - ops[3] = i >> 8; - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * ADD ?,? - */ -int op_add(void) -{ - register int len; - register char *p1, *p2; - - if (pass == 1) - if (*label) - put_label(); - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - switch (get_reg(tmp)) { - case REGA: /* ADD A,? */ - len = adda(); - break; - case REGHL: /* ADD HL,? */ - len = addhl(); - break; - case REGIX: /* ADD IX,? */ - len = addix(); - break; - case REGIY: /* ADD IY,? */ - len = addiy(); - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * ADD A,? - */ -int adda(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* ADD A,A */ - case REGB: /* ADD A,B */ - case REGC: /* ADD A,C */ - case REGD: /* ADD A,D */ - case REGE: /* ADD A,E */ - case REGH: /* ADD A,H */ - case REGL: /* ADD A,L */ - case REGIHL: /* ADD A,(HL) */ - len = 1; - ops[0] = 0x80 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { - len = 3; /* ADD A,(IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x86; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - } else if (strncmp(p, "(IY+", 4) == 0) { - len = 3; /* ADD A,(IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x86; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - } else { - len = 2; /* ADD A,n */ - if (pass == 2) { - ops[0] = 0xc6; - ops[1] = chk_v1(eval(p)); - } - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * ADD HL,? - */ -int addhl(void) -{ - switch (get_reg(get_second(operand))) { - case REGBC: /* ADD HL,BC */ - ops[0] = 0x09; - break; - case REGDE: /* ADD HL,DE */ - ops[0] = 0x19; - break; - case REGHL: /* ADD HL,HL */ - ops[0] = 0x29; - break; - case REGSP: /* ADD HL,SP */ - ops[0] = 0x39; - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_ILLOPE); - } - return(1); -} - -/* - * ADD IX,? - */ -int addix(void) -{ - switch (get_reg(get_second(operand))) { - case REGBC: /* ADD IX,BC */ - ops[0] = 0xdd; - ops[1] = 0x09; - break; - case REGDE: /* ADD IX,DE */ - ops[0] = 0xdd; - ops[1] = 0x19; - break; - case REGIX: /* ADD IX,IX */ - ops[0] = 0xdd; - ops[1] = 0x29; - break; - case REGSP: /* ADD IX,SP */ - ops[0] = 0xdd; - ops[1] = 0x39; - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_ILLOPE); - } - return(2); -} - -/* - * ADD IY,? - */ -int addiy(void) -{ - switch (get_reg(get_second(operand))) { - case REGBC: /* ADD IY,BC */ - ops[0] = 0xfd; - ops[1] = 0x09; - break; - case REGDE: /* ADD IY,DE */ - ops[0] = 0xfd; - ops[1] = 0x19; - break; - case REGIY: /* ADD IY,IY */ - ops[0] = 0xfd; - ops[1] = 0x29; - break; - case REGSP: /* ADD IY,SP */ - ops[0] = 0xfd; - ops[1] = 0x39; - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_ILLOPE); - } - return(2); -} - -/* - * ADC ?,? - */ -int op_adc(void) -{ - register int len; - register char *p1, *p2; - - if (pass == 1) - if (*label) - put_label(); - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - switch (get_reg(tmp)) { - case REGA: /* ADC A,? */ - len = adca(); - break; - case REGHL: /* ADC HL,? */ - len = adchl(); - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * ADC A,? - */ -int adca(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* ADC A,A */ - case REGB: /* ADC A,B */ - case REGC: /* ADC A,C */ - case REGD: /* ADC A,D */ - case REGE: /* ADC A,E */ - case REGH: /* ADC A,H */ - case REGL: /* ADC A,L */ - case REGIHL: /* ADC A,(HL) */ - len = 1; - ops[0] = 0x88 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { - len = 3; /* ADC A,(IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x8e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - } else if (strncmp(p, "(IY+", 4) == 0) { - len = 3; /* ADC A,(IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x8e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - } else { - len = 2; /* ADD A,n */ - if (pass == 2) { - ops[0] = 0xce; - ops[1] = chk_v1(eval(p)); - } - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * ADC HL,? - */ -int adchl(void) -{ - switch (get_reg(get_second(operand))) { - case REGBC: /* ADC HL,BC */ - ops[0] = 0xed; - ops[1] = 0x4a; - break; - case REGDE: /* ADC HL,DE */ - ops[0] = 0xed; - ops[1] = 0x5a; - break; - case REGHL: /* ADC HL,HL */ - ops[0] = 0xed; - ops[1] = 0x6a; - break; - case REGSP: /* ADC HL,SP */ - ops[0] = 0xed; - ops[1] = 0x7a; - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_ILLOPE); - } - return(2); -} - -/* - * SUB - */ -int op_sub(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* SUB A */ - case REGB: /* SUB B */ - case REGC: /* SUB C */ - case REGD: /* SUB D */ - case REGE: /* SUB E */ - case REGH: /* SUB H */ - case REGL: /* SUB L */ - case REGIHL: /* SUB (HL) */ - len = 1; - ops[0] = 0x90 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 3; /* SUB (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x96; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 3; /* SUB (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x96; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else { - len = 2; /* SUB n */ - if (pass == 2) { - ops[0] = 0xd6; - ops[1] = chk_v1(eval(operand)); - } - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * SBC ?,? - */ -int op_sbc(void) -{ - register int len; - register char *p1, *p2; - - if (pass == 1) - if (*label) - put_label(); - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - switch (get_reg(tmp)) { - case REGA: /* SBC A,? */ - len = sbca(); - break; - case REGHL: /* SBC HL,? */ - len = sbchl(); - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * SBC A,? - */ -int sbca(void) -{ - register int op; - register int len; - register char *p; - - p = get_second(operand); - switch (op = get_reg(p)) { - case REGA: /* SBC A,A */ - case REGB: /* SBC A,B */ - case REGC: /* SBC A,C */ - case REGD: /* SBC A,D */ - case REGE: /* SBC A,E */ - case REGH: /* SBC A,H */ - case REGL: /* SBC A,L */ - case REGIHL: /* SBC A,(HL) */ - len = 1; - ops[0] = 0x98 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p, "(IX+", 4) == 0) { - len = 3; /* SBC A,(IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x9e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - } else if (strncmp(p, "(IY+", 4) == 0) { - len = 3; /* SBC A,(IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x9e; - ops[2] = chk_v2(calc_val(strchr(p, '+') + 1)); - } - } else { - len = 2; /* SBC A,n */ - if (pass == 2) { - ops[0] = 0xde; - ops[1] = chk_v1(eval(p)); - } - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * SBC HL,? - */ -int sbchl(void) -{ - switch (get_reg(get_second(operand))) { - case REGBC: /* SBC HL,BC */ - ops[0] = 0xed; - ops[1] = 0x42; - break; - case REGDE: /* SBC HL,DE */ - ops[0] = 0xed; - ops[1] = 0x52; - break; - case REGHL: /* SBC HL,HL */ - ops[0] = 0xed; - ops[1] = 0x62; - break; - case REGSP: /* SBC HL,SP */ - ops[0] = 0xed; - ops[1] = 0x72; - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_ILLOPE); - } - return(2); -} - -/* - * INC - */ -int op_inc(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* INC A */ - case REGB: /* INC B */ - case REGC: /* INC C */ - case REGD: /* INC D */ - case REGE: /* INC E */ - case REGH: /* INC H */ - case REGL: /* INC L */ - case REGIHL: /* INC (HL) */ - len = 1; - ops[0] = 0x04 + (op << 3); - break; - case REGBC: /* INC BC */ - len = 1; - ops[0] = 0x03; - break; - case REGDE: /* INC DE */ - len = 1; - ops[0] = 0x13; - break; - case REGHL: /* INC HL */ - len = 1; - ops[0] = 0x23; - break; - case REGSP: /* INC SP */ - len = 1; - ops[0] = 0x33; - break; - case REGIX: /* INC IX */ - len = 2; - ops[0] = 0xdd; - ops[1] = 0x23; - break; - case REGIY: /* INC IY */ - len = 2; - ops[0] = 0xfd; - ops[1] = 0x23; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 3; /* INC (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x34; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 3; /* INC (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x34; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * DEC - */ -int op_dec(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* DEC A */ - case REGB: /* DEC B */ - case REGC: /* DEC C */ - case REGD: /* DEC D */ - case REGE: /* DEC E */ - case REGH: /* DEC H */ - case REGL: /* DEC L */ - case REGIHL: /* DEC (HL) */ - len = 1; - ops[0] = 0x05 + (op << 3); - break; - case REGBC: /* DEC BC */ - len = 1; - ops[0] = 0x0b; - break; - case REGDE: /* DEC DE */ - len = 1; - ops[0] = 0x1b; - break; - case REGHL: /* DEC HL */ - len = 1; - ops[0] = 0x2b; - break; - case REGSP: /* DEC SP */ - len = 1; - ops[0] = 0x3b; - break; - case REGIX: /* DEC IX */ - len = 2; - ops[0] = 0xdd; - ops[1] = 0x2b; - break; - case REGIY: /* DEC IY */ - len = 2; - ops[0] = 0xfd; - ops[1] = 0x2b; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 3; /* DEC (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0x35; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 3; /* DEC (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0x35; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * OR - */ -int op_or(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* OR A */ - case REGB: /* OR B */ - case REGC: /* OR C */ - case REGD: /* OR D */ - case REGE: /* OR E */ - case REGH: /* OR H */ - case REGL: /* OR L */ - case REGIHL: /* OR (HL) */ - len = 1; - ops[0] = 0xb0 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 3; /* OR (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xb6; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 3; /* OR (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xb6; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else { - len = 2; /* OR n */ - if (pass == 2) { - ops[0] = 0xf6; - ops[1] = chk_v1(eval(operand)); - } - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * XOR - */ -int op_xor(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* XOR A */ - case REGB: /* XOR B */ - case REGC: /* XOR C */ - case REGD: /* XOR D */ - case REGE: /* XOR E */ - case REGH: /* XOR H */ - case REGL: /* XOR L */ - case REGIHL: /* XOR (HL) */ - len = 1; - ops[0] = 0xa8 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 3; /* XOR (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xae; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 3; /* XOR (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xae; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else { - len = 2; /* XOR n */ - if (pass == 2) { - ops[0] = 0xee; - ops[1] = chk_v1(eval(operand)); - } - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * AND - */ -int op_and(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* AND A */ - case REGB: /* AND B */ - case REGC: /* AND C */ - case REGD: /* AND D */ - case REGE: /* AND E */ - case REGH: /* AND H */ - case REGL: /* AND L */ - case REGIHL: /* AND (HL) */ - len = 1; - ops[0] = 0xa0 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 3; /* AND (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xa6; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 3; /* AND (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xa6; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else { - len = 2; /* AND n */ - if (pass == 2) { - ops[0] = 0xe6; - ops[1] = chk_v1(eval(operand)); - } - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * CP - */ -int op_cp(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* CP A */ - case REGB: /* CP B */ - case REGC: /* CP C */ - case REGD: /* CP D */ - case REGE: /* CP E */ - case REGH: /* CP H */ - case REGL: /* CP L */ - case REGIHL: /* CP (HL) */ - len = 1; - ops[0] = 0xb8 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 3; /* CP (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xbe; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 3; /* CP (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xbe; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - } - } else { - len = 2; /* OR n */ - if (pass == 2) { - ops[0] = 0xfe; - ops[1] = chk_v1(eval(operand)); - } - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * RL - */ -int op_rl(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* RL A */ - case REGB: /* RL B */ - case REGC: /* RL C */ - case REGD: /* RL D */ - case REGE: /* RL E */ - case REGH: /* RL H */ - case REGL: /* RL L */ - case REGIHL: /* RL (HL) */ - len = 2; - ops[0] = 0xcb; - ops[1] = 0x10 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 4; /* RL (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x16; - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 4; /* RL (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x16; - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * RR - */ -int op_rr(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* RR A */ - case REGB: /* RR B */ - case REGC: /* RR C */ - case REGD: /* RR D */ - case REGE: /* RR E */ - case REGH: /* RR H */ - case REGL: /* RR L */ - case REGIHL: /* RR (HL) */ - len = 2; - ops[0] = 0xcb; - ops[1] = 0x18 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 4; /* RR (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x1e; - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 4; /* RR (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x1e; - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * SLA - */ -int op_sla(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* SLA A */ - case REGB: /* SLA B */ - case REGC: /* SLA C */ - case REGD: /* SLA D */ - case REGE: /* SLA E */ - case REGH: /* SLA H */ - case REGL: /* SLA L */ - case REGIHL: /* SLA (HL) */ - len = 2; - ops[0] = 0xcb; - ops[1] = 0x20 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 4; /* SLA (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x26; - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 4; /* SLA (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x26; - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * SRA - */ -int op_sra(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* SRA A */ - case REGB: /* SRA B */ - case REGC: /* SRA C */ - case REGD: /* SRA D */ - case REGE: /* SRA E */ - case REGH: /* SRA H */ - case REGL: /* SRA L */ - case REGIHL: /* SRA (HL) */ - len = 2; - ops[0] = 0xcb; - ops[1] = 0x28 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 4; /* SRA (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x2e; - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 4; /* SRA (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x2e; - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * SRL - */ -int op_srl(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* SRL A */ - case REGB: /* SRL B */ - case REGC: /* SRL C */ - case REGD: /* SRL D */ - case REGE: /* SRL E */ - case REGH: /* SRL H */ - case REGL: /* SRL L */ - case REGIHL: /* SRL (HL) */ - len = 2; - ops[0] = 0xcb; - ops[1] = 0x38 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 4; /* SRL (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x3e; - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 4; /* SRL (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x3e; - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * RLC - */ -int op_rlc(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* RLC A */ - case REGB: /* RLC B */ - case REGC: /* RLC C */ - case REGD: /* RLC D */ - case REGE: /* RLC E */ - case REGH: /* RLC H */ - case REGL: /* RLC L */ - case REGIHL: /* RLC (HL) */ - len = 2; - ops[0] = 0xcb; - ops[1] = 0x00 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 4; /* RLC (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x06; - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 4; /* RLC (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x06; - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * RRC - */ -int op_rrc(void) -{ - register int len, op; - - if (pass == 1) - if (*label) - put_label(); - switch (op = get_reg(operand)) { - case REGA: /* RRC A */ - case REGB: /* RRC B */ - case REGC: /* RRC C */ - case REGD: /* RRC D */ - case REGE: /* RRC E */ - case REGH: /* RRC H */ - case REGL: /* RRC L */ - case REGIHL: /* RRC (HL) */ - len = 2; - ops[0] = 0xcb; - ops[1] = 0x08 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(operand, "(IX+", 4) == 0) { - len = 4; /* RRC (IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x0e; - } - } else if (strncmp(operand, "(IY+", 4) == 0) { - len = 4; /* RRC (IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x0e; - } - } else { - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - len = 1; - ops[0] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - len = 1; - ops[0] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * OUT - */ -int op_out(void) -{ - register int op; - - if (pass == 1) { /* PASS 1 */ - if (*label) - put_label(); - } else { /* PASS 2 */ - if (strncmp(operand, "(C),", 4) == 0) { - switch(op = get_reg(get_second(operand))) { - case REGA: /* OUT (C),A */ - case REGB: /* OUT (C),B */ - case REGC: /* OUT (C),C */ - case REGD: /* OUT (C),D */ - case REGE: /* OUT (C),E */ - case REGH: /* OUT (C),H */ - case REGL: /* OUT (C),L */ - ops[0] = 0xed; - ops[1] = 0x41 + (op << 3); - break; - case NOOPERA: /* missing operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_ILLOPE); - } - } else { - ops[0] = 0xd3; /* OUT (n),A */ - ops[1] = chk_v1(calc_val(operand + 1)); - } - } - return(2); -} - -/* - * IN - */ -int op_in(void) -{ - register char *p1, *p2; - register int op; - - if (pass == 1) { /* PASS 1 */ - if (*label) - put_label(); - } else { /* PASS 2 */ - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - switch (op = get_reg(tmp)) { - case REGA: - if (strncmp(operand, "A,(C)", 5) == 0) { - ops[0] = 0xed; /* IN A,(C) */ - ops[1] = 0x78; - } else { - ops[0] = 0xdb; /* IN A,(n) */ - ops[1] = chk_v1(calc_val(get_second(operand) + 1)); - } - break; - case REGB: /* IN B,(C) */ - case REGC: /* IN C,(C) */ - case REGD: /* IN D,(C) */ - case REGE: /* IN E,(C) */ - case REGH: /* IN H,(C) */ - case REGL: /* IN L,(C) */ - ops[0] = 0xed; - ops[1] = 0x40 + (op << 3); - break; - default: /* invalid operand */ - ops[0] = 0; - ops[1] = 0; - asmerr(E_ILLOPE); - } - } - return(2); -} - -/* - * SET - */ -int op_set(void) -{ - register char *p1, *p2; - register int len; - register int i; - register int op; - - len = 2; - i = 0; - if (pass == 1) - if (*label) - put_label(); - ops[0] = 0xcb; - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - if (pass == 2) { - i = eval(tmp); - if (i < 0 || i > 7) - asmerr(E_VALOUT); - } - switch (op = get_reg(++p1)) { - case REGA: /* SET n,A */ - case REGB: /* SET n,B */ - case REGC: /* SET n,C */ - case REGD: /* SET n,D */ - case REGE: /* SET n,E */ - case REGH: /* SET n,H */ - case REGL: /* SET n,L */ - case REGIHL: /* SET n,(HL) */ - ops[1] = 0xc0 + i * 8 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p1, "(IX+", 4) == 0) { - len = 4; /* SET n,(IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0xc6 + i * 8; - } - } else if (strncmp(p1, "(IY+", 4) == 0) { - len = 4; /* SET n,(IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0xc6 + i * 8; - } - } else { - ops[1] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[1] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * RES - */ -int op_res(void) -{ - register char *p1, *p2; - register int len; - register int i; - register int op; - - len = 2; - i = 0; - if (pass == 1) - if (*label) - put_label(); - ops[0] = 0xcb; - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - if (pass == 2) { - i = eval(tmp); - if (i < 0 || i > 7) - asmerr(E_VALOUT); - } - switch (op = get_reg(++p1)) { - case REGA: /* RES n,A */ - case REGB: /* RES n,B */ - case REGC: /* RES n,C */ - case REGD: /* RES n,D */ - case REGE: /* RES n,E */ - case REGH: /* RES n,H */ - case REGL: /* RES n,L */ - case REGIHL: /* RES n,(HL) */ - ops[1] = 0x80 + i * 8 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p1, "(IX+", 4) == 0) { - len = 4; /* RES n,(IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x86 + i * 8; - } - } else if (strncmp(p1, "(IY+", 4) == 0) { - len = 4; /* RES n,(IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x86 + i * 8; - } - } else { - ops[1] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[1] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * BIT - */ -int op_bit(void) -{ - register char *p1, *p2; - register int len; - register int i; - register int op; - - len = 2; - i = 0; - if (pass == 1) - if (*label) - put_label(); - ops[0] = 0xcb; - p1 = operand; - p2 = tmp; - while (*p1 != ',' && *p1 != '\0') - *p2++ = *p1++; - *p2 = '\0'; - if (pass == 2) { - i = eval(tmp); - if (i < 0 || i > 7) - asmerr(E_VALOUT); - } - switch (op = get_reg(++p1)) { - case REGA: /* BIT n,A */ - case REGB: /* BIT n,B */ - case REGC: /* BIT n,C */ - case REGD: /* BIT n,D */ - case REGE: /* BIT n,E */ - case REGH: /* BIT n,H */ - case REGL: /* BIT n,L */ - case REGIHL: /* BIT n,(HL) */ - ops[1] = 0x40 + i * 8 + op; - break; - case NOREG: /* operand isn't register */ - if (strncmp(p1, "(IX+", 4) == 0) { - len = 4; /* BIT n,(IX+d) */ - if (pass == 2) { - ops[0] = 0xdd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x46 + i * 8; - } - } else if (strncmp(p1, "(IY+", 4) == 0) { - len = 4; /* BIT n,(IY+d) */ - if (pass == 2) { - ops[0] = 0xfd; - ops[1] = 0xcb; - ops[2] = chk_v2(calc_val(strchr(operand, '+') + 1)); - ops[3] = 0x46 + i * 8; - } - } else { - ops[1] = 0; - asmerr(E_ILLOPE); - } - break; - case NOOPERA: /* missing operand */ - ops[1] = 0; - asmerr(E_MISOPE); - break; - default: /* invalid operand */ - ops[1] = 0; - asmerr(E_ILLOPE); - } - return(len); -} - -/* - * returns a pointer to the second operand for - * opcodes: opcode destination,source - * if source is missing returns NULL - */ -char *get_second(char *s) -{ - register char *p; - - if ((p = strchr(s, ',')) != NULL) - return(p + 1); - else - return(NULL); -} - -/* - * computes value of expressions in offsets: - * LD A,(IX+7) - * -- - */ -int calc_val(char *s) -{ - register char *p; - register int i; - - if ((p = strrchr(s, ')')) == NULL) { - asmerr(E_MISPAR); - return(0); - } - i = p - s; - strncpy(tmp, s, i); - *(tmp + i) = '\0'; - return(eval(tmp)); -} diff --git a/emu/z80pack-1.9/z80asm/z80atab.c b/emu/z80pack-1.9/z80asm/z80atab.c deleted file mode 100644 index 4cb4f9f..0000000 --- a/emu/z80pack-1.9/z80asm/z80atab.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Z80 - Assembler - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 17-SEP-1987 Development under Digital Research CP/M 2.2 - * 28-JUN-1988 Switched to Unix System V.3 - * 22-OCT-2006 changed to ANSI C for modern POSIX OS's - */ - -/* - * module with table oprations on opcode and symbol tables - */ - -#include -#include -#include -#include "z80a.h" -#include "z80aglb.h" - -extern void fatal(int, char *); -extern void asmerr(int); - -/* - * binary search in sorted table opctab - * - * Input: pointer to string with opcode - * - * Output: pointer to table element, or NULL if not found - */ -struct opc *search_op(char *op_name) -{ - register int cond; - register struct opc *low, *high, *mid; - - low = &opctab[0]; - high = &opctab[no_opcodes - 1]; - while (low <= high) { - mid = low + (high - low) / 2; - if ((cond = strcmp(op_name, mid->op_name)) < 0) - high = mid - 1; - else if (cond > 0) - low = mid + 1; - else - return(mid); - } - return(NULL); -} - -/* - * binary search on sorted table opetab - * - * Input: pointer to string with operand - * - * Output: symbol for operand, NOOPERA if empty operand, - * NOREG if operand not found - */ -int get_reg(char *s) -{ - register int cond; - register struct ope *low, *high, *mid; - - if (s == NULL || *s == '\0') - return(NOOPERA); - low = &opetab[0]; - high = &opetab[no_operands - 1]; - while (low <= high) { - mid = low + (high - low) / 2; - if ((cond = strcmp(s, mid->ope_name)) < 0) - high = mid - 1; - else if (cond > 0) - low = mid + 1; - else - return(mid->ope_sym); - } - return(NOREG); -} - -/* - * hash search on symbol table symtab - * - * Input: pointer to string with symbol - * - * Output: pointer to table element, or NULL if not found - */ -struct sym *get_sym(char *sym_name) -{ - register struct sym *np; - - for (np = symtab[hash(sym_name)]; np != NULL; np = np->sym_next) - if (strcmp(sym_name, np->sym_name) == 0) - return(np); - return(NULL); -} - -/* - * add symbol to symbol table symtab, or modify existing symbol - * - * Input: sym_name pointer to string with symbol name - * sym_wert value of symbol - * - * Output: 0 symbol added/modified - * 1 out of memory - */ -int put_sym(char *sym_name, int sym_wert) -{ - struct sym *get_sym(); - register int hashval; - register struct sym *np; - - char *strsave(char *); - - if (!gencode) - return(0); - if ((np = get_sym(sym_name)) == NULL) { - np = (struct sym *) malloc(sizeof (struct sym)); - if (np == NULL) - return(1); - if ((np->sym_name = strsave(sym_name)) == NULL) - return(1); - hashval = hash(sym_name); - np->sym_next = symtab[hashval]; - symtab[hashval] = np; - } - np->sym_wert = sym_wert; - return(0); -} - -/* - * add label to symbol table, error if symbol already exists - */ -void put_label(void) -{ - struct sym *get_sym(char *); - - if (get_sym(label) == NULL) { - if (put_sym(label, pc)) - fatal(F_OUTMEM, "symbols"); - } else - asmerr(E_MULSYM); -} - -/* - * hash algorithm - * - * Input: pointer to string with name - * - * Output: hash value - */ -int hash(char *name) -{ - register int hashval; - - for (hashval = 0; *name;) - hashval += *name++; - return(hashval % HASHSIZE); -} - -/* - * save string into allocated memory - * - * Input: pointer to string - * - * Output: pointer to allocated memory with string - */ -char *strsave(char *s) -{ - register char *p; - - if ((p = malloc((unsigned) strlen(s)+1)) != NULL) - strcpy(p, s); - return(p); -} - -/* - * copy whole symbol hast table into allocated pointer array - * used for sorting the symbol table later - */ -int copy_sym(void) -{ - register int i, j; - register struct sym *np; - - symarray = (struct sym **) malloc(SYMINC * sizeof(struct sym *)); - if (symarray == NULL) - fatal(F_OUTMEM, "sorting symbol table"); - symsize = SYMINC; - for (i = 0, j = 0; i < HASHSIZE; i++) { - if (symtab[i] != NULL) { - for (np = symtab[i]; np != NULL; np = np->sym_next) { - symarray[j++] = np; - if (j == symsize) { - symarray = (struct sym **) realloc((char *) symarray, symsize * sizeof(struct sym *) + SYMINC * sizeof(struct sym *)); - if (symarray == NULL) - fatal(F_OUTMEM, "sorting symbol table"); - symsize += SYMINC; - } - } - } - } - return(j); -} - -/* - * sort symbol table by name - */ -void n_sort_sym(int len) -{ - register int gap, i, j; - register struct sym *temp; - - for (gap = len/2; gap > 0; gap /= 2) - for (i = gap; i < len; i++) - for (j = i-gap; j >= 0; j -= gap) { - if (strcmp(symarray[j]->sym_name, - symarray[j+gap]->sym_name) <= 0) - break; - temp = symarray[j]; - symarray[j] = symarray[j+gap]; - symarray[j+gap] = temp; - } -} - -/* - * sort symbol table by address - */ -void a_sort_sym(int len) -{ - register int gap, i, j; - register struct sym *temp; - - for (gap = len/2; gap > 0; gap /= 2) - for (i = gap; i < len; i++) - for (j = i-gap; j >= 0; j -= gap) { - if (numcmp(symarray[j]->sym_wert, - symarray[j+gap]->sym_wert) <= 0) - break; - temp = symarray[j]; - symarray[j] = symarray[j+gap]; - symarray[j+gap] = temp; - } -} - -/* - * compares two 16bit values, result like strcmp() - */ -int numcmp(int n1, int n2) -{ - if ((unsigned) (n1 & 0xffff) < (unsigned) (n2 & 0xffff)) - return(-1); - else if ((unsigned) (n1 & 0xffff) > (unsigned) (n2 & 0xffff)) - return(1); - else - return(0); -} diff --git a/emu/z80pack-1.9/z80sim/Makefile b/emu/z80pack-1.9/z80sim/Makefile deleted file mode 100644 index ea9022b..0000000 --- a/emu/z80pack-1.9/z80sim/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# Makefile for Z80-CPU emulator unter UNIX System V - -CFLAGS= -O -c -Wall -LFLAGS= -s - -#CFLAGS= -g -c -Wall -#LFLAGS= - -OBJ = sim0.o \ - sim1.o \ - sim2.o \ - sim3.o \ - sim4.o \ - sim5.o \ - sim6.o \ - sim7.o \ - simctl.o \ - disas.o \ - simint.o \ - iosim.o \ - simfun.o \ - simglb.o - -z80sim : $(OBJ) - cc $(OBJ) $(LFLAGS) -o z80sim - -sim0.o : sim0.c sim.h simglb.h - cc $(CFLAGS) sim0.c - -sim1.o : sim1.c sim.h simglb.h - cc $(CFLAGS) sim1.c - -sim2.o : sim2.c sim.h simglb.h - cc $(CFLAGS) sim2.c - -sim3.o : sim3.c sim.h simglb.h - cc $(CFLAGS) sim3.c - -sim4.o : sim4.c sim.h simglb.h - cc $(CFLAGS) sim4.c - -sim5.o : sim5.c sim.h simglb.h - cc $(CFLAGS) sim5.c - -sim6.o : sim6.c sim.h simglb.h - cc $(CFLAGS) sim6.c - -sim7.o : sim7.c sim.h simglb.h - cc $(CFLAGS) sim7.c - -simctl.o : simctl.c sim.h simglb.h - cc $(CFLAGS) simctl.c - -disas.o : disas.c - cc $(CFLAGS) disas.c - -simint.o : simint.c sim.h simglb.h - cc $(CFLAGS) simint.c - -iosim.o : iosim.c sim.h simglb.h - cc $(CFLAGS) iosim.c - -simfun.o : simfun.c sim.h - cc $(CFLAGS) simfun.c - -simglb.o : simglb.c sim.h - cc $(CFLAGS) simglb.c - -clean: - rm -f *.o core z80sim diff --git a/emu/z80pack-1.9/z80sim/disas.c b/emu/z80pack-1.9/z80sim/disas.c deleted file mode 100644 index b7e426c..0000000 --- a/emu/z80pack-1.9/z80sim/disas.c +++ /dev/null @@ -1,883 +0,0 @@ -/* - * Z80 disassembler for Z80-CPU simulator - * - * Copyright (C) 1989-2006 by Udo Munk - * - * History: - * 06-DEC-89 Development on TARGON/35 with AT&T Unix System V.3 - * 07-APR-92 forget to implement Op-Codes LD A,R and LD R,A, added - * 25-JUN-92 comments in english - * 03-OCT-06 changed to ANSI C for modern POSIX OS's - */ - -#include - -/* - * Forward declarations - */ -static int opout(char *, char **); -static int nout(char *, unsigned char **); -static int iout(char *, unsigned char **); -static int rout(char *, char **); -static int nnout(char *, unsigned char **); -static int inout(char *, unsigned char **); -static int cbop(char *, unsigned char **); -static int edop(char *, unsigned char **); -static int ddfd(char *, unsigned char **); - -/* - * Op-code tables - */ -struct opt { - int (*fun) (); - char *text; -}; - -static struct opt optab[256] = { - { opout, "NOP" }, /* 0x00 */ - { nnout, "LD\tBC," }, /* 0x01 */ - { opout, "LD\t(BC),A" }, /* 0x02 */ - { opout, "INC\tBC" }, /* 0x03 */ - { opout, "INC\tB" }, /* 0x04 */ - { opout, "DEC\tB" }, /* 0x05 */ - { nout, "LD\tB," }, /* 0x06 */ - { opout, "RLCA" }, /* 0x07 */ - { opout, "EX\tAF,AF'" }, /* 0x08 */ - { opout, "ADD\tHL,BC" }, /* 0x09 */ - { opout, "LD\tA,(BC)" }, /* 0x0a */ - { opout, "DEC\tBC" }, /* 0x0b */ - { opout, "INC\tC" }, /* 0x0c */ - { opout, "DEC\tC" }, /* 0x0d */ - { nout, "LD\tC," }, /* 0x0e */ - { opout, "RRCA" }, /* 0x0f */ - { rout, "DJNZ\t" }, /* 0x10 */ - { nnout, "LD\tDE," }, /* 0x11 */ - { opout, "LD\t(DE),A" }, /* 0x12 */ - { opout, "INC\tDE" }, /* 0x13 */ - { opout, "INC\tD" }, /* 0x14 */ - { opout, "DEC\tD" }, /* 0x15 */ - { nout, "LD\tD," }, /* 0x16 */ - { opout, "RLA" }, /* 0x17 */ - { rout, "JR\t" }, /* 0x18 */ - { opout, "ADD\tHL,DE" }, /* 0x19 */ - { opout, "LD\tA,(DE)" }, /* 0x1a */ - { opout, "DEC\tDE" }, /* 0x1b */ - { opout, "INC\tE" }, /* 0x1c */ - { opout, "DEC\tE" }, /* 0x1d */ - { nout, "LD\tE," }, /* 0x1e */ - { opout, "RRA" }, /* 0x1f */ - { rout, "JR\tNZ," }, /* 0x20 */ - { nnout, "LD\tHL," }, /* 0x21 */ - { inout, "LD\t(%04x),HL" }, /* 0x22 */ - { opout, "INC\tHL" }, /* 0x23 */ - { opout, "INC\tH" }, /* 0x24 */ - { opout, "DEC\tH" }, /* 0x25 */ - { nout, "LD\tH," }, /* 0x26 */ - { opout, "DAA" }, /* 0x27 */ - { rout, "JR\tZ," }, /* 0x28 */ - { opout, "ADD\tHL,HL" }, /* 0x29 */ - { inout, "LD\tHL,(%04x)" }, /* 0x2a */ - { opout, "DEC\tHL" }, /* 0x2b */ - { opout, "INC\tL" }, /* 0x2c */ - { opout, "DEC\tL" }, /* 0x2d */ - { nout, "LD\tL," }, /* 0x2e */ - { opout, "CPL" }, /* 0x2f */ - { rout, "JR\tNC," }, /* 0x30 */ - { nnout, "LD\tSP," }, /* 0x31 */ - { inout, "LD\t(%04x),A" }, /* 0x32 */ - { opout, "INC\tSP" }, /* 0x33 */ - { opout, "INC\t(HL)" }, /* 0x34 */ - { opout, "DEC\t(HL)" }, /* 0x35 */ - { nout, "LD\t(HL)," }, /* 0x36 */ - { opout, "SCF" }, /* 0x37 */ - { rout, "JR\tC," }, /* 0x38 */ - { opout, "ADD\tHL,SP" }, /* 0x39 */ - { inout, "LD\tA,(%04x)" }, /* 0x3a */ - { opout, "DEC\tSP" }, /* 0x3b */ - { opout, "INC\tA" }, /* 0x3c */ - { opout, "DEC\tA" }, /* 0x3d */ - { nout, "LD\tA," }, /* 0x3e */ - { opout, "CCF" }, /* 0x3f */ - { opout, "LD\tB,B" }, /* 0x40 */ - { opout, "LD\tB,C" }, /* 0x41 */ - { opout, "LD\tB,D" }, /* 0x42 */ - { opout, "LD\tB,E" }, /* 0x43 */ - { opout, "LD\tB,H" }, /* 0x44 */ - { opout, "LD\tB,L" }, /* 0x45 */ - { opout, "LD\tB,(HL)" }, /* 0x46 */ - { opout, "LD\tB,A" }, /* 0x47 */ - { opout, "LD\tC,B" }, /* 0x48 */ - { opout, "LD\tC,C" }, /* 0x49 */ - { opout, "LD\tC,D" }, /* 0x4a */ - { opout, "LD\tC,E" }, /* 0x4b */ - { opout, "LD\tC,H" }, /* 0x4c */ - { opout, "LD\tC,L" }, /* 0x4d */ - { opout, "LD\tC,(HL)" }, /* 0x4e */ - { opout, "LD\tC,A" }, /* 0x4f */ - { opout, "LD\tD,B" }, /* 0x50 */ - { opout, "LD\tD,C" }, /* 0x51 */ - { opout, "LD\tD,D" }, /* 0x52 */ - { opout, "LD\tD,E" }, /* 0x53 */ - { opout, "LD\tD,H" }, /* 0x54 */ - { opout, "LD\tD,L" }, /* 0x55 */ - { opout, "LD\tD,(HL)" }, /* 0x56 */ - { opout, "LD\tD,A" }, /* 0x57 */ - { opout, "LD\tE,B" }, /* 0x58 */ - { opout, "LD\tE,C" }, /* 0x59 */ - { opout, "LD\tE,D" }, /* 0x5a */ - { opout, "LD\tE,E" }, /* 0x5b */ - { opout, "LD\tE,H" }, /* 0x5c */ - { opout, "LD\tE,L" }, /* 0x5d */ - { opout, "LD\tE,(HL)" }, /* 0x5e */ - { opout, "LD\tE,A" }, /* 0x5f */ - { opout, "LD\tH,B" }, /* 0x60 */ - { opout, "LD\tH,C" }, /* 0x61 */ - { opout, "LD\tH,D" }, /* 0x62 */ - { opout, "LD\tH,E" }, /* 0x63 */ - { opout, "LD\tH,H" }, /* 0x64 */ - { opout, "LD\tH,L" }, /* 0x65 */ - { opout, "LD\tH,(HL)" }, /* 0x66 */ - { opout, "LD\tH,A" }, /* 0x67 */ - { opout, "LD\tL,B" }, /* 0x68 */ - { opout, "LD\tL,C" }, /* 0x69 */ - { opout, "LD\tL,D" }, /* 0x6a */ - { opout, "LD\tL,E" }, /* 0x6b */ - { opout, "LD\tL,H" }, /* 0x6c */ - { opout, "LD\tL,L" }, /* 0x6d */ - { opout, "LD\tL,(HL)" }, /* 0x6e */ - { opout, "LD\tL,A" }, /* 0x6f */ - { opout, "LD\t(HL),B" }, /* 0x70 */ - { opout, "LD\t(HL),C" }, /* 0x71 */ - { opout, "LD\t(HL),D" }, /* 0x72 */ - { opout, "LD\t(HL),E" }, /* 0x73 */ - { opout, "LD\t(HL),H" }, /* 0x74 */ - { opout, "LD\t(HL),L" }, /* 0x75 */ - { opout, "HALT" }, /* 0x76 */ - { opout, "LD\t(HL),A" }, /* 0x77 */ - { opout, "LD\tA,B" }, /* 0x78 */ - { opout, "LD\tA,C" }, /* 0x79 */ - { opout, "LD\tA,D" }, /* 0x7a */ - { opout, "LD\tA,E" }, /* 0x7b */ - { opout, "LD\tA,H" }, /* 0x7c */ - { opout, "LD\tA,L" }, /* 0x7d */ - { opout, "LD\tA,(HL)" }, /* 0x7e */ - { opout, "LD\tA,A" }, /* 0x7f */ - { opout, "ADD\tA,B" }, /* 0x80 */ - { opout, "ADD\tA,C" }, /* 0x81 */ - { opout, "ADD\tA,D" }, /* 0x82 */ - { opout, "ADD\tA,E" }, /* 0x83 */ - { opout, "ADD\tA,H" }, /* 0x84 */ - { opout, "ADD\tA,L" }, /* 0x85 */ - { opout, "ADD\tA,(HL)" }, /* 0x86 */ - { opout, "ADD\tA,A" }, /* 0x87 */ - { opout, "ADC\tA,B" }, /* 0x88 */ - { opout, "ADC\tA,C" }, /* 0x89 */ - { opout, "ADC\tA,D" }, /* 0x8a */ - { opout, "ADC\tA,E" }, /* 0x8b */ - { opout, "ADC\tA,H" }, /* 0x8c */ - { opout, "ADC\tA,L" }, /* 0x8d */ - { opout, "ADC\tA,(HL)" }, /* 0x8e */ - { opout, "ADC\tA,A" }, /* 0x8f */ - { opout, "SUB\tB" }, /* 0x90 */ - { opout, "SUB\tC" }, /* 0x91 */ - { opout, "SUB\tD" }, /* 0x92 */ - { opout, "SUB\tE" }, /* 0x93 */ - { opout, "SUB\tH" }, /* 0x94 */ - { opout, "SUB\tL" }, /* 0x95 */ - { opout, "SUB\t(HL)" }, /* 0x96 */ - { opout, "SUB\tA" }, /* 0x97 */ - { opout, "SBC\tA,B" }, /* 0x98 */ - { opout, "SBC\tA,C" }, /* 0x99 */ - { opout, "SBC\tA,D" }, /* 0x9a */ - { opout, "SBC\tA,E" }, /* 0x9b */ - { opout, "SBC\tA,H" }, /* 0x9c */ - { opout, "SBC\tA,L" }, /* 0x9d */ - { opout, "SBC\tA,(HL)" }, /* 0x9e */ - { opout, "SBC\tA,A" }, /* 0x9f */ - { opout, "AND\tB" }, /* 0xa0 */ - { opout, "AND\tC" }, /* 0xa1 */ - { opout, "AND\tD" }, /* 0xa2 */ - { opout, "AND\tE" }, /* 0xa3 */ - { opout, "AND\tH" }, /* 0xa4 */ - { opout, "AND\tL" }, /* 0xa5 */ - { opout, "AND\t(HL)" }, /* 0xa6 */ - { opout, "AND\tA" }, /* 0xa7 */ - { opout, "XOR\tB" }, /* 0xa8 */ - { opout, "XOR\tC" }, /* 0xa9 */ - { opout, "XOR\tD" }, /* 0xaa */ - { opout, "XOR\tE" }, /* 0xab */ - { opout, "XOR\tH" }, /* 0xac */ - { opout, "XOR\tL" }, /* 0xad */ - { opout, "XOR\t(HL)" }, /* 0xae */ - { opout, "XOR\tA" }, /* 0xaf */ - { opout, "OR\tB" }, /* 0xb0 */ - { opout, "OR\tC" }, /* 0xb1 */ - { opout, "OR\tD" }, /* 0xb2 */ - { opout, "OR\tE" }, /* 0xb3 */ - { opout, "OR\tH" }, /* 0xb4 */ - { opout, "OR\tL" }, /* 0xb5 */ - { opout, "OR\t(HL)" }, /* 0xb6 */ - { opout, "OR\tA" }, /* 0xb7 */ - { opout, "CP\tB" }, /* 0xb8 */ - { opout, "CP\tC" }, /* 0xb9 */ - { opout, "CP\tD" }, /* 0xba */ - { opout, "CP\tE" }, /* 0xbb */ - { opout, "CP\tH" }, /* 0xbc */ - { opout, "CP\tL" }, /* 0xbd */ - { opout, "CP\t(HL)" }, /* 0xbe */ - { opout, "CP\tA" }, /* 0xbf */ - { opout, "RET\tNZ" }, /* 0xc0 */ - { opout, "POP\tBC" }, /* 0xc1 */ - { nnout, "JP\tNZ," }, /* 0xc2 */ - { nnout, "JP\t" }, /* 0xc3 */ - { nnout, "CALL\tNZ," }, /* 0xc4 */ - { opout, "PUSH\tBC" }, /* 0xc5 */ - { nout, "ADD\tA," }, /* 0xc6 */ - { opout, "RST\t0" }, /* 0xc7 */ - { opout, "RET\tZ" }, /* 0xc8 */ - { opout, "RET" }, /* 0xc9 */ - { nnout, "JP\tZ," }, /* 0xca */ - { cbop, "" }, /* 0xcb */ - { nnout, "CALL\tZ," }, /* 0xcc */ - { nnout, "CALL\t" }, /* 0xcd */ - { nout, "ADC\tA," }, /* 0xce */ - { opout, "RST\t8" }, /* 0xcf */ - { opout, "RET\tNC" }, /* 0xd0 */ - { opout, "POP\tDE" }, /* 0xd1 */ - { nnout, "JP\tNC," }, /* 0xd2 */ - { iout, "OUT\t(%02x),A" }, /* 0xd3 */ - { nnout, "CALL\tNC," }, /* 0xd4 */ - { opout, "PUSH\tDE" }, /* 0xd5 */ - { nout, "SUB\t" }, /* 0xd6 */ - { opout, "RST\t10" }, /* 0xd7 */ - { opout, "RET\tC" }, /* 0xd8 */ - { opout, "EXX" }, /* 0xd9 */ - { nnout, "JP\tC," }, /* 0xda */ - { iout, "IN\tA,(%02x)" }, /* 0xdb */ - { nnout, "CALL\tC," }, /* 0xdc */ - { ddfd, "" }, /* 0xdd */ - { nout, "SBC\tA," }, /* 0xde */ - { opout, "RST\t18" }, /* 0xdf */ - { opout, "RET\tPO" }, /* 0xe0 */ - { opout, "POP\tHL" }, /* 0xe1 */ - { nnout, "JP\tPO," }, /* 0xe2 */ - { opout, "EX\t(SP),HL" }, /* 0xe3 */ - { nnout, "CALL\tPO," }, /* 0xe4 */ - { opout, "PUSH\tHL" }, /* 0xe5 */ - { nout, "AND\t" }, /* 0xe6 */ - { opout, "RST\t20" }, /* 0xe7 */ - { opout, "RET\tPE" }, /* 0xe8 */ - { opout, "JP\t(HL)" }, /* 0xe9 */ - { nnout, "JP\tPE," }, /* 0xea */ - { opout, "EX\tDE,HL" }, /* 0xeb */ - { nnout, "CALL\tPE," }, /* 0xec */ - { edop, "" }, /* 0xed */ - { nout, "XOR\t" }, /* 0xee */ - { opout, "RST\t28" }, /* 0xef */ - { opout, "RET\tP" }, /* 0xf0 */ - { opout, "POP\tAF" }, /* 0xf1 */ - { nnout, "JP\tP," }, /* 0xf2 */ - { opout, "DI" }, /* 0xf3 */ - { nnout, "CALL\tP," }, /* 0xf4 */ - { opout, "PUSH\tAF" }, /* 0xf5 */ - { nout, "OR\t" }, /* 0xf6 */ - { opout, "RST\t30" }, /* 0xf7 */ - { opout, "RET\tM" }, /* 0xf8 */ - { opout, "LD\tSP,HL" }, /* 0xf9 */ - { nnout, "JP\tM," }, /* 0xfa */ - { opout, "EI" }, /* 0xfb */ - { nnout, "CALL\tM," }, /* 0xfc */ - { ddfd, "" }, /* 0xfd */ - { nout, "CP\t" }, /* 0xfe */ - { opout, "RST\t38" } /* 0xff */ -}; - -static int addr; -static char *unkown = "???"; -static char *reg[] = { "B", "C", "D", "E", "H", "L", "(HL)", "A" }; -static char *regix = "IX"; -static char *regiy = "IY"; - -/* - * The function disass() is the only global function of - * this module. The first argument is a pointer to a - * unsigned char pointer, which points to the op-code - * to disassemble. The output of the disassembly goes - * to stdout, terminated by a newline. After the - * disassembly the pointer to the op-code will be - * increased by the size of the op-code, so that - * disass() can be called again. - * The secound argument is the (Z80) address of the - * op-code to disassemble. It is used to calculate the - * destination address of relative jumps. - */ -void disass(unsigned char **p, int adr) -{ - register int len; - - addr = adr; - len = (*optab[**p].fun) (optab[**p].text, p); - *p += len; -} - -/* - * disassemble 1 byte op-codes - */ -static int opout(char *s, char **p) -{ - puts(s); - return(1); -} - -/* - * disassemble 2 byte op-codes of type "Op n" - */ -static int nout(char *s, unsigned char **p) -{ - printf("%s%02x\n", s, *(*p + 1)); - return(2); -} - -/* - * disassemble 2 byte op-codes with indirect addressing - */ -static int iout(char *s, unsigned char **p) -{ - printf(s, *(*p + 1)); - putchar('\n'); - return(2); -} - -/* - * disassemble 2 byte op-codes with relative addressing - */ -static int rout(char *s, char **p) -{ - printf("%s%04x\n", s, addr + *(*p + 1) + 2); - return(2); -} - -/* - * disassemble 3 byte op-codes of type "Op nn" - */ -static int nnout(char *s, unsigned char **p) -{ - register int i; - - i = *(*p + 1) + (*(*p + 2) << 8); - printf("%s%04x\n", s, i); - return(3); -} - -/* - * disassemble 3 byte op-codes with indirect addressing - */ -static int inout(char *s, unsigned char **p) -{ - register int i; - - i = *(*p + 1) + (*(*p + 2) << 8); - printf(s, i); - putchar('\n'); - return(3); -} - -/* - * disassemble multi byte op-codes with prefix 0xcb - */ -static int cbop(char *s, unsigned char **p) -{ - register int b2; - - b2 = *(*p + 1); - if (b2 >= 0x00 && b2 <= 0x07) { - printf("RLC\t"); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0x08 && b2 <= 0x0f) { - printf("RRC\t"); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0x10 && b2 <= 0x17) { - printf("RL\t"); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0x18 && b2 <= 0x1f) { - printf("RR\t"); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0x20 && b2 <= 0x27) { - printf("SLA\t"); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0x28 && b2 <= 0x2f) { - printf("SRA\t"); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0x38 && b2 <= 0x3f) { - printf("SRL\t"); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0x40 && b2 <= 0x7f) { - printf("BIT\t"); - printf("%c,", ((b2 >> 3) & 7) + '0'); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0x80 && b2 <= 0xbf) { - printf("RES\t"); - printf("%c,", ((b2 >> 3) & 7) + '0'); - printf("%s\n", reg[b2 & 7]); - return(2); - } - if (b2 >= 0xc0) { - printf("SET\t"); - printf("%c,", ((b2 >> 3) & 7) + '0'); - printf("%s\n", reg[b2 & 7]); - return(2); - } - puts(unkown); - return(2); -} - -/* - * disassemble multi byte op-codes with prefix 0xed - */ -static int edop(char *s, unsigned char **p) -{ - register int b2, i; - int len = 2; - - b2 = *(*p + 1); - switch (b2) { - case 0x40: - puts("IN\tB,(C)"); - break; - case 0x41: - puts("OUT\t(C),B"); - break; - case 0x42: - puts("SBC\tHL,BC"); - break; - case 0x43: - i = *(*p + 2) + (*(*p + 3) << 8); - printf("LD\t(%04x),BC\n", i); - len = 4; - break; - case 0x44: - puts("NEG"); - break; - case 0x45: - puts("RETN"); - break; - case 0x46: - puts("IM\t0"); - break; - case 0x47: - puts("LD\tI,A"); - break; - case 0x48: - puts("IN\tC,(C)"); - break; - case 0x49: - puts("OUT\t(C),C"); - break; - case 0x4a: - puts("ADC\tHL,BC"); - break; - case 0x4b: - i = *(*p + 2) + (*(*p + 3) << 8); - printf("LD\tBC,(%04x)\n", i); - len = 4; - break; - case 0x4d: - puts("RETI"); - break; - case 0x4f: - puts("LD\tR,A"); - break; - case 0x50: - puts("IN\tD,(C)"); - break; - case 0x51: - puts("OUT\t(C),D"); - break; - case 0x52: - puts("SBC\tHL,DE"); - break; - case 0x53: - i = *(*p + 2) + (*(*p + 3) << 8); - printf("LD\t(%04x),DE\n", i); - len = 4; - break; - case 0x56: - puts("IM\t1"); - break; - case 0x57: - puts("LD\tA,I"); - break; - case 0x58: - puts("IN\tE,(C)"); - break; - case 0x59: - puts("OUT\t(C),E"); - break; - case 0x5a: - puts("ADC\tHL,DE"); - break; - case 0x5b: - i = *(*p + 2) + (*(*p + 3) << 8); - printf("LD\tDE,(%04x)\n", i); - len = 4; - break; - case 0x5e: - puts("IM\t2"); - break; - case 0x5f: - puts("LD\tA,R"); - break; - case 0x60: - puts("IN\tH,(C)"); - break; - case 0x61: - puts("OUT\t(C),H"); - break; - case 0x62: - puts("SBC\tHL,HL"); - break; - case 0x67: - puts("RRD"); - break; - case 0x68: - puts("IN\tL,(C)"); - break; - case 0x69: - puts("OUT\t(C),L"); - break; - case 0x6a: - puts("ADC\tHL,HL"); - break; - case 0x6f: - puts("RLD"); - break; - case 0x72: - puts("SBC\tHL,SP"); - break; - case 0x73: - i = *(*p + 2) + (*(*p + 3) << 8); - printf("LD\t(%04x),SP\n", i); - len = 4; - break; - case 0x78: - puts("IN\tA,(C)"); - break; - case 0x79: - puts("OUT\t(C),A"); - break; - case 0x7a: - puts("ADC\tHL,SP"); - break; - case 0x7b: - i = *(*p + 2) + (*(*p + 3) << 8); - printf("LD\tSP,(%04x)\n", i); - len = 4; - break; - case 0xa0: - puts("LDI"); - break; - case 0xa1: - puts("CPI"); - break; - case 0xa2: - puts("INI"); - break; - case 0xa3: - puts("OUTI"); - break; - case 0xa8: - puts("LDD"); - break; - case 0xa9: - puts("CPD"); - break; - case 0xaa: - puts("IND"); - break; - case 0xab: - puts("OUTD"); - break; - case 0xb0: - puts("LDIR"); - break; - case 0xb1: - puts("CPIR"); - break; - case 0xb2: - puts("INIR"); - break; - case 0xb3: - puts("OTIR"); - break; - case 0xb8: - puts("LDDR"); - break; - case 0xb9: - puts("CPDR"); - break; - case 0xba: - puts("INDR"); - break; - case 0xbb: - puts("OTDR"); - break; - default: - puts(unkown); - } - return(len); -} - -/* - * disassemble multi byte op-codes with prefix 0xdd and 0xfd - */ -static int ddfd(char *s, unsigned char **p) -{ - register int b2; - register char *ireg; - int len = 3; - - if (**p == 0xdd) - ireg = regix; - else - ireg = regiy; - b2 = *(*p + 1); - if (b2 >= 0x70 && b2 <= 0x77) { - printf("LD\t(%s+%02x),%s\n", ireg, *(*p + 2), reg[b2 & 7]); - return(3); - } - switch (b2) { - case 0x09: - printf("ADD\t%s,BC\n", ireg); - len = 2; - break; - case 0x19: - printf("ADD\t%s,DE\n", ireg); - len = 2; - break; - case 0x21: - printf("LD\t%s,%04x\n", ireg, *(*p + 2) + (*(*p + 3) << 8)); - len = 4; - break; - case 0x22: - printf("LD\t(%04x),%s\n", *(*p + 2) + (*(*p + 3) << 8), ireg); - len = 4; - break; - case 0x23: - printf("INC\t%s\n", ireg); - len = 2; - break; - case 0x29: - if (**p == 0xdd) - printf("ADD\tIX,IX\n"); - else - printf("ADD\tIY,IY\n"); - len = 2; - break; - case 0x2a: - printf("LD\t%s,(%04x)\n", ireg, *(*p + 2) + (*(*p + 3) << 8)); - len = 4; - break; - case 0x2b: - printf("DEC\t%s\n", ireg); - len = 2; - break; - case 0x34: - printf("INC\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x35: - printf("DEC\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x36: - printf("LD\t(%s+%02x),%02x\n", ireg, *(*p + 2), *(*p + 3)); - len = 4; - break; - case 0x39: - printf("ADD\t%s,SP\n", ireg); - len = 2; - break; - case 0x46: - printf("LD\tB,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x4e: - printf("LD\tC,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x56: - printf("LD\tD,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x5e: - printf("LD\tE,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x66: - printf("LD\tH,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x6e: - printf("LD\tL,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x7e: - printf("LD\tA,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x86: - printf("ADD\tA,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x8e: - printf("ADC\tA,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x96: - printf("SUB\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x9e: - printf("SBC\tA,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xa6: - printf("AND\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xae: - printf("XOR\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xb6: - printf("OR\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xbe: - printf("CP\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xcb: - switch (*(*p + 3)) { - case 0x06: - printf("RLC\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x0e: - printf("RRC\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x16: - printf("RL\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x1e: - printf("RR\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x26: - printf("SLA\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x2e: - printf("SRA\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x3e: - printf("SRL\t(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x46: - printf("BIT\t0,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x4e: - printf("BIT\t1,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x56: - printf("BIT\t2,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x5e: - printf("BIT\t3,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x66: - printf("BIT\t4,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x6e: - printf("BIT\t5,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x76: - printf("BIT\t6,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x7e: - printf("BIT\t7,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x86: - printf("RES\t0,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x8e: - printf("RES\t1,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x96: - printf("RES\t2,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0x9e: - printf("RES\t3,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xa6: - printf("RES\t4,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xae: - printf("RES\t5,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xb6: - printf("RES\t6,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xbe: - printf("RES\t7,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xc6: - printf("SET\t0,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xce: - printf("SET\t1,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xd6: - printf("SET\t2,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xde: - printf("SET\t3,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xe6: - printf("SET\t4,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xee: - printf("SET\t5,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xf6: - printf("SET\t6,(%s+%02x)\n", ireg, *(*p + 2)); - break; - case 0xfe: - printf("SET\t7,(%s+%02x)\n", ireg, *(*p + 2)); - break; - default: - puts(unkown); - } - len = 4; - break; - case 0xe1: - printf("POP\t%s\n", ireg); - len = 2; - break; - case 0xe3: - printf("EX\t(SP),%s\n", ireg); - len = 2; - break; - case 0xe5: - printf("PUSH\t%s\n", ireg); - len = 2; - break; - case 0xe9: - printf("JP\t(%s)\n", ireg); - len = 2; - break; - case 0xf9: - printf("LD\tSP,%s\n", ireg); - len = 2; - break; - default: - puts(unkown); - } - return(len); -} diff --git a/emu/z80pack-1.9/z80sim/disas.o b/emu/z80pack-1.9/z80sim/disas.o deleted file mode 100644 index 6b8597d..0000000 Binary files a/emu/z80pack-1.9/z80sim/disas.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/iosim.c b/emu/z80pack-1.9/z80sim/iosim.c deleted file mode 100644 index 0e5c25f..0000000 --- a/emu/z80pack-1.9/z80sim/iosim.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * This modul of the simulator contains a simple terminal I/O - * simulation as an example. - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 03-OCT-06 Release 1.8 changed to ANSI C for modern POSIX OS's - */ - -/* - * Sample I/O-handler - * - * Port 0 input: reads the next byte from stdin - * Port 0 output: writes the byte to stdout - * - * All the other ports are connected to a I/O-trap handler, - * I/O to this ports stops the simulation with an I/O error. - */ - -#include -#include "sim.h" -#include "simglb.h" - -/* - * Forward declarations of the I/O functions - * for all port addresses. - */ -static BYTE io_trap(void); -static BYTE p000_in(void); -static void p000_out(BYTE); - -/* - * This two dimensional array contains function pointers - * for every I/O port (0 - 255), to do the needed I/O. - * The first entry is for input, the second for output. - */ -static BYTE (*port[256][2]) () = { - { p000_in, p000_out } /* port 0 */ -}; - -/* - * This function is to initiate the I/O devices. - * It will be called from the CPU simulation before - * any operation with the Z80 is possible. - * - * In this sample I/O simulation we initialize all - * unused port with an error trap handler, so that - * simulation stops at I/O on the unused ports. - * - * See the I/O simulation of CP/M for a more complex - * example. - */ -void init_io(void) -{ - register int i; - - for (i = 1; i <= 255; i++) - port[i][0] = port[i][1] = io_trap; -} - -/* - * This function is to stop the I/O devices. It is - * called from the CPU simulation on exit. - * - * Here is just nothing to do, see the I/O simulation - * of CP/M for a more complex example. - */ -void exit_io(void) -{ -} - -/* - * This is the main handler for all IN op-codes, - * called by the simulator. It calls the input - * function for port adr. - */ -BYTE io_in(BYTE adr) -{ - return((*port[adr][0]) ()); -} - -/* - * This is the main handler for all OUT op-codes, - * called by the simulator. It calls the output - * function for port adr. - */ -void io_out(BYTE adr, BYTE data) -{ - (*port[adr][1]) (data); -} - -/* - * I/O trap funtion - * This function should be added into all unused - * entrys of the port array. It stops the emulation - * with an I/O error. - */ -static BYTE io_trap(void) -{ - if (i_flag) { - cpu_error = IOTRAP; - cpu_state = STOPPED; - } - return((BYTE) 0); -} - -/* - * I/O function port 0 read: - * Read next byte from stdin. - */ -static BYTE p000_in(void) -{ - return((BYTE) getchar()); -} - -/* - * I/O function port 0 write: - * Write byte to stdout and flush the output. - */ -static void p000_out(BYTE data) -{ - putchar((int) data); - fflush(stdout); -} diff --git a/emu/z80pack-1.9/z80sim/iosim.o b/emu/z80pack-1.9/z80sim/iosim.o deleted file mode 100644 index 1230fd5..0000000 Binary files a/emu/z80pack-1.9/z80sim/iosim.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/run.sh b/emu/z80pack-1.9/z80sim/run.sh deleted file mode 100755 index 3b79f22..0000000 --- a/emu/z80pack-1.9/z80sim/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -./z80sim diff --git a/emu/z80pack-1.9/z80sim/sim.h b/emu/z80pack-1.9/z80sim/sim.h deleted file mode 100644 index 4e22072..0000000 --- a/emu/z80pack-1.9/z80sim/sim.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * This is the configuration I'm using for software testing and debugging - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * The following defines may be activated, commented or modified - * by user for her/his own purpose. - */ -/*#define WANT_INT*/ /* activate CPU's interrupts */ -#define WANT_SPC /* activate SP over-/underrun handling 0000<->FFFF */ -#define WANT_PCC /* activate PC overrun handling FFFF->0000 */ -#define CNTL_C /* cntl-c will stop running emulation */ -#define CNTL_BS /* cntl-\ will stop running emulation */ -#define CNTL_Z /* cntl-z will suspend emulator */ -#define WANT_TIM /* activate runtime measurement */ -#define HISIZE 100 /* number of entrys in history */ -#define SBSIZE 4 /* number of software breakpoints */ - -/* - * The following defines may be modified and activated by - * user, to print her/his copyright for a developed system, - * which contains the Z80-CPU simulation as a part. - */ -/* -#define USR_COM "XYZ-System Simulation" -#define USR_REL "x.y" -#define USR_CPR "Copyright (C) 20xx by XYZ" -*/ - -/* - * The following lines of this file should not be modified by user - */ -#define COPYR "Copyright (C) 1987-2006 by Udo Munk" -#define RELEASE "1.9" - -#define LENCMD 80 /* length of command buffers etc */ - -#define S_FLAG 128 /* bit definitions of CPU flags */ -#define Z_FLAG 64 -#define N2_FLAG 32 -#define H_FLAG 16 -#define N1_FLAG 8 -#define P_FLAG 4 -#define N_FLAG 2 -#define C_FLAG 1 - - /* operation of simulated CPU */ -#define SINGLE_STEP 0 /* single step */ -#define CONTIN_RUN 1 /* continual run */ -#define STOPPED 0 /* stop CPU because of error */ - - /* causes of error */ -#define NONE 0 /* no error */ -#define OPHALT 1 /* HALT op-code trap */ -#define IOTRAP 2 /* IN/OUT trap */ -#define OPTRAP1 3 /* illegal 1 byte op-code trap */ -#define OPTRAP2 4 /* illegal 2 byte op-code trap */ -#define OPTRAP4 5 /* illegal 4 byte op-code trap */ -#define USERINT 6 /* user interrupt */ - - /* type of CPU interrupt */ -#define INT_NMI 1 /* non maskable interrupt */ -#define INT_INT 2 /* maskable interrupt */ - -typedef unsigned short WORD; /* 16 bit unsigned */ -typedef unsigned char BYTE; /* 8 bit unsigned */ - -#ifdef HISIZE -struct history { /* structure of a history entry */ - WORD h_adr; /* address of execution */ - WORD h_af; /* register AF */ - WORD h_bc; /* register BC */ - WORD h_de; /* register DE */ - WORD h_hl; /* register HL */ - WORD h_ix; /* register IX */ - WORD h_iy; /* register IY */ - WORD h_sp; /* register SP */ -}; -#endif - -#ifdef SBSIZE -struct softbreak { /* structure of a breakpoint */ - WORD sb_adr; /* address of breakpoint */ - BYTE sb_oldopc; /* op-code at address of breakpoint */ - int sb_passcount; /* pass counter of breakpoint */ - int sb_pass; /* no. of pass to break */ -}; -#endif diff --git a/emu/z80pack-1.9/z80sim/sim.h.debug b/emu/z80pack-1.9/z80sim/sim.h.debug deleted file mode 100644 index 4e22072..0000000 --- a/emu/z80pack-1.9/z80sim/sim.h.debug +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * This is the configuration I'm using for software testing and debugging - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * The following defines may be activated, commented or modified - * by user for her/his own purpose. - */ -/*#define WANT_INT*/ /* activate CPU's interrupts */ -#define WANT_SPC /* activate SP over-/underrun handling 0000<->FFFF */ -#define WANT_PCC /* activate PC overrun handling FFFF->0000 */ -#define CNTL_C /* cntl-c will stop running emulation */ -#define CNTL_BS /* cntl-\ will stop running emulation */ -#define CNTL_Z /* cntl-z will suspend emulator */ -#define WANT_TIM /* activate runtime measurement */ -#define HISIZE 100 /* number of entrys in history */ -#define SBSIZE 4 /* number of software breakpoints */ - -/* - * The following defines may be modified and activated by - * user, to print her/his copyright for a developed system, - * which contains the Z80-CPU simulation as a part. - */ -/* -#define USR_COM "XYZ-System Simulation" -#define USR_REL "x.y" -#define USR_CPR "Copyright (C) 20xx by XYZ" -*/ - -/* - * The following lines of this file should not be modified by user - */ -#define COPYR "Copyright (C) 1987-2006 by Udo Munk" -#define RELEASE "1.9" - -#define LENCMD 80 /* length of command buffers etc */ - -#define S_FLAG 128 /* bit definitions of CPU flags */ -#define Z_FLAG 64 -#define N2_FLAG 32 -#define H_FLAG 16 -#define N1_FLAG 8 -#define P_FLAG 4 -#define N_FLAG 2 -#define C_FLAG 1 - - /* operation of simulated CPU */ -#define SINGLE_STEP 0 /* single step */ -#define CONTIN_RUN 1 /* continual run */ -#define STOPPED 0 /* stop CPU because of error */ - - /* causes of error */ -#define NONE 0 /* no error */ -#define OPHALT 1 /* HALT op-code trap */ -#define IOTRAP 2 /* IN/OUT trap */ -#define OPTRAP1 3 /* illegal 1 byte op-code trap */ -#define OPTRAP2 4 /* illegal 2 byte op-code trap */ -#define OPTRAP4 5 /* illegal 4 byte op-code trap */ -#define USERINT 6 /* user interrupt */ - - /* type of CPU interrupt */ -#define INT_NMI 1 /* non maskable interrupt */ -#define INT_INT 2 /* maskable interrupt */ - -typedef unsigned short WORD; /* 16 bit unsigned */ -typedef unsigned char BYTE; /* 8 bit unsigned */ - -#ifdef HISIZE -struct history { /* structure of a history entry */ - WORD h_adr; /* address of execution */ - WORD h_af; /* register AF */ - WORD h_bc; /* register BC */ - WORD h_de; /* register DE */ - WORD h_hl; /* register HL */ - WORD h_ix; /* register IX */ - WORD h_iy; /* register IY */ - WORD h_sp; /* register SP */ -}; -#endif - -#ifdef SBSIZE -struct softbreak { /* structure of a breakpoint */ - WORD sb_adr; /* address of breakpoint */ - BYTE sb_oldopc; /* op-code at address of breakpoint */ - int sb_passcount; /* pass counter of breakpoint */ - int sb_pass; /* no. of pass to break */ -}; -#endif diff --git a/emu/z80pack-1.9/z80sim/sim.h.fast b/emu/z80pack-1.9/z80sim/sim.h.fast deleted file mode 100644 index 8cdf8ee..0000000 --- a/emu/z80pack-1.9/z80sim/sim.h.fast +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * With this configuration the simulated Z80 runs with the - * highest possible speed - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * The following defines may be activated, commented or modified - * by user for her/his own purpose. - */ -/*#define WANT_INT*/ /* activate CPU's interrupts */ -/*#define WANT_SPC*/ /* activate SP over-/underrun handling 0000<->FFFF */ -/*#define WANT_PCC*/ /* activate PC overrun handling FFFF->0000 */ -#define CNTL_C /* cntl-c will stop running emulation */ -#define CNTL_BS /* cntl-\ will stop running emulation */ -#define CNTL_Z /* cntl-z will suspend emulator */ -/*#define WANT_TIM*/ /* activate runtime measurement */ -/*#define HISIZE 100*/ /* number of entrys in history */ -/*#define SBSIZE 4*/ /* number of software breakpoints */ - -/* - * The following defines may be modified and activated by - * user, to print her/his copyright for a developed system, - * which contains the Z80-CPU simulation as a part. - */ -/* -#define USR_COM "XYZ-System Simulation" -#define USR_REL "x.y" -#define USR_CPR "Copyright (C) 20xx by XYZ" -*/ - -/* - * The following lines of this file should not be modified by user - */ -#define COPYR "Copyright (C) 1987-2006 by Udo Munk" -#define RELEASE "1.9" - -#define LENCMD 80 /* length of command buffers etc */ - -#define S_FLAG 128 /* bit definitions of CPU flags */ -#define Z_FLAG 64 -#define N2_FLAG 32 -#define H_FLAG 16 -#define N1_FLAG 8 -#define P_FLAG 4 -#define N_FLAG 2 -#define C_FLAG 1 - - /* operation of simulated CPU */ -#define SINGLE_STEP 0 /* single step */ -#define CONTIN_RUN 1 /* continual run */ -#define STOPPED 0 /* stop CPU because of error */ - - /* causes of error */ -#define NONE 0 /* no error */ -#define OPHALT 1 /* HALT op-code trap */ -#define IOTRAP 2 /* IN/OUT trap */ -#define OPTRAP1 3 /* illegal 1 byte op-code trap */ -#define OPTRAP2 4 /* illegal 2 byte op-code trap */ -#define OPTRAP4 5 /* illegal 4 byte op-code trap */ -#define USERINT 6 /* user interrupt */ - - /* type of CPU interrupt */ -#define INT_NONE 0 -#define INT_NMI 1 /* non maskable interrupt */ -#define INT_INT 2 /* maskable interrupt */ - -typedef unsigned short WORD; /* 16 bit unsigned */ -typedef unsigned char BYTE; /* 8 bit unsigned */ - -#ifdef HISIZE -struct history { /* structure of a history entry */ - WORD h_adr; /* address of execution */ - WORD h_af; /* register AF */ - WORD h_bc; /* register BC */ - WORD h_de; /* register DE */ - WORD h_hl; /* register HL */ - WORD h_ix; /* register IX */ - WORD h_iy; /* register IY */ - WORD h_sp; /* register SP */ -}; -#endif - -#ifdef SBSIZE -struct softbreak { /* structure of a breakpoint */ - WORD sb_adr; /* address of breakpoint */ - BYTE sb_oldopc; /* op-code at address of breakpoint */ - int sb_passcount; /* pass counter of breakpoint */ - int sb_pass; /* no. of pass to break */ -}; -#endif diff --git a/emu/z80pack-1.9/z80sim/sim0.c b/emu/z80pack-1.9/z80sim/sim0.c deleted file mode 100644 index cf5fd06..0000000 --- a/emu/z80pack-1.9/z80sim/sim0.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0 - * 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * This modul contain the 'main()' function of the simulator, - * where the options are checked and variables are initialized. - * After initialization of the UNIX interrupts ( int_on() ) - * and initialization of the I/O simulation ( init_io() ) - * the user interface ( mon() ) is called. - */ - -#include -#include -#include -#include -#include -#include -#include "sim.h" -#include "simglb.h" - -static void save_core(void), load_core(void); -extern void int_on(void), int_off(void), mon(void); -extern void init_io(void), exit_io(void); -extern int exatoi(char *); - -int main(int argc, char *argv[]) -{ - register char *s, *p; - register char *pn = argv[0]; - - while (--argc > 0 && (*++argv)[0] == '-') - for (s = argv[0] + 1; *s != '\0'; s++) - switch (*s) { - case 's': /* save core and CPU on exit */ - s_flag = 1; - break; - case 'l': /* load core and CPU from file */ - l_flag = 1; - break; - case 'h': /* execute HALT opcode */ - break_flag = 0; - break; - case 'i': /* trap I/O on unused ports */ - i_flag = 1; - break; - case 'm': /* initialize Z80 memory */ - m_flag = exatoi(s+1); - s += strlen(s+1); - break; - case 'f': - f_flag = atoi(s+1); - s += strlen(s+1); - freq = (float) 1 / (float) f_flag; - break; - case 'x': /* get filename with Z80 executable */ - x_flag = 1; - s++; - p = xfn; - while (*s) - *p++ = *s++; - *p = '\0'; - s--; - break; - case '?': - goto usage; - default: - printf("illegal option %c\n", *s); -usage: printf("usage:\t%s -s -l -i -h -mn -fn -xfilename\n", pn); - puts("\ts = save core and cpu"); - puts("\tl = load core and cpu"); - puts("\ti = trap on I/O to unused ports"); - puts("\th = execute HALT op-code"); - puts("\tm = init memory with n"); - puts("\tf = CPU frequenzy n in MHz (not implemented yet)"); - puts("\tx = load and execute filename"); - exit(1); - } - - putchar('\n'); - puts("####### ##### ### ##### ### # #"); - puts(" # # # # # # # # ## ##"); - puts(" # # # # # # # # # # #"); - puts(" # ##### # # ##### ##### # # # #"); - puts(" # # # # # # # # #"); - puts(" # # # # # # # # # #"); - puts("####### ##### ### ##### ### # #"); - printf("\nRelease %s, %s\n", RELEASE, COPYR); -#ifdef USR_COM - printf("%s Release %s, %s\n", USR_COM, USR_REL, USR_CPR); -#endif - putchar('\n'); - fflush(stdout); - - wrk_ram = PC = STACK = ram; - memset((char *) ram, m_flag, 32768); - memset((char *) ram + 32768, m_flag, 32768); - if (l_flag) - load_core(); - int_on(); - init_io(); - mon(); - if (s_flag) - save_core(); - exit_io(); - int_off(); - return(0); -} - -/* - * This function saves the CPU and the memory into the file core.z80 - * - */ -static void save_core(void) -{ - int fd; - - if ((fd = open("core.z80", O_WRONLY | O_CREAT, 0600)) == -1) { - puts("can't open file core.z80"); - return; - } - write(fd, (char *) &A, sizeof(A)); - write(fd, (char *) &F, sizeof(F)); - write(fd, (char *) &B, sizeof(B)); - write(fd, (char *) &C, sizeof(C)); - write(fd, (char *) &D, sizeof(D)); - write(fd, (char *) &E, sizeof(E)); - write(fd, (char *) &H, sizeof(H)); - write(fd, (char *) &L, sizeof(L)); - write(fd, (char *) &A_, sizeof(A_)); - write(fd, (char *) &F_, sizeof(F_)); - write(fd, (char *) &B_, sizeof(B_)); - write(fd, (char *) &C_, sizeof(C_)); - write(fd, (char *) &D_, sizeof(D_)); - write(fd, (char *) &E_, sizeof(E_)); - write(fd, (char *) &H_, sizeof(H_)); - write(fd, (char *) &L_, sizeof(L_)); - write(fd, (char *) &I, sizeof(I)); - write(fd, (char *) &IFF, sizeof(IFF)); - write(fd, (char *) &R, sizeof(R)); - write(fd, (char *) &PC, sizeof(PC)); - write(fd, (char *) &STACK, sizeof(STACK)); - write(fd, (char *) &IX, sizeof(IX)); - write(fd, (char *) &IY, sizeof(IY)); - write(fd, (char *) ram, 32768); - write(fd, (char *) ram + 32768, 32768); - close(fd); -} - -/* - * This function loads the CPU and memory from the file core.z80 - * - */ -static void load_core(void) -{ - int fd; - - if ((fd = open("core.z80", O_RDONLY)) == -1) { - puts("can't open file core.z80"); - return; - } - read(fd, (char *) &A, sizeof(A)); - read(fd, (char *) &F, sizeof(F)); - read(fd, (char *) &B, sizeof(B)); - read(fd, (char *) &C, sizeof(C)); - read(fd, (char *) &D, sizeof(D)); - read(fd, (char *) &E, sizeof(E)); - read(fd, (char *) &H, sizeof(H)); - read(fd, (char *) &L, sizeof(L)); - read(fd, (char *) &A_, sizeof(A_)); - read(fd, (char *) &F_, sizeof(F_)); - read(fd, (char *) &B_, sizeof(B_)); - read(fd, (char *) &C_, sizeof(C_)); - read(fd, (char *) &D_, sizeof(D_)); - read(fd, (char *) &E_, sizeof(E_)); - read(fd, (char *) &H_, sizeof(H_)); - read(fd, (char *) &L_, sizeof(L_)); - read(fd, (char *) &I, sizeof(I)); - read(fd, (char *) &IFF, sizeof(IFF)); - read(fd, (char *) &R, sizeof(R)); - read(fd, (char *) &PC, sizeof(PC)); - read(fd, (char *) &STACK, sizeof(STACK)); - read(fd, (char *) &IX, sizeof(IX)); - read(fd, (char *) &IY, sizeof(IY)); - read(fd, (char *) ram, 32768); - read(fd, (char *) ram + 32768, 32768); - close(fd); -} diff --git a/emu/z80pack-1.9/z80sim/sim0.o b/emu/z80pack-1.9/z80sim/sim0.o deleted file mode 100644 index 31bec71..0000000 Binary files a/emu/z80pack-1.9/z80sim/sim0.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/sim1.c b/emu/z80pack-1.9/z80sim/sim1.c deleted file mode 100644 index d671cc3..0000000 --- a/emu/z80pack-1.9/z80sim/sim1.c +++ /dev/null @@ -1,3298 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 04-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -#include -#include -#include -#include "sim.h" -#include "simglb.h" - -static int op_notimpl(void); -static int op_nop(void), op_halt(void), op_scf(void); -static int op_ccf(void), op_cpl(void), op_daa(void); -static int op_ei(void), op_di(void); -static int op_in(void), op_out(void); -static int op_ldan(void), op_ldbn(void), op_ldcn(void); -static int op_lddn(void), op_lden(void); -static int op_ldhn(void), op_ldln(void); -static int op_ldabc(void), op_ldade(void), op_ldann(void); -static int op_ldbca(void), op_lddea(void), op_ldnna(void); -static int op_ldhla(void), op_ldhlb(void), op_ldhlc(void), op_ldhld(void); -static int op_ldhle(void), op_ldhlh(void), op_ldhll(void), op_ldhl1(void); -static int op_ldaa(void), op_ldab(void), op_ldac(void); -static int op_ldad(void), op_ldae(void); -static int op_ldah(void), op_ldal(void), op_ldahl(void); -static int op_ldba(void), op_ldbb(void), op_ldbc(void); -static int op_ldbd(void), op_ldbe(void); -static int op_ldbh(void), op_ldbl(void), op_ldbhl(void); -static int op_ldca(void), op_ldcb(void), op_ldcc(void); -static int op_ldcd(void), op_ldce(void); -static int op_ldch(void), op_ldcl(void), op_ldchl(void); -static int op_ldda(void), op_lddb(void), op_lddc(void); -static int op_lddd(void), op_ldde(void); -static int op_lddh(void), op_lddl(void), op_lddhl(void); -static int op_ldea(void), op_ldeb(void), op_ldec(void); -static int op_lded(void), op_ldee(void); -static int op_ldeh(void), op_ldel(void), op_ldehl(void); -static int op_ldha(void), op_ldhb(void), op_ldhc(void); -static int op_ldhd(void), op_ldhe(void); -static int op_ldhh(void), op_ldhl(void), op_ldhhl(void); -static int op_ldla(void), op_ldlb(void), op_ldlc(void); -static int op_ldld(void), op_ldle(void); -static int op_ldlh(void), op_ldll(void), op_ldlhl(void); -static int op_ldbcnn(void), op_lddenn(void), op_ldhlnn(void); -static int op_ldspnn(void), op_ldsphl(void); -static int op_ldhlin(void), op_ldinhl(void); -static int op_incbc(void), op_incde(void), op_inchl(void), op_incsp(void); -static int op_decbc(void), op_decde(void), op_dechl(void), op_decsp(void); -static int op_adhlbc(void), op_adhlde(void), op_adhlhl(void), op_adhlsp(void); -static int op_anda(void), op_andb(void), op_andc(void), op_andd(void), op_ande(void); -static int op_andh(void), op_andl(void), op_andhl(void), op_andn(void); -static int op_ora(void), op_orb(void), op_orc(void), op_ord(void), op_ore(void); -static int op_orh(void), op_orl(void), op_orhl(void), op_orn(void); -static int op_xora(void), op_xorb(void), op_xorc(void), op_xord(void), op_xore(void); -static int op_xorh(void), op_xorl(void), op_xorhl(void), op_xorn(void); -static int op_adda(void), op_addb(void), op_addc(void), op_addd(void), op_adde(void); -static int op_addh(void), op_addl(void), op_addhl(void), op_addn(void); -static int op_adca(void), op_adcb(void), op_adcc(void), op_adcd(void), op_adce(void); -static int op_adch(void), op_adcl(void), op_adchl(void), op_adcn(void); -static int op_suba(void), op_subb(void), op_subc(void), op_subd(void), op_sube(void); -static int op_subh(void), op_subl(void), op_subhl(void), op_subn(void); -static int op_sbca(void), op_sbcb(void), op_sbcc(void), op_sbcd(void), op_sbce(void); -static int op_sbch(void), op_sbcl(void), op_sbchl(void), op_sbcn(void); -static int op_cpa(void), op_cpb(void), op_cpc(void), op_cpd(void), op_cpe(void); -static int op_cph(void), op_cplr(void), op_cphl(void), op_cpn(void); -static int op_inca(void), op_incb(void), op_incc(void), op_incd(void), op_ince(void); -static int op_inch(void), op_incl(void), op_incihl(void); -static int op_deca(void), op_decb(void), op_decc(void), op_decd(void), op_dece(void); -static int op_dech(void), op_decl(void), op_decihl(void); -static int op_rlca(void), op_rrca(void),op_rla(void),op_rra(void); -static int op_exdehl(void), op_exafaf(void), op_exx(void), op_exsphl(void); -static int op_pushaf(void), op_pushbc(void), op_pushde(void), op_pushhl(void); -static int op_popaf(void), op_popbc(void), op_popde(void), op_pophl(void); -static int op_jp(void), op_jphl(void), op_jr(void), op_djnz(void), op_call(void), op_ret(void); -static int op_jpz(void), op_jpnz(void), op_jpc(void), op_jpnc(void); -static int op_jppe(void), op_jppo(void), op_jpm(void), op_jpp(void); -static int op_calz(void), op_calnz(void), op_calc(void), op_calnc(void); -static int op_calpe(void), op_calpo(void), op_calm(void), op_calp(void); -static int op_retz(void), op_retnz(void), op_retc(void), op_retnc(void); -static int op_retpe(void), op_retpo(void), op_retm(void), op_retp(void); -static int op_jrz(void), op_jrnz(void), op_jrc(void), op_jrnc(void); -static int op_rst00(void), op_rst08(void), op_rst10(void), op_rst18(void); -static int op_rst20(void), op_rst28(void), op_rst30(void), op_rst38(void); -extern int op_cb_handel(void), op_dd_handel(void); -extern int op_ed_handel(void), op_fd_handel(void); - -/* - * This function builds the Z80 central processing unit. - * The opcode where PC points to is fetched from the memory - * and PC incremented by one. The opcode is used as an - * index to an array with function pointers, to execute a - * function which emulates this Z80 opcode. - */ -void cpu(void) -{ - static int (*op_sim[256]) (void) = { - op_nop, /* 0x00 */ - op_ldbcnn, /* 0x01 */ - op_ldbca, /* 0x02 */ - op_incbc, /* 0x03 */ - op_incb, /* 0x04 */ - op_decb, /* 0x05 */ - op_ldbn, /* 0x06 */ - op_rlca, /* 0x07 */ - op_exafaf, /* 0x08 */ - op_adhlbc, /* 0x09 */ - op_ldabc, /* 0x0a */ - op_decbc, /* 0x0b */ - op_incc, /* 0x0c */ - op_decc, /* 0x0d */ - op_ldcn, /* 0x0e */ - op_rrca, /* 0x0f */ - op_djnz, /* 0x10 */ - op_lddenn, /* 0x11 */ - op_lddea, /* 0x12 */ - op_incde, /* 0x13 */ - op_incd, /* 0x14 */ - op_decd, /* 0x15 */ - op_lddn, /* 0x16 */ - op_rla, /* 0x17 */ - op_jr, /* 0x18 */ - op_adhlde, /* 0x19 */ - op_ldade, /* 0x1a */ - op_decde, /* 0x1b */ - op_ince, /* 0x1c */ - op_dece, /* 0x1d */ - op_lden, /* 0x1e */ - op_rra, /* 0x1f */ - op_jrnz, /* 0x20 */ - op_ldhlnn, /* 0x21 */ - op_ldinhl, /* 0x22 */ - op_inchl, /* 0x23 */ - op_inch, /* 0x24 */ - op_dech, /* 0x25 */ - op_ldhn, /* 0x26 */ - op_daa, /* 0x27 */ - op_jrz, /* 0x28 */ - op_adhlhl, /* 0x29 */ - op_ldhlin, /* 0x2a */ - op_dechl, /* 0x2b */ - op_incl, /* 0x2c */ - op_decl, /* 0x2d */ - op_ldln, /* 0x2e */ - op_cpl, /* 0x2f */ - op_jrnc, /* 0x30 */ - op_ldspnn, /* 0x31 */ - op_ldnna, /* 0x32 */ - op_incsp, /* 0x33 */ - op_incihl, /* 0x34 */ - op_decihl, /* 0x35 */ - op_ldhl1, /* 0x36 */ - op_scf, /* 0x37 */ - op_jrc, /* 0x38 */ - op_adhlsp, /* 0x39 */ - op_ldann, /* 0x3a */ - op_decsp, /* 0x3b */ - op_inca, /* 0x3c */ - op_deca, /* 0x3d */ - op_ldan, /* 0x3e */ - op_ccf, /* 0x3f */ - op_ldbb, /* 0x40 */ - op_ldbc, /* 0x41 */ - op_ldbd, /* 0x42 */ - op_ldbe, /* 0x43 */ - op_ldbh, /* 0x44 */ - op_ldbl, /* 0x45 */ - op_ldbhl, /* 0x46 */ - op_ldba, /* 0x47 */ - op_ldcb, /* 0x48 */ - op_ldcc, /* 0x49 */ - op_ldcd, /* 0x4a */ - op_ldce, /* 0x4b */ - op_ldch, /* 0x4c */ - op_ldcl, /* 0x4d */ - op_ldchl, /* 0x4e */ - op_ldca, /* 0x4f */ - op_lddb, /* 0x50 */ - op_lddc, /* 0x51 */ - op_lddd, /* 0x52 */ - op_ldde, /* 0x53 */ - op_lddh, /* 0x54 */ - op_lddl, /* 0x55 */ - op_lddhl, /* 0x56 */ - op_ldda, /* 0x57 */ - op_ldeb, /* 0x58 */ - op_ldec, /* 0x59 */ - op_lded, /* 0x5a */ - op_ldee, /* 0x5b */ - op_ldeh, /* 0x5c */ - op_ldel, /* 0x5d */ - op_ldehl, /* 0x5e */ - op_ldea, /* 0x5f */ - op_ldhb, /* 0x60 */ - op_ldhc, /* 0x61 */ - op_ldhd, /* 0x62 */ - op_ldhe, /* 0x63 */ - op_ldhh, /* 0x64 */ - op_ldhl, /* 0x65 */ - op_ldhhl, /* 0x66 */ - op_ldha, /* 0x67 */ - op_ldlb, /* 0x68 */ - op_ldlc, /* 0x69 */ - op_ldld, /* 0x6a */ - op_ldle, /* 0x6b */ - op_ldlh, /* 0x6c */ - op_ldll, /* 0x6d */ - op_ldlhl, /* 0x6e */ - op_ldla, /* 0x6f */ - op_ldhlb, /* 0x70 */ - op_ldhlc, /* 0x71 */ - op_ldhld, /* 0x72 */ - op_ldhle, /* 0x73 */ - op_ldhlh, /* 0x74 */ - op_ldhll, /* 0x75 */ - op_halt, /* 0x76 */ - op_ldhla, /* 0x77 */ - op_ldab, /* 0x78 */ - op_ldac, /* 0x79 */ - op_ldad, /* 0x7a */ - op_ldae, /* 0x7b */ - op_ldah, /* 0x7c */ - op_ldal, /* 0x7d */ - op_ldahl, /* 0x7e */ - op_ldaa, /* 0x7f */ - op_addb, /* 0x80 */ - op_addc, /* 0x81 */ - op_addd, /* 0x82 */ - op_adde, /* 0x83 */ - op_addh, /* 0x84 */ - op_addl, /* 0x85 */ - op_addhl, /* 0x86 */ - op_adda, /* 0x87 */ - op_adcb, /* 0x88 */ - op_adcc, /* 0x89 */ - op_adcd, /* 0x8a */ - op_adce, /* 0x8b */ - op_adch, /* 0x8c */ - op_adcl, /* 0x8d */ - op_adchl, /* 0x8e */ - op_adca, /* 0x8f */ - op_subb, /* 0x90 */ - op_subc, /* 0x91 */ - op_subd, /* 0x92 */ - op_sube, /* 0x93 */ - op_subh, /* 0x94 */ - op_subl, /* 0x95 */ - op_subhl, /* 0x96 */ - op_suba, /* 0x97 */ - op_sbcb, /* 0x98 */ - op_sbcc, /* 0x99 */ - op_sbcd, /* 0x9a */ - op_sbce, /* 0x9b */ - op_sbch, /* 0x9c */ - op_sbcl, /* 0x9d */ - op_sbchl, /* 0x9e */ - op_sbca, /* 0x9f */ - op_andb, /* 0xa0 */ - op_andc, /* 0xa1 */ - op_andd, /* 0xa2 */ - op_ande, /* 0xa3 */ - op_andh, /* 0xa4 */ - op_andl, /* 0xa5 */ - op_andhl, /* 0xa6 */ - op_anda, /* 0xa7 */ - op_xorb, /* 0xa8 */ - op_xorc, /* 0xa9 */ - op_xord, /* 0xaa */ - op_xore, /* 0xab */ - op_xorh, /* 0xac */ - op_xorl, /* 0xad */ - op_xorhl, /* 0xae */ - op_xora, /* 0xaf */ - op_orb, /* 0xb0 */ - op_orc, /* 0xb1 */ - op_ord, /* 0xb2 */ - op_ore, /* 0xb3 */ - op_orh, /* 0xb4 */ - op_orl, /* 0xb5 */ - op_orhl, /* 0xb6 */ - op_ora, /* 0xb7 */ - op_cpb, /* 0xb8 */ - op_cpc, /* 0xb9 */ - op_cpd, /* 0xba */ - op_cpe, /* 0xbb */ - op_cph, /* 0xbc */ - op_cplr, /* 0xbd */ - op_cphl, /* 0xbe */ - op_cpa, /* 0xbf */ - op_retnz, /* 0xc0 */ - op_popbc, /* 0xc1 */ - op_jpnz, /* 0xc2 */ - op_jp, /* 0xc3 */ - op_calnz, /* 0xc4 */ - op_pushbc, /* 0xc5 */ - op_addn, /* 0xc6 */ - op_rst00, /* 0xc7 */ - op_retz, /* 0xc8 */ - op_ret, /* 0xc9 */ - op_jpz, /* 0xca */ - op_cb_handel, /* 0xcb */ - op_calz, /* 0xcc */ - op_call, /* 0xcd */ - op_adcn, /* 0xce */ - op_rst08, /* 0xcf */ - op_retnc, /* 0xd0 */ - op_popde, /* 0xd1 */ - op_jpnc, /* 0xd2 */ - op_out, /* 0xd3 */ - op_calnc, /* 0xd4 */ - op_pushde, /* 0xd5 */ - op_subn, /* 0xd6 */ - op_rst10, /* 0xd7 */ - op_retc, /* 0xd8 */ - op_exx, /* 0xd9 */ - op_jpc, /* 0xda */ - op_in, /* 0xdb */ - op_calc, /* 0xdc */ - op_dd_handel, /* 0xdd */ - op_sbcn, /* 0xde */ - op_rst18, /* 0xdf */ - op_retpo, /* 0xe0 */ - op_pophl, /* 0xe1 */ - op_jppo, /* 0xe2 */ - op_exsphl, /* 0xe3 */ - op_calpo, /* 0xe4 */ - op_pushhl, /* 0xe5 */ - op_andn, /* 0xe6 */ - op_rst20, /* 0xe7 */ - op_retpe, /* 0xe8 */ - op_jphl, /* 0xe9 */ - op_jppe, /* 0xea */ - op_exdehl, /* 0xeb */ - op_calpe, /* 0xec */ - op_ed_handel, /* 0xed */ - op_xorn, /* 0xee */ - op_rst28, /* 0xef */ - op_retp, /* 0xf0 */ - op_popaf, /* 0xf1 */ - op_jpp, /* 0xf2 */ - op_di, /* 0xf3 */ - op_calp, /* 0xf4 */ - op_pushaf, /* 0xf5 */ - op_orn, /* 0xf6 */ - op_rst30, /* 0xf7 */ - op_retm, /* 0xf8 */ - op_ldsphl, /* 0xf9 */ - op_jpm, /* 0xfa */ - op_ei, /* 0xfb */ - op_calm, /* 0xfc */ - op_fd_handel, /* 0xfd */ - op_cpn, /* 0xfe */ - op_rst38 /* 0xff */ - }; - -#ifdef WANT_TIM - register int t; -#endif - - do { - -#ifdef HISIZE /* write history */ - his[h_next].h_adr = PC - ram; - his[h_next].h_af = (A << 8) + F; - his[h_next].h_bc = (B << 8) + C; - his[h_next].h_de = (D << 8) + E; - his[h_next].h_hl = (H << 8) + L; - his[h_next].h_ix = IX; - his[h_next].h_iy = IY; - his[h_next].h_sp = STACK - ram; - h_next++; - if (h_next == HISIZE) { - h_flag = 1; - h_next = 0; - } -#endif - -#ifdef WANT_TIM /* check for start address of runtime measurement */ - if (PC == t_start && !t_flag) { - t_flag = 1; /* switch measurement on */ - t_states = 0L; /* initialize counted T-states */ - } -#endif - -#ifdef WANT_INT /* CPU interrupt handling */ - if (int_type) - switch (int_type) { - case INT_NMI: /* non maskable interrupt */ - int_type = INT_NONE; - IFF <<= 1; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x66; - break; - case INT_INT: /* maskable interrupt */ - if (IFF != 3) - break; - IFF = 0; - switch (int_mode) { - case 0: - break; - case 1: - int_type = INT_NONE; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x38; - break; - case 2: - break; - } - break; - } -#endif - -#ifdef WANT_TIM - t = (*op_sim[*PC++]) ();/* execute next opcode */ - if (f_flag) { /* adjust CPU speed */ - - } -#else - (*op_sim[*PC++]) (); -#endif - -#ifdef WANT_PCC - if (PC > ram + 65535) /* check for PC overrun */ - PC = ram; -#endif - - R++; /* increment refresh register */ - -#ifdef WANT_TIM /* do runtime measurement */ - if (t_flag) { - t_states += t; /* add T-states for this opcode */ - if (PC == t_end) /* check for end address */ - t_flag = 0; /* if reached, switch off */ - } -#endif - - } while (cpu_state); -} - -/* - * Trap not implemented opcodes. This function may be usefull - * later to trap some wanted opcodes. - */ -static int op_notimpl(void) -{ - cpu_error = OPTRAP1; - cpu_state = STOPPED; - return(0); -} - -static int op_nop(void) /* NOP */ -{ - return(4); -} - -static int op_halt(void) /* HALT */ -{ - struct timespec timer; - - if (break_flag) { - cpu_error = OPHALT; - cpu_state = STOPPED; - } else - while (int_type == 0) { - timer.tv_sec = 0; - timer.tv_nsec = 10000000; - nanosleep(&timer, NULL); - R += 99999; - } - return(0); -} - -static int op_scf(void) /* SCF */ -{ - F |= C_FLAG; - F &= ~(N_FLAG | H_FLAG); - return(4); -} - -static int op_ccf(void) /* CCF */ -{ - if (F & C_FLAG) { - F |= H_FLAG; - F &= ~C_FLAG; - } else { - F &= ~H_FLAG; - F |= C_FLAG; - } - F &= ~N_FLAG; - return(4); -} - -static int op_cpl(void) /* CPL */ -{ - A = ~A; - F |= H_FLAG | N_FLAG; - return(4); -} - -static int op_daa(void) /* DAA */ -{ - register int old_a; - - old_a = A; - if (F & N_FLAG) { /* subtractions */ - if (((A & 0x0f) > 9) || (F & H_FLAG)) { - (((old_a & 0x0f) - 6) < 0) ? (F |= H_FLAG) : (F &= ~H_FLAG); - A = old_a -= 6; - } - if (((A & 0xf0) > 0x90) || (F & C_FLAG)) { - A -= 0x60; - if (old_a - 0x60 < 0) - F |= C_FLAG; - } - } else { /* additions */ - if (((A & 0x0f) > 9) || (F & H_FLAG)) { - (((old_a & 0x0f) + 6) > 0x0f) ? (F |= H_FLAG) : (F &= ~H_FLAG); - A = old_a += 6; - } - if (((A & 0xf0) > 0x90) || (F & C_FLAG)) { - A += 0x60; - if (old_a + 0x60 > 255) - F |= C_FLAG; - } - } - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(4); -} - -static int op_ei(void) /* EI */ -{ - IFF = 3; - return(4); -} - -static int op_di(void) /* DI */ -{ - IFF = 0; - return(4); -} - -static int op_in(void) /* IN A,(n) */ -{ - BYTE io_in(); - - A = io_in(*PC++); - return(11); -} - -static int op_out(void) /* OUT (n),A */ -{ - BYTE io_out(); - - io_out(*PC++, A); - return(11); -} - -static int op_ldan(void) /* LD A,n */ -{ - A = *PC++; - return(7); -} - -static int op_ldbn(void) /* LD B,n */ -{ - B = *PC++; - return(7); -} - -static int op_ldcn(void) /* LD C,n */ -{ - C = *PC++; - return(7); -} - -static int op_lddn(void) /* LD D,n */ -{ - D = *PC++; - return(7); -} - -static int op_lden(void) /* LD E,n */ -{ - E = *PC++; - return(7); -} - -static int op_ldhn(void) /* LD H,n */ -{ - H = *PC++; - return(7); -} - -static int op_ldln(void) /* LD L,n */ -{ - L = *PC++; - return(7); -} - -static int op_ldabc(void) /* LD A,(BC) */ -{ - A = *(ram + (B << 8) + C); - return(7); -} - -static int op_ldade(void) /* LD A,(DE) */ -{ - A = *(ram + (D << 8) + E); - return(7); -} - -static int op_ldann(void) /* LD A,(nn) */ -{ - register unsigned i; - - i = *PC++; - i += *PC++ << 8; - A = *(ram + i); - return(13); -} - -static int op_ldbca(void) /* LD (BC),A */ -{ - *(ram + (B << 8) + C) = A; - return(7); -} - -static int op_lddea(void) /* LD (DE),A */ -{ - *(ram + (D << 8) + E) = A; - return(7); -} - -static int op_ldnna(void) /* LD (nn),A */ -{ - register unsigned i; - - i = *PC++; - i += *PC++ << 8; - *(ram + i) = A; - return(13); -} - -static int op_ldhla(void) /* LD (HL),A */ -{ - *(ram + (H << 8) + L) = A; - return(7); -} - -static int op_ldhlb(void) /* LD (HL),B */ -{ - *(ram + (H << 8) + L) = B; - return(7); -} - -static int op_ldhlc(void) /* LD (HL),C */ -{ - *(ram + (H << 8) + L) = C; - return(7); -} - -static int op_ldhld(void) /* LD (HL),D */ -{ - *(ram + (H << 8) + L) = D; - return(7); -} - -static int op_ldhle(void) /* LD (HL),E */ -{ - *(ram + (H << 8) + L) = E; - return(7); -} - -static int op_ldhlh(void) /* LD (HL),H */ -{ - *(ram + (H << 8) + L) = H; - return(7); -} - -static int op_ldhll(void) /* LD (HL),L */ -{ - *(ram + (H << 8) + L) = L; - return(7); -} - -static int op_ldhl1(void) /* LD (HL),n */ -{ - *(ram + (H << 8) + L) = *PC++; - return(10); -} - -static int op_ldaa(void) /* LD A,A */ -{ - return(4); -} - -static int op_ldab(void) /* LD A,B */ -{ - A = B; - return(4); -} - -static int op_ldac(void) /* LD A,C */ -{ - A = C; - return(4); -} - -static int op_ldad(void) /* LD A,D */ -{ - A = D; - return(4); -} - -static int op_ldae(void) /* LD A,E */ -{ - A = E; - return(4); -} - -static int op_ldah(void) /* LD A,H */ -{ - A = H; - return(4); -} - -static int op_ldal(void) /* LD A,L */ -{ - A = L; - return(4); -} - -static int op_ldahl(void) /* LD A,(HL) */ -{ - A = *(ram + (H << 8) + L); - return(7); -} - -static int op_ldba(void) /* LD B,A */ -{ - B = A; - return(4); -} - -static int op_ldbb(void) /* LD B,B */ -{ - return(4); -} - -static int op_ldbc(void) /* LD B,C */ -{ - B = C; - return(4); -} - -static int op_ldbd(void) /* LD B,D */ -{ - B = D; - return(4); -} - -static int op_ldbe(void) /* LD B,E */ -{ - B = E; - return(4); -} - -static int op_ldbh(void) /* LD B,H */ -{ - B = H; - return(4); -} - -static int op_ldbl(void) /* LD B,L */ -{ - B = L; - return(4); -} - -static int op_ldbhl(void) /* LD B,(HL) */ -{ - B = *(ram + (H << 8) + L); - return(7); -} - -static int op_ldca(void) /* LD C,A */ -{ - C = A; - return(4); -} - -static int op_ldcb(void) /* LD C,B */ -{ - C = B; - return(4); -} - -static int op_ldcc(void) /* LD C,C */ -{ - return(4); -} - -static int op_ldcd(void) /* LD C,D */ -{ - C = D; - return(4); -} - -static int op_ldce(void) /* LD C,E */ -{ - C = E; - return(4); -} - -static int op_ldch(void) /* LD C,H */ -{ - C = H; - return(4); -} - -static int op_ldcl(void) /* LD C,L */ -{ - C = L; - return(4); -} - -static int op_ldchl(void) /* LD C,(HL) */ -{ - C = *(ram + (H << 8) + L); - return(7); -} - -static int op_ldda(void) /* LD D,A */ -{ - D = A; - return(4); -} - -static int op_lddb(void) /* LD D,B */ -{ - D = B; - return(4); -} - -static int op_lddc(void) /* LD D,C */ -{ - D = C; - return(4); -} - -static int op_lddd(void) /* LD D,D */ -{ - return(4); -} - -static int op_ldde(void) /* LD D,E */ -{ - D = E; - return(4); -} - -static int op_lddh(void) /* LD D,H */ -{ - D = H; - return(4); -} - -static int op_lddl(void) /* LD D,L */ -{ - D = L; - return(4); -} - -static int op_lddhl(void) /* LD D,(HL) */ -{ - D = *(ram + (H << 8) + L); - return(7); -} - -static int op_ldea(void) /* LD E,A */ -{ - E = A; - return(4); -} - -static int op_ldeb(void) /* LD E,B */ -{ - E = B; - return(4); -} - -static int op_ldec(void) /* LD E,C */ -{ - E = C; - return(4); -} - -static int op_lded(void) /* LD E,D */ -{ - E = D; - return(4); -} - -static int op_ldee(void) /* LD E,E */ -{ - return(4); -} - -static int op_ldeh(void) /* LD E,H */ -{ - E = H; - return(4); -} - -static int op_ldel(void) /* LD E,L */ -{ - E = L; - return(4); -} - -static int op_ldehl(void) /* LD E,(HL) */ -{ - E = *(ram + (H << 8) + L); - return(7); -} - -static int op_ldha(void) /* LD H,A */ -{ - H = A; - return(4); -} - -static int op_ldhb(void) /* LD H,B */ -{ - H = B; - return(4); -} - -static int op_ldhc(void) /* LD H,C */ -{ - H = C; - return(4); -} - -static int op_ldhd(void) /* LD H,D */ -{ - H = D; - return(4); -} - -static int op_ldhe(void) /* LD H,E */ -{ - H = E; - return(4); -} - -static int op_ldhh(void) /* LD H,H */ -{ - return(4); -} - -static int op_ldhl(void) /* LD H,L */ -{ - H = L; - return(4); -} - -static int op_ldhhl(void) /* LD H,(HL) */ -{ - H = *(ram + (H << 8) + L); - return(7); -} - -static int op_ldla(void) /* LD L,A */ -{ - L = A; - return(4); -} - -static int op_ldlb(void) /* LD L,B */ -{ - L = B; - return(4); -} - -static int op_ldlc(void) /* LD L,C */ -{ - L = C; - return(4); -} - -static int op_ldld(void) /* LD L,D */ -{ - L = D; - return(4); -} - -static int op_ldle(void) /* LD L,E */ -{ - L = E; - return(4); -} - -static int op_ldlh(void) /* LD L,H */ -{ - L = H; - return(4); -} - -static int op_ldll(void) /* LD L,L */ -{ - return(4); -} - -static int op_ldlhl(void) /* LD L,(HL) */ -{ - L = *(ram + (H << 8) + L); - return(7); -} - -static int op_ldbcnn(void) /* LD BC,nn */ -{ - C = *PC++; - B = *PC++; - return(10); -} - -static int op_lddenn(void) /* LD DE,nn */ -{ - E = *PC++; - D = *PC++; - return(10); -} - -static int op_ldhlnn(void) /* LD HL,nn */ -{ - L = *PC++; - H = *PC++; - return(10); -} - -static int op_ldspnn(void) /* LD SP,nn */ -{ - STACK = ram + *PC++; - STACK += *PC++ << 8; - return(10); -} - -static int op_ldsphl(void) /* LD SP,HL */ -{ - STACK = ram + (H << 8) + L; - return(6); -} - -static int op_ldhlin(void) /* LD HL,(nn) */ -{ - register unsigned i; - - i = *PC++; - i += *PC++ << 8; - L = *(ram + i); - H = *(ram + i + 1); - return(16); -} - -static int op_ldinhl(void) /* LD (nn),HL */ -{ - register unsigned i; - - i = *PC++; - i += *PC++ << 8; - *(ram + i) = L; - *(ram + i + 1) = H; - return(16); -} - -static int op_incbc(void) /* INC BC */ -{ - C++; - if (!C) - B++; - return(6); -} - -static int op_incde(void) /* INC DE */ -{ - E++; - if (!E) - D++; - return(6); -} - -static int op_inchl(void) /* INC HL */ -{ - L++; - if (!L) - H++; - return(6); -} - -static int op_incsp(void) /* INC SP */ -{ - STACK++; -#ifdef WANT_SPC - if (STACK > ram + 65535) - STACK = ram; -#endif - return(6); -} - -static int op_decbc(void) /* DEC BC */ -{ - C--; - if (C == 0xff) - B--; - return(6); -} - -static int op_decde(void) /* DEC DE */ -{ - E--; - if (E == 0xff) - D--; - return(6); -} - -static int op_dechl(void) /* DEC HL */ -{ - L--; - if (L == 0xff) - H--; - return(6); -} - -static int op_decsp(void) /* DEC SP */ -{ - STACK--; -#ifdef WANT_SPC - if (STACK < ram) - STACK = ram + 65535; -#endif - return(6); -} - -static int op_adhlbc(void) /* ADD HL,BC */ -{ - register int carry; - - carry = (L + C > 255) ? 1 : 0; - L += C; - ((H & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (H + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H += B + carry; - F &= ~N_FLAG; - return(11); -} - -static int op_adhlde(void) /* ADD HL,DE */ -{ - register int carry; - - carry = (L + E > 255) ? 1 : 0; - L += E; - ((H & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (H + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H += D + carry; - F &= ~N_FLAG; - return(11); -} - -static int op_adhlhl(void) /* ADD HL,HL */ -{ - register int carry; - - carry = (L << 1 > 255) ? 1 : 0; - L <<= 1; - ((H & 0xf) + (H & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (H + H + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H += H + carry; - F &= ~N_FLAG; - return(11); -} - -static int op_adhlsp(void) /* ADD HL,SP */ -{ - register int carry; - BYTE spl = (STACK - ram) & 0xff; - BYTE sph = (STACK - ram) >> 8; - - carry = (L + spl > 255) ? 1 : 0; - L += spl; - ((H & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG) - : (F &= ~H_FLAG); - (H + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H += sph + carry; - F &= ~N_FLAG; - return(11); -} - -static int op_anda(void) /* AND A */ -{ - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(4); -} - -static int op_andb(void) /* AND B */ -{ - A &= B; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(4); -} - -static int op_andc(void) /* AND C */ -{ - A &= C; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(4); -} - -static int op_andd(void) /* AND D */ -{ - A &= D; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(4); -} - -static int op_ande(void) /* AND E */ -{ - A &= E; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(4); -} - -static int op_andh(void) /* AND H */ -{ - A &= H; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(4); -} - -static int op_andl(void) /* AND L */ -{ - A &= L; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(4); -} - -static int op_andhl(void) /* AND (HL) */ -{ - A &= *(ram + (H << 8) + L); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(7); -} - -static int op_andn(void) /* AND n */ -{ - A &= *PC++; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(7); -} - -static int op_ora(void) /* OR A */ -{ - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_orb(void) /* OR B */ -{ - A |= B; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_orc(void) /* OR C */ -{ - A |= C; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_ord(void) /* OR D */ -{ - A |= D; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_ore(void) /* OR E */ -{ - A |= E; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_orh(void) /* OR H */ -{ - A |= H; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_orl(void) /* OR L */ -{ - A |= L; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_orhl(void) /* OR (HL) */ -{ - A |= *(ram + (H << 8) + L); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(7); -} - -static int op_orn(void) /* OR n */ -{ - A |= *PC++; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(7); -} - -static int op_xora(void) /* XOR A */ -{ - A = 0; - F &= ~(S_FLAG | H_FLAG | N_FLAG | C_FLAG); - F |= Z_FLAG | P_FLAG; - return(4); -} - -static int op_xorb(void) /* XOR B */ -{ - A ^= B; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_xorc(void) /* XOR C */ -{ - A ^= C; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_xord(void) /* XOR D */ -{ - A ^= D; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_xore(void) /* XOR E */ -{ - A ^= E; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_xorh(void) /* XOR H */ -{ - A ^= H; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_xorl(void) /* XOR L */ -{ - A ^= L; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(4); -} - -static int op_xorhl(void) /* XOR (HL) */ -{ - A ^= *(ram + (H << 8) + L); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(7); -} - -static int op_xorn(void) /* XOR n */ -{ - A ^= *PC++; - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(7); -} - -static int op_adda(void) /* ADD A,A */ -{ - register int i; - - ((A & 0xf) + (A & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - ((A << 1) > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = ((char) A) << 1; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_addb(void) /* ADD A,B */ -{ - register int i; - - ((A & 0xf) + (B & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + B > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) B; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_addc(void) /* ADD A,C */ -{ - register int i; - - ((A & 0xf) + (C & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + C > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) C; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_addd(void) /* ADD A,Dn*/ -{ - register int i; - - ((A & 0xf) + (D & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + D > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) D; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_adde(void) /* ADD A,E */ -{ - register int i; - - ((A & 0xf) + (E & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + E > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) E; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_addh(void) /* ADD A,H */ -{ - register int i; - - ((A & 0xf) + (H & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + H > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) H; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_addl(void) /* ADD A,L */ -{ - register int i; - - ((A & 0xf) + (L & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + L > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) L; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_addhl(void) /* ADD A,(HL) */ -{ - register int i; - register BYTE P; - - P = *(ram + (H << 8) + L); - ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(7); -} - -static int op_addn(void) /* ADD A,n */ -{ - register int i; - register BYTE P; - - P = *PC++; - ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(7); -} - -static int op_adca(void) /* ADC A,A */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((A & 0xf) + (A & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - ((A << 1) + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (((char) A) << 1) + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_adcb(void) /* ADC A,B */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((A & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) B + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_adcc(void) /* ADC A,C */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((A & 0xf) + (C & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + C + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) C + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_adcd(void) /* ADC A,D */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((A & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) D + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_adce(void) /* ADC A,E */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((A & 0xf) + (E & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + E + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) E + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_adch(void) /* ADC A,H */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((A & 0xf) + (H & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + H + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) H + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_adcl(void) /* ADC A,L */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((A & 0xf) + (L & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + L + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) L + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_adchl(void) /* ADC A,(HL) */ -{ - register int i, carry; - register BYTE P; - - P = *(ram + (H << 8) + L); - carry = (F & C_FLAG) ? 1 : 0; - ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) P + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(7); -} - -static int op_adcn(void) /* ADC A,n */ -{ - register int i, carry; - register BYTE P; - - carry = (F & C_FLAG) ? 1 : 0; - P = *PC++; - ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) P + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(7); -} - -static int op_suba(void) /* SUB A,A */ -{ - A = 0; - F &= ~(S_FLAG | H_FLAG | P_FLAG | C_FLAG); - F |= Z_FLAG | N_FLAG; - return(4); -} - -static int op_subb(void) /* SUB A,B */ -{ - register int i; - - ((B & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (B > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) B; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_subc(void) /* SUB A,C */ -{ - register int i; - - ((C & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (C > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) C; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_subd(void) /* SUB A,D */ -{ - register int i; - - ((D & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (D > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) D; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_sube(void) /* SUB A,E */ -{ - register int i; - - ((E & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (E > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) E; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_subh(void) /* SUB A,H */ -{ - register int i; - - ((H & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (H > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) H; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_subl(void) /* SUB A,L */ -{ - register int i; - - ((L & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (L > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) L; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_subhl(void) /* SUB A,(HL) */ -{ - register int i; - register BYTE P; - - P = *(ram + (H << 8) + L); - ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(7); -} - -static int op_subn(void) /* SUB A,n */ -{ - register int i; - register BYTE P; - - P = *PC++; - ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(7); -} - -static int op_sbca(void) /* SBC A,A */ -{ - if (F & C_FLAG) { - F |= S_FLAG | H_FLAG | N_FLAG | C_FLAG; - F &= ~(Z_FLAG | P_FLAG); - A = 255; - } else { - F |= Z_FLAG | N_FLAG; - F &= ~(S_FLAG | H_FLAG | P_FLAG | C_FLAG); - A = 0; - } - return(4); -} - -static int op_sbcb(void) /* SBC A,B */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((B & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (B + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) B - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_sbcc(void) /* SBC A,C */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((C & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (C + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) C - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_sbcd(void) /* SBC A,D */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((D & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (D + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) D - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_sbce(void) /* SBC A,E */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((E & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (E + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) E - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_sbch(void) /* SBC A,H */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((H & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (H + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) H - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_sbcl(void) /* SBC A,L */ -{ - register int i, carry; - - carry = (F & C_FLAG) ? 1 : 0; - ((L & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (L + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) L - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_sbchl(void) /* SBC A,(HL) */ -{ - register int i, carry; - register BYTE P; - - P = *(ram + (H << 8) + L); - carry = (F & C_FLAG) ? 1 : 0; - ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) P - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(7); -} - -static int op_sbcn(void) /* SBC A,n */ -{ - register int i, carry; - register BYTE P; - - P = *PC++; - carry = (F & C_FLAG) ? 1 : 0; - ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) P - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(7); -} - -static int op_cpa(void) /* CP A */ -{ - F &= ~(S_FLAG | H_FLAG | P_FLAG | C_FLAG); - F |= Z_FLAG | N_FLAG; - return(4); -} - -static int op_cpb(void) /* CP B */ -{ - register int i; - - ((B & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (B > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) B; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_cpc(void) /* CP C */ -{ - register int i; - - ((C & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (C > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) C; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_cpd(void) /* CP D */ -{ - register int i; - - ((D & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (D > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) D; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_cpe(void) /* CP E */ -{ - register int i; - - ((E & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (E > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) E; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_cph(void) /* CP H */ -{ - register int i; - - ((H & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (H > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) H; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_cplr(void) /* CP L */ -{ - register int i; - - ((L & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (L > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) L; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_cphl(void) /* CP (HL) */ -{ - register int i; - register BYTE P; - - P = *(ram + (H << 8) + L); - ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(7); -} - -static int op_cpn(void) /* CP n */ -{ - register int i; - register BYTE P; - - P = *PC++; - ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(7); -} - -static int op_inca(void) /* INC A */ -{ - ((A & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - A++; - (A == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_incb(void) /* INC B */ -{ - ((B & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - B++; - (B == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_incc(void) /* INC C */ -{ - ((C & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - C++; - (C == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_incd(void) /* INC D */ -{ - ((D & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - D++; - (D == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_ince(void) /* INC E */ -{ - ((E & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - E++; - (E == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_inch(void) /* INC H */ -{ - ((H & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - H++; - (H == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_incl(void) /* INC L */ -{ - ((L & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - L++; - (L == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(4); -} - -static int op_incihl(void) /* INC (HL) */ -{ - register BYTE *p; - - p = ram + (H << 8) + L; - ((*p & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (*p)++; - (*p == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(11); -} - -static int op_deca(void) /* DEC A */ -{ - (((A - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - A--; - (A == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_decb(void) /* DEC B */ -{ - (((B - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - B--; - (B == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_decc(void) /* DEC C */ -{ - (((C - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - C--; - (C == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_decd(void) /* DEC D */ -{ - (((D - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - D--; - (D == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_dece(void) /* DEC E */ -{ - (((E - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - E--; - (E == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_dech(void) /* DEC H */ -{ - (((H - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - H--; - (H == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_decl(void) /* DEC L */ -{ - (((L - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - L--; - (L == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(4); -} - -static int op_decihl(void) /* DEC (HL) */ -{ - register BYTE *p; - - p = ram + (H << 8) + L; - (((*p - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (*p)--; - (*p == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(11); -} - -static int op_rlca(void) /* RLCA */ -{ - register int i; - - i = (A & 128) ? 1 : 0; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - A <<= 1; - A |= i; - return(4); -} - -static int op_rrca(void) /* RRCA */ -{ - register int i; - - i = A & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - A >>= 1; - if (i) A |= 128; - return(4); -} - -static int op_rla(void) /* RLA */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (A & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - A <<= 1; - if (old_c_flag) A |= 1; - return(4); -} - -static int op_rra(void) /* RRA */ -{ - register int i, old_c_flag; - - old_c_flag = F & C_FLAG; - i = A & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - A >>= 1; - if (old_c_flag) A |= 128; - return(4); -} - -static int op_exdehl(void) /* EX DE,HL */ -{ - register unsigned i; - - i = D; - D = H; - H = i; - i = E; - E = L; - L = i; - return(4); -} - -static int op_exafaf(void) /* EX AF,AF' */ -{ - register unsigned i; - - i = A; - A = A_; - A_ = i; - i = F; - F = F_; - F_ = i; - return(4); -} - -static int op_exx(void) /* EXX */ -{ - register unsigned i; - - i = B; - B = B_; - B_ = i; - i = C; - C = C_; - C_ = i; - i = D; - D = D_; - D_ = i; - i = E; - E = E_; - E_ = i; - i = H; - H = H_; - H_ = i; - i = L; - L = L_; - L_ = i; - return(4); -} - -static int op_exsphl(void) /* EX (SP),HL */ -{ - register int i; - - i = *STACK; - *STACK = L; - L = i; - i = *(STACK + 1); - *(STACK + 1) = H; - H = i; - return(19); -} - -static int op_pushaf(void) /* PUSH AF */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = A; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = F; - return(11); -} - -static int op_pushbc(void) /* PUSH BC */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = B; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = C; - return(11); -} - -static int op_pushde(void) /* PUSH DE */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = D; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = E; - return(11); -} - -static int op_pushhl(void) /* PUSH HL */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = H; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = L; - return(11); -} - -static int op_popaf(void) /* POP AF */ -{ - F = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - A = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - return(10); -} - -static int op_popbc(void) /* POP BC */ -{ - C = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - B = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - return(10); -} - -static int op_popde(void) /* POP DE */ -{ - E = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - D = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - return(10); -} - -static int op_pophl(void) /* POP HL */ -{ - L = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - H = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - return(10); -} - -static int op_jp(void) /* JP */ -{ - register unsigned i; - - i = *PC++; - i += *PC << 8; - PC = ram + i; - return(10); -} - -static int op_jphl(void) /* JP (HL) */ -{ - PC = ram + (H << 8) + L; - return(4); -} - -static int op_jr(void) /* JR */ -{ - PC += (char) *PC + 1; - return(12); -} - -static int op_djnz(void) /* DJNZ */ -{ - if (--B) { - PC += (char) *PC + 1; - return(13); - } else { - PC++; - return(8); - } -} - -static int op_call(void) /* CALL */ -{ - register unsigned i; - - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); -} - -static int op_ret(void) /* RET */ -{ - register unsigned i; - - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(10); -} - -static int op_jpz(void) /* JP Z,nn */ -{ - register unsigned i; - - if (F & Z_FLAG) { - i = *PC++; - i += *PC++ << 8; - PC = ram + i; - } else - PC += 2; - return(10); -} - -static int op_jpnz(void) /* JP NZ,nn */ -{ - register unsigned i; - - if (!(F & Z_FLAG)) { - i = *PC++; - i += *PC++ << 8; - PC = ram + i; - } else - PC += 2; - return(10); -} - -static int op_jpc(void) /* JP C,nn */ -{ - register unsigned i; - - if (F & C_FLAG) { - i = *PC++; - i += *PC++ << 8; - PC = ram + i; - } else - PC += 2; - return(10); -} - -static int op_jpnc(void) /* JP NC,nn */ -{ - register unsigned i; - - if (!(F & C_FLAG)) { - i = *PC++; - i += *PC++ << 8; - PC = ram + i; - } else - PC += 2; - return(10); -} - -static int op_jppe(void) /* JP PE,nn */ -{ - register unsigned i; - - if (F & P_FLAG) { - i = *PC++; - i += *PC++ << 8; - PC = ram + i; - } else - PC += 2; - return(10); -} - -static int op_jppo(void) /* JP PO,nn */ -{ - register unsigned i; - - if (!(F & P_FLAG)) { - i = *PC++; - i += *PC++ << 8; - PC = ram + i; - } else - PC += 2; - return(10); -} - -static int op_jpm(void) /* JP M,nn */ -{ - register unsigned i; - - if (F & S_FLAG) { - i = *PC++; - i += *PC++ << 8; - PC = ram + i; - } else - PC += 2; - return(10); -} - -static int op_jpp(void) /* JP P,nn */ -{ - register unsigned i; - - if (!(F & S_FLAG)) { - i = *PC++; - i += *PC++ << 8; - PC = ram + i; - } else - PC += 2; - return(10); -} - -static int op_calz(void) /* CALL Z,nn */ -{ - register unsigned i; - - if (F & Z_FLAG) { - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); - } else { - PC += 2; - return(10); - } -} - -static int op_calnz(void) /* CALL NZ,nn */ -{ - register unsigned i; - - if (!(F & Z_FLAG)) { - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); - } else { - PC += 2; - return(10); - } -} - -static int op_calc(void) /* CALL C,nn */ -{ - register unsigned i; - - if (F & C_FLAG) { - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); - } else { - PC += 2; - return(10); - } -} - -static int op_calnc(void) /* CALL NC,nn */ -{ - register unsigned i; - - if (!(F & C_FLAG)) { - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); - } else { - PC += 2; - return(10); - } -} - -static int op_calpe(void) /* CALL PE,nn */ -{ - register unsigned i; - - if (F & P_FLAG) { - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); - } else { - PC += 2; - return(10); - } -} - -static int op_calpo(void) /* CALL PO,nn */ -{ - register unsigned i; - - if (!(F & P_FLAG)) { - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); - } else { - PC += 2; - return(10); - } -} - -static int op_calm(void) /* CALL M,nn */ -{ - register unsigned i; - - if (F & S_FLAG) { - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); - } else { - PC += 2; - return(10); - } -} - -static int op_calp(void) /* CALL P,nn */ -{ - register unsigned i; - - if (!(F & S_FLAG)) { - i = *PC++; - i += *PC++ << 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + i; - return(17); - } else { - PC += 2; - return(10); - } -} - -static int op_retz(void) /* RET Z */ -{ - register unsigned i; - - if (F & Z_FLAG) { - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(11); - } else { - return(5); - } -} - -static int op_retnz(void) /* RET NZ */ -{ - register unsigned i; - - if (!(F & Z_FLAG)) { - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(11); - } else { - return(5); - } -} - -static int op_retc(void) /* RET C */ -{ - register unsigned i; - - if (F & C_FLAG) { - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(11); - } else { - return(5); - } -} - -static int op_retnc(void) /* RET NC */ -{ - register unsigned i; - - if (!(F & C_FLAG)) { - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(11); - } else { - return(5); - } -} - -static int op_retpe(void) /* RET PE */ -{ - register unsigned i; - - if (F & P_FLAG) { - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(11); - } else { - return(5); - } -} - -static int op_retpo(void) /* RET PO */ -{ - register unsigned i; - - if (!(F & P_FLAG)) { - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(11); - } else { - return(5); - } -} - -static int op_retm(void) /* RET M */ -{ - register unsigned i; - - if (F & S_FLAG) { - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(11); - } else { - return(5); - } -} - -static int op_retp(void) /* RET P */ -{ - register unsigned i; - - if (!(F & S_FLAG)) { - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(11); - } else { - return(5); - } -} - -static int op_jrz(void) /* JR Z,n */ -{ - if (F & Z_FLAG) { - PC += (char) *PC + 1; - return(12); - } else { - PC++; - return(7); - } -} - -static int op_jrnz(void) /* JR NZ,n */ -{ - if (!(F & Z_FLAG)) { - PC += (char) *PC + 1; - return(12); - } else { - PC++; - return(7); - } -} - -static int op_jrc(void) /* JR C,n */ -{ - if (F & C_FLAG) { - PC += (char) *PC + 1; - return(12); - } else { - PC++; - return(7); - } -} - -static int op_jrnc(void) /* JR NC,n */ -{ - if (!(F & C_FLAG)) { - PC += (char) *PC + 1; - return(12); - } else { - PC++; - return(7); - } -} - -static int op_rst00(void) /* RST 00 */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram; - return(11); -} - -static int op_rst08(void) /* RST 08 */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x08; - return(11); -} - -static int op_rst10(void) /* RST 10 */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x10; - return(11); -} - -static int op_rst18(void) /* RST 18 */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x18; - return(11); -} - -static int op_rst20(void) /* RST 20 */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x20; - return(11); -} - -static int op_rst28(void) /* RST 28 */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x28; - return(11); -} - -static int op_rst30(void) /* RST 30 */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x30; - return(11); -} - -static int op_rst38(void) /* RST 38 */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram) >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = (PC - ram); - PC = ram + 0x38; - return(11); -} diff --git a/emu/z80pack-1.9/z80sim/sim1.o b/emu/z80pack-1.9/z80sim/sim1.o deleted file mode 100644 index d2c2f48..0000000 Binary files a/emu/z80pack-1.9/z80sim/sim1.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/sim2.c b/emu/z80pack-1.9/z80sim/sim2.c deleted file mode 100644 index 1c7d3fd..0000000 --- a/emu/z80pack-1.9/z80sim/sim2.c +++ /dev/null @@ -1,2511 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * Like the function "cpu()" this one emulates multi byte opcodes - * starting with 0xcb - */ - -#include "sim.h" -#include "simglb.h" - -static int trap_cb(void); -static int op_srla(void), op_srlb(void), op_srlc(void); -static int op_srld(void), op_srle(void); -static int op_srlh(void), op_srll(void), op_srlhl(void); -static int op_slaa(void), op_slab(void), op_slac(void); -static int op_slad(void), op_slae(void); -static int op_slah(void), op_slal(void), op_slahl(void); -static int op_rlra(void), op_rlb(void), op_rlc(void); -static int op_rld(void), op_rle(void); -static int op_rlh(void), op_rll(void), op_rlhl(void); -static int op_rrra(void), op_rrb(void), op_rrc(void); -static int op_rrd(void), op_rre(void); -static int op_rrh(void), op_rrl(void), op_rrhl(void); -static int op_rrcra(void), op_rrcb(void), op_rrcc(void); -static int op_rrcd(void), op_rrce(void); -static int op_rrch(void), op_rrcl(void), op_rrchl(void); -static int op_rlcra(void), op_rlcb(void), op_rlcc(void); -static int op_rlcd(void), op_rlce(void); -static int op_rlch(void), op_rlcl(void), op_rlchl(void); -static int op_sraa(void), op_srab(void), op_srac(void); -static int op_srad(void), op_srae(void); -static int op_srah(void), op_sral(void), op_srahl(void); -static int op_sb0a(void), op_sb1a(void), op_sb2a(void), op_sb3a(void); -static int op_sb4a(void), op_sb5a(void), op_sb6a(void), op_sb7a(void); -static int op_sb0b(void), op_sb1b(void), op_sb2b(void), op_sb3b(void); -static int op_sb4b(void), op_sb5b(void), op_sb6b(void), op_sb7b(void); -static int op_sb0c(void), op_sb1c(void), op_sb2c(void), op_sb3c(void); -static int op_sb4c(void), op_sb5c(void), op_sb6c(void), op_sb7c(void); -static int op_sb0d(void), op_sb1d(void), op_sb2d(void), op_sb3d(void); -static int op_sb4d(void), op_sb5d(void), op_sb6d(void), op_sb7d(void); -static int op_sb0e(void), op_sb1e(void), op_sb2e(void), op_sb3e(void); -static int op_sb4e(void), op_sb5e(void), op_sb6e(void), op_sb7e(void); -static int op_sb0h(void), op_sb1h(void), op_sb2h(void), op_sb3h(void); -static int op_sb4h(void), op_sb5h(void), op_sb6h(void), op_sb7h(void); -static int op_sb0l(void), op_sb1l(void), op_sb2l(void), op_sb3l(void); -static int op_sb4l(void), op_sb5l(void), op_sb6l(void), op_sb7l(void); -static int op_sb0hl(void), op_sb1hl(void), op_sb2hl(void), op_sb3hl(void); -static int op_sb4hl(void), op_sb5hl(void), op_sb6hl(void), op_sb7hl(void); -static int op_rb0a(void), op_rb1a(void), op_rb2a(void), op_rb3a(void); -static int op_rb4a(void), op_rb5a(void), op_rb6a(void), op_rb7a(void); -static int op_rb0b(void), op_rb1b(void), op_rb2b(void), op_rb3b(void); -static int op_rb4b(void), op_rb5b(void), op_rb6b(void), op_rb7b(void); -static int op_rb0c(void), op_rb1c(void), op_rb2c(void), op_rb3c(void); -static int op_rb4c(void), op_rb5c(void), op_rb6c(void), op_rb7c(void); -static int op_rb0d(void), op_rb1d(void), op_rb2d(void), op_rb3d(void); -static int op_rb4d(void), op_rb5d(void), op_rb6d(void), op_rb7d(void); -static int op_rb0e(void), op_rb1e(void), op_rb2e(void), op_rb3e(void); -static int op_rb4e(void), op_rb5e(void), op_rb6e(void), op_rb7e(void); -static int op_rb0h(void), op_rb1h(void), op_rb2h(void), op_rb3h(void); -static int op_rb4h(void), op_rb5h(void), op_rb6h(void), op_rb7h(void); -static int op_rb0l(void), op_rb1l(void), op_rb2l(void), op_rb3l(void); -static int op_rb4l(void), op_rb5l(void), op_rb6l(void), op_rb7l(void); -static int op_rb0hl(void), op_rb1hl(void), op_rb2hl(void), op_rb3hl(void); -static int op_rb4hl(void), op_rb5hl(void), op_rb6hl(void), op_rb7hl(void); -static int op_tb0a(void), op_tb1a(void), op_tb2a(void), op_tb3a(void); -static int op_tb4a(void), op_tb5a(void), op_tb6a(void), op_tb7a(void); -static int op_tb0b(void), op_tb1b(void), op_tb2b(void), op_tb3b(void); -static int op_tb4b(void), op_tb5b(void), op_tb6b(void), op_tb7b(void); -static int op_tb0c(void), op_tb1c(void), op_tb2c(void), op_tb3c(void); -static int op_tb4c(void), op_tb5c(void), op_tb6c(void), op_tb7c(void); -static int op_tb0d(void), op_tb1d(void), op_tb2d(void), op_tb3d(void); -static int op_tb4d(void), op_tb5d(void), op_tb6d(void), op_tb7d(void); -static int op_tb0e(void), op_tb1e(void), op_tb2e(void), op_tb3e(void); -static int op_tb4e(void), op_tb5e(void), op_tb6e(void), op_tb7e(void); -static int op_tb0h(void), op_tb1h(void), op_tb2h(void), op_tb3h(void); -static int op_tb4h(void), op_tb5h(void), op_tb6h(void), op_tb7h(void); -static int op_tb0l(void), op_tb1l(void), op_tb2l(void), op_tb3l(void); -static int op_tb4l(void), op_tb5l(void), op_tb6l(void), op_tb7l(void); -static int op_tb0hl(void), op_tb1hl(void), op_tb2hl(void), op_tb3hl(void); -static int op_tb4hl(void), op_tb5hl(void), op_tb6hl(void), op_tb7hl(void); - -int op_cb_handel(void) -{ - register int t; - - static int (*op_cb[256]) (void) = { - op_rlcb, /* 0x00 */ - op_rlcc, /* 0x01 */ - op_rlcd, /* 0x02 */ - op_rlce, /* 0x03 */ - op_rlch, /* 0x04 */ - op_rlcl, /* 0x05 */ - op_rlchl, /* 0x06 */ - op_rlcra, /* 0x07 */ - op_rrcb, /* 0x08 */ - op_rrcc, /* 0x09 */ - op_rrcd, /* 0x0a */ - op_rrce, /* 0x0b */ - op_rrch, /* 0x0c */ - op_rrcl, /* 0x0d */ - op_rrchl, /* 0x0e */ - op_rrcra, /* 0x0f */ - op_rlb, /* 0x10 */ - op_rlc, /* 0x11 */ - op_rld, /* 0x12 */ - op_rle, /* 0x13 */ - op_rlh, /* 0x14 */ - op_rll, /* 0x15 */ - op_rlhl, /* 0x16 */ - op_rlra, /* 0x17 */ - op_rrb, /* 0x18 */ - op_rrc, /* 0x19 */ - op_rrd, /* 0x1a */ - op_rre, /* 0x1b */ - op_rrh, /* 0x1c */ - op_rrl, /* 0x1d */ - op_rrhl, /* 0x1e */ - op_rrra, /* 0x1f */ - op_slab, /* 0x20 */ - op_slac, /* 0x21 */ - op_slad, /* 0x22 */ - op_slae, /* 0x23 */ - op_slah, /* 0x24 */ - op_slal, /* 0x25 */ - op_slahl, /* 0x26 */ - op_slaa, /* 0x27 */ - op_srab, /* 0x28 */ - op_srac, /* 0x29 */ - op_srad, /* 0x2a */ - op_srae, /* 0x2b */ - op_srah, /* 0x2c */ - op_sral, /* 0x2d */ - op_srahl, /* 0x2e */ - op_sraa, /* 0x2f */ - trap_cb, /* 0x30 */ - trap_cb, /* 0x31 */ - trap_cb, /* 0x32 */ - trap_cb, /* 0x33 */ - trap_cb, /* 0x34 */ - trap_cb, /* 0x35 */ - trap_cb, /* 0x36 */ - trap_cb, /* 0x37 */ - op_srlb, /* 0x38 */ - op_srlc, /* 0x39 */ - op_srld, /* 0x3a */ - op_srle, /* 0x3b */ - op_srlh, /* 0x3c */ - op_srll, /* 0x3d */ - op_srlhl, /* 0x3e */ - op_srla, /* 0x3f */ - op_tb0b, /* 0x40 */ - op_tb0c, /* 0x41 */ - op_tb0d, /* 0x42 */ - op_tb0e, /* 0x43 */ - op_tb0h, /* 0x44 */ - op_tb0l, /* 0x45 */ - op_tb0hl, /* 0x46 */ - op_tb0a, /* 0x47 */ - op_tb1b, /* 0x48 */ - op_tb1c, /* 0x49 */ - op_tb1d, /* 0x4a */ - op_tb1e, /* 0x4b */ - op_tb1h, /* 0x4c */ - op_tb1l, /* 0x4d */ - op_tb1hl, /* 0x4e */ - op_tb1a, /* 0x4f */ - op_tb2b, /* 0x50 */ - op_tb2c, /* 0x51 */ - op_tb2d, /* 0x52 */ - op_tb2e, /* 0x53 */ - op_tb2h, /* 0x54 */ - op_tb2l, /* 0x55 */ - op_tb2hl, /* 0x56 */ - op_tb2a, /* 0x57 */ - op_tb3b, /* 0x58 */ - op_tb3c, /* 0x59 */ - op_tb3d, /* 0x5a */ - op_tb3e, /* 0x5b */ - op_tb3h, /* 0x5c */ - op_tb3l, /* 0x5d */ - op_tb3hl, /* 0x5e */ - op_tb3a, /* 0x5f */ - op_tb4b, /* 0x60 */ - op_tb4c, /* 0x61 */ - op_tb4d, /* 0x62 */ - op_tb4e, /* 0x63 */ - op_tb4h, /* 0x64 */ - op_tb4l, /* 0x65 */ - op_tb4hl, /* 0x66 */ - op_tb4a, /* 0x67 */ - op_tb5b, /* 0x68 */ - op_tb5c, /* 0x69 */ - op_tb5d, /* 0x6a */ - op_tb5e, /* 0x6b */ - op_tb5h, /* 0x6c */ - op_tb5l, /* 0x6d */ - op_tb5hl, /* 0x6e */ - op_tb5a, /* 0x6f */ - op_tb6b, /* 0x70 */ - op_tb6c, /* 0x71 */ - op_tb6d, /* 0x72 */ - op_tb6e, /* 0x73 */ - op_tb6h, /* 0x74 */ - op_tb6l, /* 0x75 */ - op_tb6hl, /* 0x76 */ - op_tb6a, /* 0x77 */ - op_tb7b, /* 0x78 */ - op_tb7c, /* 0x79 */ - op_tb7d, /* 0x7a */ - op_tb7e, /* 0x7b */ - op_tb7h, /* 0x7c */ - op_tb7l, /* 0x7d */ - op_tb7hl, /* 0x7e */ - op_tb7a, /* 0x7f */ - op_rb0b, /* 0x80 */ - op_rb0c, /* 0x81 */ - op_rb0d, /* 0x82 */ - op_rb0e, /* 0x83 */ - op_rb0h, /* 0x84 */ - op_rb0l, /* 0x85 */ - op_rb0hl, /* 0x86 */ - op_rb0a, /* 0x87 */ - op_rb1b, /* 0x88 */ - op_rb1c, /* 0x89 */ - op_rb1d, /* 0x8a */ - op_rb1e, /* 0x8b */ - op_rb1h, /* 0x8c */ - op_rb1l, /* 0x8d */ - op_rb1hl, /* 0x8e */ - op_rb1a, /* 0x8f */ - op_rb2b, /* 0x90 */ - op_rb2c, /* 0x91 */ - op_rb2d, /* 0x92 */ - op_rb2e, /* 0x93 */ - op_rb2h, /* 0x94 */ - op_rb2l, /* 0x95 */ - op_rb2hl, /* 0x96 */ - op_rb2a, /* 0x97 */ - op_rb3b, /* 0x98 */ - op_rb3c, /* 0x99 */ - op_rb3d, /* 0x9a */ - op_rb3e, /* 0x9b */ - op_rb3h, /* 0x9c */ - op_rb3l, /* 0x9d */ - op_rb3hl, /* 0x9e */ - op_rb3a, /* 0x9f */ - op_rb4b, /* 0xa0 */ - op_rb4c, /* 0xa1 */ - op_rb4d, /* 0xa2 */ - op_rb4e, /* 0xa3 */ - op_rb4h, /* 0xa4 */ - op_rb4l, /* 0xa5 */ - op_rb4hl, /* 0xa6 */ - op_rb4a, /* 0xa7 */ - op_rb5b, /* 0xa8 */ - op_rb5c, /* 0xa9 */ - op_rb5d, /* 0xaa */ - op_rb5e, /* 0xab */ - op_rb5h, /* 0xac */ - op_rb5l, /* 0xad */ - op_rb5hl, /* 0xae */ - op_rb5a, /* 0xaf */ - op_rb6b, /* 0xb0 */ - op_rb6c, /* 0xb1 */ - op_rb6d, /* 0xb2 */ - op_rb6e, /* 0xb3 */ - op_rb6h, /* 0xb4 */ - op_rb6l, /* 0xb5 */ - op_rb6hl, /* 0xb6 */ - op_rb6a, /* 0xb7 */ - op_rb7b, /* 0xb8 */ - op_rb7c, /* 0xb9 */ - op_rb7d, /* 0xba */ - op_rb7e, /* 0xbb */ - op_rb7h, /* 0xbc */ - op_rb7l, /* 0xbd */ - op_rb7hl, /* 0xbe */ - op_rb7a, /* 0xbf */ - op_sb0b, /* 0xc0 */ - op_sb0c, /* 0xc1 */ - op_sb0d, /* 0xc2 */ - op_sb0e, /* 0xc3 */ - op_sb0h, /* 0xc4 */ - op_sb0l, /* 0xc5 */ - op_sb0hl, /* 0xc6 */ - op_sb0a, /* 0xc7 */ - op_sb1b, /* 0xc8 */ - op_sb1c, /* 0xc9 */ - op_sb1d, /* 0xca */ - op_sb1e, /* 0xcb */ - op_sb1h, /* 0xcc */ - op_sb1l, /* 0xcd */ - op_sb1hl, /* 0xce */ - op_sb1a, /* 0xcf */ - op_sb2b, /* 0xd0 */ - op_sb2c, /* 0xd1 */ - op_sb2d, /* 0xd2 */ - op_sb2e, /* 0xd3 */ - op_sb2h, /* 0xd4 */ - op_sb2l, /* 0xd5 */ - op_sb2hl, /* 0xd6 */ - op_sb2a, /* 0xd7 */ - op_sb3b, /* 0xd8 */ - op_sb3c, /* 0xd9 */ - op_sb3d, /* 0xda */ - op_sb3e, /* 0xdb */ - op_sb3h, /* 0xdc */ - op_sb3l, /* 0xdd */ - op_sb3hl, /* 0xde */ - op_sb3a, /* 0xdf */ - op_sb4b, /* 0xe0 */ - op_sb4c, /* 0xe1 */ - op_sb4d, /* 0xe2 */ - op_sb4e, /* 0xe3 */ - op_sb4h, /* 0xe4 */ - op_sb4l, /* 0xe5 */ - op_sb4hl, /* 0xe6 */ - op_sb4a, /* 0xe7 */ - op_sb5b, /* 0xe8 */ - op_sb5c, /* 0xe9 */ - op_sb5d, /* 0xea */ - op_sb5e, /* 0xeb */ - op_sb5h, /* 0xec */ - op_sb5l, /* 0xed */ - op_sb5hl, /* 0xee */ - op_sb5a, /* 0xef */ - op_sb6b, /* 0xf0 */ - op_sb6c, /* 0xf1 */ - op_sb6d, /* 0xf2 */ - op_sb6e, /* 0xf3 */ - op_sb6h, /* 0xf4 */ - op_sb6l, /* 0xf5 */ - op_sb6hl, /* 0xf6 */ - op_sb6a, /* 0xf7 */ - op_sb7b, /* 0xf8 */ - op_sb7c, /* 0xf9 */ - op_sb7d, /* 0xfa */ - op_sb7e, /* 0xfb */ - op_sb7h, /* 0xfc */ - op_sb7l, /* 0xfd */ - op_sb7hl, /* 0xfe */ - op_sb7a /* 0xff */ - }; - -#ifdef WANT_TIM - t = (*op_cb[*PC++]) (); /* execute next opcode */ -#else - (*op_cb[*PC++]) (); -#endif - -#ifdef WANT_PCC - if (PC > ram + 65535) /* correct PC overrun */ - PC = ram; -#endif - - return(t); -} - -/* - * This function traps all illegal opcodes following the - * initial 0xcb of a multi byte opcode. - */ -static int trap_cb(void) -{ - cpu_error = OPTRAP2; - cpu_state = STOPPED; - return(0); -} - -static int op_srla(void) /* SRL A */ -{ - (A & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A >>= 1; - F &= ~(H_FLAG | N_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srlb(void) /* SRL B */ -{ - (B & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - B >>= 1; - F &= ~(H_FLAG | N_FLAG); - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srlc(void) /* SRL C */ -{ - (C & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - C >>= 1; - F &= ~(H_FLAG | N_FLAG); - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srld(void) /* SRL D */ -{ - (D & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - D >>= 1; - F &= ~(H_FLAG | N_FLAG); - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srle(void) /* SRL E */ -{ - (E & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - E >>= 1; - F &= ~(H_FLAG | N_FLAG); - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[E]) ? (F &= ~P_FLAG) :(F |= P_FLAG); - return(8); -} - -static int op_srlh(void) /* SRL H */ -{ - (H & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H >>= 1; - F &= ~(H_FLAG | N_FLAG); - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srll(void) /* SRL L */ -{ - (L & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - L >>= 1; - F &= ~(H_FLAG | N_FLAG); - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srlhl(void) /* SRL (HL) */ -{ - register BYTE *p; - - p = ram + (H << 8) + L; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(15); -} - -static int op_slaa(void) /* SLA A */ -{ - (A & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A <<= 1; - F &= ~(H_FLAG | N_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_slab(void) /* SLA B */ -{ - (B & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - B <<= 1; - F &= ~(H_FLAG | N_FLAG); - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_slac(void) /* SLA C */ -{ - (C & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - C <<= 1; - F &= ~(H_FLAG | N_FLAG); - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_slad(void) /* SLA D */ -{ - (D & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - D <<= 1; - F &= ~(H_FLAG | N_FLAG); - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_slae(void) /* SLA E */ -{ - (E & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - E <<= 1; - F &= ~(H_FLAG | N_FLAG); - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_slah(void) /* SLA H */ -{ - (H & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H <<= 1; - F &= ~(H_FLAG | N_FLAG); - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_slal(void) /* SLA L */ -{ - (L & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - L <<= 1; - F &= ~(H_FLAG | N_FLAG); - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_slahl(void) /* SLA (HL) */ -{ - register BYTE *p; - - p = ram + (H << 8) + L; - (*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p <<= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(15); -} - -static int op_rlra(void) /* RL A */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (A & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A <<= 1; - if (old_c_flag) A |= 1; - F &= ~(H_FLAG | N_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlb(void) /* RL B */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (B & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - B <<= 1; - if (old_c_flag) B |= 1; - F &= ~(H_FLAG | N_FLAG); - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlc(void) /* RL C */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (C & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - C <<= 1; - if (old_c_flag) C |= 1; - F &= ~(H_FLAG | N_FLAG); - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rld(void) /* RL D */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (D & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - D <<= 1; - if (old_c_flag) D |= 1; - F &= ~(H_FLAG | N_FLAG); - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rle(void) /* RL E */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (E & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - E <<= 1; - if (old_c_flag) E |= 1; - F &= ~(H_FLAG | N_FLAG); - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlh(void) /* RL H */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (H & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H <<= 1; - if (old_c_flag) H |= 1; - F &= ~(H_FLAG | N_FLAG); - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[H]) ? (F &= ~P_FLAG) :(F |= P_FLAG); - return(8); -} - -static int op_rll(void) /* RL L */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (L & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - L <<= 1; - if (old_c_flag) L |= 1; - F &= ~(H_FLAG | N_FLAG); - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlhl(void) /* RL (HL) */ -{ - register int old_c_flag; - register BYTE *p; - - p = ram + (H << 8) + L; - old_c_flag = F & C_FLAG; - (*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p <<= 1; - if (old_c_flag) *p |= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(15); -} - -static int op_rrra(void) /* RR A */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (A & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A >>= 1; - if (old_c_flag) A |= 128; - F &= ~(H_FLAG | N_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrb(void) /* RR B */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (B & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - B >>= 1; - if (old_c_flag) B |= 128; - F &= ~(H_FLAG | N_FLAG); - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrc(void) /* RR C */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (C & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - C >>= 1; - if (old_c_flag) C |= 128; - F &= ~(H_FLAG | N_FLAG); - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrd(void) /* RR D */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (D & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - D >>= 1; - if (old_c_flag) D |= 128; - F &= ~(H_FLAG | N_FLAG); - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rre(void) /* RR E */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (E & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - E >>= 1; - if (old_c_flag) E |= 128; - F &= ~(H_FLAG | N_FLAG); - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrh(void) /* RR H */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (H & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H >>= 1; - if (old_c_flag) H |= 128; - F &= ~(H_FLAG | N_FLAG); - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrl(void) /* RR L */ -{ - register int old_c_flag; - - old_c_flag = F & C_FLAG; - (L & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - L >>= 1; - if (old_c_flag) L |= 128; - F &= ~(H_FLAG | N_FLAG); - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrhl(void) /* RR (HL) */ -{ - register int old_c_flag; - register BYTE *p; - - old_c_flag = F & C_FLAG; - p = ram + (H << 8) + L; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - if (old_c_flag) *p |= 128; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(15); -} - -static int op_rrcra(void) /* RRC A */ -{ - register int i; - - i = A & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - A >>= 1; - if (i) A |= 128; - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrcb(void) /* RRC B */ -{ - register int i; - - i = B & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - B >>= 1; - if (i) B |= 128; - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrcc(void) /* RRC C */ -{ - register int i; - - i = C & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - C >>= 1; - if (i) C |= 128; - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrcd(void) /* RRC D */ -{ - register int i; - - i = D & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - D >>= 1; - if (i) D |= 128; - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrce(void) /* RRC E */ -{ - register int i; - - i = E & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - E >>= 1; - if (i) E |= 128; - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrch(void) /* RRC H */ -{ - register int i; - - i = H & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - H >>= 1; - if (i) H |= 128; - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrcl(void) /* RRC L */ -{ - register int i; - - i = L & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - L >>= 1; - if (i) L |= 128; - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rrchl(void) /* RRC (HL) */ -{ - register int i; - register BYTE *p; - - p = ram + (H << 8) + L; - i = *p & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - *p >>= 1; - if (i) *p |= 128; - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(15); -} - -static int op_rlcra(void) /* RLC A */ -{ - register int i; - - i = A & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - A <<= 1; - if (i) A |= 1; - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlcb(void) /* RLC B */ -{ - register int i; - - i = B & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - B <<= 1; - if (i) B |= 1; - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlcc(void) /* RLC C */ -{ - register int i; - - i = C & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - C <<= 1; - if (i) C |= 1; - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlcd(void) /* RLC D */ -{ - register int i; - - i = D & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - D <<= 1; - if (i) D |= 1; - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlce(void) /* RLC E */ -{ - register int i; - - i = E & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - E <<= 1; - if (i) E |= 1; - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlch(void) /* RLC H */ -{ - register int i; - - i = H & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - H <<= 1; - if (i) H |= 1; - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlcl(void) /* RLC L */ -{ - register int i; - - i = L & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - L <<= 1; - if (i) L |= 1; - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_rlchl(void) /* RLC (HL) */ -{ - register int i; - register BYTE *p; - - p = ram + (H << 8) + L; - i = *p & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - *p <<= 1; - if (i) *p |= 1; - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(15); -} - -static int op_sraa(void) /* SRA A */ -{ - register int i; - - i = A & 128; - (A & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A >>= 1; - A |= i; - F &= ~(H_FLAG | N_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srab(void) /* SRA B */ -{ - register int i; - - i = B & 128; - (B & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - B >>= 1; - B |= i; - F &= ~(H_FLAG | N_FLAG); - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srac(void) /* SRA C */ -{ - register int i; - - i = C & 128; - (C & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - C >>= 1; - C |= i; - F &= ~(H_FLAG | N_FLAG); - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srad(void) /* SRA D */ -{ - register int i; - - i = D & 128; - (D & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - D >>= 1; - D |= i; - F &= ~(H_FLAG | N_FLAG); - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srae(void) /* SRA E */ -{ - register int i; - - i = E & 128; - (E & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - E >>= 1; - E |= i; - F &= ~(H_FLAG | N_FLAG); - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srah(void) /* SRA H */ -{ - register int i; - - i = H & 128; - (H & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - H >>= 1; - H |= i; - F &= ~(H_FLAG | N_FLAG); - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_sral(void) /* SRA L */ -{ - register int i; - - i = L & 128; - (L & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - L >>= 1; - L |= i; - F &= ~(H_FLAG | N_FLAG); - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(8); -} - -static int op_srahl(void) /* SRA (HL) */ -{ - register int i; - register BYTE *p; - - p = ram + (H << 8) + L; - i = *p & 128; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - *p |= i; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(15); -} - -static int op_sb0a(void) /* SET 0,A */ -{ - A |= 1; - return(8); -} - -static int op_sb1a(void) /* SET 1,A */ -{ - A |= 2; - return(8); -} - -static int op_sb2a(void) /* SET 2,A */ -{ - A |= 4; - return(8); -} - -static int op_sb3a(void) /* SET 3,A */ -{ - A |= 8; - return(8); -} - -static int op_sb4a(void) /* SET 4,A */ -{ - A |= 16; - return(8); -} - -static int op_sb5a(void) /* SET 5,A */ -{ - A |= 32; - return(8); -} - -static int op_sb6a(void) /* SET 6,A */ -{ - A |= 64; - return(8); -} - -static int op_sb7a(void) /* SET 7,A */ -{ - A |= 128; - return(8); -} - -static int op_sb0b(void) /* SET 0,B */ -{ - B |= 1; - return(8); -} - -static int op_sb1b(void) /* SET 1,B */ -{ - B |= 2; - return(8); -} - -static int op_sb2b(void) /* SET 2,B */ -{ - B |= 4; - return(8); -} - -static int op_sb3b(void) /* SET 3,B */ -{ - B |= 8; - return(8); -} - -static int op_sb4b(void) /* SET 4,B */ -{ - B |= 16; - return(8); -} - -static int op_sb5b(void) /* SET 5,B */ -{ - B |= 32; - return(8); -} - -static int op_sb6b(void) /* SET 6,B */ -{ - B |= 64; - return(8); -} - -static int op_sb7b(void) /* SET 7,B */ -{ - B |= 128; - return(8); -} - -static int op_sb0c(void) /* SET 0,C */ -{ - C |= 1; - return(8); -} - -static int op_sb1c(void) /* SET 1,C */ -{ - C |= 2; - return(8); -} - -static int op_sb2c(void) /* SET 2,C */ -{ - C |= 4; - return(8); -} - -static int op_sb3c(void) /* SET 3,C */ -{ - C |= 8; - return(8); -} - -static int op_sb4c(void) /* SET 4,C */ -{ - C |= 16; - return(8); -} - -static int op_sb5c(void) /* SET 5,C */ -{ - C |= 32; - return(8); -} - -static int op_sb6c(void) /* SET 6,C */ -{ - C |= 64; - return(8); -} - -static int op_sb7c(void) /* SET 7,C */ -{ - C |= 128; - return(8); -} - -static int op_sb0d(void) /* SET 0,D */ -{ - D |= 1; - return(8); -} - -static int op_sb1d(void) /* SET 1,D */ -{ - D |= 2; - return(8); -} - -static int op_sb2d(void) /* SET 2,D */ -{ - D |= 4; - return(8); -} - -static int op_sb3d(void) /* SET 3,D */ -{ - D |= 8; - return(8); -} - -static int op_sb4d(void) /* SET 4,D */ -{ - D |= 16; - return(8); -} - -static int op_sb5d(void) /* SET 5,D */ -{ - D |= 32; - return(8); -} - -static int op_sb6d(void) /* SET 6,D */ -{ - D |= 64; - return(8); -} - -static int op_sb7d(void) /* SET 7,D */ -{ - D |= 128; - return(8); -} - -static int op_sb0e(void) /* SET 0,E */ -{ - E |= 1; - return(8); -} - -static int op_sb1e(void) /* SET 1,E */ -{ - E |= 2; - return(8); -} - -static int op_sb2e(void) /* SET 2,E */ -{ - E |= 4; - return(8); -} - -static int op_sb3e(void) /* SET 3,E */ -{ - E |= 8; - return(8); -} - -static int op_sb4e(void) /* SET 4,E */ -{ - E |= 16; - return(8); -} - -static int op_sb5e(void) /* SET 5,E */ -{ - E |= 32; - return(8); -} - -static int op_sb6e(void) /* SET 6,E */ -{ - E |= 64; - return(8); -} - -static int op_sb7e(void) /* SET 7,E */ -{ - E |= 128; - return(8); -} - -static int op_sb0h(void) /* SET 0,H */ -{ - H |= 1; - return(8); -} - -static int op_sb1h(void) /* SET 1,H */ -{ - H |= 2; - return(8); -} - -static int op_sb2h(void) /* SET 2,H */ -{ - H |= 4; - return(8); -} - -static int op_sb3h(void) /* SET 3,H */ -{ - H |= 8; - return(8); -} - -static int op_sb4h(void) /* SET 4,H */ -{ - H |= 16; - return(8); -} - -static int op_sb5h(void) /* SET 5,H */ -{ - H |= 32; - return(8); -} - -static int op_sb6h(void) /* SET 6,H */ -{ - H |= 64; - return(8); -} - -static int op_sb7h(void) /* SET 7,H */ -{ - H |= 128; - return(8); -} - -static int op_sb0l(void) /* SET 0,L */ -{ - L |= 1; - return(8); -} - -static int op_sb1l(void) /* SET 1,L */ -{ - L |= 2; - return(8); -} - -static int op_sb2l(void) /* SET 2,L */ -{ - L |= 4; - return(8); -} - -static int op_sb3l(void) /* SET 3,L */ -{ - L |= 8; - return(8); -} - -static int op_sb4l(void) /* SET 4,L */ -{ - L |= 16; - return(8); -} - -static int op_sb5l(void) /* SET 5,L */ -{ - L |= 32; - return(8); -} - -static int op_sb6l(void) /* SET 6,L */ -{ - L |= 64; - return(8); -} - -static int op_sb7l(void) /* SET 7,L */ -{ - L |= 128; - return(8); -} - -static int op_sb0hl(void) /* SET 0,(HL) */ -{ - *(ram + (H << 8) + L) |= 1; - return(15); -} - -static int op_sb1hl(void) /* SET 1,(HL) */ -{ - *(ram + (H << 8) + L) |= 2; - return(15); -} - -static int op_sb2hl(void) /* SET 2,(HL) */ -{ - *(ram + (H << 8) + L) |= 4; - return(15); -} - -static int op_sb3hl(void) /* SET 3,(HL) */ -{ - *(ram + (H << 8) + L) |= 8; - return(15); -} - -static int op_sb4hl(void) /* SET 4,(HL) */ -{ - *(ram + (H << 8) + L) |= 16; - return(15); -} - -static int op_sb5hl(void) /* SET 5,(HL) */ -{ - *(ram + (H << 8) + L) |= 32; - return(15); -} - -static int op_sb6hl(void) /* SET 6,(HL) */ -{ - *(ram + (H << 8) + L) |= 64; - return(15); -} - -static int op_sb7hl(void) /* SET 7,(HL) */ -{ - *(ram + (H << 8) + L) |= 128; - return(15); -} - -static int op_rb0a(void) /* RES 0,A */ -{ - A &= ~1; - return(8); -} - -static int op_rb1a(void) /* RES 1,A */ -{ - A &= ~2; - return(8); -} - -static int op_rb2a(void) /* RES 2,A */ -{ - A &= ~4; - return(8); -} - -static int op_rb3a(void) /* RES 3,A */ -{ - A &= ~8; - return(8); -} - -static int op_rb4a(void) /* RES 4,A */ -{ - A &= ~16; - return(8); -} - -static int op_rb5a(void) /* RES 5,A */ -{ - A &= ~32; - return(8); -} - -static int op_rb6a(void) /* RES 6,A */ -{ - A &= ~64; - return(8); -} - -static int op_rb7a(void) /* RES 7,A */ -{ - A &= ~128; - return(8); -} - -static int op_rb0b(void) /* RES 0,B */ -{ - B &= ~1; - return(8); -} - -static int op_rb1b(void) /* RES 1,B */ -{ - B &= ~2; - return(8); -} - -static int op_rb2b(void) /* RES 2,B */ -{ - B &= ~4; - return(8); -} - -static int op_rb3b(void) /* RES 3,B */ -{ - B &= ~8; - return(8); -} - -static int op_rb4b(void) /* RES 4,B */ -{ - B &= ~16; - return(8); -} - -static int op_rb5b(void) /* RES 5,B */ -{ - B &= ~32; - return(8); -} - -static int op_rb6b(void) /* RES 6,B */ -{ - B &= ~64; - return(8); -} - -static int op_rb7b(void) /* RES 7,B */ -{ - B &= ~128; - return(8); -} - -static int op_rb0c(void) /* RES 0,C */ -{ - C &= ~1; - return(8); -} - -static int op_rb1c(void) /* RES 1,C */ -{ - C &= ~2; - return(8); -} - -static int op_rb2c(void) /* RES 2,C */ -{ - C &= ~4; - return(8); -} - -static int op_rb3c(void) /* RES 3,C */ -{ - C &= ~8; - return(8); -} - -static int op_rb4c(void) /* RES 4,C */ -{ - C &= ~16; - return(8); -} - -static int op_rb5c(void) /* RES 5,C */ -{ - C &= ~32; - return(8); -} - -static int op_rb6c(void) /* RES 6,C */ -{ - C &= ~64; - return(8); -} - -static int op_rb7c(void) /* RES 7,C */ -{ - C &= ~128; - return(8); -} - -static int op_rb0d(void) /* RES 0,D */ -{ - D &= ~1; - return(8); -} - -static int op_rb1d(void) /* RES 1,D */ -{ - D &= ~2; - return(8); -} - -static int op_rb2d(void) /* RES 2,D */ -{ - D &= ~4; - return(8); -} - -static int op_rb3d(void) /* RES 3,D */ -{ - D &= ~8; - return(8); -} - -static int op_rb4d(void) /* RES 4,D */ -{ - D &= ~16; - return(8); -} - -static int op_rb5d(void) /* RES 5,D */ -{ - D &= ~32; - return(8); -} - -static int op_rb6d(void) /* RES 6,D */ -{ - D &= ~64; - return(8); -} - -static int op_rb7d(void) /* RES 7,D */ -{ - D &= ~128; - return(8); -} - -static int op_rb0e(void) /* RES 0,E */ -{ - E &= ~1; - return(8); -} - -static int op_rb1e(void) /* RES 1,E */ -{ - E &= ~2; - return(8); -} - -static int op_rb2e(void) /* RES 2,E */ -{ - E &= ~4; - return(8); -} - -static int op_rb3e(void) /* RES 3,E */ -{ - E &= ~8; - return(8); -} - -static int op_rb4e(void) /* RES 4,E */ -{ - E &= ~16; - return(8); -} - -static int op_rb5e(void) /* RES 5,E */ -{ - E &= ~32; - return(8); -} - -static int op_rb6e(void) /* RES 6,E */ -{ - E &= ~64; - return(8); -} - -static int op_rb7e(void) /* RES 7,E */ -{ - E &= ~128; - return(8); -} - -static int op_rb0h(void) /* RES 0,H */ -{ - H &= ~1; - return(8); -} - -static int op_rb1h(void) /* RES 1,H */ -{ - H &= ~2; - return(8); -} - -static int op_rb2h(void) /* RES 2,H */ -{ - H &= ~4; - return(8); -} - -static int op_rb3h(void) /* RES 3,H */ -{ - H &= ~8; - return(8); -} - -static int op_rb4h(void) /* RES 4,H */ -{ - H &= ~16; - return(8); -} - -static int op_rb5h(void) /* RES 5,H */ -{ - H &= ~32; - return(8); -} - -static int op_rb6h(void) /* RES 6,H */ -{ - H &= ~64; - return(8); -} - -static int op_rb7h(void) /* RES 7,H */ -{ - H &= ~128; - return(8); -} - -static int op_rb0l(void) /* RES 0,L */ -{ - L &= ~1; - return(8); -} - -static int op_rb1l(void) /* RES 1,L */ -{ - L &= ~2; - return(8); -} - -static int op_rb2l(void) /* RES 2,L */ -{ - L &= ~4; - return(8); -} - -static int op_rb3l(void) /* RES 3,L */ -{ - L &= ~8; - return(8); -} - -static int op_rb4l(void) /* RES 4,L */ -{ - L &= ~16; - return(8); -} - -static int op_rb5l(void) /* RES 5,L */ -{ - L &= ~32; - return(8); -} - -static int op_rb6l(void) /* RES 6,L */ -{ - L &= ~64; - return(8); -} - -static int op_rb7l(void) /* RES 7,L */ -{ - L &= ~128; - return(8); -} - -static int op_rb0hl(void) /* RES 0,(HL) */ -{ - *(ram + (H << 8) + L) &= ~1; - return(15); -} - -static int op_rb1hl(void) /* RES 1,(HL) */ -{ - *(ram + (H << 8) + L) &= ~2; - return(15); -} - -static int op_rb2hl(void) /* RES 2,(HL) */ -{ - *(ram + (H << 8) + L) &= ~4; - return(15); -} - -static int op_rb3hl(void) /* RES 3,(HL) */ -{ - *(ram + (H << 8) + L) &= ~8; - return(15); -} - -static int op_rb4hl(void) /* RES 4,(HL) */ -{ - *(ram + (H << 8) + L) &= ~16; - return(15); -} - -static int op_rb5hl(void) /* RES 5,(HL) */ -{ - *(ram + (H << 8) + L) &= ~32; - return(15); -} - -static int op_rb6hl(void) /* RES 6,(HL) */ -{ - *(ram + (H << 8) + L) &= ~64; - return(15); -} - -static int op_rb7hl(void) /* RES 7,(HL) */ -{ - *(ram + (H << 8) + L) &= ~128; - return(15); -} - -static int op_tb0a(void) /* BIT 0,A */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (A & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb1a(void) /* BIT 1,A */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (A & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb2a(void) /* BIT 2,A */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (A & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb3a(void) /* BIT 3,A */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (A & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb4a(void) /* BIT 4,A */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (A & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb5a(void) /* BIT 5,A */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (A & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb6a(void) /* BIT 6,A */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (A & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb7a(void) /* BIT 7,A */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (A & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(8); -} - -static int op_tb0b(void) /* BIT 0,B */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (B & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb1b(void) /* BIT 1,B */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (B & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb2b(void) /* BIT 2,B */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (B & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb3b(void) /* BIT 3,B */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (B & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb4b(void) /* BIT 4,B */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (B & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb5b(void) /* BIT 5,B */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (B & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb6b(void) /* BIT 6,B */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (B & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb7b(void) /* BIT 7,B */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (B & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(8); -} - -static int op_tb0c(void) /* BIT 0,C */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (C & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb1c(void) /* BIT 1,C */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (C & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb2c(void) /* BIT 2,C */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (C & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb3c(void) /* BIT 3,C */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (C & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb4c(void) /* BIT 4,C */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (C & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb5c(void) /* BIT 5,C */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (C & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb6c(void) /* BIT 6,C */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (C & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb7c(void) /* BIT 7,C */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (C & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(8); -} - -static int op_tb0d(void) /* BIT 0,D */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (D & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb1d(void) /* BIT 1,D */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (D & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb2d(void) /* BIT 2,D */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (D & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb3d(void) /* BIT 3,D */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (D & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb4d(void) /* BIT 4,D */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (D & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb5d(void) /* BIT 5,D */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (D & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb6d(void) /* BIT 6,D */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (D & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb7d(void) /* BIT 7,D */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (D & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(8); -} - -static int op_tb0e(void) /* BIT 0,E */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (E & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb1e(void) /* BIT 1,E */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (E & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb2e(void) /* BIT 2,E */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (E & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb3e(void) /* BIT 3,E */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (E & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb4e(void) /* BIT 4,E */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (E & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb5e(void) /* BIT 5,E */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (E & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb6e(void) /* BIT 6,E */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (E & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb7e(void) /* BIT 7,E */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (E & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(8); -} - -static int op_tb0h(void) /* BIT 0,H */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (H & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb1h(void) /* BIT 1,H */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (H & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb2h(void) /* BIT 2,H */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (H & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb3h(void) /* BIT 3,H */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (H & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb4h(void) /* BIT 4,H */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (H & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb5h(void) /* BIT 5,H */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (H & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb6h(void) /* BIT 6,H */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (H & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb7h(void) /* BIT 7,H */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (H & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(8); -} - -static int op_tb0l(void) /* BIT 0,L */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (L & 1) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb1l(void) /* BIT 1,L */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (L & 2) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb2l(void) /* BIT 2,L */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (L & 4) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb3l(void) /* BIT 3,L */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (L & 8) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb4l(void) /* BIT 4,L */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (L & 16) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb5l(void) /* BIT 5,L */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (L & 32) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb6l(void) /* BIT 6,L */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (L & 64) ? (F &= ~(Z_FLAG | P_FLAG)) : (F |= (Z_FLAG | P_FLAG)); - return(8); -} - -static int op_tb7l(void) /* BIT 7,L */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (L & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(8); -} - -static int op_tb0hl(void) /* BIT 0,(HL) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + (H << 8) + L) & 1) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(12); -} - -static int op_tb1hl(void) /* BIT 1,(HL) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + (H << 8) + L) & 2) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(12); -} - -static int op_tb2hl(void) /* BIT 2,(HL) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + (H << 8) + L) & 4) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(12); -} - -static int op_tb3hl(void) /* BIT 3,(HL) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + (H << 8) + L) & 8) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(12); -} - -static int op_tb4hl(void) /* BIT 4,(HL) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + (H << 8) + L) & 16) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(12); -} - -static int op_tb5hl(void) /* BIT 5,(HL) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + (H << 8) + L) & 32) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(12); -} - -static int op_tb6hl(void) /* BIT 6,(HL) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + (H << 8) + L) & 64) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(12); -} - -static int op_tb7hl(void) /* BIT 7,(HL) */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (*(ram + (H << 8) + L) & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(12); -} diff --git a/emu/z80pack-1.9/z80sim/sim2.o b/emu/z80pack-1.9/z80sim/sim2.o deleted file mode 100644 index 3183a5e..0000000 Binary files a/emu/z80pack-1.9/z80sim/sim2.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/sim3.c b/emu/z80pack-1.9/z80sim/sim3.c deleted file mode 100644 index e7940f9..0000000 --- a/emu/z80pack-1.9/z80sim/sim3.c +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * Like the function "cpu()" this one emulates multi byte opcodes - * starting with 0xdd - */ - -#include "sim.h" -#include "simglb.h" - -static int trap_dd(void); -static int op_popix(void), op_pusix(void); -static int op_jpix(void); -static int op_exspx(void); -static int op_ldspx(void); -static int op_ldixnn(void), op_ldixinn(void), op_ldinx(void); -static int op_adaxd(void), op_acaxd(void), op_suaxd(void), op_scaxd(void); -static int op_andxd(void), op_xorxd(void), op_orxd(void), op_cpxd(void); -static int op_decxd(void), op_incxd(void); -static int op_addxb(void), op_addxd(void), op_addxs(void), op_addxx(); -static int op_incix(void), op_decix(void); -static int op_ldaxd(void), op_ldbxd(void), op_ldcxd(void); -static int op_lddxd(), op_ldexd(void); -static int op_ldhxd(void), op_ldlxd(void); -static int op_ldxda(void), op_ldxdb(void), op_ldxdc(void); -static int op_ldxdd(), op_ldxde(void); -static int op_ldxdh(void), op_ldxdl(void), op_ldxdn(void); -extern int op_ddcb_handel(void); - -long op_dd_handel(void) -{ - register int t; - - static int (*op_dd[256]) (void) = { - trap_dd, /* 0x00 */ - trap_dd, /* 0x01 */ - trap_dd, /* 0x02 */ - trap_dd, /* 0x03 */ - trap_dd, /* 0x04 */ - trap_dd, /* 0x05 */ - trap_dd, /* 0x06 */ - trap_dd, /* 0x07 */ - trap_dd, /* 0x08 */ - op_addxb, /* 0x09 */ - trap_dd, /* 0x0a */ - trap_dd, /* 0x0b */ - trap_dd, /* 0x0c */ - trap_dd, /* 0x0d */ - trap_dd, /* 0x0e */ - trap_dd, /* 0x0f */ - trap_dd, /* 0x10 */ - trap_dd, /* 0x11 */ - trap_dd, /* 0x12 */ - trap_dd, /* 0x13 */ - trap_dd, /* 0x14 */ - trap_dd, /* 0x15 */ - trap_dd, /* 0x16 */ - trap_dd, /* 0x17 */ - trap_dd, /* 0x18 */ - op_addxd, /* 0x19 */ - trap_dd, /* 0x1a */ - trap_dd, /* 0x1b */ - trap_dd, /* 0x1c */ - trap_dd, /* 0x1d */ - trap_dd, /* 0x1e */ - trap_dd, /* 0x1f */ - trap_dd, /* 0x20 */ - op_ldixnn, /* 0x21 */ - op_ldinx, /* 0x22 */ - op_incix, /* 0x23 */ - trap_dd, /* 0x24 */ - trap_dd, /* 0x25 */ - trap_dd, /* 0x26 */ - trap_dd, /* 0x27 */ - trap_dd, /* 0x28 */ - op_addxx, /* 0x29 */ - op_ldixinn, /* 0x2a */ - op_decix, /* 0x2b */ - trap_dd, /* 0x2c */ - trap_dd, /* 0x2d */ - trap_dd, /* 0x2e */ - trap_dd, /* 0x2f */ - trap_dd, /* 0x30 */ - trap_dd, /* 0x31 */ - trap_dd, /* 0x32 */ - trap_dd, /* 0x33 */ - op_incxd, /* 0x34 */ - op_decxd, /* 0x35 */ - op_ldxdn, /* 0x36 */ - trap_dd, /* 0x37 */ - trap_dd, /* 0x38 */ - op_addxs, /* 0x39 */ - trap_dd, /* 0x3a */ - trap_dd, /* 0x3b */ - trap_dd, /* 0x3c */ - trap_dd, /* 0x3d */ - trap_dd, /* 0x3e */ - trap_dd, /* 0x3f */ - trap_dd, /* 0x40 */ - trap_dd, /* 0x41 */ - trap_dd, /* 0x42 */ - trap_dd, /* 0x43 */ - trap_dd, /* 0x44 */ - trap_dd, /* 0x45 */ - op_ldbxd, /* 0x46 */ - trap_dd, /* 0x47 */ - trap_dd, /* 0x48 */ - trap_dd, /* 0x49 */ - trap_dd, /* 0x4a */ - trap_dd, /* 0x4b */ - trap_dd, /* 0x4c */ - trap_dd, /* 0x4d */ - op_ldcxd, /* 0x4e */ - trap_dd, /* 0x4f */ - trap_dd, /* 0x50 */ - trap_dd, /* 0x51 */ - trap_dd, /* 0x52 */ - trap_dd, /* 0x53 */ - trap_dd, /* 0x54 */ - trap_dd, /* 0x55 */ - op_lddxd, /* 0x56 */ - trap_dd, /* 0x57 */ - trap_dd, /* 0x58 */ - trap_dd, /* 0x59 */ - trap_dd, /* 0x5a */ - trap_dd, /* 0x5b */ - trap_dd, /* 0x5c */ - trap_dd, /* 0x5d */ - op_ldexd, /* 0x5e */ - trap_dd, /* 0x5f */ - trap_dd, /* 0x60 */ - trap_dd, /* 0x61 */ - trap_dd, /* 0x62 */ - trap_dd, /* 0x63 */ - trap_dd, /* 0x64 */ - trap_dd, /* 0x65 */ - op_ldhxd, /* 0x66 */ - trap_dd, /* 0x67 */ - trap_dd, /* 0x68 */ - trap_dd, /* 0x69 */ - trap_dd, /* 0x6a */ - trap_dd, /* 0x6b */ - trap_dd, /* 0x6c */ - trap_dd, /* 0x6d */ - op_ldlxd, /* 0x6e */ - trap_dd, /* 0x6f */ - op_ldxdb, /* 0x70 */ - op_ldxdc, /* 0x71 */ - op_ldxdd, /* 0x72 */ - op_ldxde, /* 0x73 */ - op_ldxdh, /* 0x74 */ - op_ldxdl, /* 0x75 */ - trap_dd, /* 0x76 */ - op_ldxda, /* 0x77 */ - trap_dd, /* 0x78 */ - trap_dd, /* 0x79 */ - trap_dd, /* 0x7a */ - trap_dd, /* 0x7b */ - trap_dd, /* 0x7c */ - trap_dd, /* 0x7d */ - op_ldaxd, /* 0x7e */ - trap_dd, /* 0x7f */ - trap_dd, /* 0x80 */ - trap_dd, /* 0x81 */ - trap_dd, /* 0x82 */ - trap_dd, /* 0x83 */ - trap_dd, /* 0x84 */ - trap_dd, /* 0x85 */ - op_adaxd, /* 0x86 */ - trap_dd, /* 0x87 */ - trap_dd, /* 0x88 */ - trap_dd, /* 0x89 */ - trap_dd, /* 0x8a */ - trap_dd, /* 0x8b */ - trap_dd, /* 0x8c */ - trap_dd, /* 0x8d */ - op_acaxd, /* 0x8e */ - trap_dd, /* 0x8f */ - trap_dd, /* 0x90 */ - trap_dd, /* 0x91 */ - trap_dd, /* 0x92 */ - trap_dd, /* 0x93 */ - trap_dd, /* 0x94 */ - trap_dd, /* 0x95 */ - op_suaxd, /* 0x96 */ - trap_dd, /* 0x97 */ - trap_dd, /* 0x98 */ - trap_dd, /* 0x99 */ - trap_dd, /* 0x9a */ - trap_dd, /* 0x9b */ - trap_dd, /* 0x9c */ - trap_dd, /* 0x9d */ - op_scaxd, /* 0x9e */ - trap_dd, /* 0x9f */ - trap_dd, /* 0xa0 */ - trap_dd, /* 0xa1 */ - trap_dd, /* 0xa2 */ - trap_dd, /* 0xa3 */ - trap_dd, /* 0xa4 */ - trap_dd, /* 0xa5 */ - op_andxd, /* 0xa6 */ - trap_dd, /* 0xa7 */ - trap_dd, /* 0xa8 */ - trap_dd, /* 0xa9 */ - trap_dd, /* 0xaa */ - trap_dd, /* 0xab */ - trap_dd, /* 0xac */ - trap_dd, /* 0xad */ - op_xorxd, /* 0xae */ - trap_dd, /* 0xaf */ - trap_dd, /* 0xb0 */ - trap_dd, /* 0xb1 */ - trap_dd, /* 0xb2 */ - trap_dd, /* 0xb3 */ - trap_dd, /* 0xb4 */ - trap_dd, /* 0xb5 */ - op_orxd, /* 0xb6 */ - trap_dd, /* 0xb7 */ - trap_dd, /* 0xb8 */ - trap_dd, /* 0xb9 */ - trap_dd, /* 0xba */ - trap_dd, /* 0xbb */ - trap_dd, /* 0xbc */ - trap_dd, /* 0xbd */ - op_cpxd, /* 0xbe */ - trap_dd, /* 0xbf */ - trap_dd, /* 0xc0 */ - trap_dd, /* 0xc1 */ - trap_dd, /* 0xc2 */ - trap_dd, /* 0xc3 */ - trap_dd, /* 0xc4 */ - trap_dd, /* 0xc5 */ - trap_dd, /* 0xc6 */ - trap_dd, /* 0xc7 */ - trap_dd, /* 0xc8 */ - trap_dd, /* 0xc9 */ - trap_dd, /* 0xca */ - op_ddcb_handel, /* 0xcb */ - trap_dd, /* 0xcc */ - trap_dd, /* 0xcd */ - trap_dd, /* 0xce */ - trap_dd, /* 0xcf */ - trap_dd, /* 0xd0 */ - trap_dd, /* 0xd1 */ - trap_dd, /* 0xd2 */ - trap_dd, /* 0xd3 */ - trap_dd, /* 0xd4 */ - trap_dd, /* 0xd5 */ - trap_dd, /* 0xd6 */ - trap_dd, /* 0xd7 */ - trap_dd, /* 0xd8 */ - trap_dd, /* 0xd9 */ - trap_dd, /* 0xda */ - trap_dd, /* 0xdb */ - trap_dd, /* 0xdc */ - trap_dd, /* 0xdd */ - trap_dd, /* 0xde */ - trap_dd, /* 0xdf */ - trap_dd, /* 0xe0 */ - op_popix, /* 0xe1 */ - trap_dd, /* 0xe2 */ - op_exspx, /* 0xe3 */ - trap_dd, /* 0xe4 */ - op_pusix, /* 0xe5 */ - trap_dd, /* 0xe6 */ - trap_dd, /* 0xe7 */ - trap_dd, /* 0xe8 */ - op_jpix, /* 0xe9 */ - trap_dd, /* 0xea */ - trap_dd, /* 0xeb */ - trap_dd, /* 0xec */ - trap_dd, /* 0xed */ - trap_dd, /* 0xee */ - trap_dd, /* 0xef */ - trap_dd, /* 0xf0 */ - trap_dd, /* 0xf1 */ - trap_dd, /* 0xf2 */ - trap_dd, /* 0xf3 */ - trap_dd, /* 0xf4 */ - trap_dd, /* 0xf5 */ - trap_dd, /* 0xf6 */ - trap_dd, /* 0xf7 */ - trap_dd, /* 0xf8 */ - op_ldspx, /* 0xf9 */ - trap_dd, /* 0xfa */ - trap_dd, /* 0xfb */ - trap_dd, /* 0xfc */ - trap_dd, /* 0xfd */ - trap_dd, /* 0xfe */ - trap_dd /* 0xff */ - }; - - -#ifdef WANT_TIM - t = (*op_dd[*PC++]) (); /* execute next opcode */ -#else - (*op_dd[*PC++]) (); -#endif - -#ifdef WANT_PCC - if (PC > ram + 65535) /* correct PC overrun */ - PC = ram; -#endif - - return(t); -} - -/* - * This function traps all illegal opcodes following the - * initial 0xdd of a multi byte opcode. - */ -static int trap_dd(void) -{ - cpu_error = OPTRAP2; - cpu_state = STOPPED; - return(0); -} - -static int op_popix(void) /* POP IX */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - IX = *STACK++; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - IX += *STACK++ << 8; - return(14); -} - -static int op_pusix(void) /* PUSH IX */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = IX >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = IX; - return(15); -} - -static int op_jpix(void) /* JP (IX) */ -{ - PC = ram + IX; - return(8); -} - -static int op_exspx(void) /* EX (SP),IX */ -{ - register int i; - - i = *STACK + (*(STACK + 1) << 8); - *STACK = IX; - *(STACK + 1) = IX >> 8; - IX = i; - return(23); -} - -static int op_ldspx(void) /* LD SP,IX */ -{ - STACK = ram + IX; - return(10); -} - -static int op_ldixnn(void) /* LD IX,nn */ -{ - IX = *PC++; - IX += *PC++ << 8; - return(14); -} - -static int op_ldixinn(void) /* LD IX,(nn) */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - IX = *p++; - IX += *p << 8; - return(20); -} - -static int op_ldinx(void) /* LD (nn),IX */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - *p++ = IX; - *p = IX >> 8; - return(20); -} - -static int op_adaxd(void) /* ADD A,(IX+d) */ -{ - register int i; - register BYTE P; - - P = *(ram + IX + (char) *PC++); - ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(19); -} - -static int op_acaxd(void) /* ADC A,(IX+d) */ -{ - register int i, carry; - register BYTE P; - - carry = (F & C_FLAG) ? 1 : 0; - P = *(ram + IX + (char) *PC++); - ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) P + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(19); -} - -static int op_suaxd(void) /* SUB A,(IX+d) */ -{ - register int i; - register BYTE P; - - P = *(ram + IX + (char) *PC++); - ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(19); -} - -static int op_scaxd(void) /* SBC A,(IX+d) */ -{ - register int i, carry; - register BYTE P; - - carry = (F & C_FLAG) ? 1 : 0; - P = *(ram + IX + (char) *PC++); - ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) P - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(19); -} - -static int op_andxd(void) /* AND (IX+d) */ -{ - A &= *(ram + IX + (char) *PC++); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(19); -} - -static int op_xorxd(void) /* XOR (IX+d) */ -{ - A ^= *(ram + IX + (char) *PC++); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(19); -} - -static int op_orxd(void) /* OR (IX+d) */ -{ - A |= *(ram + IX + (char) *PC++); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(19); -} - -static int op_cpxd(void) /* CP (IX+d) */ -{ - register int i; - register BYTE P; - - P = *(ram + IX + (char) *PC++); - ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(19); -} - -static int op_incxd(void) /* INC (IX+d) */ -{ - register BYTE *p; - - p = ram + IX + (char) *PC++; - ((*p & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (*p)++; - (*p == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(23); -} - -static int op_decxd(void) /* DEC (IX+d) */ -{ - register BYTE *p; - - p = ram + IX + (char) *PC++; - (((*p - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (*p)--; - (*p == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(23); -} - -static int op_addxb(void) /* ADD IX,BC */ -{ - register int carry; - BYTE ixl = IX & 0xff; - BYTE ixh = IX >> 8; - - carry = (ixl + C > 255) ? 1 : 0; - ixl += C; - ((ixh & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (ixh + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - ixh += B + carry; - IX = (ixh << 8) + ixl; - F &= ~N_FLAG; - return(15); -} - -static int op_addxd(void) /* ADD IX,DE */ -{ - register int carry; - BYTE ixl = IX & 0xff; - BYTE ixh = IX >> 8; - - carry = (ixl + E > 255) ? 1 : 0; - ixl += E; - ((ixh & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (ixh + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - ixh += D + carry; - IX = (ixh << 8) + ixl; - F &= ~N_FLAG; - return(15); -} - -static int op_addxs(void) /* ADD IX,SP */ -{ - register int carry; - BYTE ixl = IX & 0xff; - BYTE ixh = IX >> 8; - BYTE spl = (STACK - ram) & 0xff; - BYTE sph = (STACK - ram) >> 8; - - carry = (ixl + spl > 255) ? 1 : 0; - ixl += spl; - ((ixh & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (ixh + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - ixh += sph + carry; - IX = (ixh << 8) + ixl; - F &= ~N_FLAG; - return(15); -} - -static int op_addxx(void) /* ADD IX,IX */ -{ - register int carry; - BYTE ixl = IX & 0xff; - BYTE ixh = IX >> 8; - - carry = (ixl << 1 > 255) ? 1 : 0; - ixl <<= 1; - ((ixh & 0xf) + (ixh & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (ixh + ixh + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - ixh += ixh + carry; - IX = (ixh << 8) + ixl; - F &= ~N_FLAG; - return(15); -} - -static int op_incix(void) /* INC IX */ -{ - IX++; - return(10); -} - -static int op_decix(void) /* DEC IX */ -{ - IX--; - return(10); -} - -static int op_ldaxd(void) /* LD A,(IX+d) */ -{ - A = *(IX + (char) *PC++ + ram); - return(19); -} - -static int op_ldbxd(void) /* LD B,(IX+d) */ -{ - B = *(IX + (char) *PC++ + ram); - return(19); -} - -static int op_ldcxd(void) /* LD C,(IX+d) */ -{ - C = *(IX + (char) *PC++ + ram); - return(19); -} - -static int op_lddxd(void) /* LD D,(IX+d) */ -{ - D = *(IX + (char) *PC++ + ram); - return(19); -} - -static int op_ldexd(void) /* LD E,(IX+d) */ -{ - E = *(IX + (char) *PC++ + ram); - return(19); -} - -static int op_ldhxd(void) /* LD H,(IX+d) */ -{ - H = *(IX + (char) *PC++ + ram); - return(19); -} - -static int op_ldlxd(void) /* LD L,(IX+d) */ -{ - L = *(IX + (char) *PC++ + ram); - return(19); -} - -static int op_ldxda(void) /* LD (IX+d),A */ -{ - *(IX + (char) *PC++ + ram) = A; - return(19); -} - -static int op_ldxdb(void) /* LD (IX+d),B */ -{ - *(IX + (char) *PC++ + ram) = B; - return(19); -} - -static int op_ldxdc(void) /* LD (IX+d),C */ -{ - *(IX + (char) *PC++ + ram) = C; - return(19); -} - -static int op_ldxdd(void) /* LD (IX+d),D */ -{ - *(IX + (char) *PC++ + ram) = D; - return(19); -} - -static int op_ldxde(void) /* LD (IX+d),E */ -{ - *(IX + (char) *PC++ + ram) = E; - return(19); -} - -static int op_ldxdh(void) /* LD (IX+d),H */ -{ - *(IX + (char) *PC++ + ram) = H; - return(19); -} - -static int op_ldxdl(void) /* LD (IX+d),L */ -{ - *(IX + (char) *PC++ + ram) = L; - return(19); -} - -static int op_ldxdn(void) /* LD (IX+d),n */ -{ - register int d; - - d = (char) *PC++; - *(IX + d + ram) = *PC++; - return(19); -} diff --git a/emu/z80pack-1.9/z80sim/sim3.o b/emu/z80pack-1.9/z80sim/sim3.o deleted file mode 100644 index a481850..0000000 Binary files a/emu/z80pack-1.9/z80sim/sim3.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/sim4.c b/emu/z80pack-1.9/z80sim/sim4.c deleted file mode 100644 index 1785c71..0000000 --- a/emu/z80pack-1.9/z80sim/sim4.c +++ /dev/null @@ -1,1151 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * Like the function "cpu()" this one emulates multi byte opcodes - * starting with 0xed - */ - -#include "sim.h" -#include "simglb.h" - -static int trap_ed(void); -static int op_im0(void), op_im1(void), op_im2(void); -static int op_reti(void), op_retn(void); -static int op_neg(void); -static int op_inaic(void), op_inbic(void), op_incic(void); -static int op_indic(void), op_ineic(void); -static int op_inhic(void), op_inlic(void); -static int op_outca(void), op_outcb(void), op_outcc(void); -static int op_outcd(void), op_outce(void); -static int op_outch(void), op_outcl(void); -static int op_ini(void), op_inir(void), op_ind(void), op_indr(void); -static int op_outi(void), op_otir(void), op_outd(void), op_otdr(void); -static int op_ldai(void), op_ldar(void), op_ldia(void), op_ldra(void); -static int op_ldbcinn(void), op_lddeinn(void), op_ldspinn(void); -static int op_ldinbc(void), op_ldinde(void), op_ldinsp(void); -static int op_adchb(void), op_adchd(void), op_adchh(void), op_adchs(void); -static int op_sbchb(void), op_sbchd(void), op_sbchh(void), op_sbchs(void); -static int op_ldi(void), op_ldir(void), op_ldd(void), op_lddr(void); -static int op_cpi(void), op_cpir(void), op_cpdop(void), op_cpdr(void); -static int op_oprld(void), op_oprrd(void); - -int op_ed_handel(void) -{ - register int t; - - static int (*op_ed[256]) (void) = { - trap_ed, /* 0x00 */ - trap_ed, /* 0x01 */ - trap_ed, /* 0x02 */ - trap_ed, /* 0x03 */ - trap_ed, /* 0x04 */ - trap_ed, /* 0x05 */ - trap_ed, /* 0x06 */ - trap_ed, /* 0x07 */ - trap_ed, /* 0x08 */ - trap_ed, /* 0x09 */ - trap_ed, /* 0x0a */ - trap_ed, /* 0x0b */ - trap_ed, /* 0x0c */ - trap_ed, /* 0x0d */ - trap_ed, /* 0x0e */ - trap_ed, /* 0x0f */ - trap_ed, /* 0x10 */ - trap_ed, /* 0x11 */ - trap_ed, /* 0x12 */ - trap_ed, /* 0x13 */ - trap_ed, /* 0x14 */ - trap_ed, /* 0x15 */ - trap_ed, /* 0x16 */ - trap_ed, /* 0x17 */ - trap_ed, /* 0x18 */ - trap_ed, /* 0x19 */ - trap_ed, /* 0x1a */ - trap_ed, /* 0x1b */ - trap_ed, /* 0x1c */ - trap_ed, /* 0x1d */ - trap_ed, /* 0x1e */ - trap_ed, /* 0x1f */ - trap_ed, /* 0x20 */ - trap_ed, /* 0x21 */ - trap_ed, /* 0x22 */ - trap_ed, /* 0x23 */ - trap_ed, /* 0x24 */ - trap_ed, /* 0x25 */ - trap_ed, /* 0x26 */ - trap_ed, /* 0x27 */ - trap_ed, /* 0x28 */ - trap_ed, /* 0x29 */ - trap_ed, /* 0x2a */ - trap_ed, /* 0x2b */ - trap_ed, /* 0x2c */ - trap_ed, /* 0x2d */ - trap_ed, /* 0x2e */ - trap_ed, /* 0x2f */ - trap_ed, /* 0x30 */ - trap_ed, /* 0x31 */ - trap_ed, /* 0x32 */ - trap_ed, /* 0x33 */ - trap_ed, /* 0x34 */ - trap_ed, /* 0x35 */ - trap_ed, /* 0x36 */ - trap_ed, /* 0x37 */ - trap_ed, /* 0x38 */ - trap_ed, /* 0x39 */ - trap_ed, /* 0x3a */ - trap_ed, /* 0x3b */ - trap_ed, /* 0x3c */ - trap_ed, /* 0x3d */ - trap_ed, /* 0x3e */ - trap_ed, /* 0x3f */ - op_inbic, /* 0x40 */ - op_outcb, /* 0x41 */ - op_sbchb, /* 0x42 */ - op_ldinbc, /* 0x43 */ - op_neg, /* 0x44 */ - op_retn, /* 0x45 */ - op_im0, /* 0x46 */ - op_ldia, /* 0x47 */ - op_incic, /* 0x48 */ - op_outcc, /* 0x49 */ - op_adchb, /* 0x4a */ - op_ldbcinn, /* 0x4b */ - trap_ed, /* 0x4c */ - op_reti, /* 0x4d */ - trap_ed, /* 0x4e */ - op_ldra, /* 0x4f */ - op_indic, /* 0x50 */ - op_outcd, /* 0x51 */ - op_sbchd, /* 0x52 */ - op_ldinde, /* 0x53 */ - trap_ed, /* 0x54 */ - trap_ed, /* 0x55 */ - op_im1, /* 0x56 */ - op_ldai, /* 0x57 */ - op_ineic, /* 0x58 */ - op_outce, /* 0x59 */ - op_adchd, /* 0x5a */ - op_lddeinn, /* 0x5b */ - trap_ed, /* 0x5c */ - trap_ed, /* 0x5d */ - op_im2, /* 0x5e */ - op_ldar, /* 0x5f */ - op_inhic, /* 0x60 */ - op_outch, /* 0x61 */ - op_sbchh, /* 0x62 */ - trap_ed, /* 0x63 */ - trap_ed, /* 0x64 */ - trap_ed, /* 0x65 */ - trap_ed, /* 0x66 */ - op_oprrd, /* 0x67 */ - op_inlic, /* 0x68 */ - op_outcl, /* 0x69 */ - op_adchh, /* 0x6a */ - trap_ed, /* 0x6b */ - trap_ed, /* 0x6c */ - trap_ed, /* 0x6d */ - trap_ed, /* 0x6e */ - op_oprld, /* 0x6f */ - trap_ed, /* 0x70 */ - trap_ed, /* 0x71 */ - op_sbchs, /* 0x72 */ - op_ldinsp, /* 0x73 */ - trap_ed, /* 0x74 */ - trap_ed, /* 0x75 */ - trap_ed, /* 0x76 */ - trap_ed, /* 0x77 */ - op_inaic, /* 0x78 */ - op_outca, /* 0x79 */ - op_adchs, /* 0x7a */ - op_ldspinn, /* 0x7b */ - trap_ed, /* 0x7c */ - trap_ed, /* 0x7d */ - trap_ed, /* 0x7e */ - trap_ed, /* 0x7f */ - trap_ed, /* 0x80 */ - trap_ed, /* 0x81 */ - trap_ed, /* 0x82 */ - trap_ed, /* 0x83 */ - trap_ed, /* 0x84 */ - trap_ed, /* 0x85 */ - trap_ed, /* 0x86 */ - trap_ed, /* 0x87 */ - trap_ed, /* 0x88 */ - trap_ed, /* 0x89 */ - trap_ed, /* 0x8a */ - trap_ed, /* 0x8b */ - trap_ed, /* 0x8c */ - trap_ed, /* 0x8d */ - trap_ed, /* 0x8e */ - trap_ed, /* 0x8f */ - trap_ed, /* 0x90 */ - trap_ed, /* 0x91 */ - trap_ed, /* 0x92 */ - trap_ed, /* 0x93 */ - trap_ed, /* 0x94 */ - trap_ed, /* 0x95 */ - trap_ed, /* 0x96 */ - trap_ed, /* 0x97 */ - trap_ed, /* 0x98 */ - trap_ed, /* 0x99 */ - trap_ed, /* 0x9a */ - trap_ed, /* 0x9b */ - trap_ed, /* 0x9c */ - trap_ed, /* 0x9d */ - trap_ed, /* 0x9e */ - trap_ed, /* 0x9f */ - op_ldi, /* 0xa0 */ - op_cpi, /* 0xa1 */ - op_ini, /* 0xa2 */ - op_outi, /* 0xa3 */ - trap_ed, /* 0xa4 */ - trap_ed, /* 0xa5 */ - trap_ed, /* 0xa6 */ - trap_ed, /* 0xa7 */ - op_ldd, /* 0xa8 */ - op_cpdop, /* 0xa9 */ - op_ind, /* 0xaa */ - op_outd, /* 0xab */ - trap_ed, /* 0xac */ - trap_ed, /* 0xad */ - trap_ed, /* 0xae */ - trap_ed, /* 0xaf */ - op_ldir, /* 0xb0 */ - op_cpir, /* 0xb1 */ - op_inir, /* 0xb2 */ - op_otir, /* 0xb3 */ - trap_ed, /* 0xb4 */ - trap_ed, /* 0xb5 */ - trap_ed, /* 0xb6 */ - trap_ed, /* 0xb7 */ - op_lddr, /* 0xb8 */ - op_cpdr, /* 0xb9 */ - op_indr, /* 0xba */ - op_otdr, /* 0xbb */ - trap_ed, /* 0xbc */ - trap_ed, /* 0xbd */ - trap_ed, /* 0xbe */ - trap_ed, /* 0xbf */ - trap_ed, /* 0xc0 */ - trap_ed, /* 0xc1 */ - trap_ed, /* 0xc2 */ - trap_ed, /* 0xc3 */ - trap_ed, /* 0xc4 */ - trap_ed, /* 0xc5 */ - trap_ed, /* 0xc6 */ - trap_ed, /* 0xc7 */ - trap_ed, /* 0xc8 */ - trap_ed, /* 0xc9 */ - trap_ed, /* 0xca */ - trap_ed, /* 0xcb */ - trap_ed, /* 0xcc */ - trap_ed, /* 0xcd */ - trap_ed, /* 0xce */ - trap_ed, /* 0xcf */ - trap_ed, /* 0xd0 */ - trap_ed, /* 0xd1 */ - trap_ed, /* 0xd2 */ - trap_ed, /* 0xd3 */ - trap_ed, /* 0xd4 */ - trap_ed, /* 0xd5 */ - trap_ed, /* 0xd6 */ - trap_ed, /* 0xd7 */ - trap_ed, /* 0xd8 */ - trap_ed, /* 0xd9 */ - trap_ed, /* 0xda */ - trap_ed, /* 0xdb */ - trap_ed, /* 0xdc */ - trap_ed, /* 0xdd */ - trap_ed, /* 0xde */ - trap_ed, /* 0xdf */ - trap_ed, /* 0xe0 */ - trap_ed, /* 0xe1 */ - trap_ed, /* 0xe2 */ - trap_ed, /* 0xe3 */ - trap_ed, /* 0xe4 */ - trap_ed, /* 0xe5 */ - trap_ed, /* 0xe6 */ - trap_ed, /* 0xe7 */ - trap_ed, /* 0xe8 */ - trap_ed, /* 0xe9 */ - trap_ed, /* 0xea */ - trap_ed, /* 0xeb */ - trap_ed, /* 0xec */ - trap_ed, /* 0xed */ - trap_ed, /* 0xee */ - trap_ed, /* 0xef */ - trap_ed, /* 0xf0 */ - trap_ed, /* 0xf1 */ - trap_ed, /* 0xf2 */ - trap_ed, /* 0xf3 */ - trap_ed, /* 0xf4 */ - trap_ed, /* 0xf5 */ - trap_ed, /* 0xf6 */ - trap_ed, /* 0xf7 */ - trap_ed, /* 0xf8 */ - trap_ed, /* 0xf9 */ - trap_ed, /* 0xfa */ - trap_ed, /* 0xfb */ - trap_ed, /* 0xfc */ - trap_ed, /* 0xfd */ - trap_ed, /* 0xfe */ - trap_ed /* 0xff */ - }; - -#ifdef WANT_TIM - t = (*op_ed[*PC++]) (); /* execute next opcode */ -#else - (*op_ed[*PC++]) (); -#endif - -#ifdef WANT_PCC - if (PC > ram + 65535) /* correct PC overrun */ - PC = ram; -#endif - - return(t); -} - -/* - * This function traps all illegal opcodes following the - * initial 0xed of a multi byte opcode. - */ -static int trap_ed(void) -{ - cpu_error = OPTRAP2; - cpu_state = STOPPED; - return(0); -} - -static int op_im0(void) /* IM 0 */ -{ - int_mode = 0; - return(8); -} - -static int op_im1(void) /* IM 1 */ -{ - int_mode = 1; - return(8); -} - -static int op_im2(void) /* IM 2 */ -{ - int_mode = 2; - return(8); -} - -static int op_reti(void) /* RETI */ -{ - register unsigned i; - - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - return(14); -} - -static int op_retn(void) /* RETN */ -{ - register unsigned i; - - i = *STACK++; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - i += *STACK++ << 8; -#ifdef WANT_SPC - if (STACK >= ram + 65536L) - STACK = ram; -#endif - PC = ram + i; - if (IFF & 2) - IFF |= 1; - return(14); -} - -static int op_neg(void) /* NEG */ -{ - (A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - (A == 0x80) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (0 - ((char) A & 0xf) < 0) ? (F |= H_FLAG) : (F &= ~H_FLAG); - A = 0 - A; - F |= N_FLAG; - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(8); -} - -static int op_inaic(void) /* IN A,(C) */ -{ - BYTE io_in(); - - A = io_in(C); - F &= ~(N_FLAG | H_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(12); -} - -static int op_inbic(void) /* IN B,(C) */ -{ - BYTE io_in(); - - B = io_in(C); - F &= ~(N_FLAG | H_FLAG); - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (B & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[B]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(12); -} - -static int op_incic(void) /* IN C,(C) */ -{ - BYTE io_in(); - - C = io_in(C); - F &= ~(N_FLAG | H_FLAG); - (C) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (C & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[C]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(12); -} - -static int op_indic(void) /* IN D,(C) */ -{ - BYTE io_in(); - - D = io_in(C); - F &= ~(N_FLAG | H_FLAG); - (D) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (D & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[D]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(12); -} - -static int op_ineic(void) /* IN E,(C) */ -{ - BYTE io_in(); - - E = io_in(C); - F &= ~(N_FLAG | H_FLAG); - (E) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (E & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[E]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(12); -} - -static int op_inhic(void) /* IN H,(C) */ -{ - BYTE io_in(); - - H = io_in(C); - F &= ~(N_FLAG | H_FLAG); - (H) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[H]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(12); -} - -static int op_inlic(void) /* IN L,(C) */ -{ - BYTE io_in(); - - L = io_in(C); - F &= ~(N_FLAG | H_FLAG); - (L) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (L & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[L]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(12); -} - -static int op_outca(void) /* OUT (C),A */ -{ - BYTE io_out(); - - io_out(C, A); - return(12); -} - -static int op_outcb(void) /* OUT (C),B */ -{ - BYTE io_out(); - - io_out(C, B); - return(12); -} - -static int op_outcc(void) /* OUT (C),C */ -{ - BYTE io_out(); - - io_out(C, C); - return(12); -} - -static int op_outcd(void) /* OUT (C),D */ -{ - BYTE io_out(); - - io_out(C, D); - return(12); -} - -static int op_outce(void) /* OUT (C),E */ -{ - BYTE io_out(); - - io_out(C, E); - return(12); -} - -static int op_outch(void) /* OUT (C),H */ -{ - BYTE io_out(); - - io_out(C, H); - return(12); -} - -static int op_outcl(void) /* OUT (C),L */ -{ - BYTE io_out(); - - io_out(C, L); - return(12); -} - -static int op_ini(void) /* INI */ -{ - BYTE io_in(); - - *(ram + (H << 8) + L) = io_in(C); - L++; - if (!L) - H++; - B--; - F |= N_FLAG; - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - return(16); -} - -static int op_inir(void) /* INIR */ -{ - register int t = -21; - register BYTE *d; - BYTE io_in(); - - d = ram + (H << 8) + L; - do { - *d++ = io_in(C); - B--; - t += 21; - } while (B); - H = (d - ram) >> 8; - L = d - ram; - F |= N_FLAG | Z_FLAG; - return(t + 16); -} - -static int op_ind(void) /* IND */ -{ - BYTE io_in(); - - *(ram + (H << 8) + L) = io_in(C); - L--; - if (L == 0xff) - H--; - B--; - F |= N_FLAG; - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - return(16); -} - -static int op_indr(void) /* INDR */ -{ - register int t = -21; - register BYTE *d; - BYTE io_in(); - - d = ram + (H << 8) + L; - do { - *d-- = io_in(C); - B--; - t += 21; - } while (B); - H = (d - ram) >> 8; - L = d - ram; - F |= N_FLAG | Z_FLAG; - return(t + 16); -} - -static int op_outi(void) /* OUTI */ -{ - BYTE io_out(); - - io_out(C, *(ram + (H << 8) * L)); - L++; - if (!L) - H++; - B--; - F |= N_FLAG; - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - return(16); -} - -static int op_otir(void) /* OTIR */ -{ - register int t = -21; - register BYTE *d; - BYTE io_out(); - - d = ram + (H << 8) + L; - do { - io_out(C, *d++); - B--; - t += 21; - } while (B); - H = (d - ram) >> 8; - L = d - ram; - F |= N_FLAG | Z_FLAG; - return(t + 16); -} - -static int op_outd(void) /* OUTD */ -{ - BYTE io_out(); - - io_out(C, *(ram + (H << 8) * L)); - L--; - if (L == 0xff) - H--; - B--; - F |= N_FLAG; - (B) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - return(16); -} - -static int op_otdr(void) /* OTDR */ -{ - register int t = -21; - register BYTE *d; - BYTE io_out(); - - d = ram + (H << 8) + L; - do { - io_out(C, *d--); - B--; - t += 21; - } while (B); - H = (d - ram) >> 8; - L = d - ram; - F |= N_FLAG | Z_FLAG; - return(t + 16); -} - -static int op_ldai(void) /* LD A,I */ -{ - A = I; - F &= ~(N_FLAG | H_FLAG); - (IFF & 2) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(9); -} - -static int op_ldar(void) /* LD A,R */ -{ - A = (BYTE) R; - F &= ~(N_FLAG | H_FLAG); - (IFF & 2) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(9); -} - -static int op_ldia(void) /* LD I,A */ -{ - I = A; - return(9); -} - -static int op_ldra(void) /* LD R,A */ -{ - R = A; - return(9); -} - -static int op_ldbcinn(void) /* LD BC,(nn) */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - C = *p++; - B = *p; - return(20); -} - -static int op_lddeinn(void) /* LD DE,(nn) */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - E = *p++; - D = *p; - return(20); -} - -static int op_ldspinn(void) /* LD SP,(nn) */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - STACK = ram + *p++; - STACK += *p << 8; - return(20); -} - -static int op_ldinbc(void) /* LD (nn),BC */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - *p++ = C; - *p = B; - return(20); -} - -static int op_ldinde(void) /* LD (nn),DE */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - *p++ = E; - *p = D; - return(20); -} - -static int op_ldinsp(void) /* LD (nn),SP */ -{ - register BYTE *p; - register int i; - - p = ram + *PC++; - p += *PC++ << 8; - i = STACK - ram; - *p++ = i; - *p = i >> 8; - return(20); -} - -static int op_adchb(void) /* ADC HL,BC */ -{ - register int carry; - int lcarry; - register WORD hl, bc; - register long i; - - carry = (F & C_FLAG) ? 1 : 0; - lcarry = (L + C > 255) ? 1 : 0; - ((H & 0xf) + (B & 0xf) + carry + lcarry > 0xf) ? (F |= H_FLAG) - : (F &= ~H_FLAG); - hl = (H << 8) + L; - bc = (B << 8) + C; - i = ((long)hl) + ((long)bc) + carry; - ((hl < 0x8000) && (i > 0x7fffL)) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i > 0xffffL) ? (F |= C_FLAG) : (F &= ~C_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - H = i >> 8; - L = i; - F &= ~N_FLAG; - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(15); -} - -static int op_adchd(void) /* ADC HL,DE */ -{ - register int carry; - int lcarry; - register WORD hl, de; - register long i; - - carry = (F & C_FLAG) ? 1 : 0; - lcarry = (L + E > 255) ? 1 : 0; - ((H & 0xf) + (D & 0xf) + carry + lcarry > 0xf) ? (F |= H_FLAG) - : (F &= ~H_FLAG); - hl = (H << 8) + L; - de = (D << 8) + E; - i = ((long)hl) + ((long)de) + carry; - ((hl < 0x8000) && (i > 0x7fffL)) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i > 0xffffL) ? (F |= C_FLAG) : (F &= ~C_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - H = i >> 8; - L = i; - F &= ~N_FLAG; - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(15); -} - -static int op_adchh(void) /* ADC HL,HL */ -{ - register int carry; - int lcarry; - register WORD hl; - register long i; - - carry = (F & C_FLAG) ? 1 : 0; - lcarry = (L + L > 255) ? 1 : 0; - ((H & 0xf) + (H & 0xf) + carry + lcarry > 0xf) ? (F |= H_FLAG) - : (F &= ~H_FLAG); - hl = (H << 8) + L; - i = ((((long)hl) << 1) + carry); - ((hl < 0x8000) && (i > 0x7fffL)) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i > 0xffffL) ? (F |= C_FLAG) : (F &= ~C_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - H = i >> 8; - L = i; - F &= ~N_FLAG; - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(15); -} - -static int op_adchs(void) /* ADC HL,SP */ -{ - register int carry; - int lcarry; - register WORD hl, sp; - register long i; - - carry = (F & C_FLAG) ? 1 : 0; - hl = (H << 8) + L; - sp = STACK - ram; - lcarry = (L + (sp & 0xff) > 255) ? 1 : 0; - ((H & 0xf) + ((sp >> 8) & 0xf) + carry + lcarry > 0xf) ? (F |= H_FLAG) - : (F &= ~H_FLAG); - i = ((long)hl) + ((long)sp) + carry; - ((hl < 0x8000) && (i > 0x7fffL)) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i > 0xffffL) ? (F |= C_FLAG) : (F &= ~C_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - H = i >> 8; - L = i; - F &= ~N_FLAG; - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(15); -} - -static int op_sbchb(void) /* SBC HL,BC */ -{ - register int carry; - int lcarry; - register WORD hl, bc; - register long i; - - carry = (F & C_FLAG) ? 1 : 0; - lcarry = (C > L) ? 1 : 0; - ((B & 0xf) + carry + lcarry > (H & 0xf)) ? (F |= H_FLAG) - : (F &= ~H_FLAG); - hl = (H << 8) + L; - bc = (B << 8) + C; - i = ((long)hl) - ((long)bc) - carry; - ((hl > 0x7fff) && (i < 0x8000L)) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i < 0L) ? (F |= C_FLAG) : (F &= ~C_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - H = i >> 8; - L = i; - F |= N_FLAG; - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(15); -} - -static int op_sbchd(void) /* SBC HL,DE */ -{ - register int carry; - int lcarry; - register WORD hl, de; - register long i; - - carry = (F & C_FLAG) ? 1 : 0; - lcarry = (E > L) ? 1 : 0; - ((D & 0xf) + carry + lcarry > (H & 0xf)) ? (F |= H_FLAG) - : (F &= ~H_FLAG); - hl = (H << 8) + L; - de = (D << 8) + E; - i = ((long)hl) - ((long)de) - carry; - ((hl > 0x7fff) && (i < 0x8000L)) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i < 0L) ? (F |= C_FLAG) : (F &= ~C_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - H = i >> 8; - L = i; - F |= N_FLAG; - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(15); -} - -static int op_sbchh(void) /* SBC HL,HL */ -{ - if (F & C_FLAG) { - F |= S_FLAG | P_FLAG | N_FLAG | C_FLAG | H_FLAG; - F &= ~Z_FLAG; - H = L = 255; - } else { - F |= Z_FLAG | N_FLAG; - F &= ~(S_FLAG | P_FLAG | C_FLAG | H_FLAG); - H = L = 0; - } - return(15); -} - -static int op_sbchs(void) /* SBC HL,SP */ -{ - register int carry; - int lcarry; - register WORD hl, sp; - register long i; - - carry = (F & C_FLAG) ? 1 : 0; - hl = (H << 8) + L; - sp = STACK - ram; - lcarry = ((sp & 0xff) > L) ? 1 : 0; - (((sp >> 8) & 0xf) + carry + lcarry > (H & 0xf)) ? (F |= H_FLAG) - : (F &= ~H_FLAG); - i = ((long)hl) - ((long)sp) - carry; - ((hl > 0x7fff) && (i < 0x8000L)) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i < 0L) ? (F |= C_FLAG) : (F &= ~C_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - H = i >> 8; - L = i; - F |= N_FLAG; - (H & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(15); -} - -static int op_ldi(void) /* LDI */ -{ - *(ram + (D << 8) + E) = *(ram + (H << 8) + L); - E++; - if (!E) - D++; - L++; - if (!L) - H++; - C--; - if (C == 0xff) - B--; - (B | C) ? (F |= P_FLAG) : (F &= ~P_FLAG); - F &= ~(N_FLAG | H_FLAG); - return(16); -} - -static int op_ldir(void) /* LDIR */ -{ - register int t = -21; - register WORD i; - register BYTE *s, *d; - - i = (B << 8) + C; - d = ram + (D << 8) + E; - s = ram + (H << 8) + L; - do { - *d++ = *s++; - t += 21; - } while (--i); - B = C = 0; - D = (d - ram) >> 8; - E = d - ram; - H = (s - ram) >> 8; - L = s - ram; - F &= ~(N_FLAG | P_FLAG | H_FLAG); - return(t + 16); -} - -static int op_ldd(void) /* LDD */ -{ - *(ram + (D << 8) + E) = *(ram + (H << 8) + L); - E--; - if (E == 0xff) - D--; - L--; - if (L == 0xff) - H--; - C--; - if (C == 0xff) - B--; - (B | C) ? (F |= P_FLAG) : (F &= ~P_FLAG); - F &= ~(N_FLAG | H_FLAG); - return(16); -} - -static int op_lddr(void) /* LDDR */ -{ - register int t = -21; - register WORD i; - register BYTE *s, *d; - - i = (B << 8) + C; - d = ram + (D << 8) + E; - s = ram + (H << 8) + L; - do { - *d-- = *s--; - t += 21; - } while (--i); - B = C = 0; - D = (d - ram) >> 8; - E = d - ram; - H = (s - ram) >> 8; - L = s - ram; - F &= ~(N_FLAG | P_FLAG | H_FLAG); - return(t + 16); -} - -static int op_cpi(void) /* CPI */ -{ - register BYTE i; - - i = *(ram + ((H << 8) + L)); - ((i & 0xf) > (A & 0xF)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - i = A - i; - L++; - if (!L) - H++; - C--; - if (C == 0xff) - B--; - F |= N_FLAG; - (B | C) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(16); -} - -static int op_cpir(void) /* CPIR */ - /* H Flag not set!!! */ -{ - register int t = -21; - register BYTE *s; - register BYTE d; - register WORD i; - - i = (B << 8) + C; - s = ram + (H << 8) + L; - do { - d = A - *s++; - t += 21; - } while (--i && d); - F |= N_FLAG; - B = i >> 8; - C = i; - H = (s - ram) >> 8; - L = s - ram; - (i) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (d) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (d & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(t + 16); -} - -static int op_cpdop(void) /* CPD */ -{ - register BYTE i; - - i = *(ram + ((H << 8) + L)); - ((i & 0xf) > (A & 0xF)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - i = A - i; - L--; - if (L == 0xff) - H--; - C--; - if (C == 0xff) - B--; - F |= N_FLAG; - (B | C) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(16); -} - -static int op_cpdr(void) /* CPDR */ - /* H Flag not set!!! */ -{ - register int t = -21; - register BYTE *s; - register BYTE d; - register WORD i; - - i = (B << 8) + C; - s = ram + (H << 8) + L; - do { - d = A - *s--; - t += 21; - } while (--i && d); - F |= N_FLAG; - B = i >> 8; - C = i; - H = (s - ram) >> 8; - L = s - ram; - (i) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (d) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (d & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - return(t + 16); -} - -static int op_oprld(void) /* RLD (HL) */ -{ - register int i, j; - - i = *(ram + (H << 8) + L); - j = A & 0x0f; - A = (A & 0xf0) | (i >> 4); - i = (i << 4) | j; - *(ram + (H << 8) + L) = i; - F &= ~(H_FLAG | N_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(18); -} - -static int op_oprrd(void) /* RRD (HL) */ -{ - register int i, j; - - i = *(ram + (H << 8) + L); - j = A & 0x0f; - A = (A & 0xf0) | (i & 0x0f); - i = (i >> 4) | (j << 4); - *(ram + (H << 8) + L) = i; - F &= ~(H_FLAG | N_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(18); -} diff --git a/emu/z80pack-1.9/z80sim/sim4.o b/emu/z80pack-1.9/z80sim/sim4.o deleted file mode 100644 index cd636e2..0000000 Binary files a/emu/z80pack-1.9/z80sim/sim4.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/sim5.c b/emu/z80pack-1.9/z80sim/sim5.c deleted file mode 100644 index a485feb..0000000 --- a/emu/z80pack-1.9/z80sim/sim5.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * Like the function "cpu()" this one emulates multi byte opcodes - * starting with 0xfd - */ - -#include "sim.h" -#include "simglb.h" - -static int trap_fd(void); -static int op_popiy(void), op_pusiy(void); -static int op_jpiy(void); -static int op_exspy(void); -static int op_ldspy(void); -static int op_ldiynn(void), op_ldiyinn(void), op_ldiny(void); -static int op_adayd(void), op_acayd(void), op_suayd(void), op_scayd(void); -static int op_andyd(void), op_xoryd(void), op_oryd(void), op_cpyd(void); -static int op_decyd(void), op_incyd(void); -static int op_addyb(void), op_addyd(void), op_addys(void), op_addyy(void); -static int op_andyd(void), op_xoryd(void), op_oryd(void), op_cpyd(void); -static int op_decyd(void), op_incyd(void); -static int op_inciy(void), op_deciy(void); -static int op_ldayd(void), op_ldbyd(void), op_ldcyd(void); -static int op_lddyd(void), op_ldeyd(void); -static int op_ldhyd(void), op_ldlyd(void); -static int op_ldyda(void), op_ldydb(void), op_ldydc(void); -static int op_ldydd(void), op_ldyde(void); -static int op_ldydh(void), op_ldydl(void), op_ldydn(void); -extern int op_fdcb_handel(void); - -int op_fd_handel(void) -{ - register int t; - - static int (*op_fd[256]) () = { - trap_fd, /* 0x00 */ - trap_fd, /* 0x01 */ - trap_fd, /* 0x02 */ - trap_fd, /* 0x03 */ - trap_fd, /* 0x04 */ - trap_fd, /* 0x05 */ - trap_fd, /* 0x06 */ - trap_fd, /* 0x07 */ - trap_fd, /* 0x08 */ - op_addyb, /* 0x09 */ - trap_fd, /* 0x0a */ - trap_fd, /* 0x0b */ - trap_fd, /* 0x0c */ - trap_fd, /* 0x0d */ - trap_fd, /* 0x0e */ - trap_fd, /* 0x0f */ - trap_fd, /* 0x10 */ - trap_fd, /* 0x11 */ - trap_fd, /* 0x12 */ - trap_fd, /* 0x13 */ - trap_fd, /* 0x14 */ - trap_fd, /* 0x15 */ - trap_fd, /* 0x16 */ - trap_fd, /* 0x17 */ - trap_fd, /* 0x18 */ - op_addyd, /* 0x19 */ - trap_fd, /* 0x1a */ - trap_fd, /* 0x1b */ - trap_fd, /* 0x1c */ - trap_fd, /* 0x1d */ - trap_fd, /* 0x1e */ - trap_fd, /* 0x1f */ - trap_fd, /* 0x20 */ - op_ldiynn, /* 0x21 */ - op_ldiny, /* 0x22 */ - op_inciy, /* 0x23 */ - trap_fd, /* 0x24 */ - trap_fd, /* 0x25 */ - trap_fd, /* 0x26 */ - trap_fd, /* 0x27 */ - trap_fd, /* 0x28 */ - op_addyy, /* 0x29 */ - op_ldiyinn, /* 0x2a */ - op_deciy, /* 0x2b */ - trap_fd, /* 0x2c */ - trap_fd, /* 0x2d */ - trap_fd, /* 0x2e */ - trap_fd, /* 0x2f */ - trap_fd, /* 0x30 */ - trap_fd, /* 0x31 */ - trap_fd, /* 0x32 */ - trap_fd, /* 0x33 */ - op_incyd, /* 0x34 */ - op_decyd, /* 0x35 */ - op_ldydn, /* 0x36 */ - trap_fd, /* 0x37 */ - trap_fd, /* 0x38 */ - op_addys, /* 0x39 */ - trap_fd, /* 0x3a */ - trap_fd, /* 0x3b */ - trap_fd, /* 0x3c */ - trap_fd, /* 0x3d */ - trap_fd, /* 0x3e */ - trap_fd, /* 0x3f */ - trap_fd, /* 0x40 */ - trap_fd, /* 0x41 */ - trap_fd, /* 0x42 */ - trap_fd, /* 0x43 */ - trap_fd, /* 0x44 */ - trap_fd, /* 0x45 */ - op_ldbyd, /* 0x46 */ - trap_fd, /* 0x47 */ - trap_fd, /* 0x48 */ - trap_fd, /* 0x49 */ - trap_fd, /* 0x4a */ - trap_fd, /* 0x4b */ - trap_fd, /* 0x4c */ - trap_fd, /* 0x4d */ - op_ldcyd, /* 0x4e */ - trap_fd, /* 0x4f */ - trap_fd, /* 0x50 */ - trap_fd, /* 0x51 */ - trap_fd, /* 0x52 */ - trap_fd, /* 0x53 */ - trap_fd, /* 0x54 */ - trap_fd, /* 0x55 */ - op_lddyd, /* 0x56 */ - trap_fd, /* 0x57 */ - trap_fd, /* 0x58 */ - trap_fd, /* 0x59 */ - trap_fd, /* 0x5a */ - trap_fd, /* 0x5b */ - trap_fd, /* 0x5c */ - trap_fd, /* 0x5d */ - op_ldeyd, /* 0x5e */ - trap_fd, /* 0x5f */ - trap_fd, /* 0x60 */ - trap_fd, /* 0x61 */ - trap_fd, /* 0x62 */ - trap_fd, /* 0x63 */ - trap_fd, /* 0x64 */ - trap_fd, /* 0x65 */ - op_ldhyd, /* 0x66 */ - trap_fd, /* 0x67 */ - trap_fd, /* 0x68 */ - trap_fd, /* 0x69 */ - trap_fd, /* 0x6a */ - trap_fd, /* 0x6b */ - trap_fd, /* 0x6c */ - trap_fd, /* 0x6d */ - op_ldlyd, /* 0x6e */ - trap_fd, /* 0x6f */ - op_ldydb, /* 0x70 */ - op_ldydc, /* 0x71 */ - op_ldydd, /* 0x72 */ - op_ldyde, /* 0x73 */ - op_ldydh, /* 0x74 */ - op_ldydl, /* 0x75 */ - trap_fd, /* 0x76 */ - op_ldyda, /* 0x77 */ - trap_fd, /* 0x78 */ - trap_fd, /* 0x79 */ - trap_fd, /* 0x7a */ - trap_fd, /* 0x7b */ - trap_fd, /* 0x7c */ - trap_fd, /* 0x7d */ - op_ldayd, /* 0x7e */ - trap_fd, /* 0x7f */ - trap_fd, /* 0x80 */ - trap_fd, /* 0x81 */ - trap_fd, /* 0x82 */ - trap_fd, /* 0x83 */ - trap_fd, /* 0x84 */ - trap_fd, /* 0x85 */ - op_adayd, /* 0x86 */ - trap_fd, /* 0x87 */ - trap_fd, /* 0x88 */ - trap_fd, /* 0x89 */ - trap_fd, /* 0x8a */ - trap_fd, /* 0x8b */ - trap_fd, /* 0x8c */ - trap_fd, /* 0x8d */ - op_acayd, /* 0x8e */ - trap_fd, /* 0x8f */ - trap_fd, /* 0x90 */ - trap_fd, /* 0x91 */ - trap_fd, /* 0x92 */ - trap_fd, /* 0x93 */ - trap_fd, /* 0x94 */ - trap_fd, /* 0x95 */ - op_suayd, /* 0x96 */ - trap_fd, /* 0x97 */ - trap_fd, /* 0x98 */ - trap_fd, /* 0x99 */ - trap_fd, /* 0x9a */ - trap_fd, /* 0x9b */ - trap_fd, /* 0x9c */ - trap_fd, /* 0x9d */ - op_scayd, /* 0x9e */ - trap_fd, /* 0x9f */ - trap_fd, /* 0xa0 */ - trap_fd, /* 0xa1 */ - trap_fd, /* 0xa2 */ - trap_fd, /* 0xa3 */ - trap_fd, /* 0xa4 */ - trap_fd, /* 0xa5 */ - op_andyd, /* 0xa6 */ - trap_fd, /* 0xa7 */ - trap_fd, /* 0xa8 */ - trap_fd, /* 0xa9 */ - trap_fd, /* 0xaa */ - trap_fd, /* 0xab */ - trap_fd, /* 0xac */ - trap_fd, /* 0xad */ - op_xoryd, /* 0xae */ - trap_fd, /* 0xaf */ - trap_fd, /* 0xb0 */ - trap_fd, /* 0xb1 */ - trap_fd, /* 0xb2 */ - trap_fd, /* 0xb3 */ - trap_fd, /* 0xb4 */ - trap_fd, /* 0xb5 */ - op_oryd, /* 0xb6 */ - trap_fd, /* 0xb7 */ - trap_fd, /* 0xb8 */ - trap_fd, /* 0xb9 */ - trap_fd, /* 0xba */ - trap_fd, /* 0xbb */ - trap_fd, /* 0xbc */ - trap_fd, /* 0xbd */ - op_cpyd, /* 0xbe */ - trap_fd, /* 0xbf */ - trap_fd, /* 0xc0 */ - trap_fd, /* 0xc1 */ - trap_fd, /* 0xc2 */ - trap_fd, /* 0xc3 */ - trap_fd, /* 0xc4 */ - trap_fd, /* 0xc5 */ - trap_fd, /* 0xc6 */ - trap_fd, /* 0xc7 */ - trap_fd, /* 0xc8 */ - trap_fd, /* 0xc9 */ - trap_fd, /* 0xca */ - op_fdcb_handel, /* 0xcb */ - trap_fd, /* 0xcc */ - trap_fd, /* 0xcd */ - trap_fd, /* 0xce */ - trap_fd, /* 0xcf */ - trap_fd, /* 0xd0 */ - trap_fd, /* 0xd1 */ - trap_fd, /* 0xd2 */ - trap_fd, /* 0xd3 */ - trap_fd, /* 0xd4 */ - trap_fd, /* 0xd5 */ - trap_fd, /* 0xd6 */ - trap_fd, /* 0xd7 */ - trap_fd, /* 0xd8 */ - trap_fd, /* 0xd9 */ - trap_fd, /* 0xda */ - trap_fd, /* 0xdb */ - trap_fd, /* 0xdc */ - trap_fd, /* 0xdd */ - trap_fd, /* 0xde */ - trap_fd, /* 0xdf */ - trap_fd, /* 0xe0 */ - op_popiy, /* 0xe1 */ - trap_fd, /* 0xe2 */ - op_exspy, /* 0xe3 */ - trap_fd, /* 0xe4 */ - op_pusiy, /* 0xe5 */ - trap_fd, /* 0xe6 */ - trap_fd, /* 0xe7 */ - trap_fd, /* 0xe8 */ - op_jpiy, /* 0xe9 */ - trap_fd, /* 0xea */ - trap_fd, /* 0xeb */ - trap_fd, /* 0xec */ - trap_fd, /* 0xed */ - trap_fd, /* 0xee */ - trap_fd, /* 0xef */ - trap_fd, /* 0xf0 */ - trap_fd, /* 0xf1 */ - trap_fd, /* 0xf2 */ - trap_fd, /* 0xf3 */ - trap_fd, /* 0xf4 */ - trap_fd, /* 0xf5 */ - trap_fd, /* 0xf6 */ - trap_fd, /* 0xf7 */ - trap_fd, /* 0xf8 */ - op_ldspy, /* 0xf9 */ - trap_fd, /* 0xfa */ - trap_fd, /* 0xfb */ - trap_fd, /* 0xfc */ - trap_fd, /* 0xfd */ - trap_fd, /* 0xfe */ - trap_fd /* 0xff */ - }; - -#ifdef WANT_TIM - t = (*op_fd[*PC++]) (); /* execute next opcode */ -#else - (*op_fd[*PC++]) (); -#endif - -#ifdef WANT_PCC - if (PC > ram + 65535) /* correct PC overrun */ - PC = ram; -#endif - - return(t); -} - -/* - * This function traps all illegal opcodes following the - * initial 0xfd of a multi byte opcode. - */ -static int trap_fd(void) -{ - cpu_error = OPTRAP2; - cpu_state = STOPPED; - return(0); -} - -static int op_popiy(void) /* POP IY */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - IY = *STACK++; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - IY += *STACK++ << 8; - return(14); -} - -static int op_pusiy(void) /* PUSH IY */ -{ -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = IY >> 8; -#ifdef WANT_SPC - if (STACK <= ram) - STACK = ram + 65536L; -#endif - *--STACK = IY; - return(15); -} - -static int op_jpiy(void) /* JP (IY) */ -{ - PC = ram + IY; - return(8); -} - -static int op_exspy(void) /* EX (SP),IY */ -{ - register int i; - - i = *STACK + (*(STACK + 1) << 8); - *STACK = IY; - *(STACK + 1) = IY >> 8; - IY = i; - return(23); -} - -static int op_ldspy(void) /* LD SP,IY */ -{ - STACK = ram + IY; - return(10); -} - -static int op_ldiynn(void) /* LD IY,nn */ -{ - IY = *PC++; - IY += *PC++ << 8; - return(14); -} - -static int op_ldiyinn(void) /* LD IY,(nn) */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - IY = *p++; - IY += *p << 8; - return(20); -} - -static int op_ldiny(void) /* LD (nn),IY */ -{ - register BYTE *p; - - p = ram + *PC++; - p += *PC++ << 8; - *p++ = IY; - *p = IY >> 8; - return(20); -} - -static int op_adayd(void) /* ADD A,(IY+d) */ -{ - register int i; - register BYTE P; - - P = *(ram + IY + (char) *PC++); - ((A & 0xf) + (P & 0xf) > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + P > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(19); -} - -static int op_acayd(void) /* ADC A,(IY+d) */ -{ - register int i, carry; - register BYTE P; - - carry = (F & C_FLAG) ? 1 : 0; - P = *(ram + IY + (char) *PC++); - ((A & 0xf) + (P & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (A + P + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A + (char) P + carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(19); -} - -static int op_suayd(void) /* SUB A,(IY+d) */ -{ - register int i; - register BYTE P; - - P = *(ram + IY + (char) *PC++); - ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(19); -} - -static int op_scayd(void) /* SBC A,(IY+d) */ -{ - register int i, carry; - register BYTE P; - - carry = (F & C_FLAG) ? 1 : 0; - P = *(ram + IY + (char) *PC++); - ((P & 0xf) + carry > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P + carry > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - A = i = (char) A - (char) P - carry; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(19); -} - -static int op_andyd(void) /* AND (IY+d) */ -{ - A &= *(ram + IY + (char) *PC++); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= H_FLAG; - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(N_FLAG | C_FLAG); - return(19); -} - -static int op_xoryd(void) /* XOR (IY+d) */ -{ - A ^= *(ram + IY + (char) *PC++); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(19); -} - -static int op_oryd(void) /* OR (IY+d) */ -{ - A |= *(ram + IY + (char) *PC++); - (A & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (A) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (parrity[A]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - F &= ~(H_FLAG | N_FLAG | C_FLAG); - return(19); -} - -static int op_cpyd(void) /* CP (IY+d) */ -{ - register int i; - register BYTE P; - - P = *(ram + IY + (char) *PC++); - ((P & 0xf) > (A & 0xf)) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (P > A) ? (F |= C_FLAG) : (F &= ~C_FLAG); - i = (char) A - (char) P; - (i < -128 || i > 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (i & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (i) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(19); -} - -static int op_incyd(void) /* INC (IY+d) */ -{ - register BYTE *p; - - p = ram + IY + (char) *PC++; - ((*p & 0xf) + 1 > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (*p)++; - (*p == 128) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F &= ~N_FLAG; - return(23); -} - -static int op_decyd(void) /* DEC (IY+d) */ -{ - register BYTE *p; - - p = ram + IY + (char) *PC++; - (((*p - 1) & 0xf) == 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (*p)--; - (*p == 127) ? (F |= P_FLAG) : (F &= ~P_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - F |= N_FLAG; - return(23); -} - -static int op_addyb(void) /* ADD IY,BC */ -{ - register int carry; - BYTE iyl = IY & 0xff; - BYTE iyh = IY >> 8; - - carry = (iyl + C > 255) ? 1 : 0; - iyl += C; - ((iyh & 0xf) + (B & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (iyh + B + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - iyh += B + carry; - IY = (iyh << 8) + iyl; - F &= ~N_FLAG; - return(15); -} - -static int op_addyd(void) /* ADD IY,DE */ -{ - register int carry; - BYTE iyl = IY & 0xff; - BYTE iyh = IY >> 8; - - carry = (iyl + E > 255) ? 1 : 0; - iyl += E; - ((iyh & 0xf) + (D & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (iyh + D + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - iyh += D + carry; - IY = (iyh << 8) + iyl; - F &= ~N_FLAG; - return(15); -} - -static int op_addys(void) /* ADD IY,SP */ -{ - register int carry; - BYTE iyl = IY & 0xff; - BYTE iyh = IY >> 8; - BYTE spl = (STACK - ram) & 0xff; - BYTE sph = (STACK - ram) >> 8; - - carry = (iyl + spl > 255) ? 1 : 0; - iyl += spl; - ((iyh & 0xf) + (sph & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (iyh + sph + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - iyh += sph + carry; - IY = (iyh << 8) + iyl; - F &= ~N_FLAG; - return(15); -} - -static int op_addyy(void) /* ADD IY,IY */ -{ - register int carry; - BYTE iyl = IY & 0xff; - BYTE iyh = IY >> 8; - - carry = (iyl << 1 > 255) ? 1 : 0; - iyl <<= 1; - ((iyh & 0xf) + (iyh & 0xf) + carry > 0xf) ? (F |= H_FLAG) : (F &= ~H_FLAG); - (iyh + iyh + carry > 255) ? (F |= C_FLAG) : (F &= ~C_FLAG); - iyh += iyh + carry; - IY = (iyh << 8) + iyl; - F &= ~N_FLAG; - return(15); -} - -static int op_inciy(void) /* INC IY */ -{ - IY++; - return(10); -} - -static int op_deciy(void) /* DEC IY */ -{ - IY--; - return(10); -} - -static int op_ldayd(void) /* LD A,(IY+d) */ -{ - A = *(IY + (char) *PC++ + ram); - return(19); -} - -static int op_ldbyd(void) /* LD B,(IY+d) */ -{ - B = *(IY + (char) *PC++ + ram); - return(19); -} - -static int op_ldcyd(void) /* LD C,(IY+d) */ -{ - C = *(IY + (char) *PC++ + ram); - return(19); -} - -static int op_lddyd(void) /* LD D,(IY+d) */ -{ - D = *(IY + (char) *PC++ + ram); - return(19); -} - -static int op_ldeyd(void) /* LD E,(IY+d) */ -{ - E = *(IY + (char) *PC++ + ram); - return(19); -} - -static int op_ldhyd(void) /* LD H,(IY+d) */ -{ - H = *(IY + (char) *PC++ + ram); - return(19); -} - -static int op_ldlyd(void) /* LD L,(IY+d) */ -{ - L = *(IY + (char) *PC++ + ram); - return(19); -} - -static int op_ldyda(void) /* LD (IY+d),A */ -{ - *(IY + (char) *PC++ + ram) = A; - return(19); -} - -static int op_ldydb(void) /* LD (IY+d),B */ -{ - *(IY + (char) *PC++ + ram) = B; - return(19); -} - -static int op_ldydc(void) /* LD (IY+d),C */ -{ - *(IY + (char) *PC++ + ram) = C; - return(19); -} - -static int op_ldydd(void) /* LD (IY+d),D */ -{ - *(IY + (char) *PC++ + ram) = D; - return(19); -} - -static int op_ldyde(void) /* LD (IY+d),E */ -{ - *(IY + (char) *PC++ + ram) = E; - return(19); -} - -static int op_ldydh(void) /* LD (IY+d),H */ -{ - *(IY + (char) *PC++ + ram) = H; - return(19); -} - -static int op_ldydl(void) /* LD (IY+d),L */ -{ - *(IY + (char) *PC++ + ram) = L; - return(19); -} - -static int op_ldydn(void) /* LD (IY+d),n */ -{ - register int d; - - d = (char) *PC++; - *(IY + d + ram) = *PC++; - return(19); -} diff --git a/emu/z80pack-1.9/z80sim/sim5.o b/emu/z80pack-1.9/z80sim/sim5.o deleted file mode 100644 index 2fa3608..0000000 Binary files a/emu/z80pack-1.9/z80sim/sim5.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/sim6.c b/emu/z80pack-1.9/z80sim/sim6.c deleted file mode 100644 index 509b8e5..0000000 --- a/emu/z80pack-1.9/z80sim/sim6.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * Like the function "cpu()" this one emulates 4 byte opcodes - * starting with 0xdd 0xcb - */ - -#include "sim.h" -#include "simglb.h" - -static int trap_ddcb(void); -static int op_tb0ixd(int), op_tb1ixd(int), op_tb2ixd(int), op_tb3ixd(int); -static int op_tb4ixd(int), op_tb5ixd(int), op_tb6ixd(int), op_tb7ixd(int); -static int op_rb0ixd(int), op_rb1ixd(int), op_rb2ixd(int), op_rb3ixd(int); -static int op_rb4ixd(int), op_rb5ixd(int), op_rb6ixd(int), op_rb7ixd(int); -static int op_sb0ixd(int), op_sb1ixd(int), op_sb2ixd(int), op_sb3ixd(int); -static int op_sb4ixd(int), op_sb5ixd(int), op_sb6ixd(int), op_sb7ixd(int); -static int op_rlcixd(int), op_rrcixd(int), op_rlixd(int), op_rrixd(int); -static int op_slaixd(int), op_sraixd(int), op_srlixd(int); - -int op_ddcb_handel(void) -{ - static int (*op_ddcb[256]) () = { - trap_ddcb, /* 0x00 */ - trap_ddcb, /* 0x01 */ - trap_ddcb, /* 0x02 */ - trap_ddcb, /* 0x03 */ - trap_ddcb, /* 0x04 */ - trap_ddcb, /* 0x05 */ - op_rlcixd, /* 0x06 */ - trap_ddcb, /* 0x07 */ - trap_ddcb, /* 0x08 */ - trap_ddcb, /* 0x09 */ - trap_ddcb, /* 0x0a */ - trap_ddcb, /* 0x0b */ - trap_ddcb, /* 0x0c */ - trap_ddcb, /* 0x0d */ - op_rrcixd, /* 0x0e */ - trap_ddcb, /* 0x0f */ - trap_ddcb, /* 0x10 */ - trap_ddcb, /* 0x11 */ - trap_ddcb, /* 0x12 */ - trap_ddcb, /* 0x13 */ - trap_ddcb, /* 0x14 */ - trap_ddcb, /* 0x15 */ - op_rlixd, /* 0x16 */ - trap_ddcb, /* 0x17 */ - trap_ddcb, /* 0x18 */ - trap_ddcb, /* 0x19 */ - trap_ddcb, /* 0x1a */ - trap_ddcb, /* 0x1b */ - trap_ddcb, /* 0x1c */ - trap_ddcb, /* 0x1d */ - op_rrixd, /* 0x1e */ - trap_ddcb, /* 0x1f */ - trap_ddcb, /* 0x20 */ - trap_ddcb, /* 0x21 */ - trap_ddcb, /* 0x22 */ - trap_ddcb, /* 0x23 */ - trap_ddcb, /* 0x24 */ - trap_ddcb, /* 0x25 */ - op_slaixd, /* 0x26 */ - trap_ddcb, /* 0x27 */ - trap_ddcb, /* 0x28 */ - trap_ddcb, /* 0x29 */ - trap_ddcb, /* 0x2a */ - trap_ddcb, /* 0x2b */ - trap_ddcb, /* 0x2c */ - trap_ddcb, /* 0x2d */ - op_sraixd, /* 0x2e */ - trap_ddcb, /* 0x2f */ - trap_ddcb, /* 0x30 */ - trap_ddcb, /* 0x31 */ - trap_ddcb, /* 0x32 */ - trap_ddcb, /* 0x33 */ - trap_ddcb, /* 0x34 */ - trap_ddcb, /* 0x35 */ - trap_ddcb, /* 0x36 */ - trap_ddcb, /* 0x37 */ - trap_ddcb, /* 0x38 */ - trap_ddcb, /* 0x39 */ - trap_ddcb, /* 0x3a */ - trap_ddcb, /* 0x3b */ - trap_ddcb, /* 0x3c */ - trap_ddcb, /* 0x3d */ - op_srlixd, /* 0x3e */ - trap_ddcb, /* 0x3f */ - trap_ddcb, /* 0x40 */ - trap_ddcb, /* 0x41 */ - trap_ddcb, /* 0x42 */ - trap_ddcb, /* 0x43 */ - trap_ddcb, /* 0x44 */ - trap_ddcb, /* 0x45 */ - op_tb0ixd, /* 0x46 */ - trap_ddcb, /* 0x47 */ - trap_ddcb, /* 0x48 */ - trap_ddcb, /* 0x49 */ - trap_ddcb, /* 0x4a */ - trap_ddcb, /* 0x4b */ - trap_ddcb, /* 0x4c */ - trap_ddcb, /* 0x4d */ - op_tb1ixd, /* 0x4e */ - trap_ddcb, /* 0x4f */ - trap_ddcb, /* 0x50 */ - trap_ddcb, /* 0x51 */ - trap_ddcb, /* 0x52 */ - trap_ddcb, /* 0x53 */ - trap_ddcb, /* 0x54 */ - trap_ddcb, /* 0x55 */ - op_tb2ixd, /* 0x56 */ - trap_ddcb, /* 0x57 */ - trap_ddcb, /* 0x58 */ - trap_ddcb, /* 0x59 */ - trap_ddcb, /* 0x5a */ - trap_ddcb, /* 0x5b */ - trap_ddcb, /* 0x5c */ - trap_ddcb, /* 0x5d */ - op_tb3ixd, /* 0x5e */ - trap_ddcb, /* 0x5f */ - trap_ddcb, /* 0x60 */ - trap_ddcb, /* 0x61 */ - trap_ddcb, /* 0x62 */ - trap_ddcb, /* 0x63 */ - trap_ddcb, /* 0x64 */ - trap_ddcb, /* 0x65 */ - op_tb4ixd, /* 0x66 */ - trap_ddcb, /* 0x67 */ - trap_ddcb, /* 0x68 */ - trap_ddcb, /* 0x69 */ - trap_ddcb, /* 0x6a */ - trap_ddcb, /* 0x6b */ - trap_ddcb, /* 0x6c */ - trap_ddcb, /* 0x6d */ - op_tb5ixd, /* 0x6e */ - trap_ddcb, /* 0x6f */ - trap_ddcb, /* 0x70 */ - trap_ddcb, /* 0x71 */ - trap_ddcb, /* 0x72 */ - trap_ddcb, /* 0x73 */ - trap_ddcb, /* 0x74 */ - trap_ddcb, /* 0x75 */ - op_tb6ixd, /* 0x76 */ - trap_ddcb, /* 0x77 */ - trap_ddcb, /* 0x78 */ - trap_ddcb, /* 0x79 */ - trap_ddcb, /* 0x7a */ - trap_ddcb, /* 0x7b */ - trap_ddcb, /* 0x7c */ - trap_ddcb, /* 0x7d */ - op_tb7ixd, /* 0x7e */ - trap_ddcb, /* 0x7f */ - trap_ddcb, /* 0x80 */ - trap_ddcb, /* 0x81 */ - trap_ddcb, /* 0x82 */ - trap_ddcb, /* 0x83 */ - trap_ddcb, /* 0x84 */ - trap_ddcb, /* 0x85 */ - op_rb0ixd, /* 0x86 */ - trap_ddcb, /* 0x87 */ - trap_ddcb, /* 0x88 */ - trap_ddcb, /* 0x89 */ - trap_ddcb, /* 0x8a */ - trap_ddcb, /* 0x8b */ - trap_ddcb, /* 0x8c */ - trap_ddcb, /* 0x8d */ - op_rb1ixd, /* 0x8e */ - trap_ddcb, /* 0x8f */ - trap_ddcb, /* 0x90 */ - trap_ddcb, /* 0x91 */ - trap_ddcb, /* 0x92 */ - trap_ddcb, /* 0x93 */ - trap_ddcb, /* 0x94 */ - trap_ddcb, /* 0x95 */ - op_rb2ixd, /* 0x96 */ - trap_ddcb, /* 0x97 */ - trap_ddcb, /* 0x98 */ - trap_ddcb, /* 0x99 */ - trap_ddcb, /* 0x9a */ - trap_ddcb, /* 0x9b */ - trap_ddcb, /* 0x9c */ - trap_ddcb, /* 0x9d */ - op_rb3ixd, /* 0x9e */ - trap_ddcb, /* 0x9f */ - trap_ddcb, /* 0xa0 */ - trap_ddcb, /* 0xa1 */ - trap_ddcb, /* 0xa2 */ - trap_ddcb, /* 0xa3 */ - trap_ddcb, /* 0xa4 */ - trap_ddcb, /* 0xa5 */ - op_rb4ixd, /* 0xa6 */ - trap_ddcb, /* 0xa7 */ - trap_ddcb, /* 0xa8 */ - trap_ddcb, /* 0xa9 */ - trap_ddcb, /* 0xaa */ - trap_ddcb, /* 0xab */ - trap_ddcb, /* 0xac */ - trap_ddcb, /* 0xad */ - op_rb5ixd, /* 0xae */ - trap_ddcb, /* 0xaf */ - trap_ddcb, /* 0xb0 */ - trap_ddcb, /* 0xb1 */ - trap_ddcb, /* 0xb2 */ - trap_ddcb, /* 0xb3 */ - trap_ddcb, /* 0xb4 */ - trap_ddcb, /* 0xb5 */ - op_rb6ixd, /* 0xb6 */ - trap_ddcb, /* 0xb7 */ - trap_ddcb, /* 0xb8 */ - trap_ddcb, /* 0xb9 */ - trap_ddcb, /* 0xba */ - trap_ddcb, /* 0xbb */ - trap_ddcb, /* 0xbc */ - trap_ddcb, /* 0xbd */ - op_rb7ixd, /* 0xbe */ - trap_ddcb, /* 0xbf */ - trap_ddcb, /* 0xc0 */ - trap_ddcb, /* 0xc1 */ - trap_ddcb, /* 0xc2 */ - trap_ddcb, /* 0xc3 */ - trap_ddcb, /* 0xc4 */ - trap_ddcb, /* 0xc5 */ - op_sb0ixd, /* 0xc6 */ - trap_ddcb, /* 0xc7 */ - trap_ddcb, /* 0xc8 */ - trap_ddcb, /* 0xc9 */ - trap_ddcb, /* 0xca */ - trap_ddcb, /* 0xcb */ - trap_ddcb, /* 0xcc */ - trap_ddcb, /* 0xcd */ - op_sb1ixd, /* 0xce */ - trap_ddcb, /* 0xcf */ - trap_ddcb, /* 0xd0 */ - trap_ddcb, /* 0xd1 */ - trap_ddcb, /* 0xd2 */ - trap_ddcb, /* 0xd3 */ - trap_ddcb, /* 0xd4 */ - trap_ddcb, /* 0xd5 */ - op_sb2ixd, /* 0xd6 */ - trap_ddcb, /* 0xd7 */ - trap_ddcb, /* 0xd8 */ - trap_ddcb, /* 0xd9 */ - trap_ddcb, /* 0xda */ - trap_ddcb, /* 0xdb */ - trap_ddcb, /* 0xdc */ - trap_ddcb, /* 0xdd */ - op_sb3ixd, /* 0xde */ - trap_ddcb, /* 0xdf */ - trap_ddcb, /* 0xe0 */ - trap_ddcb, /* 0xe1 */ - trap_ddcb, /* 0xe2 */ - trap_ddcb, /* 0xe3 */ - trap_ddcb, /* 0xe4 */ - trap_ddcb, /* 0xe5 */ - op_sb4ixd, /* 0xe6 */ - trap_ddcb, /* 0xe7 */ - trap_ddcb, /* 0xe8 */ - trap_ddcb, /* 0xe9 */ - trap_ddcb, /* 0xea */ - trap_ddcb, /* 0xeb */ - trap_ddcb, /* 0xec */ - trap_ddcb, /* 0xed */ - op_sb5ixd, /* 0xee */ - trap_ddcb, /* 0xef */ - trap_ddcb, /* 0xf0 */ - trap_ddcb, /* 0xf1 */ - trap_ddcb, /* 0xf2 */ - trap_ddcb, /* 0xf3 */ - trap_ddcb, /* 0xf4 */ - trap_ddcb, /* 0xf5 */ - op_sb6ixd, /* 0xf6 */ - trap_ddcb, /* 0xf7 */ - trap_ddcb, /* 0xf8 */ - trap_ddcb, /* 0xf9 */ - trap_ddcb, /* 0xfa */ - trap_ddcb, /* 0xfb */ - trap_ddcb, /* 0xfc */ - trap_ddcb, /* 0xfd */ - op_sb7ixd, /* 0xfe */ - trap_ddcb /* 0xff */ - }; - - register int d; - register int t; - - d = (char) *PC++; - -#ifdef WANT_PCC - if (PC > ram + 65535) /* correct PC overrun */ - PC = ram; -#endif - -#ifdef WANT_TIM - t = (*op_ddcb[*PC++]) (d); /* execute next opcode */ -#else - (*op_ddcb[*PC++]) (d); -#endif - -#ifdef WANT_PCC - if (PC > ram + 65535) /* again correct PC overrun */ - PC = ram; -#endif - - return(t); -} - -/* - * This function traps all illegal opcodes following the - * initial 0xdd 0xcb of a 4 byte opcode. - */ -static int trap_ddcb(void) -{ - cpu_error = OPTRAP4; - cpu_state = STOPPED; - return(0); -} - -static int op_tb0ixd(int data) /* BIT 0,(IX+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IX + data) & 1) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb1ixd(int data) /* BIT 1,(IX+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IX + data) & 2) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb2ixd(int data) /* BIT 2,(IX+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IX + data) & 4) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb3ixd(int data) /* BIT 3,(IX+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IX + data) & 8) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb4ixd(int data) /* BIT 4,(IX+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IX + data) & 16) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb5ixd(int data) /* BIT 5,(IX+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IX + data) & 32) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb6ixd(int data) /* BIT 6,(IX+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IX + data) & 64) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb7ixd(int data) /* BIT 7,(IX+d) */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (*(ram + IX + data) & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(20); -} - -static int op_rb0ixd(int data) /* RES 0,(IX+d) */ -{ - *(ram + IX + data) &= ~1; - return(23); -} - -static int op_rb1ixd(int data) /* RES 1,(IX+d) */ -{ - *(ram + IX + data) &= ~2; - return(23); -} - -static int op_rb2ixd(int data) /* RES 2,(IX+d) */ -{ - *(ram + IX + data) &= ~4; - return(23); -} - -static int op_rb3ixd(int data) /* RES 3,(IX+d) */ -{ - *(ram + IX + data) &= ~8; - return(23); -} - -static int op_rb4ixd(int data) /* RES 4,(IX+d) */ -{ - *(ram + IX + data) &= ~16; - return(23); -} - -static int op_rb5ixd(int data) /* RES 5,(IX+d) */ -{ - *(ram + IX + data) &= ~32; - return(23); -} - -static int op_rb6ixd(int data) /* RES 6,(IX+d) */ -{ - *(ram + IX + data) &= ~64; - return(23); -} - -static int op_rb7ixd(int data) /* RES 7,(IX+d) */ -{ - *(ram + IX + data) &= ~128; - return(23); -} - -static int op_sb0ixd(int data) /* SET 0,(IX+d) */ -{ - *(ram + IX + data) |= 1; - return(23); -} - -static int op_sb1ixd(int data) /* SET 1,(IX+d) */ -{ - *(ram + IX + data) |= 2; - return(23); -} - -static int op_sb2ixd(int data) /* SET 2,(IX+d) */ -{ - *(ram + IX + data) |= 4; - return(23); -} - -static int op_sb3ixd(int data) /* SET 3,(IX+d) */ -{ - *(ram + IX + data) |= 8; - return(23); -} - -static int op_sb4ixd(int data) /* SET 4,(IX+d) */ -{ - *(ram + IX + data) |= 16; - return(23); -} - -static int op_sb5ixd(int data) /* SET 5,(IX+d) */ -{ - *(ram + IX + data) |= 32; - return(23); -} - -static int op_sb6ixd(int data) /* SET 6,(IX+d) */ -{ - *(ram + IX + data) |= 64; - return(23); -} - -static int op_sb7ixd(int data) /* SET 7,(IX+d) */ -{ - *(ram + IX + data) |= 128; - return(23); -} - -static int op_rlcixd(int data) /* RLC (IX+d) */ -{ - register int i; - register BYTE *p; - - p = ram + IX + data; - i = *p & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - *p <<= 1; - if (i) *p |= 1; - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_rrcixd(int data) /* RRC (IX+d) */ -{ - register int i; - register BYTE *p; - - p = ram + IX + data; - i = *p & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - *p >>= 1; - if (i) *p |= 128; - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_rlixd(int data) /* RL (IX+d) */ -{ - register int old_c_flag; - register BYTE *p; - - p = ram + IX + data; - old_c_flag = F & C_FLAG; - (*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p <<= 1; - if (old_c_flag) *p |= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_rrixd(int data) /* RR (IX+d) */ -{ - register int old_c_flag; - register BYTE *p; - - old_c_flag = F & C_FLAG; - p = ram + IX + data; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - if (old_c_flag) *p |= 128; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_slaixd(int data) /* SLA (IX+d) */ -{ - register BYTE *p; - - p = ram + IX + data; - (*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p <<= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_sraixd(int data) /* SRA (IX+d) */ -{ - register int i; - register BYTE *p; - - p = ram + IX + data; - i = *p & 128; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - *p |= i; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_srlixd(int data) /* SRL (IX+d) */ -{ - register BYTE *p; - - p = ram + IX + data; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} diff --git a/emu/z80pack-1.9/z80sim/sim6.o b/emu/z80pack-1.9/z80sim/sim6.o deleted file mode 100644 index 64db5cc..0000000 Binary files a/emu/z80pack-1.9/z80sim/sim6.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/sim7.c b/emu/z80pack-1.9/z80sim/sim7.c deleted file mode 100644 index 272e8e0..0000000 --- a/emu/z80pack-1.9/z80sim/sim7.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V(3.1) - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 07-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * Like the function "cpu()" this one emulates 4 byte opcodes - * starting with 0xfd 0xcb - */ - -#include "sim.h" -#include "simglb.h" - -static int trap_fdcb(void); -static int op_tb0iyd(int), op_tb1iyd(int), op_tb2iyd(int), op_tb3iyd(int); -static int op_tb4iyd(int), op_tb5iyd(int), op_tb6iyd(int), op_tb7iyd(int); -static int op_rb0iyd(int), op_rb1iyd(int), op_rb2iyd(int), op_rb3iyd(int); -static int op_rb4iyd(int), op_rb5iyd(int), op_rb6iyd(int), op_rb7iyd(int); -static int op_sb0iyd(int), op_sb1iyd(int), op_sb2iyd(int), op_sb3iyd(int); -static int op_sb4iyd(int), op_sb5iyd(int), op_sb6iyd(int), op_sb7iyd(int); -static int op_rlciyd(int), op_rrciyd(int), op_rliyd(int), op_rriyd(int); -static int op_slaiyd(int), op_sraiyd(int), op_srliyd(int); - -int op_fdcb_handel(void) -{ - static int (*op_fdcb[256]) () = { - trap_fdcb, /* 0x00 */ - trap_fdcb, /* 0x01 */ - trap_fdcb, /* 0x02 */ - trap_fdcb, /* 0x03 */ - trap_fdcb, /* 0x04 */ - trap_fdcb, /* 0x05 */ - op_rlciyd, /* 0x06 */ - trap_fdcb, /* 0x07 */ - trap_fdcb, /* 0x08 */ - trap_fdcb, /* 0x09 */ - trap_fdcb, /* 0x0a */ - trap_fdcb, /* 0x0b */ - trap_fdcb, /* 0x0c */ - trap_fdcb, /* 0x0d */ - op_rrciyd, /* 0x0e */ - trap_fdcb, /* 0x0f */ - trap_fdcb, /* 0x10 */ - trap_fdcb, /* 0x11 */ - trap_fdcb, /* 0x12 */ - trap_fdcb, /* 0x13 */ - trap_fdcb, /* 0x14 */ - trap_fdcb, /* 0x15 */ - op_rliyd, /* 0x16 */ - trap_fdcb, /* 0x17 */ - trap_fdcb, /* 0x18 */ - trap_fdcb, /* 0x19 */ - trap_fdcb, /* 0x1a */ - trap_fdcb, /* 0x1b */ - trap_fdcb, /* 0x1c */ - trap_fdcb, /* 0x1d */ - op_rriyd, /* 0x1e */ - trap_fdcb, /* 0x1f */ - trap_fdcb, /* 0x20 */ - trap_fdcb, /* 0x21 */ - trap_fdcb, /* 0x22 */ - trap_fdcb, /* 0x23 */ - trap_fdcb, /* 0x24 */ - trap_fdcb, /* 0x25 */ - op_slaiyd, /* 0x26 */ - trap_fdcb, /* 0x27 */ - trap_fdcb, /* 0x28 */ - trap_fdcb, /* 0x29 */ - trap_fdcb, /* 0x2a */ - trap_fdcb, /* 0x2b */ - trap_fdcb, /* 0x2c */ - trap_fdcb, /* 0x2d */ - op_sraiyd, /* 0x2e */ - trap_fdcb, /* 0x2f */ - trap_fdcb, /* 0x30 */ - trap_fdcb, /* 0x31 */ - trap_fdcb, /* 0x32 */ - trap_fdcb, /* 0x33 */ - trap_fdcb, /* 0x34 */ - trap_fdcb, /* 0x35 */ - trap_fdcb, /* 0x36 */ - trap_fdcb, /* 0x37 */ - trap_fdcb, /* 0x38 */ - trap_fdcb, /* 0x39 */ - trap_fdcb, /* 0x3a */ - trap_fdcb, /* 0x3b */ - trap_fdcb, /* 0x3c */ - trap_fdcb, /* 0x3d */ - op_srliyd, /* 0x3e */ - trap_fdcb, /* 0x3f */ - trap_fdcb, /* 0x40 */ - trap_fdcb, /* 0x41 */ - trap_fdcb, /* 0x42 */ - trap_fdcb, /* 0x43 */ - trap_fdcb, /* 0x44 */ - trap_fdcb, /* 0x45 */ - op_tb0iyd, /* 0x46 */ - trap_fdcb, /* 0x47 */ - trap_fdcb, /* 0x48 */ - trap_fdcb, /* 0x49 */ - trap_fdcb, /* 0x4a */ - trap_fdcb, /* 0x4b */ - trap_fdcb, /* 0x4c */ - trap_fdcb, /* 0x4d */ - op_tb1iyd, /* 0x4e */ - trap_fdcb, /* 0x4f */ - trap_fdcb, /* 0x50 */ - trap_fdcb, /* 0x51 */ - trap_fdcb, /* 0x52 */ - trap_fdcb, /* 0x53 */ - trap_fdcb, /* 0x54 */ - trap_fdcb, /* 0x55 */ - op_tb2iyd, /* 0x56 */ - trap_fdcb, /* 0x57 */ - trap_fdcb, /* 0x58 */ - trap_fdcb, /* 0x59 */ - trap_fdcb, /* 0x5a */ - trap_fdcb, /* 0x5b */ - trap_fdcb, /* 0x5c */ - trap_fdcb, /* 0x5d */ - op_tb3iyd, /* 0x5e */ - trap_fdcb, /* 0x5f */ - trap_fdcb, /* 0x60 */ - trap_fdcb, /* 0x61 */ - trap_fdcb, /* 0x62 */ - trap_fdcb, /* 0x63 */ - trap_fdcb, /* 0x64 */ - trap_fdcb, /* 0x65 */ - op_tb4iyd, /* 0x66 */ - trap_fdcb, /* 0x67 */ - trap_fdcb, /* 0x68 */ - trap_fdcb, /* 0x69 */ - trap_fdcb, /* 0x6a */ - trap_fdcb, /* 0x6b */ - trap_fdcb, /* 0x6c */ - trap_fdcb, /* 0x6d */ - op_tb5iyd, /* 0x6e */ - trap_fdcb, /* 0x6f */ - trap_fdcb, /* 0x70 */ - trap_fdcb, /* 0x71 */ - trap_fdcb, /* 0x72 */ - trap_fdcb, /* 0x73 */ - trap_fdcb, /* 0x74 */ - trap_fdcb, /* 0x75 */ - op_tb6iyd, /* 0x76 */ - trap_fdcb, /* 0x77 */ - trap_fdcb, /* 0x78 */ - trap_fdcb, /* 0x79 */ - trap_fdcb, /* 0x7a */ - trap_fdcb, /* 0x7b */ - trap_fdcb, /* 0x7c */ - trap_fdcb, /* 0x7d */ - op_tb7iyd, /* 0x7e */ - trap_fdcb, /* 0x7f */ - trap_fdcb, /* 0x80 */ - trap_fdcb, /* 0x81 */ - trap_fdcb, /* 0x82 */ - trap_fdcb, /* 0x83 */ - trap_fdcb, /* 0x84 */ - trap_fdcb, /* 0x85 */ - op_rb0iyd, /* 0x86 */ - trap_fdcb, /* 0x87 */ - trap_fdcb, /* 0x88 */ - trap_fdcb, /* 0x89 */ - trap_fdcb, /* 0x8a */ - trap_fdcb, /* 0x8b */ - trap_fdcb, /* 0x8c */ - trap_fdcb, /* 0x8d */ - op_rb1iyd, /* 0x8e */ - trap_fdcb, /* 0x8f */ - trap_fdcb, /* 0x90 */ - trap_fdcb, /* 0x91 */ - trap_fdcb, /* 0x92 */ - trap_fdcb, /* 0x93 */ - trap_fdcb, /* 0x94 */ - trap_fdcb, /* 0x95 */ - op_rb2iyd, /* 0x96 */ - trap_fdcb, /* 0x97 */ - trap_fdcb, /* 0x98 */ - trap_fdcb, /* 0x99 */ - trap_fdcb, /* 0x9a */ - trap_fdcb, /* 0x9b */ - trap_fdcb, /* 0x9c */ - trap_fdcb, /* 0x9d */ - op_rb3iyd, /* 0x9e */ - trap_fdcb, /* 0x9f */ - trap_fdcb, /* 0xa0 */ - trap_fdcb, /* 0xa1 */ - trap_fdcb, /* 0xa2 */ - trap_fdcb, /* 0xa3 */ - trap_fdcb, /* 0xa4 */ - trap_fdcb, /* 0xa5 */ - op_rb4iyd, /* 0xa6 */ - trap_fdcb, /* 0xa7 */ - trap_fdcb, /* 0xa8 */ - trap_fdcb, /* 0xa9 */ - trap_fdcb, /* 0xaa */ - trap_fdcb, /* 0xab */ - trap_fdcb, /* 0xac */ - trap_fdcb, /* 0xad */ - op_rb5iyd, /* 0xae */ - trap_fdcb, /* 0xaf */ - trap_fdcb, /* 0xb0 */ - trap_fdcb, /* 0xb1 */ - trap_fdcb, /* 0xb2 */ - trap_fdcb, /* 0xb3 */ - trap_fdcb, /* 0xb4 */ - trap_fdcb, /* 0xb5 */ - op_rb6iyd, /* 0xb6 */ - trap_fdcb, /* 0xb7 */ - trap_fdcb, /* 0xb8 */ - trap_fdcb, /* 0xb9 */ - trap_fdcb, /* 0xba */ - trap_fdcb, /* 0xbb */ - trap_fdcb, /* 0xbc */ - trap_fdcb, /* 0xbd */ - op_rb7iyd, /* 0xbe */ - trap_fdcb, /* 0xbf */ - trap_fdcb, /* 0xc0 */ - trap_fdcb, /* 0xc1 */ - trap_fdcb, /* 0xc2 */ - trap_fdcb, /* 0xc3 */ - trap_fdcb, /* 0xc4 */ - trap_fdcb, /* 0xc5 */ - op_sb0iyd, /* 0xc6 */ - trap_fdcb, /* 0xc7 */ - trap_fdcb, /* 0xc8 */ - trap_fdcb, /* 0xc9 */ - trap_fdcb, /* 0xca */ - trap_fdcb, /* 0xcb */ - trap_fdcb, /* 0xcc */ - trap_fdcb, /* 0xcd */ - op_sb1iyd, /* 0xce */ - trap_fdcb, /* 0xcf */ - trap_fdcb, /* 0xd0 */ - trap_fdcb, /* 0xd1 */ - trap_fdcb, /* 0xd2 */ - trap_fdcb, /* 0xd3 */ - trap_fdcb, /* 0xd4 */ - trap_fdcb, /* 0xd5 */ - op_sb2iyd, /* 0xd6 */ - trap_fdcb, /* 0xd7 */ - trap_fdcb, /* 0xd8 */ - trap_fdcb, /* 0xd9 */ - trap_fdcb, /* 0xda */ - trap_fdcb, /* 0xdb */ - trap_fdcb, /* 0xdc */ - trap_fdcb, /* 0xdd */ - op_sb3iyd, /* 0xde */ - trap_fdcb, /* 0xdf */ - trap_fdcb, /* 0xe0 */ - trap_fdcb, /* 0xe1 */ - trap_fdcb, /* 0xe2 */ - trap_fdcb, /* 0xe3 */ - trap_fdcb, /* 0xe4 */ - trap_fdcb, /* 0xe5 */ - op_sb4iyd, /* 0xe6 */ - trap_fdcb, /* 0xe7 */ - trap_fdcb, /* 0xe8 */ - trap_fdcb, /* 0xe9 */ - trap_fdcb, /* 0xea */ - trap_fdcb, /* 0xeb */ - trap_fdcb, /* 0xec */ - trap_fdcb, /* 0xed */ - op_sb5iyd, /* 0xee */ - trap_fdcb, /* 0xef */ - trap_fdcb, /* 0xf0 */ - trap_fdcb, /* 0xf1 */ - trap_fdcb, /* 0xf2 */ - trap_fdcb, /* 0xf3 */ - trap_fdcb, /* 0xf4 */ - trap_fdcb, /* 0xf5 */ - op_sb6iyd, /* 0xf6 */ - trap_fdcb, /* 0xf7 */ - trap_fdcb, /* 0xf8 */ - trap_fdcb, /* 0xf9 */ - trap_fdcb, /* 0xfa */ - trap_fdcb, /* 0xfb */ - trap_fdcb, /* 0xfc */ - trap_fdcb, /* 0xfd */ - op_sb7iyd, /* 0xfe */ - trap_fdcb /* 0xff */ - }; - - register int d; - register int t; - - d = (char) *PC++; - -#ifdef WANT_PCC - if (PC > ram + 65535) /* correct PC overrun */ - PC = ram; -#endif - -#ifdef WANT_TIM - t = (*op_fdcb[*PC++]) (d); /* execute next opcode */ -#else - (*op_fdcb[*PC++]) (d); -#endif - -#ifdef WANT_PCC - if (PC > ram + 65535) /* again correct PC overrun */ - PC = ram; -#endif - - return(t); -} - -/* - * This function traps all illegal opcodes following the - * initial 0xfd 0xcb of a 4 byte opcode. - */ -static int trap_fdcb(void) -{ - cpu_error = OPTRAP4; - cpu_state = STOPPED; - return(0L); -} - -static int op_tb0iyd(int data) /* BIT 0,(IY+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IY + data) & 1) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb1iyd(int data) /* BIT 1,(IY+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IY + data) & 2) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb2iyd(int data) /* BIT 2,(IY+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IY + data) & 4) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb3iyd(int data) /* BIT 3,(IY+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IY + data) & 8) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb4iyd(int data) /* BIT 4,(IY+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IY + data) & 16) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb5iyd(int data) /* BIT 5,(IY+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IY + data) & 32) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb6iyd(int data) /* BIT 6,(IY+d) */ -{ - F &= ~(N_FLAG | S_FLAG); - F |= H_FLAG; - (*(ram + IY + data) & 64) ? (F &= ~(Z_FLAG | P_FLAG)) - : (F |= (Z_FLAG | P_FLAG)); - return(20); -} - -static int op_tb7iyd(int data) /* BIT 7,(IY+d) */ -{ - F &= ~N_FLAG; - F |= H_FLAG; - if (*(ram + IY + data) & 128) { - F &= ~(Z_FLAG | P_FLAG); - F |= S_FLAG; - } else { - F |= (Z_FLAG | P_FLAG); - F &= ~S_FLAG; - } - return(20); -} - -static int op_rb0iyd(int data) /* RES 0,(IY+d) */ -{ - *(ram + IY + data) &= ~1; - return(23); -} - -static int op_rb1iyd(int data) /* RES 1,(IY+d) */ -{ - *(ram + IY + data) &= ~2; - return(23); -} - -static int op_rb2iyd(int data) /* RES 2,(IY+d) */ -{ - *(ram + IY + data) &= ~4; - return(23); -} - -static int op_rb3iyd(int data) /* RES 3,(IY+d) */ -{ - *(ram + IY + data) &= ~8; - return(23); -} - -static int op_rb4iyd(int data) /* RES 4,(IY+d) */ -{ - *(ram + IY + data) &= ~16; - return(23); -} - -static int op_rb5iyd(int data) /* RES 5,(IY+d) */ -{ - *(ram + IY + data) &= ~32; - return(23); -} - -static int op_rb6iyd(int data) /* RES 6,(IY+d) */ -{ - *(ram + IY + data) &= ~64; - return(23); -} - -static int op_rb7iyd(int data) /* RES 7,(IY+d) */ -{ - *(ram + IY + data) &= ~128; - return(23); -} - -static int op_sb0iyd(int data) /* SET 0,(IY+d) */ -{ - *(ram + IY + data) |= 1; - return(23); -} - -static int op_sb1iyd(int data) /* SET 1,(IY+d) */ -{ - *(ram + IY + data) |= 2; - return(23); -} - -static int op_sb2iyd(int data) /* SET 2,(IY+d) */ -{ - *(ram + IY + data) |= 4; - return(23); -} - -static int op_sb3iyd(int data) /* SET 3,(IY+d) */ -{ - *(ram + IY + data) |= 8; - return(23); -} - -static int op_sb4iyd(int data) /* SET 4,(IY+d) */ -{ - *(ram + IY + data) |= 16; - return(23); -} - -static int op_sb5iyd(int data) /* SET 5,(IY+d) */ -{ - *(ram + IY + data) |= 32; - return(23); -} - -static int op_sb6iyd(int data) /* SET 6,(IY+d) */ -{ - *(ram + IY + data) |= 64; - return(23); -} - -static int op_sb7iyd(int data) /* SET 7,(IY+d) */ -{ - *(ram + IY + data) |= 128; - return(23); -} - -static int op_rlciyd(int data) /* RLC (IY+d) */ -{ - register int i; - register BYTE *p; - - p = ram + IY + data; - i = *p & 128; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - *p <<= 1; - if (i) *p |= 1; - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_rrciyd(int data) /* RRC (IY+d) */ -{ - register int i; - register BYTE *p; - - p = ram + IY + data; - i = *p & 1; - (i) ? (F |= C_FLAG) : (F &= ~C_FLAG); - F &= ~(H_FLAG | N_FLAG); - *p >>= 1; - if (i) *p |= 128; - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_rliyd(int data) /* RL (IY+d) */ -{ - register int old_c_flag; - register BYTE *p; - - p = ram + IY + data; - old_c_flag = F & C_FLAG; - (*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p <<= 1; - if (old_c_flag) *p |= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_rriyd(int data) /* RR (IY+d) */ -{ - register int old_c_flag; - register BYTE *p; - - old_c_flag = F & C_FLAG; - p = ram + IY + data; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - if (old_c_flag) *p |= 128; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_slaiyd(int data) /* SLA (IY+d) */ -{ - register BYTE *p; - - p = ram + IY + data; - (*p & 128) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p <<= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_sraiyd(int data) /* SRA (IY+d) */ -{ - register int i; - register BYTE *p; - - p = ram + IY + data; - i = *p & 128; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - *p |= i; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} - -static int op_srliyd(int data) /* SRL (IY+d) */ -{ - register BYTE *p; - - p = ram + IY + data; - (*p & 1) ? (F |= C_FLAG) : (F &= ~C_FLAG); - *p >>= 1; - F &= ~(H_FLAG | N_FLAG); - (*p) ? (F &= ~Z_FLAG) : (F |= Z_FLAG); - (*p & 128) ? (F |= S_FLAG) : (F &= ~S_FLAG); - (parrity[*p]) ? (F &= ~P_FLAG) : (F |= P_FLAG); - return(23); -} diff --git a/emu/z80pack-1.9/z80sim/sim7.o b/emu/z80pack-1.9/z80sim/sim7.o deleted file mode 100644 index 6028f12..0000000 Binary files a/emu/z80pack-1.9/z80sim/sim7.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/simctl.c b/emu/z80pack-1.9/z80sim/simctl.c deleted file mode 100644 index 464b799..0000000 --- a/emu/z80pack-1.9/z80sim/simctl.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * This modul contains the user interface, a full qualified ICE, - * for the Z80-CPU simulation. - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0 - * 02-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * This modul is an ICE type user interface to debug Z80 programs - * on a host system. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "sim.h" -#include "simglb.h" - -extern void cpu(void); -extern void disass(unsigned char **, int); -extern int exatoi(char *); -extern int getkey(void); -extern void int_on(void), int_off(void); - -static void do_step(void); -static void do_trace(char *); -static void do_go(char *); -static int handel_break(void); -static void do_dump(char *); -static void do_list(char *); -static void do_modify(char *); -static void do_fill(char *); -static void do_move(char *); -static void do_port(char *); -static void do_reg(char *); -static void print_head(void); -static void print_reg(void); -static void do_break(char *); -static void do_hist(char *); -static void do_count(char *); -static void do_clock(void); -static void timeout(int); -static void do_show(void); -static int do_getfile(char *); -static int load_mos(int, char *); -static void do_unix(char *); -static void do_help(void); -static void cpu_err_msg(void); - -struct termios old_term; - -/* - * The function "mon()" is the dialog user interface, called - * from the simulation just after program start. - */ -void mon(void) -{ - register int eoj = 1; - static char cmd[LENCMD]; - - tcgetattr(0, &old_term); - - if (x_flag) { - if (do_getfile(xfn) == 0) - do_go(""); - } - while (eoj) { - next: - printf(">>> "); - fflush(stdout); - if (fgets(cmd, LENCMD, stdin) == NULL) { - putchar('\n'); - goto next; - } - switch (*cmd) { - case '\n': - do_step(); - break; - case 't': - do_trace(cmd + 1); - break; - case 'g': - do_go(cmd + 1); - break; - case 'd': - do_dump(cmd + 1); - break; - case 'l': - do_list(cmd + 1); - break; - case 'm': - do_modify(cmd + 1); - break; - case 'f': - do_fill(cmd + 1); - break; - case 'v': - do_move(cmd + 1); - break; - case 'x': - do_reg(cmd + 1); - break; - case 'p': - do_port(cmd + 1); - break; - case 'b': - do_break(cmd + 1); - break; - case 'h': - do_hist(cmd + 1); - break; - case 'z': - do_count(cmd + 1); - break; - case 'c': - do_clock(); - break; - case 's': - do_show(); - break; - case '?': - do_help(); - break; - case 'r': - do_getfile(cmd + 1); - break; - case '!': - do_unix(cmd + 1); - break; - case 'q': - eoj = 0; - break; - default: - puts("what??"); - break; - } - } -} - -/* - * Execute a single step - */ -static void do_step(void) -{ - BYTE *p; - - cpu_state = SINGLE_STEP; - cpu_error = NONE; - cpu(); - if (cpu_error == OPHALT) - handel_break(); - cpu_err_msg(); - print_head(); - print_reg(); - p = PC; - disass(&p, p - ram); -} - -/* - * Execute several steps with trace output - */ -static void do_trace(char *s) -{ - register int count, i; - - while (isspace(*s)) - s++; - if (*s == '\0') - count = 20; - else - count = atoi(s); - cpu_state = SINGLE_STEP; - cpu_error = NONE; - print_head(); - print_reg(); - for (i = 0; i < count; i++) { - cpu(); - print_reg(); - if (cpu_error) { - if (cpu_error == OPHALT) { - if (!handel_break()) { - break; - } - } else - break; - } - } - cpu_err_msg(); -} - -/* - * Run the CPU emulation endless - */ -static void do_go(char *s) -{ - while (isspace(*s)) - s++; - if (isxdigit(*s)) - PC = ram + exatoi(s); - cont: - cpu_state = CONTIN_RUN; - cpu_error = NONE; - cpu(); - if (cpu_error == OPHALT) - if (handel_break()) - if (!cpu_error) - goto cont; - cpu_err_msg(); - print_head(); - print_reg(); -} - -/* - * Handling of software breakpoints (HALT opcode): - * - * Output: 0 breakpoint or other HALT opcode reached (stop) - * 1 breakpoint reached, passcounter not reached (continue) - */ -static int handel_break(void) -{ -#ifdef SBSIZE - register int i; - int break_address; - - for (i = 0; i < SBSIZE; i++) /* search for breakpoint */ - if (soft[i].sb_adr == PC - ram - 1) - goto was_softbreak; - return(0); - was_softbreak: -#ifdef HISIZE - h_next--; /* correct history */ - if (h_next < 0) - h_next = 0; -#endif - break_address = PC - ram - 1; /* store adr of breakpoint */ - cpu_error = NONE; /* HALT was a breakpoint */ - PC--; /* substitute HALT opcode by */ - *PC = soft[i].sb_oldopc; /* original opcode */ - cpu_state = SINGLE_STEP; /* and execute it */ - cpu(); - *(ram + soft[i].sb_adr) = 0x76; /* restore HALT opcode again */ - soft[i].sb_passcount++; /* increment passcounter */ - if (soft[i].sb_passcount != soft[i].sb_pass) - return(1); /* pass not reached, continue */ - printf("Software breakpoint %d reached at %04x\n", i, break_address); - soft[i].sb_passcount = 0; /* reset passcounter */ - return(0); /* pass reached, stop */ -#endif -} - -/* - * Memory dump - */ -static void do_dump(char *s) -{ - register int i, j; - BYTE c; - - while (isspace(*s)) - s++; - if (isxdigit(*s)) - wrk_ram = ram + exatoi(s) - exatoi(s) % 16; - printf("Adr "); - for (i = 0; i < 16; i++) - printf("%02x ", i); - puts(" ASCII"); - for (i = 0; i < 16; i++) { - printf("%04x - ", (unsigned int)(wrk_ram - ram)); - for (j = 0; j < 16; j++) { - printf("%02x ", *wrk_ram); - wrk_ram++; - if (wrk_ram > ram + 65535) - wrk_ram = ram; - } - putchar('\t'); - for (j = -16; j < 0; j++) - printf("%c",((c = *(wrk_ram+j))>=' ' && c<=0x7f) ? c : '.'); - putchar('\n'); - } -} - -/* - * Disassemble - */ -static void do_list(char *s) -{ - register int i; - - while (isspace(*s)) - s++; - if (isxdigit(*s)) - wrk_ram = ram + exatoi(s); - for (i = 0; i < 10; i++) { - printf("%04x - ", (unsigned int)(wrk_ram - ram)); - disass(&wrk_ram, wrk_ram - ram); - if (wrk_ram > ram + 65535) - wrk_ram = ram; - } -} - -/* - * Memory modify - */ -static void do_modify(char *s) -{ - static char nv[LENCMD]; - - while (isspace(*s)) - s++; - if (isxdigit(*s)) - wrk_ram = ram + exatoi(s); - for (;;) { - printf("%04x = %02x : ", (unsigned int)(wrk_ram - ram), - *wrk_ram); - fgets(nv, sizeof(nv), stdin); - if (nv[0] == '\n') { - wrk_ram++; - if (wrk_ram > ram + 65535) - wrk_ram = ram; - continue; - } - if (!isxdigit(nv[0])) - break; - *wrk_ram++ = exatoi(nv); - if (wrk_ram > ram + 65535) - wrk_ram = ram; - } -} - -/* - * Memory fill - */ -static void do_fill(char *s) -{ - register BYTE *p; - register int i; - register BYTE val; - - while (isspace(*s)) - s++; - p = ram + exatoi(s); - while (*s != ',' && *s != '\0') - s++; - if (*s) { - i = exatoi(++s); - } else { - puts("count missing"); - return; - } - while (*s != ',' && *s != '\0') - s++; - if (*s) { - val = exatoi(++s); - } else { - puts("value missing"); - return; - } - while (i--) { - *p++ = val; - if (p > ram + 65535) - p = ram; - } -} - -/* - * Memory move - */ -static void do_move(char *s) -{ - register BYTE *p1, *p2; - register int count; - - - while (isspace(*s)) - s++; - p1 = ram + exatoi(s); - while (*s != ',' && *s != '\0') - s++; - if (*s) { - p2 = ram + exatoi(++s); - } else { - puts("to missing"); - return; - } - while (*s != ',' && *s != '\0') - s++; - if (*s) { - count = exatoi(++s); - } else { - puts("count missing"); - return; - } - while (count--) { - *p2++ = *p1++; - if (p1 > ram + 65535) - p1 = ram; - if (p2 > ram + 65535) - p2 = ram; - } -} - -/* - * Port modify - */ -static void do_port(char *s) -{ - register BYTE port; - static char nv[LENCMD]; - extern BYTE io_out(), io_in(); - - while (isspace(*s)) - s++; - port = exatoi(s); - printf("%02x = %02x : ", port, io_in(port)); - fgets(nv, sizeof(nv), stdin); - if (isxdigit(*nv)) - io_out(port, (BYTE) exatoi(nv)); -} - -/* - * Register modify - */ -static void do_reg(char *s) -{ - static char nv[LENCMD]; - - while (isspace(*s)) - s++; - if (*s == '\0') { - print_head(); - print_reg(); - } else { - if (strncmp(s, "bc'", 3) == 0) { - printf("BC' = %04x : ", B_ * 256 + C_); - fgets(nv, sizeof(nv), stdin); - B_ = (exatoi(nv) & 0xffff) / 256; - C_ = (exatoi(nv) & 0xffff) % 256; - } else if (strncmp(s, "de'", 3) == 0) { - printf("DE' = %04x : ", D_ * 256 + E_); - fgets(nv, sizeof(nv), stdin); - D_ = (exatoi(nv) & 0xffff) / 256; - E_ = (exatoi(nv) & 0xffff) % 256; - } else if (strncmp(s, "hl'", 3) == 0) { - printf("HL' = %04x : ", H_ * 256 + L_); - fgets(nv, sizeof(nv), stdin); - H_ = (exatoi(nv) & 0xffff) / 256; - L_ = (exatoi(nv) & 0xffff) % 256; - } else if (strncmp(s, "pc", 2) == 0) { - printf("PC = %04x : ", (unsigned int)(PC - ram)); - fgets(nv, sizeof(nv), stdin); - PC = ram + (exatoi(nv) & 0xffff); - } else if (strncmp(s, "bc", 2) == 0) { - printf("BC = %04x : ", B * 256 + C); - fgets(nv, sizeof(nv), stdin); - B = (exatoi(nv) & 0xffff) / 256; - C = (exatoi(nv) & 0xffff) % 256; - } else if (strncmp(s, "de", 2) == 0) { - printf("DE = %04x : ", D * 256 + E); - fgets(nv, sizeof(nv), stdin); - D = (exatoi(nv) & 0xffff) / 256; - E = (exatoi(nv) & 0xffff) % 256; - } else if (strncmp(s, "hl", 2) == 0) { - printf("HL = %04x : ", H * 256 + L); - fgets(nv, sizeof(nv), stdin); - H = (exatoi(nv) & 0xffff) / 256; - L = (exatoi(nv) & 0xffff) % 256; - } else if (strncmp(s, "ix", 2) == 0) { - printf("IX = %04x : ", IX); - fgets(nv, sizeof(nv), stdin); - IX = exatoi(nv) & 0xffff; - } else if (strncmp(s, "iy", 2) == 0) { - printf("IY = %04x : ", IY); - fgets(nv, sizeof(nv), stdin); - IY = exatoi(nv) & 0xffff; - } else if (strncmp(s, "sp", 2) == 0) { - printf("SP = %04x : ", (unsigned int)(STACK - ram)); - fgets(nv, sizeof(nv), stdin); - STACK = ram + (exatoi(nv) & 0xffff); - } else if (strncmp(s, "fs", 2) == 0) { - printf("S-FLAG = %c : ", (F & S_FLAG) ? '1' : '0'); - fgets(nv, sizeof(nv), stdin); - F = (exatoi(nv)) ? (F | S_FLAG) : (F & ~S_FLAG); - } else if (strncmp(s, "fz", 2) == 0) { - printf("Z-FLAG = %c : ", (F & Z_FLAG) ? '1' : '0'); - fgets(nv, sizeof(nv), stdin); - F = (exatoi(nv)) ? (F | Z_FLAG) : (F & ~Z_FLAG); - } else if (strncmp(s, "fh", 2) == 0) { - printf("H-FLAG = %c : ", (F & H_FLAG) ? '1' : '0'); - fgets(nv, sizeof(nv), stdin); - F = (exatoi(nv)) ? (F | H_FLAG) : (F & ~H_FLAG); - } else if (strncmp(s, "fp", 2) == 0) { - printf("P-FLAG = %c : ", (F & P_FLAG) ? '1' : '0'); - fgets(nv, sizeof(nv), stdin); - F = (exatoi(nv)) ? (F | P_FLAG) : (F & ~P_FLAG); - } else if (strncmp(s, "fn", 2) == 0) { - printf("N-FLAG = %c : ", (F & N_FLAG) ? '1' : '0'); - fgets(nv, sizeof(nv), stdin); - F = (exatoi(nv)) ? (F | N_FLAG) : (F & ~N_FLAG); - } else if (strncmp(s, "fc", 2) == 0) { - printf("C-FLAG = %c : ", (F & C_FLAG) ? '1' : '0'); - fgets(nv, sizeof(nv), stdin); - F = (exatoi(nv)) ? (F | C_FLAG) : (F & ~C_FLAG); - } else if (strncmp(s, "a'", 2) == 0) { - printf("A' = %02x : ", A_); - fgets(nv, sizeof(nv), stdin); - A_ = exatoi(nv) & 0xff; - } else if (strncmp(s, "f'", 2) == 0) { - printf("F' = %02x : ", F_); - fgets(nv, sizeof(nv), stdin); - F_ = exatoi(nv) & 0xff; - } else if (strncmp(s, "b'", 2) == 0) { - printf("B' = %02x : ", B_); - fgets(nv, sizeof(nv), stdin); - B_ = exatoi(nv) & 0xff; - } else if (strncmp(s, "c'", 2) == 0) { - printf("C' = %02x : ", C_); - fgets(nv, sizeof(nv), stdin); - C_ = exatoi(nv) & 0xff; - } else if (strncmp(s, "d'", 2) == 0) { - printf("D' = %02x : ", D_); - fgets(nv, sizeof(nv), stdin); - D_ = exatoi(nv) & 0xff; - } else if (strncmp(s, "e'", 2) == 0) { - printf("E' = %02x : ", E_); - fgets(nv, sizeof(nv), stdin); - E_ = exatoi(nv) & 0xff; - } else if (strncmp(s, "h'", 2) == 0) { - printf("H' = %02x : ", H_); - fgets(nv, sizeof(nv), stdin); - H_ = exatoi(nv) & 0xff; - } else if (strncmp(s, "l'", 2) == 0) { - printf("L' = %02x : ", L_); - fgets(nv, sizeof(nv), stdin); - L_ = exatoi(nv) & 0xff; - } else if (strncmp(s, "i", 1) == 0) { - printf("I = %02x : ", I); - fgets(nv, sizeof(nv), stdin); - I = exatoi(nv) & 0xff; - } else if (strncmp(s, "a", 1) == 0) { - printf("A = %02x : ", A); - fgets(nv, sizeof(nv), stdin); - A = exatoi(nv) & 0xff; - } else if (strncmp(s, "f", 1) == 0) { - printf("F = %02x : ", F); - fgets(nv, sizeof(nv), stdin); - F = exatoi(nv) & 0xff; - } else if (strncmp(s, "b", 1) == 0) { - printf("B = %02x : ", B); - fgets(nv, sizeof(nv), stdin); - B = exatoi(nv) & 0xff; - } else if (strncmp(s, "c", 1) == 0) { - printf("C = %02x : ", C); - fgets(nv, sizeof(nv), stdin); - C = exatoi(nv) & 0xff; - } else if (strncmp(s, "d", 1) == 0) { - printf("D = %02x : ", D); - fgets(nv, sizeof(nv), stdin); - D = exatoi(nv) & 0xff; - } else if (strncmp(s, "e", 1) == 0) { - printf("E = %02x : ", E); - fgets(nv, sizeof(nv), stdin); - E = exatoi(nv) & 0xff; - } else if (strncmp(s, "h", 1) == 0) { - printf("H = %02x : ", H); - fgets(nv, sizeof(nv), stdin); - H = exatoi(nv) & 0xff; - } else if (strncmp(s, "l", 1) == 0) { - printf("L = %02x : ", L); - fgets(nv, sizeof(nv), stdin); - L = exatoi(nv) & 0xff; - } else - printf("can't change register %s\n", nv); - print_head(); - print_reg(); - } -} - -/* - * Output header for the CPU registers - */ -static void print_head(void) -{ - printf("\nPC A SZHPNC I IFF BC DE HL A'F' B'C' D'E' H'L' IX IY SP\n"); -} - -/* - * Output all CPU registers - */ -static void print_reg(void) -{ - printf("%04x %02x ", (unsigned int)(PC - ram), A); - printf("%c", F & S_FLAG ? '1' : '0'); - printf("%c", F & Z_FLAG ? '1' : '0'); - printf("%c", F & H_FLAG ? '1' : '0'); - printf("%c", F & P_FLAG ? '1' : '0'); - printf("%c", F & N_FLAG ? '1' : '0'); - printf("%c", F & C_FLAG ? '1' : '0'); - printf(" %02x ", I); - printf("%c", IFF & 1 ? '1' : '0'); - printf("%c", IFF & 2 ? '1' : '0'); - printf(" %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %02x%02x %04x %04x %04x\n", - B, C, D, E, H, L, A_, F_, B_, C_, D_, E_, H_, L_, IX, IY, - (unsigned int)(STACK - ram)); -} - -/* - * Software breakpoints - */ -static void do_break(char *s) -{ -#ifndef SBSIZE - puts("Sorry, no breakpoints available"); - puts("Please recompile with SBSIZE defined in sim.h"); -#else - register int i; - - if (!break_flag) { - puts("Can't use softbreaks with -h option."); - return; - } - if (*s == '\n') { - puts("No Addr Pass Counter"); - for (i = 0; i < SBSIZE; i++) - if (soft[i].sb_pass) - printf("%02d %04x %05d %05d\n", i, - soft[i].sb_adr,soft[i].sb_pass,soft[i].sb_passcount); - return; - } - if (isxdigit(*s)) { - i = atoi(s++); - if (i >= SBSIZE) { - printf("breakpoint %d not available\n", i); - return; - } - } else { - i = sb_next++; - if (sb_next == SBSIZE) - sb_next = 0; - } - while (isspace(*s)) - s++; - if (*s == 'c') { - *(ram + soft[i].sb_adr) = soft[i].sb_oldopc; - memset((char *) &soft[i], 0, sizeof(struct softbreak)); - return; - } - if (soft[i].sb_pass) - *(ram + soft[i].sb_adr) = soft[i].sb_oldopc; - soft[i].sb_adr = exatoi(s); - soft[i].sb_oldopc = *(ram + soft[i].sb_adr); - *(ram + soft[i].sb_adr) = 0x76; - while (!iscntrl(*s) && !ispunct(*s)) - s++; - if (*s != ',') - soft[i].sb_pass = 1; - else - soft[i].sb_pass = exatoi(++s); - soft[i].sb_passcount = 0; -#endif -} - -/* - * History - */ -static void do_hist(char *s) -{ -#ifndef HISIZE - puts("Sorry, no history available"); - puts("Please recompile with HISIZE defined in sim.h"); -#else - int i, l, b, e, c, sa; - - while (isspace(*s)) - s++; - switch (*s) { - case 'c': - memset((char *) his, 0, sizeof(struct history) * HISIZE); - h_next = 0; - h_flag = 0; - break; - default: - if ((h_next == 0) && (h_flag == 0)) { - puts("History memory is empty"); - break; - } - e = h_next; - b = (h_flag) ? h_next + 1 : 0; - l = 0; - while (isspace(*s)) - s++; - if (*s) - sa = exatoi(s); - else - sa = -1; - for (i = b; i != e; i++) { - if (i == HISIZE) - i = 0; - if (sa != -1) { - if (his[i].h_adr < sa) - continue; - else - sa = -1; - } - printf("%04x AF=%04x BC=%04x DE=%04x HL=%04x IX=%04x IY=%04x SP=%04x\n", - his[i].h_adr, his[i].h_af, his[i].h_bc, - his[i].h_de, his[i].h_hl, his[i].h_ix, - his[i].h_iy, his[i].h_sp); - l++; - if (l == 20) { - l = 0; - printf("q = quit, else continue: "); - c = getkey(); - putchar('\n'); - if (toupper(c) == 'Q') - break; - } - } - break; - } -#endif -} - -/* - * Runtime measurement by counting the executed T states - */ -static void do_count(char *s) -{ -#ifndef WANT_TIM - puts("Sorry, no t-state count available"); - puts("Please recompile with WANT_TIM defined in sim.h"); -#else - while (isspace(*s)) - s++; - if (*s == '\0') { - puts("start stop status T-states"); - printf("%04x %04x %s %lu\n", - (unsigned int)(t_start - ram), - (unsigned int)(t_end - ram), - t_flag ? "on ": "off", t_states); - } else { - t_start = ram + exatoi(s); - while (*s != ',' && *s != '\0') - s++; - if (*s) - t_end = ram + exatoi(++s); - t_states = 0L; - t_flag = 0; - } -#endif -} - -/* - * Calculate the clock frequency of the emulated CPU: - * into memory locations 0000H to 0002H the following - * code will be stored: - * LOOP: JP LOOP - * It uses 10 T states for each execution. A 3 secound - * timer is started and then the CPU. For every opcode - * fetch the R register is incremented by one and after - * the timer is down and stopps the emulation, the clock - * speed of the CPU is calculated with: - * f = R / 300000 - */ -static void do_clock(void) -{ - static BYTE save[3]; - - save[0] = *(ram + 0x0000); /* save memory locations */ - save[1] = *(ram + 0x0001); /* 0000H - 0002H */ - save[2] = *(ram + 0x0002); - *(ram + 0x0000) = 0xc3; /* store opcode JP 0000H at address */ - *(ram + 0x0001) = 0x00; /* 0000H */ - *(ram + 0x0002) = 0x00; - PC = ram + 0x0000; /* set PC to this code */ - R = 0L; /* clear refresh register */ - cpu_state = CONTIN_RUN; /* initialize CPU */ - cpu_error = NONE; - signal(SIGALRM, timeout); /* initialize timer interrupt handler */ - alarm(3); /* start 3 secound timer */ - cpu(); /* start CPU */ - *(ram + 0x0000) = save[0]; /* restore memory locations */ - *(ram + 0x0001) = save[1]; /* 0000H - 0002H */ - *(ram + 0x0002) = save[2]; - if (cpu_error == NONE) - printf("clock frequency = %5.2f Mhz\n", ((float) R) / 300000.0); - else - puts("Interrupted by user"); -} - -/* - * This function is the signal handler for the timer interrupt. - * The CPU emulation is stopped here. - */ -static void timeout(int sig) -{ - cpu_state = STOPPED; -} - -/* - * Output informations about compiling options - */ -static void do_show(void) -{ - register int i; - - printf("Release: %s\n", RELEASE); -#ifdef HISIZE - i = HISIZE; -#else - i = 0; -#endif - printf("No. of entrys in history memory: %d\n", i); -#ifdef SBSIZE - i = SBSIZE; -#else - i = 0; -#endif - printf("No. of software breakpoints: %d\n", i); -#ifdef WANT_SPC - i = 1; -#else - i = 0; -#endif - printf("Stackpointer turn around %schecked\n", i ? "" : "not "); -#ifdef WANT_PCC - i = 1; -#else - i = 0; -#endif - printf("Programcounter turn around %schecked\n", i ? "" : "not "); -#ifdef WANT_TIM - i = 1; -#else - i = 0; -#endif - printf("T-State counting %spossible\n", i ? "" : "im"); -#ifdef CNTL_C - i = 1; -#else - i = 0; -#endif - printf("CPU simulation %sstopped on cntl-c\n", i ? "" : "not "); -#ifdef CNTL_BS - i = 1; -#else - i = 0; -#endif - printf("CPU simulation %sstopped on cntl-\\\n", i ? "" : "not "); -} - -/* - * Read a file into the memory of the emulated CPU. - * The following file formats are supported: - * - * binary images with Mostek header - */ -static int do_getfile(char *s) -{ - char fn[LENCMD]; - BYTE fileb[5]; - register char *pfn = fn; - int fd; - - while (isspace(*s)) - s++; - while (*s != ',' && *s != '\n' && *s != '\0') - *pfn++ = *s++; - *pfn = '\0'; - if (strlen(fn) == 0) { - puts("no input file given"); - return(1); - } - if ((fd = open(fn, O_RDONLY)) == -1) { - printf("can't open file %s\n", fn); - return(1); - } - if (*s == ',') - wrk_ram = ram + exatoi(++s); - else - wrk_ram = NULL; - read(fd, (char *) fileb, 5); /* read first 5 bytes of file */ - if (*fileb == (BYTE) 0xff) { /* Mostek header ? */ - lseek(fd, 0l, 0); - return (load_mos(fd, fn)); - } - else { - printf("unkown format, can't load file %s\n", fn); - close(fd); - return(1); - } -} - -/* - * Loader for binary images with Mostek header. - * Format of the first 3 bytes: - * - * 0xff ll lh - * - * ll = load address low - * lh = load address high - */ -static int load_mos(int fd, char *fn) -{ - BYTE fileb[3]; - unsigned count, readed; - int rc = 0; - - read(fd, (char *) fileb, 3); /* read load address */ - if (wrk_ram == NULL) /* and set if not given */ - wrk_ram = ram + (fileb[2] * 256 + fileb[1]); - count = ram + 65535 - wrk_ram; - if ((readed = read(fd, (char *) wrk_ram, count)) == count) { - puts("Too much to load, stopped at 0xffff"); - rc = 1; - } - close(fd); - printf("Loader statistics for file %s:\n", fn); - printf("START : %04x\n", (unsigned int)(wrk_ram - ram)); - printf("END : %04x\n", (unsigned int)(wrk_ram - ram + readed - 1)); - printf("LOADED: %04x\n", readed); - PC = wrk_ram; - return(rc); -} - -/* - * Call system function from simulator - */ -static void do_unix(char *s) -{ - int_off(); - system(s); - int_on(); -} - -/* - * Output help text - */ -static void do_help(void) -{ - puts("r filename[,address] read object into memory"); - puts("d [address] dump memory"); - puts("l [address] list memory"); - puts("m [address] modify memory"); - puts("f address,count,value fill memory"); - puts("v from,to,count move memory"); - puts("p address show/modify port"); - puts("g [address] run program"); - puts("t [count] trace program"); - puts("return single step program"); - puts("x [register] show/modify register"); - puts("x f modify flag"); - puts("b[no] address[,pass] set soft breakpoint"); - puts("b show soft breakpoints"); - puts("b[no] c clear soft breakpoint"); - puts("h [address] show history"); - puts("h c clear history"); - puts("z start,stop set trigger adr for t-state count"); - puts("z show t-state count"); - puts("c measure clock frequency"); - puts("s show settings"); - puts("! command execute UNIX command"); - puts("q quit"); -} - -/* - * Error handler after CPU is stopped - */ -static void cpu_err_msg(void) -{ - switch (cpu_error) { - case NONE: - break; - case OPHALT: - printf("HALT Op-Code reached at %04x\n", - (unsigned int)(PC - ram - 1)); - break; - case IOTRAP: - printf("I/O Trap at %04x\n", (unsigned int)(PC - ram)); - break; - case OPTRAP1: - printf("Op-code trap at %04x %02x\n", - (unsigned int)(PC - 1 - ram), *(PC-1)); - break; - case OPTRAP2: - printf("Op-code trap at %04x %02x %02x\n", - (unsigned int)(PC - 2 - ram), - *(PC-2), *(PC-1)); - break; - case OPTRAP4: - printf("Op-code trap at %04x %02x %02x %02x %02x\n", - (unsigned int)(PC - 4 - ram), *(PC-4), *(PC-3), - *(PC-2), *(PC-1)); - break; - case USERINT: - puts("User Interrupt"); - break; - default: - printf("Unknown error %d\n", cpu_error); - break; - } -} diff --git a/emu/z80pack-1.9/z80sim/simctl.o b/emu/z80pack-1.9/z80sim/simctl.o deleted file mode 100644 index 79fa5dd..0000000 Binary files a/emu/z80pack-1.9/z80sim/simctl.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/simfun.c b/emu/z80pack-1.9/z80sim/simfun.c deleted file mode 100644 index b4e7634..0000000 --- a/emu/z80pack-1.9/z80sim/simfun.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0 - * 04-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * This modul contains some commonly used functions - */ - -#include -#include -#include -#include -#include "sim.h" - -/* - * atoi for hexadecimal numbers - */ -int exatoi(char *str) -{ - register int num = 0; - - while (isxdigit(*str)) { - num *= 16; - if (*str <= '9') - num += *str - '0'; - else - num += toupper(*str) - '7'; - str++; - } - return(num); -} - -/* - * Wait for a single keystroke without echo - */ -int getkey(void) -{ - register int c; - struct termios old_term, new_term; - - tcgetattr(0, &old_term); - new_term = old_term; - new_term.c_lflag &= ~(ICANON | ECHO); - new_term.c_cc[VMIN] = 1; - tcsetattr(0, TCSADRAIN, &new_term); - c = getchar(); - tcsetattr(0, TCSADRAIN, &old_term); - return(c); -} diff --git a/emu/z80pack-1.9/z80sim/simfun.o b/emu/z80pack-1.9/z80sim/simfun.o deleted file mode 100644 index 8d37933..0000000 Binary files a/emu/z80pack-1.9/z80sim/simfun.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/simglb.c b/emu/z80pack-1.9/z80sim/simglb.c deleted file mode 100644 index 6b72897..0000000 --- a/emu/z80pack-1.9/z80sim/simglb.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0 - * 04-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * This modul contains all the global variables - */ - -#include "sim.h" - -/* - * CPU-Register - */ -BYTE A,B,C,D,E,H,L; /* Z80 primary registers */ -int F; /* normaly 8-Bit, but int is faster */ -WORD IX, IY; -BYTE A_,B_,C_,D_,E_,H_,L_; /* Z80 secoundary registers */ -int F_; -BYTE *PC; /* Z80 programm counter */ -BYTE *STACK; /* Z80 stackpointer */ -BYTE I; /* Z80 interrupt register */ -BYTE IFF; /* Z80 interrupt flags */ -long R; /* Z80 refresh register */ - /* is normaly a 8 bit register */ - /* the 32 bits are used to measure the */ - /* clock frequency */ - -/* - * Variables for memory of the emulated CPU - */ -BYTE ram[65536L]; /* 64KB RAM */ -BYTE *wrk_ram; /* workpointer into memory for dump etc. */ - -/* - * Variables for history memory - */ -#ifdef HISIZE -struct history his[HISIZE]; /* memory to hold trace informations */ -int h_next; /* index into trace memory */ -int h_flag; /* flag for trace memory overrun */ -#endif - -/* - * Variables for breakpoint memory - */ -#ifdef SBSIZE -struct softbreak soft[SBSIZE]; /* memory to hold breakpoint informations */ -int sb_next; /* index into breakpoint memory */ -#endif - -/* - * Variables for runtime measurement - */ -#ifdef WANT_TIM -long t_states; /* number of counted T states */ -int t_flag; /* flag, 1 = on, 0 = off */ -BYTE *t_start = ram + 65535; /* start address for measurement */ -BYTE *t_end = ram + 65535; /* end address for measurement */ -#endif - -/* - * Flag to controll operation of simulation - */ -int s_flag; /* flag for -s option */ -int l_flag; /* flag for -l option */ -int m_flag; /* flag for -m option */ -int x_flag; /* flag for -x option */ -int i_flag; /* flag for -i option */ -int f_flag; /* flag for -f option */ -char xfn[LENCMD]; /* buffer for filename (option -x) */ -int break_flag = 1; /* 1 = break at HALT, 0 = execute HALT */ -int cpu_state; /* status of CPU emulation */ -int cpu_error; /* error status of CPU emulation */ -int int_type; /* type of interrupt */ -float freq; /* CPU clock in usec */ -int int_mode; /* CPU interrupt mode (IM 0, IM 1, IM 2) */ -int cntl_c; /* flag for cntl-c entered */ -int cntl_bs; /* flag for cntl-\ entered */ - -/* - * Table to get parrity as fast as possible - */ -int parrity[256] = { - 0 /* 00000000 */, 1 /* 00000001 */, 1 /* 00000010 */, - 0 /* 00000011 */, 1 /* 00000100 */, 0 /* 00000101 */, - 0 /* 00000110 */, 1 /* 00000111 */, 1 /* 00001000 */, - 0 /* 00001001 */, 0 /* 00001010 */, 1 /* 00001011 */, - 0 /* 00001100 */, 1 /* 00001101 */, 1 /* 00001110 */, - 0 /* 00001111 */, 1 /* 00010000 */, 0 /* 00010001 */, - 0 /* 00010010 */, 1 /* 00010011 */, 0 /* 00010100 */, - 1 /* 00010101 */, 1 /* 00010110 */, 0 /* 00010111 */, - 0 /* 00011000 */, 1 /* 00011001 */, 1 /* 00011010 */, - 0 /* 00011011 */, 1 /* 00011100 */, 0 /* 00011101 */, - 0 /* 00011110 */, 1 /* 00011111 */, 1 /* 00100000 */, - 0 /* 00100001 */, 0 /* 00100010 */, 1 /* 00100011 */, - 0 /* 00100100 */, 1 /* 00100101 */, 1 /* 00100110 */, - 0 /* 00100111 */, 0 /* 00101000 */, 1 /* 00101001 */, - 1 /* 00101010 */, 0 /* 00101011 */, 1 /* 00101100 */, - 0 /* 00101101 */, 0 /* 00101110 */, 1 /* 00101111 */, - 0 /* 00110000 */, 1 /* 00110001 */, 1 /* 00110010 */, - 0 /* 00110011 */, 1 /* 00110100 */, 0 /* 00110101 */, - 0 /* 00110110 */, 1 /* 00110111 */, 1 /* 00111000 */, - 0 /* 00111001 */, 0 /* 00111010 */, 1 /* 00111011 */, - 0 /* 00111100 */, 1 /* 00111101 */, 1 /* 00111110 */, - 0 /* 00111111 */, 1 /* 01000000 */, 0 /* 01000001 */, - 0 /* 01000010 */, 1 /* 01000011 */, 0 /* 01000100 */, - 1 /* 01000101 */, 1 /* 01000110 */, 0 /* 01000111 */, - 0 /* 01001000 */, 1 /* 01001001 */, 1 /* 01001010 */, - 0 /* 01001011 */, 1 /* 01001100 */, 0 /* 01001101 */, - 0 /* 01001110 */, 1 /* 01001111 */, 0 /* 01010000 */, - 1 /* 01010001 */, 1 /* 01010010 */, 0 /* 01010011 */, - 1 /* 01010100 */, 0 /* 01010101 */, 0 /* 01010110 */, - 1 /* 01010111 */, 1 /* 01011000 */, 0 /* 01011001 */, - 0 /* 01011010 */, 1 /* 01011011 */, 0 /* 01011100 */, - 1 /* 01011101 */, 1 /* 01011110 */, 0 /* 01011111 */, - 0 /* 01100000 */, 1 /* 01100001 */, 1 /* 01100010 */, - 0 /* 01100011 */, 1 /* 01100100 */, 0 /* 01100101 */, - 0 /* 01100110 */, 1 /* 01100111 */, 1 /* 01101000 */, - 0 /* 01101001 */, 0 /* 01101010 */, 1 /* 01101011 */, - 0 /* 01101100 */, 1 /* 01101101 */, 1 /* 01101110 */, - 0 /* 01101111 */, 1 /* 01110000 */, 0 /* 01110001 */, - 0 /* 01110010 */, 1 /* 01110011 */, 0 /* 01110100 */, - 1 /* 01110101 */, 1 /* 01110110 */, 0 /* 01110111 */, - 0 /* 01111000 */, 1 /* 01111001 */, 1 /* 01111010 */, - 0 /* 01111011 */, 1 /* 01111100 */, 0 /* 01111101 */, - 0 /* 01111110 */, 1 /* 01111111 */, - 1 /* 10000000 */, 0 /* 10000001 */, 0 /* 10000010 */, - 1 /* 10000011 */, 0 /* 10000100 */, 1 /* 10000101 */, - 1 /* 10000110 */, 0 /* 10000111 */, 0 /* 10001000 */, - 1 /* 10001001 */, 1 /* 10001010 */, 0 /* 10001011 */, - 1 /* 10001100 */, 0 /* 10001101 */, 0 /* 10001110 */, - 1 /* 10001111 */, 0 /* 10010000 */, 1 /* 10010001 */, - 1 /* 10010010 */, 0 /* 10010011 */, 1 /* 10010100 */, - 0 /* 10010101 */, 0 /* 10010110 */, 1 /* 10010111 */, - 1 /* 10011000 */, 0 /* 10011001 */, 0 /* 10011010 */, - 1 /* 10011011 */, 0 /* 10011100 */, 1 /* 10011101 */, - 1 /* 10011110 */, 0 /* 10011111 */, 0 /* 10100000 */, - 1 /* 10100001 */, 1 /* 10100010 */, 0 /* 10100011 */, - 1 /* 10100100 */, 0 /* 10100101 */, 0 /* 10100110 */, - 1 /* 10100111 */, 1 /* 10101000 */, 0 /* 10101001 */, - 0 /* 10101010 */, 1 /* 10101011 */, 0 /* 10101100 */, - 1 /* 10101101 */, 1 /* 10101110 */, 0 /* 10101111 */, - 1 /* 10110000 */, 0 /* 10110001 */, 0 /* 10110010 */, - 1 /* 10110011 */, 0 /* 10110100 */, 1 /* 10110101 */, - 1 /* 10110110 */, 0 /* 10110111 */, 0 /* 10111000 */, - 1 /* 10111001 */, 1 /* 10111010 */, 0 /* 10111011 */, - 1 /* 10111100 */, 0 /* 10111101 */, 0 /* 10111110 */, - 1 /* 10111111 */, 0 /* 11000000 */, 1 /* 11000001 */, - 1 /* 11000010 */, 0 /* 11000011 */, 1 /* 11000100 */, - 0 /* 11000101 */, 0 /* 11000110 */, 1 /* 11000111 */, - 1 /* 11001000 */, 0 /* 11001001 */, 0 /* 11001010 */, - 1 /* 11001011 */, 0 /* 11001100 */, 1 /* 11001101 */, - 1 /* 11001110 */, 0 /* 11001111 */, 1 /* 11010000 */, - 0 /* 11010001 */, 0 /* 11010010 */, 1 /* 11010011 */, - 0 /* 11010100 */, 1 /* 11010101 */, 1 /* 11010110 */, - 0 /* 11010111 */, 0 /* 11011000 */, 1 /* 11011001 */, - 1 /* 11011010 */, 0 /* 11011011 */, 1 /* 11011100 */, - 0 /* 11011101 */, 0 /* 11011110 */, 1 /* 11011111 */, - 1 /* 11100000 */, 0 /* 11100001 */, 0 /* 11100010 */, - 1 /* 11100011 */, 0 /* 11100100 */, 1 /* 11100101 */, - 1 /* 11100110 */, 0 /* 11100111 */, 0 /* 11101000 */, - 1 /* 11101001 */, 1 /* 11101010 */, 0 /* 11101011 */, - 1 /* 11101100 */, 0 /* 11101101 */, 0 /* 11101110 */, - 1 /* 11101111 */, 0 /* 11110000 */, 1 /* 11110001 */, - 1 /* 11110010 */, 0 /* 11110011 */, 1 /* 11110100 */, - 0 /* 11110101 */, 0 /* 11110110 */, 1 /* 11110111 */, - 1 /* 11111000 */, 0 /* 11111001 */, 0 /* 11111010 */, - 1 /* 11111011 */, 0 /* 11111100 */, 1 /* 11111101 */, - 1 /* 11111110 */, 0 /* 11111111 */ -}; diff --git a/emu/z80pack-1.9/z80sim/simglb.h b/emu/z80pack-1.9/z80sim/simglb.h deleted file mode 100644 index 961cedb..0000000 --- a/emu/z80pack-1.9/z80sim/simglb.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english and ported to COHERENT 4.0 - * 03-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * Declaration of variables in simglb.c - */ - -extern BYTE A,B,C,D,E,H,L,A_,B_,C_,D_,E_,H_,L_,*PC,*STACK,I,IFF; -extern WORD IX,IY; -extern int F,F_; -extern long R; - -extern BYTE ram[],*wrk_ram; - -extern int s_flag,l_flag,m_flag,x_flag,break_flag,i_flag,f_flag, - cpu_state, cpu_error,int_type,int_mode,cntl_c,cntl_bs, - parrity[],sb_next; -extern float freq; - -extern char xfn[]; - -#ifdef HISIZE -extern struct history his[]; -extern int h_next, h_flag; -#endif - -#ifdef SBSIZE -extern struct softbreak soft[]; -#endif - -#ifdef WANT_TIM -extern long t_states; -extern int t_flag; -extern BYTE *t_start, *t_end; -#endif diff --git a/emu/z80pack-1.9/z80sim/simglb.o b/emu/z80pack-1.9/z80sim/simglb.o deleted file mode 100644 index 0312074..0000000 Binary files a/emu/z80pack-1.9/z80sim/simglb.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/simint.c b/emu/z80pack-1.9/z80sim/simint.c deleted file mode 100644 index ce1f3a4..0000000 --- a/emu/z80pack-1.9/z80sim/simint.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Z80SIM - a Z80-CPU simulator - * - * Copyright (C) 1987-2006 by Udo Munk - * - * History: - * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3 - * 11-JAN-89 Release 1.1 - * 08-FEB-89 Release 1.2 - * 13-MAR-89 Release 1.3 - * 09-FEB-90 Release 1.4 Ported to TARGON/31 M10/30 - * 20-DEC-90 Release 1.5 Ported to COHERENT 3.0 - * 10-JUN-92 Release 1.6 long casting problem solved with COHERENT 3.2 - * and some optimization - * 25-JUN-92 Release 1.7 comments in english - * 04-OCT-06 Release 1.8 modified to compile on modern POSIX OS's - */ - -/* - * This module contain the interrupt handlers for the OS: - * - * int_on() : initialize interrupt handlers - * int_off() : reset interrupts to default - * user_int() : handler for user interrupt (CNTL-C) - * quit_int() : handler for signal "quit" (CNTL-\) - * term_int() : handler for signal SIGTERM when process is killed - */ - -#include -#include -#include -#include -#include -#include "sim.h" -#include "simglb.h" - -static void user_int(int), quit_int(int), term_int(int); -extern void exit_io(void), int_off(); -extern struct termios old_term; - -void int_on(void) -{ - static struct sigaction newact; - - newact.sa_handler = user_int; - sigaction(SIGINT, &newact, NULL); - newact.sa_handler = quit_int; - sigaction(SIGQUIT, &newact, NULL); - newact.sa_handler = term_int; - sigaction(SIGTERM, &newact, NULL); -} - -void int_off(void) -{ - static struct sigaction newact; - - newact.sa_handler = SIG_DFL; - sigaction(SIGINT, &newact, NULL); - sigaction(SIGQUIT, &newact, NULL); - sigaction(SIGTERM, &newact, NULL); -} - -static void user_int(int sig) -{ -#ifdef CNTL_C - cpu_error = USERINT; - cpu_state = STOPPED; -#else - cntl_c++; -#endif -} - -static void quit_int(int sig) -{ -#ifdef CNTL_BS - cpu_error = USERINT; - cpu_state = STOPPED; -#else - cntl_bs++; -#endif -} - -static void term_int(int sig) -{ - exit_io(); - int_off(); - tcsetattr(0, TCSADRAIN, &old_term); - puts("\nKilled by user"); - exit(0); -} diff --git a/emu/z80pack-1.9/z80sim/simint.o b/emu/z80pack-1.9/z80sim/simint.o deleted file mode 100644 index cc8037e..0000000 Binary files a/emu/z80pack-1.9/z80sim/simint.o and /dev/null differ diff --git a/emu/z80pack-1.9/z80sim/z80sim b/emu/z80pack-1.9/z80sim/z80sim deleted file mode 100755 index 63ec827..0000000 Binary files a/emu/z80pack-1.9/z80sim/z80sim and /dev/null differ diff --git a/emu/z80pack-1.9/z80src/float.asm b/emu/z80pack-1.9/z80src/float.asm deleted file mode 100644 index 13c2652..0000000 --- a/emu/z80pack-1.9/z80src/float.asm +++ /dev/null @@ -1,837 +0,0 @@ -; -; this is a Z80 floating point package from an ancient german computer magazine -; I'm not going to translate this into english -; assemble this source with z80asm and run it under z80sim, if everything -; is working it should print the numbers below -; -; ******************************* -; * Fliesskomma-Arithmetik fuer * -; * den Z80-Mikroprozessor * -; * (mc 12/88, Seite 100 * -; ******************************* - -; ******************************************************** -; * Die folgende Testroutine liefert die Ausgabe: -; * 40400000 -; * 00700000 -; * 7F800000 -; * 35BFFFFF -; * 00400000 -; * 7F7FFFFF -; * 7F800000 -; * 406DB6DB -; * 15400001 - -START: - LD SP,STACK - LD BC,3F80H ; Aufruf der Additionsroutine - LD DE,0000H ; mit verschiedenen Parametern - PUSH BC ; entspricht 1 + 2 - PUSH DE - LD BC,4000H - LD DE,0000H - PUSH BC - PUSH DE - CALL F_ADD - CALL HEXOUT ; anschliessend Ausgabe - - LD BC,00F0H ; eine kleine, gerade noch normalisierte - LD DE,0000H ; Zahl, dazu die kleinste normalisierte - PUSH BC ; Zahl mit negativem Vorzeichen addieren - PUSH DE - LD BC,8080H - LD DE,0000H - PUSH BC - PUSH DE - CALL F_ADD - CALL HEXOUT - - LD BC,7F00H ; die Summe dieser beiden Zahlen - LD DE,0000H ; ergibt unendlich. Setzt man - PUSH BC ; fuer die zweite Zahl den Wert - PUSH DE ; 7EFFFFFE, so ist das Ergebnis - LD BC,7EFFH ; gerade MAXFLOAT - LD DE,0FFFFH - PUSH BC - PUSH DE - CALL F_ADD - CALL HEXOUT - - LD BC,0000H ; Multiplikation testen - LD DE,0003H ; MAXFLOAT * - PUSH BC - PUSH DE - LD BC,7F7FH - LD DE,0FFFFH - PUSH BC - PUSH DE - CALL F_MUL - CALL HEXOUT - - LD BC,0080H ; die kleinste normalisierte Zahl - LD DE,0000H ; mit 0.5 multiplizieren - PUSH BC ; (ergibt eine denormalisierte Zahl) - PUSH DE - LD BC,3F00H - LD DE,0000H - PUSH BC - PUSH DE - CALL F_MUL - CALL HEXOUT - - LD BC,4000H ; eine sehr grosse Zahl mit zwei - LD DE,0000H ; multiplizieren. Das Ergebnis - PUSH BC ; ist genau MAXFLOAT - PUSH DE - LD BC,7EFFH - LD DE,0FFFFH - PUSH BC - PUSH DE - CALL F_MUL - CALL HEXOUT - - LD BC,0000H ; Test der Divisionsroutine - LD DE,0000H ; hier 1 / 0 (ergibt unendlich) - PUSH BC - PUSH DE - LD BC,3F80H - LD DE,0000H - PUSH BC - PUSH DE - CALL F_DIV - CALL HEXOUT - - LD BC,40E0H ; jetzt 26 / 7 berechnen - LD DE,0000H - PUSH BC - PUSH DE - LD BC,41D0H - LD DE,0000H - PUSH BC - PUSH DE - CALL F_DIV - CALL HEXOUT - - LD BC,1FFFH ; jetzt eine sehr kleine - LD DE,0FFFFH ; denormalisierte Zahl durch - PUSH BC ; eine kleine normalisierte - PUSH DE ; Zahl dividieren - LD BC,0000H - LD DE,0003H - PUSH BC - PUSH DE - CALL F_DIV - CALL HEXOUT - - HALT ; Ende des Tests - - DEFS 100 -STACK: - -; ************************************************ -; * Zahl in BC-DE in 8 Hexadezimalziffern drucken. -; * Dazu werden nacheinander die Nibble-Paare in -; * B, C, D und E ausgedruckt. -; * - -HEXOUT: - LD A,B ; Nacheinander die einzelnen - CALL DIG2 ; Nibble-Paare in A laden - LD A,C ; und ausdrucken - CALL DIG2 - LD A,D - CALL DIG2 - LD A,E - CALL DIG2 - LD A,10 - CALL OUTCHAR - LD A,13 - CALL OUTCHAR - RET - -DIG2: - PUSH AF ; Nibble-Paar ausdrucken - RRCA ; unterstes Nibble retten - RRCA ; oberes Nibble rechtsbuendig - RRCA ; positionieren - RRCA - AND 00001111B - ADD A,90H ; binaer in ASCII (hex) - DAA - ADC A,40H - DAA - CALL OUTCHAR ; Zeichen ausgeben - POP AF ; jetzt unteres Nibble verarbeiten - AND 00001111B ; Nibble maskieren - ADD A,90H ; binaer in ASCII (hex) - DAA - ADC A,40H - DAA - CALL OUTCHAR - RET - -OUTCHAR: ; Zeichen auf Console ausgeben - OUT (0),A - RET - -; ********************************** -; * Globale Konstanten-Definitionen -; * fuer das Fliesskommapaket -; * - -MAXEXPO EQU 255 ; Maximal zulaessiger Exponent -BIAS EQU 127 ; Bias des Exponenten - -; ************************************************* -; * Fliesskomma-Addition in Single-Precision -; * Parameter: Operand 1 und Operand 2 ueber Stack -; * Ergebnis: in BC-DE: MSB in B, LSB in E -; * - -; * Es folgen Offset-Definitionen fuer Stack-relativen Zugriff - -FHL_ALT EQU 0 ; Top of Stack liegt HL -FADR EQU 2 ; dann die Ruecksprungadresse -OP1 EQU 4 ; jetzt Offset-Definitionen fuer -OP2 EQU 8 ; Parameter-Uebergabe - -OPSIZE EQU 4 ; Groesse eines Operanden - -F_ADD: - PUSH HL ; alten Basepointer retten - LD (F_STACK),SP ; aktuellen Stackpointer abspeichern - LD HL,(F_STACK) ; und in HL laden (= Basepointer) - PUSH AF ; benoetigte Register retten - PUSH IX - PUSH IY - LD BC,OP1 ; jeztz die Zeiger auf die - ADD HL,BC ; Operanden initialisieren - PUSH HL - POP IX ; IX zeigt auf Operand 1 - LD BC,OPSIZE - ADD HL,BC - PUSH HL - POP IY ; IY zeigt auf Operand 2 -F_ADSUB: - ADD HL,BC ; HL zeigt jetzt hinter die Operanden! - LD (F_STACK),HL ; diese Adresse fuer's Ende merken - LD A,(IX+3) ; Vorzeichen von Operand 1 laden - LD E,A ; Ergebnisvorzeichen in E, Bit 7 - XOR (IY+3) ; mit Vorzeichen von OP2 verknuepfen - LD D,A ; Subtraktionsflag in D, Bit 7 - RES 7,(IX+3) ; Vorzeichen in Mantisse 1 loeschen - RES 7,(IY+3) ; Vorzeichen in Mantisse 2 loeschen - -; Die Operanden sind jetzt in der Form: 0EEE EEEE EFFF ... FFFF - - LD A,(IX+0) ; Differenz OP1 - OP2 bilden - SUB (IY+0) - LD A,(IX+1) - SBC A,(IY+1) - LD A,(IX+2) - SBC A,(IY+2) - LD A,(IX+3) - SBC A,(IY+3) - JR NC,FAD_1 ; Sprung falls OP1 groesser als OP2 - PUSH IX ; ansonsten Operanden vertauschen - EX (SP),IY ; (eigentlich nur die Pointer), so - POP IX ; dass IY den Kleineren adressiert - LD A,E ; Ergebnisvorzeichen neu berechnen - XOR D - LD E,A -FAD_1: - LD A,(IX+2) - LD C,(IX+3) ; Exponent der groesseren Zahl laden - SLA A - RL C - JR Z,AD_DN1 - SET 7,(IX+2) ; implizite Eins erzeugen -AD_DN1: - LD A,(IY+2) - LD B,(IY+3) ; Exponent der kleineren Zahl laden - SLA A - RL B - JR Z,AD_DN2 - SET 7,(IY+2) ; implizite Eins erzeugen -AD_DN2: - PUSH BC ; Jetzt die Register fuer den - PUSH DE ; Blocktransferbefehl retten - LD BC,(OPSIZE*2)-1 ; beide Operanden verschieben - DEC HL ; HL zeigt auf letztes Byte - PUSH HL ; HL nach DE kopieren - POP DE - DEC HL ; HL zeigt auf vorletztes Byte - LDDR ; Verschiebung beider Mantissen - POP DE ; um 8 Bit nach links - POP BC - XOR A - LD (IX+0),A ; Form: FFFF ... FFFF 0000 0000 - LD (IY+0),A - LD A,C ; Differenz der Exponenten berechnen - SUB B - LD B,A ; Differenz nach B fuer Loop-Befehl - JR Z,AD_NAP ; falls Null, dann keine Anpassung - CP 25 ; mehr als 24? (Abfrage mit Carry - JP NC,AD_RND ; erfordert Vergleich mit 25) -AD_ANP: - SRL (IY+3) ; Anpassung der zweiten Mantisse - RR (IY+2) ; durch Verschiebung nach rechts - RR (IY+1) - RR (IY+0) - DJNZ AD_ANP ; Loop-Befehl bis B = 0 -AD_NAP: - BIT 7,D ; Subtraktion oder Addition? - JR NZ,SUBTR ; ggf. zur Subtraktion springen - LD A,(IX+0) ; jetzt werden die beiden Mantissen - ADD A,(IY+0) ; zueinander addiert - LD (IX+0),A - LD A,(IX+1) - ADC A,(IY+1) - LD (IX+1),A - LD A,(IX+2) - ADC A,(IY+2) - LD (IX+2),A - LD A,(IX+3) - ADC A,(IY+3) - LD (IX+3),A - JR NC,AD_RND ; kein Ueberlauf --> zum Runden - RR (IX+3) ; Ueberlauf einschieben - RR (IX+2) ; und Exponent erhoehen - RR (IX+1) ; durch die Vorgeschichte ist - RR (IX+0) ; gesichert, dass B Null ist; BC - INC BC ; enthaelt den 16-Bit-Exponent - JR AD_RND ; und zum Runden -SUBTR: - LD A,(IX+0) ; Die beiden Mantissen werden - SUB (IY+0) ; voneinander subtrahiert - LD (IX+0),A - LD A,(IX+1) - SBC A,(IY+1) - LD (IX+1),A - LD A,(IX+2) - SBC A,(IY+2) - LD (IX+2),A - LD A,(IX+3) - SBC A,(IY+3) - LD (IX+3),A - JP M,AD_RND ; bei fuehrender Eins zum Runden - JR NZ,AD_NRM ; ungleich Null: Normalisieren - CP (IX+2) ; Rest der Mantisse auch Null? - JR NZ,AD_NRM - CP (IX+1) - JR NZ,AD_NRM - CP (IX+0) - JR Z,AD_ZERO ; alles Null --> Ergebnis ist Null -AD_NRM: - XOR A ; A = 0 -AD_NR1: - CP C ; Exponent ist Null? - JR NZ,AD_NR2 ; nein, Normierung moeglich - CP B ; oberes Byte auch Null? - JR Z,AD_RND ; dann ist Ergebnis denormalisiert -AD_NR2: - DEC BC ; Exponent erniedrigen - SLA (IX+0) ; Mantisse normalisieren bis - RL (IX+1) ; fuehrende Eins auftaucht - RL (IX+2) - RL (IX+3) - JP P,AD_NR1 ; weiter bis fuehrende Eins auftaucht -AD_RND: - LD A,(IX+0) ; jetzt Runden auf Bit hinter - ADD A,80H ; Mantisse - JR NC,AD_NOV ; kein Uebertrag? - INC (IX+1) ; doch, naechstes Mantissenbyte - JR NZ,AD_NOV ; behandeln, jetzt auf Null pruefen, - INC (IX+2) ; da der INC-Befehl kein Carry liefert - JR NZ,AD_NOV - INC (IX+3) - JR NZ,AD_NOV - SCF ; Eins erzeugen - RR (IX+3) ; bei Ueberlauf Mantisse durch - RR (IX+2) ; Rechtsschieben wieder normalisieren - RR (IX+1) ; (nur noch 24 Bit noetig) - INC BC ; und Exponent korrigieren -AD_NOV: - XOR A ; A = 0 - CP (IX+3) ; Mantisse auf Null pruefen - JR NZ,AD_NOZ - CP (IX+2) - JR NZ,AD_NOZ - CP (IX+1) ; alle Mantissenbytes Null? - JR NZ,AD_NOZ ; dann ist auch das Ergebnis Null -AD_ZERO: ; Null Ergebnis aufbauen - LD B,A - LD C,A - LD D,A - LD E,A - JR AD_EXIT ; dann Routine verlassen -AD_NOZ: - CP B ; A ist 0 - LD A,MAXEXPO ; Exponent oberstes Byte ungleich Null? - JR NZ,AD_OVR ; dann ist Ueberlauf eingetreten - CP C ; oder genau maxexpo erreicht? - JR NZ,AD_NUE ; nein, --> kein Ueberlauf -AD_OVR: - LD C,A ; Exponent auf maxexpo setzen - XOR A ; und Mantisse auf Null - LD (IX+3),A ; fuer unendlich - LD (IX+2),A - LD (IX+1),A - JR AD_DEN -AD_NUE: - XOR A ; A = 0 - CP C ; Exponent Null (Zahl denormalisiert)? - JR Z,AD_DEN ; ja, --> - SLA (IX+1) ; fuehrendes Bit wird nicht gespeichert - RL (IX+2) ; daher Mantisse um 1 Bit nach links - RL (IX+3) -AD_DEN: - LD B,C ; Ergebnis aufbauen: Exponent in B - LD C,(IX+3) ; Mantisse oberstes Byte - LD D,(IX+2) - SLA E ; Vorzeichen aus E in Carry schieben - LD E,(IX+1) - RR B ; Vorzeichen in Ergebnis einschieben - RR C - RR D - RR E -AD_EXIT: - POP IY ; Register restaurieren - POP IX - POP AF - POP HL - LD (F_HL),HL ; HL zwischenspeichern - EX (SP),HL ; alte Ruecksprungadresse in HL - LD SP,(F_STACK) ; Stack zuruecksetzen - PUSH HL ; Ruecksprungadresse ablegen - LD HL,(F_HL) ; HL wieder laden - RET ; Ende des Unterprogramms - -; ************************************************* -; * Fliesskomma-Subtraktion in Single-Precision -; * Parameter: Operand 1 und Operand 2 ueber Stack -; * Ergebnis: in BC-DE: MSB in B, LSB in E -; * - -F_SUB: - PUSH HL ; alten Basepointer retten - LD (F_STACK),SP ; aktuellen Stackpointer abspeichern - LD HL,(F_STACK) ; und in HL laden (= Basepointer) - PUSH AF ; benoetigte Register retten - PUSH IX - PUSH IY - LD BC,OP1 - ADD HL,BC - PUSH HL - POP IX ; IX zeigt auf Operand 1 - LD BC,OPSIZE - ADD HL,BC - PUSH HL - POP IY ; IY zeigt auf Operand 2 - LD A,80H - XOR (IY+3) ; Vorzeichenbit von Operand 2 umdrehen - LD (IY+3),A ; wieder abspeichern - JP F_ADSUB ; jetzt weiter bei Additionsroutine - -; ************************************************* -; * Fliesskomma-Multiplikation in Single-Precision -; * Parameter: Operand 1 und Operand 2 ueber Stack -; * Ergebnis: in BC-DE: MSB in B, LSB in E -; * - -TEMP EQU -10 ; Offset lokale Variable (6 Byte) - -F_MUL: - PUSH HL ; alten Basepointer retten - LD (F_STACK),SP ; aktuellen Stackpointer abspeichern - LD HL,(F_STACK) ; und in HL laden (= Basepointer) - PUSH AF ; benoetigte Register retten - PUSH IX - PUSH IY - LD BC,OP1 - ADD HL,BC - PUSH HL - EX (SP),IX ; IX zeigt auf Operand 1 - ; 2 Dummy-Byte auf Stack fuer lokale - LD BC,OPSIZE ; Variable bleiben stehen - ADD HL,BC - PUSH HL - EX (SP),IY ; IY zeigt auf Operand 2 - PUSH HL ; insgesamt 6 Byte fuer lokale Variable - ADD HL,BC ; HL zeigt jetzt hinter die Operanden! - LD (F_STACK),HL - LD A,(IX+3) ; Ergebnisvorzeichen bestimmen - XOR (IY+3) - LD C,A ; Vorzeichen in C Bit 7 merken - LD D,0 ; Exponent 1 laden - LD E,(IX+3) - LD A,(IX+2) ; Operand um 8 Bit nach links schieben - LD (IX+3),A - RES 7,(IX+3) ; implizite Null vorbesetzen - SLA A ; Exponent unterstes Bit in Carry - RL E ; und in E einschieben - JR Z,MU_DN1 ; falls Null, dann OP1 denormalisieren - SET 7,(IX+3) ; implizite Eins erzeugen - DEC DE ; Bias kompensieren -MU_DN1: - LD A,(IX+1) ; jetzt restliche Bytes verschieben - LD (IX+2),A - LD A,(IX+0) - LD (IX+1),A - XOR A ; unterste Mantissenbits loeschen - LD (IX+0),A ; Form: FFFF ... FFFF 0000 0000 - LD (IX+TEMP+5),A ; lokale Variable mit Null vorbesetzen - LD (IX+TEMP+4),A - LD (IX+TEMP+3),A - LD (IX+TEMP+2),A - LD (IX+TEMP+1),A - LD (IX+TEMP+0),A - LD H,A ; Exponent 2 in HL aufbauen - LD L,(IY+3) - LD A,(IY+2) - RES 7,(IY+2) ; implizite Null vorbesetzen - SLA A - RL L - JR Z,MU_DN2 ; gleich Null, dann Op2 denormalisieren - SET 7,(IY+2) ; implizite Eins erzeugen - DEC HL ; Bias kompensieren -MU_DN2: - ADD HL,DE ; Exponenten aufaddieren - LD DE,3-BIAS ; Bias-3 subtrahieren - ADD HL,DE ; bzw. 3-Bias addieren - JP P,MU_NOZ - LD A,L ; Exponent kleiner als -24? - CP -24 - JR NC,MU_NOZ - JP MU_ZERO ; ja, dann ist das Ergebnis Null -MU_NOZ: - LD B,24 ; Multiplikationsschleifenzaehler - LD DE,0 ; Hilfsregister fuer Multiplikand -MU_MUL: - SRL (IX+3) ; Multiplikand nach rechts schieben - RR (IX+2) - RR (IX+1) - RR (IX+0) - RR D ; DE als Verlaengerung von Operand 1 - RR E - SLA (IY+0) ; Multiplikator nach links schieben - RL (IY+1) - RL (IY+2) ; falls fuehrendes Bit Null ist, dann - JR NC,MU_NAD ; muss nicht addiert werden - LD A,(IX+TEMP+0) ; sonst Multiplikand aufaddieren - ADD A,E - LD (IX+TEMP+0),A - LD A,(IX+TEMP+1) - ADC A,D - LD (IX+TEMP+1),A - LD A,(IX+TEMP+2) - ADC A,(IX+0) - LD (IX+TEMP+2),A - LD A,(IX+TEMP+3) - ADC A,(IX+1) - LD (IX+TEMP+3),A - LD A,(IX+TEMP+4) - ADC A,(IX+2) - LD (IX+TEMP+4),A - LD A,(IX+TEMP+5) - ADC A,(IX+3) - LD (IX+TEMP+5),A -MU_NAD: - DJNZ MU_MUL ; Schleife durchlaufen - LD A,(IX+TEMP+5) - OR A ; Flags setzen - JP M,MU_RND ; bei fuerender Eins zum Runden - JR NZ,MU_NOR ; ungleich Null --> normalisieren - CP (IX+TEMP+4) - JR NZ,MU_NOR - CP (IX+TEMP+3) - JR NZ,MU_NOR - CP (IX+TEMP+2) - JR NZ,MU_NOR - JP MU_ZERO ; Mantisse komplett Null --> Null -MU_NOR: - XOR A ; A = 0 - OR H ; Exponent ist negativ? - JP M,MU_UNT ; ggf. Unterlauf behandeln -MU_NR1: - XOR A ; A = 0 - CP L ; Exponent = Null? - JR NZ,MU_NR2 - CP H ; bei Null zum Runden - JR Z,MU_RND -MU_NR2: - DEC HL ; Exponent erniedrigen - SLA (IX+TEMP+0) - RL (IX+TEMP+1) - RL (IX+TEMP+2) ; Mantisse solange nach links - RL (IX+TEMP+3) ; verschieben bis fuerende Eins - RL (IX+TEMP+4) ; auftaucht - RL (IX+TEMP+5) - JP P,MU_NR1 -MU_RND: - LD A,(IX+TEMP+2) ; jetzt Runden auf Bit hinter - ADD A,80H ; Mantisse - JR NC,MU_NOV ; kein Uebertrag? - INC (IX+TEMP+3) ; doch, naechstes Mantissenbyte - JR NZ,MU_NOV ; behandeln, jetzt auf Null pruefen - INC (IX+TEMP+4) ; da der INC-Befehl kein Carry liefert - JR NZ,MU_NOV - INC (IX+TEMP+5) - JR NZ,MU_NOV - SCF ; Eins erzeugen - RR (IX+TEMP+5) ; bei Ueberlauf Mantisse durch - RR (IX+TEMP+4) ; Rechtsschieben wieder normalisieren - RR (IX+TEMP+3) - INC HL ; und Eponent korrigieren -MU_NOV: - XOR A ; A = 0 - CP H ; Exponent pruefen - LD A,MAXEXPO ; A vorbesetzen - JR NZ,MU_OVR ; groesser Null: Ueberlauf behandeln - CP L ; oder genau maxexpo erreicht? - JR NZ,MU_NUE ; nein, kein Ueberlauf -MU_OVR: - LD L,MAXEXPO ; Ueberlauf: Exponent = maxexpo - XOR A ; Mantisse = Null - LD (IX+TEMP+5),A - LD (IX+TEMP+4),A - LD (IX+TEMP+3),A - JR MU_DEN -MU_NUE: - XOR A ; A = 0 - CP L ; Exponent ist Null? - JR Z,MU_DEN ; ja, Ergebnis ist denormalisiert - SLA (IX+TEMP+3) ; nein, fuehrendes Mantissenbit - RL (IX+TEMP+4) ; rausschieben - RL (IX+TEMP+5) -MU_DEN: - SLA C ; Vorzeichen in Carry schieben - LD B,L ; Exponent einsetzen - LD C,(IX+TEMP+5) - LD D,(IX+TEMP+4) - LD E,(IX+TEMP+3) - RR B ; und Vorzeichen einschieben - RR C - RR D ; Form: SEEE EEEE EFFF FFFF ... FFFF - RR E -MU_RES: - POP HL ; lokale Variable deallozieren - POP HL - POP HL - POP IY ; Register restaurieren - POP IX - POP AF - POP HL - LD (F_HL),HL ; Parameter vom Stack deallozieren - EX (SP),HL - LD SP,(F_STACK) - PUSH HL - LD HL,(F_HL) - RET ; und return -MU_ZERO: - XOR A ; Ergebnis ist Null - LD B,A - LD C,A - LD D,A - LD E,A - JR MU_RES -MU_UNT: - LD A,L ; Exponent in A - NEG ; negieren fuer Schleifenzaehler - CP 24 ; totaler Ueberlauf? - JR NC,MU_ZERO ; ja, dann ist Ergebnis Null - LD B,A ; in B fuer Loop -MU_SHR: - SRL (IX+TEMP+5) ; Mantisse denormalisieren - RR (IX+TEMP+4) ; bis Exponent Null ist - RR (IX+TEMP+3) - DJNZ MU_SHR - LD L,B ; Exponent in Register L = B = 0 - JP MU_DEN ; denormalisiertes Ergebnis erzeugen - -; ************************************************* -; * Fliesskomma-Division in Single-Precision -; * Parameter: Operand 1 und Operand 2 ueber Stack -; * Ergebnis: in BC-DE: MSB in B, LSB in E -; * - -F_DIV: - PUSH HL ; alten Basepointer retten - LD (F_STACK),SP ; aktuellen Stackpointer abspeichern - LD HL,(F_STACK) ; und in HL laden (= Basepointer) - PUSH AF ; benoetigte Register retten - PUSH IX - PUSH IY - LD BC,OP1 - ADD HL,BC - PUSH HL - EX (SP),IX ; IX zeigt auf Operand 1 - ; 2 Dummy-Byte auf Stack fuer lokale - LD BC,OPSIZE ; Variable bleiben stehen - ADD HL,BC - PUSH HL - EX (SP),IY ; IY zeigt auf Operand 2 - PUSH HL ; insgesamt 6 Byte fuer lokale Variable - ADD HL,BC ; HL zeigt jetzt hinter die Operanden! - LD (F_STACK),HL - LD A,(IX+3) ; Ergebnisvorzeichen bestimmen - XOR (IY+3) - LD C,A ; Vorzeichen in C Bit 7 merken - LD H,0 ; Exponent 1 laden - LD L,(IX+3) - LD A,(IX+2) - RES 7,(IX+2) ; implizite Null vorbesetzen - SLA A ; Exponent unterstes Bit in Carry - RL L ; und in E einschieben - JR Z,DV_DN1 ; falls Null, dann Op1 denormalisieren - SET 7,(IX+2) ; implizite Eins erzeugen - DEC HL ; Bias kompensieren -DV_DN1: - LD D,0 ; Exponent 2 in DE aufbauen - LD E,(IY+3) - LD A,(IY+2) - LD (IY+3),A ; Mantisse um 8 Bit verschieben - RES 7,(IY+3) ; implizite Null vorbesetzen - SLA A - RL E - JR Z,DV_DN2 ; gleich Null, dann Op2 denormalisieren - SET 7,(IY+3) ; implizite Eins erzeugen - DEC DE ; Bias kompensieren -DV_DN2: - LD A,(IY+1) ; jetzt restliche Bytes verschieben - LD (IY+2),A - LD A,(IY+0) - LD (IY+1),A - XOR A ; A = 0 - LD (IY+0),A ; Form: FFFF ... FFFF 0000 0000 - SRL (IY+3) - RR (IY+2) - RR (IY+1) - RR (IY+0) ; Form: 0FFF ... FFFF F000 0000 - JR NZ,DV_NZ1 ; Mantisse 2 auf Null pruefen - CP (IY+1) - JR NZ,DV_NZ1 - CP (IY+2) - JR NZ,DV_NZ1 - CP (IY+3) - JR NZ,DV_NZ1 - JP MU_OVR ; Bei Division durch Null: unendlich -DV_NZ1: - XOR A ; Carry-Flag loeschen - SBC HL,DE ; Exponenten subtrahieren - LD DE,BIAS ; Bias addieren - ADD HL,DE - BIT 7,H ; Exponent positiv? - JR Z,DV_NOZ - LD A,L ; Exponent kleiner als -24? - JR NC,DV_NOZ - JP MU_ZERO ; ja, dann ist das Ergebnis Null -DV_NOZ: - PUSH BC ; Vorzeichen retten - LD DE,25 ; Exponent um 25 erhoehen - ADD HL,DE ; jetzt ist er sicher groesser als Null - XOR A ; A = 0 - LD B,(IX+2) ; Divident in Register kopieren - LD C,(IX+1) - LD D,(IX+0) - LD E,A ; die untersten Bits sind Null - CP D ; ist Dividend Null? - JR NZ,DV_NZ2 - CP C - JR NZ,DV_NZ2 - CP B - JR NZ,DV_NZ2 - POP BC ; Stack bereinigen (Vorzeichen laden) - JP MU_ZERO ; und Null als Ergebnis ausgeben -DV_NZ2: - LD (IX+TEMP+5),A ; Ergebnis vorbesetzen - LD (IX+TEMP+4),A - LD (IX+TEMP+3),A - LD (IX+TEMP+2),A -DV_NLP: - BIT 6,(IY+3) ; ist der Divisor normalisiert - JR NZ,DV_NOR ; ja, --> - INC HL ; nein, Exponent erhoehen - SLA (IY+0) ; Divisor verschieben bis in - RL (IY+1) ; Form 01FF ... - RL (IY+2) - RL (IY+3) - JR DV_NLP -DV_NOR: - SRL B - RR C - RR D - RR E ; Form: 0FFF ... FFFF F000 0000 -DV_LOP: - LD (IX+3),B ; Dividend zwischenspeichern - LD (IX+2),C ; die Speicherplaetze von Op1 - LD (IX+1),D ; stehen zur Verfuegung, da wir OP1 - LD (IX+0),E ; in die Register BC-DE kopiert haben - LD A,E ; jetzt Divisor abziehen - SUB (IY+0) - LD E,A - LD A,D - SBC A,(IY+1) - LD D,A - LD A,C - SBC A,(IY+2) - LD C,A - LD A,B - SBC A,(IY+3) - LD B,A - JR NC,DV_ONE ; kein Carry: Divisor passt - LD E,(IX+0) ; zurueckkopieren - LD D,(IX+1) ; Carry bleibt dabei erhalten - LD C,(IX+2) - LD B,(IX+3) -DV_ONE: - CCF ; Carry-Flag umkehren - RL (IX+TEMP+2) ; Ergebnis aufbauen - RL (IX+TEMP+3) - RL (IX+TEMP+4) - RL (IX+TEMP+5) - SLA E ; Dividend verschieben - RL D - RL C - RL B - DEC HL ; Exponent erniedrigen - XOR A ; A = 0 - CP L ; Exponent = Null ? - JR NZ,DV_DIV - CP H - JR Z,DV_DEN ; falls Null, dann denormalisiert -DV_DIV: - BIT 0,(IX+TEMP+5) ; fuerende Eins in Ergebnis-Mantisse? - JR Z,DV_LOP ; nein, weiter rechnen -DV_DEN: - LD B,(IX+TEMP+5) ; hoechstes Bit merken - LD A,(IX+TEMP+4) - LD (IX+TEMP+5),A ; Mantisse in Form - LD A,(IX+TEMP+3) ; FFFF ... FFFF 0000 0000 - LD (IX+TEMP+4),A - LD A,(IX+TEMP+2) - LD (IX+TEMP+3),A - RR B ; hoechstes Bit einschieben - RR (IX+TEMP+5) - RR (IX+TEMP+4) - RR (IX+TEMP+3) ; Form: FFFF ... FFFF F000 0000 - RR (IX+TEMP+2) - POP BC ; Vorzeichen wieder laden - XOR A ; A = 0 - CP (IX+TEMP+5) ; Mantisse ist Null? - JR NZ,DV_NZ3 - CP (IX+TEMP+4) - JR NZ,DV_NZ3 - CP (IX+TEMP+3) - JR NZ,DV_NZ3 - CP (IX+TEMP+2) - JP Z,MU_ZERO ; dann ist Ergebnis auch Null -DV_NZ3: - JP MU_RND ; sonst weiter wie bei Multiplikation - -F_STACK: - DEFS 2 ; Hilfsspeicher fuer Stackpointer -F_HL: - DEFS 2 ; Hilfsspeicher fuer Basepointer HL - - END diff --git a/emu/z80pack-1.9/z80src/z80dis.asm b/emu/z80pack-1.9/z80src/z80dis.asm deleted file mode 100644 index 03a1217..0000000 --- a/emu/z80pack-1.9/z80src/z80dis.asm +++ /dev/null @@ -1,638 +0,0 @@ - TITLE 'Z80-Disassembler' - -; Hardware-unabhaengiger, ROM-faehiger Z80-Disassembler -; -; Die Adresse, ab der disassembliert serden soll, ist in der -; 16-Bit Speicherzelle DADR abzulegen. Danach kann eines der -; Entrys DISSCR (Ausgabe eines Bildschirms) oder DISLIN -; (Ausgabe einer Zeile) aufgerufen werden. Da die Folgeadressen -; durch das Programm ebenfalls wieder in der Speicherzelle -; DADR abgelegt werden, ist mehrfacher Aufruf ohne Laden -; von neuen Adressen moeglich. -; Zur Ausgabe muss ein Unterprogramm mit dem Namen PRTSTR -; erstellt werden, dem in HL die Adresse eines Null-terminierten -; Strings uebergeben wird. -; -; 27-JUN-89 Udo Munk - -LPP EQU 15 ; Anzahl Zeilen/Bildschirm Ausgabe -MNEPOS EQU 11H ; Offset des Mnemonics in Ausgabe-Workspace - - ; Disassembliere einen Bildschirm voll -DISSCR: LD B,LPP ; einen Bildschirm mit LPP Zeilen -$DLP1: PUSH BC ; disassemblieren - CALL DISLIN - POP BC - DJNZ $DLP1 - RET - - ; Disassembliere eine Zeile -DISLIN: CALL CLWO ; Workspace fuer eine Zeile Ausgabe loeschen - LD HL,WRKS ; Adresse der Ausgabe-Workspace -> HL - LD DE,(DADR) ; Disassemblier-Adresse -> DE - CALL PRBY ; Adresse in DE ausgeben - INC HL ; Blank ausgeben - LD (PRTMP),HL ; vordere Printposition retten - LD C,0 ; Steuerflag loeschen - DEC DE ; laufende Adr.-1 -> DE -$DL13: CALL PRNB ; laufendes Byte ausgeben - LD A,(DE) ; laufendes Byte -> A - LD B,A ; und in B retten - CP 0EDH ; Preafix ED ? - JR NZ,$DL14 - SET 4,C ; ja, ED-Flag setzen - JR $DL13 ; und naechstes Byte bearbeiten -$DL14: CP 0FDH ; Preafix FD ? - JR NZ,$DL15 - SET 6,C ; ja, FD-Flag setzen - JR $DL16 ; und Index-Flag setzen -$DL15: CP 0DDH ; Preafix DD ? - JR NZ,$DL17 -$DL16: SET 5,C ; Index-Flag fuer IX/IY-Adressierung setzen - LD HL,(PRTMP) ; vordere Printposition -> HL - JR $DL13 ; naechstes Byte bearbeiten -$DL17: LD HL,WRKS+MNEPOS ; HL auf Operator Position setzen - - ; nach Praefix CB -CB: LD A,B ; Befehlsbyte aus B holen - CP 0CBH ; Preafix CB ? - JP NZ,OHNE - INC DE ; ja, Pointer auf naechstes Byte setzen - BIT 5,C ; IX/IY-Flag ? - JR Z,$DL18 - INC DE ; ja, Pointer auf naechstes Byte setzen -$DL18: LD A,(DE) ; naechstes Byte -> A - LD B,A ; und in B retten - PUSH DE ; Disassemblieradr. retten - LD D,MNETAB > 8 ; High-Byte Operatorentabelle -> D - LD E,0E8H ; DE = Pointer auf "SET" - CP 0C0H ; SET ? - JR NC,$DL19 - LD E,0E4H ; nein, DE = Pointer auf "RES" - CP 80H ; RES ? - JR NC,$DL19 - LD E,0E0H ; nein, DE = Pointer auf "BIT" - CP 40H ; BIT ? - JR NC,$DL19 - AND 38H ; loesche Bits 0..2 und 6..7 - RRCA ; Division durch 2 - ADD A,CBMTAB & 0FFH ; zur Basis der CB-Mnemonics addieren - LD E,A - LD D,CBMTAB > 8 ; DE = Pointer auf CB-Mnemonic -$DL19: CALL TRBY ; Mnemonic ausgeben - POP DE ; akt. Disassemblieradr. wieder -> DE - LD A,B ; Byte wieder -> A - BIT 5,C ; IX/IY-Flag ? - JR Z,$DL20 - DEC DE ; eins zurueck bei IX/IY-Adressierung -$DL20: DEC DE ; Pointer wieder auf CB-Preafix - CP 40H ; CB-Befehl < 40H ? - JR C,$DL21 - AND 38H ; nein, Bits 0..2 und 6..7 loeschen - RRCA ; Division durch 8 -> 1. Operanden - RRCA - RRCA - CALL PRO1 ; 1. Operanden ausgeben - LD A,B ; Byte wieder -> A - SET 7,C ; Komma-Flag setzen -$DL21: AND 7 ; Bits 3..7 loeschen -> 2. Operanden - SET 4,A ; Buchstaben-Flag setzen - CALL PRO1 ; 2. Operanden ausgeben - CALL PRNB ; Befehlsbyte vorne ausgeben - JP INAD ; fertig, Adresse merken und Workspace ausgeben - - ; ohne Preafix CB/ED -OHNE: PUSH DE ; Disassemblieradr. retten - BIT 4,C ; ED-Flag ? - JP NZ,ED - CP 40H ; nein, < 40H ? - JR C,$DL25 - CP 80H ; nein, > 80H ? - JR NC,$DL23 - LD E,50H ; nein, DE = Pointer auf "LD" - CP 76H ; HALT ? - JR NZ,$DL22 - LD E,5CH ; nein, DE = Pointer auf "HALT" -$DL22: JR $DL26 ; Mnemonic ausgeben -$DL23: CP 0C0H ; > C0H ? - JR NC,$DL24 - AND 38H ; ja, Bits 0..2 und 6..7 loeschen - RRCA ; Division durch 2 -> Operator - LD E,A ; Operator -> E - JR $DL26 ; Mnemonic ausgeben -$DL24: SUB 80H ; wenn > C0H, -80 -> Tabellenoperator -$DL25: LD E,A ; Operator -> E - LD D,CODTAB > 8 ; High-Byte Operatortabelle -> D - LD A,(DE) ; LSB Mnemonic-Adresse -> A - LD E,A ; und nach E -$DL26: LD D,MNETAB > 8 ; MSB Mnemonic-Adresse -> D - CALL TRBY ; Mnemonic ausgeben - POP DE ; akt. Disassemblieradr. wieder -> DE - LD A,B ; Befehlsbyte wieder -> A - PUSH DE ; Disassemblieradr. retten - CP 40H ; Byte < 40 ? - JR C,$DL30 - CP 80H ; nein, > 80 ? - JR NC,$DL28 - CP 76H ; nein, HALT ? - JR NZ,$DL27 - LD A,0FFH ; ja, leeren Operanden -> A - JR $DL31 ; Operanden ausgeben -$DL27: AND 38H ; loesche Bits 0..2 und 6..7 - RRCA ; Division durch 8 -> 1. Operanden - RRCA - RRCA - SET 4,A ; Buchstabenflag setzen - JR $DL31 ; Operanden ausgeben -$DL28: CP 0C0H ; > C0 ? - JR NC,$DL29 - CP 90H ; > 90 ? - JR C,$DL51 - AND 0F8H ; ja, Register-Bits loeschen - CP 98H ; "SBC" ? - JR Z,$DL51 - LD A,B ; Byte wieder -> A - AND 7 ; nur Register Bits uebrig lassen - SET 4,A ; Buchstaben-Flag setzen - JR $DL52 -$DL51: LD A,17H ; ja, 17 = Register A ausgeben - JR $DL31 ; Operanden ausgeben -$DL29: SUB 80H ; wenn > C0, -80 -> Operandentabelle -$DL30: LD E,A ; LSB Operandentabelle -> E - LD D,OPETAB > 8 ; MSB Operandentabelle -> D - LD A,(DE) ; 1. Operanden -> A -$DL31: POP DE ; akt. Disassemblieradr. wieder -> DE - CALL PRO1 ; 1. Operanden ausgeben - LD A,B ; Befehlsbyte wieder -> A - PUSH DE ; akt. Disassemblieradr. retten - CP 40H ; < 40 ? - JR C,$DL34 - CP 0C0H ; nein, < C0 ? - JR NC,$DL33 - CP 76H ; ja, HALT ? - JR NZ,$DL32 - LD A,0FFH ; ja, wieder leeren Operanden -> A - JR $DL35 ; Operanden ausgeben -$DL32: AND 7 ; loesche Bits 3..7, -> 2. Operanden - SET 4,A ; Buchstabenflag setzen - JR $DL35 ; Operanden ausgeben -$DL33: SUB 80H ; wenn > C0 : 80 abziehen -$DL34: ADD A,80H ; LSB Operandentabelle -> A - LD E,A ; und -> E - LD D,OPETAB > 8 ; MSB Operandentabelle -> D - LD A,(DE) ; 2. Operanden -> A -$DL35: POP DE ; akt. Disassemblieradr. wieder -> DE - SET 7,C ; Komma-Flag setzen - CALL PRO1 ; 2. Operanden ausgeben - JP INAD ; fertig, Adresse merken und Workspace ausgeben - - ; nach Preafix ED -ED: SUB 40H ; 40 vom 2. Byte subtrahieren - JP C,ERRO ; Fehler wenn carry - CP 60H ; 2. Byte < A0 ? - JR NC,$DL36 - CP 40H ; ja, >= 60 ? - JP NC,ERRO ; ja, Fehler - JR $DL37 ; nein, weiter -$DL36: SUB 20H ; aus 60..7F wird 00..20 -$DL37: ADD A,80H ; LSB Operatortabelle -> A - LD E,A ; und -> E - LD D,CODTAB > 8 ; MSB Operatortabelle -> D - LD A,(DE) ; LSB Mnemonic-Adresse -> A - CP 0FFH ; leer ? - JP Z,ERRO ; ja, Fehler - LD E,A ; nein, -> E - LD D,MNETAB > 8 ; MSB Mnemonic-Adresse -> D - CALL TRBY ; Mnemonic ausgeben - POP DE ; Disassemblieradr. wieder -> DE - LD A,B ; Befehlsbyte wieder -> A - CP 80H ; < 80 ? - JP NC,INAD ; nein, Workspace ausgeben und fertig - PUSH DE ; Disassemblieradr. retten - SUB 40H ; LSB 1. Operanden in A - LD E,A ; und -> E - LD D,OP2TAB > 8 ; MSB 2. Operanden -> D - LD A,(DE) ; 1. Operanden -> A - POP DE ; akt. Disassemblieradr. wieder -> DE - CALL PRO1 ; 1. Operanden ausgeben - LD A,B ; Befehlsbyte wieder -> A - CP 80H ; < 80 ? - JP NC,INAD ; ja, Workspace ausgeben und fertig - PUSH DE ; akt. Disassemblieradr. retten - LD E,A ; LSB Operandentabelle -> E - LD D,OP2TAB > 8 ; MSB Operandentabelle -> D - LD A,(DE) ; 2. Operanden -> A - SET 7,C ; Buchstabenflag setzen -$DL52: POP DE ; akt. Disassemblieradr. retten - CALL PRO1 ; 2. Operanden ausgeben - JP INAD ; fertig, Adresse merken und Workspace ausgeben - - ; Operand 1 ausgeben -PRO1: CP 0FFH ; leere Operand ? - RET Z ; ja, fertig - CP 17H ; nein, Register "A" ausgeben ? - JR NZ,$DL01 - LD A,18H ; ja, umkodieren -$DL01: CP 16H ; Register "(HL)" ausgeben ? - JR NZ,$DL02 - LD A,0B4H ; ja, umkodieren -$DL02: BIT 7,C ; 2. Operand ? - JR Z,$DL03 - LD (HL),',' ; ja, "," ausgeben - INC HL ; naechste Printposition -> HL -$DL03: BIT 7,A ; "(...)" ? - JR Z,$DL04 - LD (HL),'(' ; ja, "(" ausgeben - INC HL ; naechste Printposition -> HL -$DL04: BIT 4,A ; Buchstabe ? - JR NZ,PRBU ; ja, Buchstaben ausgeben - BIT 6,A ; nein, Bitnummer/RST-Adresse ? - JR NZ,DIST ; ja, Distanz ausgeben - BIT 5,A ; nein, Bitnummer ? - JR NZ,PRO2 ; ja, RST ausgeben - AND 7 ; nein, Bits 3..7 loeschen - CALL PRCH ; Hexbyte ausgeben - RET - - ; RST ausgeben -PRO2: PUSH AF ; A retten - AND 6 ; loesche Bits 0 und 4..7 - RRCA ; Division durch 2 - CALL PRCH ; oberes Nibble ausgeben - POP AF ; A wieder herstellen - BIT 0,A ; RST x8 ? - LD A,'0' ; nein, "0" -> A - JR Z,$DL05 - LD A,'8' ; ja, "8" -> A -$DL05: LD (HL),A ; "0" oder "8" ausgeben - INC HL ; naechste Printposition -> HL - RET - - ; Distanz ausgeben -DIST: BIT 0,A ; relative Distanz ? - JR Z,PR_N ; nein, N ausgeben - CALL PRNB ; Byte vorne ausgeben - PUSH DE ; akt. Disassemblieradr. retten - LD A,(DE) ; Distanzbyte -> A - INC DE ; Disassemblieradr. erhoehen - RLCA ; Bit 7 Distanzbyte -> carry - RRCA - JR NC,$DL06 ; Vorwaertsprung - SET 0,C ; Flag fuer Rueckwaertssprung setzen -$DL06: ADD A,E ; Distanz zu PC addieren - LD E,A - BIT 0,C ; Flag testen - JR NC,$DL07 ; kein Ueberlauf - JR NZ,$DL08 ; Rueckwaertssprung - INC D ; MSB PC erhoehen - JR $DL08 ; Zieladresse ausgeben -$DL07: JR Z,$DL08 ; bei Vorwaertssprung Zieladresse ausgeben - DEC D ; sonst MSB PC erniedrigen -$DL08: CALL PRBY ; Zieladresse in DE ausgeben - POP DE ; akt. Disassemblieradresse wieder -> DE - RET - - ; N ausgeben -PR_N: PUSH AF ; A retten - BIT 1,A ; N ? - JR Z,PRNN ; nein, NN ausgeben - CALL PRVH ; ja, Byte vorne und hinten ausgeben - JR $DL12 ; ")" bearbeiten - - ; NN ausgeben -PRNN: CALL PRNB ; Byte vorne ausgeben - CALL PRVH ; Byte vorne und hinten ausgeben - DEC DE ; DE -> LSB von NN - CALL PRBH ; Byte hinten ausgeben - INC DE ; akt. Disassemblieradr. wieder -> DE - JR $DL12 ; ")" bearbeiten - - ; Buchstaben ausgeben -PRBU: PUSH AF ; A retten - PUSH BC ; Flags in C retten - PUSH DE ; akt. Disassemblieradr. retten - LD B,1 ; Anzahl = 1 - LD DE,REGTAB ; DE zeigt auf die Register-Namen - BIT 5,A ; 2 Buchstaben ? - JR Z,$DL09 - INC B ; ja, Anzahl erhoehen -$DL09: BIT 6,A ; Sprungbedingung ? - JR Z,$DL10 - LD DE,SPRTAB ; ja, DE zeigt auf Condition-Namen -$DL10: RES 7,A ; Klammer-Bit loeschen - CP 34H ; "(HL)" ? - JR NZ,$DL11 - BIT 5,C ; ja, Indexregister ? - JR Z,$DL11 - LD A,0AH ; ja, A -> IX-Register - BIT 6,C ; IY-Register ? - JR Z,$DL11 - LD A,0CH ; ja, A -> IY-Register -$DL11: AND 0FH ; loesche oberes Nibble - ADD A,E ; und addiere zur Basis in DE - LD E,A -$DL50: LD A,(DE) ; Zeichen -> A - LD (HL),A ; Zeichen ausgeben - INC DE ; Tabellen-Adresse erhoehen - INC HL ; naechste Printposition - DJNZ $DL50 ; naechstes Zeichen - POP DE ; Register wieder herstellen - POP BC - POP AF - PUSH AF ; A retten - CP 0B4H ; "(HL)" ? - JR NZ,$DL12 - BIT 5,C ; nein, Indexregister ? - JR Z,$DL12 - LD A,(DE) ; ja, Befehlsbyte nach DD/FD -> A - CP 0E9H ; "JP (IX/IY)" ? - JR Z,$DL12 - LD (HL),'+' ; nein, "+" ausgeben - INC HL ; naechste Printposition - CALL PRVH ; Offset ausgeben -$DL12: POP AF ; A wieder herstellen - BIT 7,A ; "()" ? - RET Z ; nein, fertig - LD (HL),')' ; ja, ")" ausgeben - INC HL ; naechste Printposition - RET - - ; Error -ERRO: LD DE,CBMTAB+24 ; Pointer auf "????" -> DE - CALL TRBY ; als Mnemonic ausgeben - POP DE ; akt. Disassemblieradr. vom Stack holen - - ; Disassemblier-Adresse erhoehen und merken -INAD: INC DE - LD (DADR),DE - - ; Workspace ausgeben -PRWO: PUSH AF ; Register retten - PUSH BC - PUSH DE - PUSH HL - LD HL,WRKS ; Adresse Workspace -> HL - CALL PRTSTR ; Workspace aufs Terminal ausgeben - LD HL,NL ; Adresse Newline-String -> HL - CALL PRTSTR ; Newline ausgeben - POP HL ; Register wieder herstellen - POP DE - POP BC - POP AF - RET - - ; Workspace loeschen -CLWO: LD HL,WRKS ; Workspace mit Space fuellen - LD DE,WRKS+1 ; und mit Null terminieren - LD (HL),32 - LD BC,32 - LDIR - XOR A - LD (DE),A - RET - - ; 4 Bytes transferieren -TRBY: PUSH BC ; BC retten - LD BC,4 ; 4 Bytes - EX DE,HL ; DE=Printposition, HL=Mnemonic - LDIR ; Bytes transferieren - EX DE,HL ; HL ist wieder Printposition - POP BC ; BC wieder herstellen - INC HL ; Leerzeichen - RET - - ; Byte vorne und hinten ausgeben -PRVH: CALL PRNB ; Byte vorne ausgeben - - ; Byte hinten ausgeben -PRBH: PUSH AF ; A retten - LD A,(DE) ; Byte -> A - CALL PRAK ; A ausgeben - POP AF ; A wieder herstellen - RET - - ; Byte vorne ausgeben -PRNB: PUSH AF ; A retten - INC DE ; DE auf naechstes Byte setzen - PUSH HL ; akt. Printposition retten - LD HL,(PRTMP) ; vordere Printposition -> HL - LD A,(DE) ; Byte -> A - CALL PRAK ; A ausgeben - INC HL ; Leerzeichen - LD (PRTMP),HL ; vordere Printposition retten - POP HL ; akt. Printposition wieder -> HL - POP AF ; A wieder herstellen - RET - - ; DE ausgeben -PRBY: LD A,D ; MSB -> A - CALL PRAK ; A ausgeben - LD A,E ; LSB -> A - - ; A ausgeben -PRAK: PUSH AF ; A retten - RRCA ; oberes Nibble ins untere schieben - RRCA - RRCA - RRCA - CALL PRCH ; oberes Nibble ausgeben - POP AF ; A wieder herstellen - CALL PRCH ; unteres Nibble ausgeben - RET - - ; unteres Nibble in ASCII-Hex umwandeln und in Workspace schreiben -PRCH: AND 0FH - ADD A,90H - DAA - ADC A,40H - DAA - LD (HL),A ; ASCII-Ziffer in Workspace schreiben - INC HL ; Printposition erhoehen - RET - - ; Die hier folgenden Tabellen muessen am Anfang einer Page - ; beginnen, und die Reihenfolge der Tabellen darf auf keinen - ; Fall geaendert werden, weil das LSB der Tabellenadressen - ; durch arithmetische Operationen mit den Op-Codes berechnet - ; wird !!! - - DEFS 256 - ($ & 0FFH) - -MNETAB: ; Tabelle mit den Z80-Mnemonics - DEFM 'ADD ADC ' - DEFM 'SUB SBC ' - DEFM 'AND XOR ' - DEFM 'OR CP ' - DEFM 'JR NOP ' - DEFM 'DJNZEX ' - DEFM 'RLCARLA ' - DEFM 'DAA SCF ' - DEFM 'RRCARRA ' - DEFM 'CPL CCF ' - DEFM 'LD INC ' - DEFM 'DEC HALT' - DEFM 'RET POP ' - DEFM 'JP OUT ' - DEFM 'EX DI ' - DEFM 'CALLPUSH' - DEFM 'RST EXX ' - DEFM 'IN EX ' - DEFM 'EI LDI ' - DEFM 'LDIRINI ' - DEFM 'INIROUTI' - DEFM 'OTIRNEG ' - DEFM 'RETNRRD ' - DEFM 'LDD LDDR' - DEFM 'CPD CPDR' - DEFM 'IND INDR' - DEFM 'OTDROUTD' - DEFM 'RETIRLD ' - DEFM 'BIT RES ' - DEFM 'SET ????' - DEFM 'CPI CPIR' - DEFM 'IM ----' - -CODTAB: ; LSB-Adressen der Mnemonics in MNETAB fuer - ; Befehle 00..3F ohne Preafix ED/CB - - DEFB 024H,050H,050H,054H,054H,058H,050H,030H ; NOP LD LD INC INC DEC LD RLCA - DEFB 070H,000H,050H,058H,054H,058H,050H,040H ; EX ADD LD DEC INC DEC LD RRCA - DEFB 028H,050H,050H,054H,054H,058H,050H,034H ; DJNZ LD LD INC INC DEC LD RLA - DEFB 020H,000H,050H,058H,054H,058H,050H,044H ; JR ADD LD DEC INC DEC LD RRA - DEFB 020H,050H,050H,054H,054H,058H,050H,038H ; JR LD LD INC INC DEC LD DAA - DEFB 020H,000H,050H,058H,054H,058H,050H,048H ; JR ADD LD DEC INC DEC LD CPL - DEFB 020H,050H,050H,054H,054H,058H,050H,03CH ; JR LD LD INC INC DEC LD SCF - DEFB 020H,000H,050H,058H,054H,058H,050H,04CH ; JR ADD LD DEC INC DEC LD CCF - - ; LSB-Adressen der Mnemonics in MNETAB fuer - ; Befehle C0..FF ohne Preafix ED/CB - - DEFB 060H,064H,068H,068H,078H,07CH,000H,080H ; RET POP JP JP CALL PUSH ADD RET - DEFB 060H,060H,068H,0F1H,078H,078H,004H,080H ; RET RET JP (CB) CALL CALL ADC RST - DEFB 060H,064H,068H,06CH,078H,07CH,008H,080H ; RET POP JP OUT CALL PUSH SUB RST - DEFB 060H,084H,068H,088H,078H,0F0H,00CH,080H ; RET EXX JP IN CALL (DD) SBC RST - DEFB 060H,064H,068H,070H,078H,07CH,010H,080H ; RET POP JP EX CALL PUSH AND RST - DEFB 060H,068H,068H,02CH,078H,0F2H,014H,080H ; RET JP JP EX CALL (ED) XOR RST - DEFB 060H,064H,068H,074H,078H,07CH,018H,080H ; RET POP JP DI CALL PUSH OR RST - DEFB 060H,050H,068H,090H,078H,0F8H,01CH,080H ; RET LD JP EI CALL (FD) CP RST - - ; LSB-Adressen der Mnemonics in MNETAB fuer - ; Befehle 40..7F mit Preafix ED - - DEFB 088H,06CH,00CH,050H,0ACH,0B0H,0F8H,050H ; IN OUT SBC LD NEG RETN IM LD - DEFB 088H,06CH,004H,050H,0FFH,0D8H,0FFH,050H ; IN OUT ADC LD RETI LD - DEFB 088H,06CH,00CH,050H,0FFH,0FFH,0F8H,050H ; IN OUT SBC LD IM LD - DEFB 088H,06CH,004H,050H,0FFH,0FFH,0F8H,050H ; IN OUT ADC LD IM LD - DEFB 088H,06CH,00CH,0FFH,0FFH,0FFH,0FFH,0B4H ; IN OUT SBC RRD - DEFB 088H,06CH,004H,0FFH,0FFH,0FFH,0FFH,0DCH ; IN OUT ADC RLD - DEFB 0FFH,0FFH,00CH,050H,0FFH,0FFH,0FFH,0FFH ; SBC LD - DEFB 088H,06CH,004H,050H,0FFH,0FFH,0FFH,0FFH ; IN OUT ADC LD - - ; LSB-Adressen der Mnemonics in MNETAB fuer - ; Befehle A0..BF mit Praefix ED - - DEFB 094H,0F0H,09CH,0A4H,0FFH,0FFH,0FFH,0FFH ; LDI CPI INI OUTI - DEFB 0B8H,0C0H,0C8H,0D4H,0FFH,0FFH,0FFH,0FFH ; LDD CPD IND OUTD - DEFB 098H,0F4H,0A0H,0A8H,0FFH,0FFH,0FFH,0FFH ; LDIR CPIR INIR OTIR - DEFB 0BCH,0C4H,0CCH,0D0H,0FFH,0FFH,0FFH,0FFH ; LDDR CPDR INDR OTDR - -SPRTAB: ; Tabelle der Sprungbedingungen - - DEFM 'NZNCPOPEPM' - DEFB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH - -REGTAB: ; Tabelle der Register - - DEFM 'BCDEHLSPAFIXIYIR' - -OPETAB: ; Tabelle der Operanden: - ; Bit 7: Zahl/Buchstabe - ; Bit 6: einfach/doppelt - ; Bit 5: Register/Sprungbedingung - ; Bit 4: ohne/mit Klammer - ; Bit 0..3: Offset in der Tabelle der Registernamen - - ; Befehle 00..3F ohne Preafix ED/CB - ; 1. Operand - - DEFB 0FFH,030H,0B0H,030H,010H,010H,010H,0FFH ; - BC (BC) BC B B B - - DEFB 038H,034H,017H,030H,011H,011H,011H,0FFH ; AF HL A BC C C C - - DEFB 041H,032H,0B2H,032H,012H,012H,012H,0FFH ; DIS DE (DE) DE D D D - - DEFB 041H,034H,017H,032H,013H,013H,013H,0FFH ; DIS HL A DE E E E - - DEFB 070H,034H,0C4H,034H,014H,014H,014H,0FFH ; NZ HL (NN) HL H H H - - DEFB 051H,034H,034H,034H,015H,015H,015H,0FFH ; Z HL HL HL L L L - - DEFB 072H,036H,0C4H,036H,016H,016H,016H,0FFH ; NC SP (NN) SP (HL) (HL) (HL) - - DEFB 011H,034H,017H,036H,017H,017H,017H,0FFH ; C HL A SP A A A - - - ; Befehle C0..FF ohne Preafix ED/CB - ; 1. Operand - - DEFB 070H,030H,070H,044H,070H,030H,017H,020H ; NZ BC NZ NN NZ BC A 00 - DEFB 051H,0FFH,051H,0F1H,051H,044H,017H,021H ; Z - Z *CB Z NN A 08 - DEFB 072H,032H,072H,0C2H,072H,032H,042H,022H ; NC DE NC (N) NC DE N 10 - DEFB 053H,0FFH,053H,017H,053H,0F2H,017H,023H ; C - C A C *DD A 18 - DEFB 074H,034H,074H,0B6H,074H,034H,042H,024H ; PO HL PO (SP) PO HL N 20 - DEFB 076H,016H,076H,032H,076H,0F4H,042H,025H ; PE (HL) PE DE PE *ED N 28 - DEFB 058H,038H,058H,0FFH,058H,038H,042H,026H ; P AF P - P AF N 30 - DEFB 059H,036H,059H,0FFH,059H,0F8H,042H,027H ; M SP M - M *FD N 38 - - ; Befehle 00..3F ohne Preafix ED/CB - ; 2. Operand - - DEFB 0FFH,044H,017H,0FFH,0FFH,0FFH,042H,0FFH ; - NN A - - - N - - DEFB 038H,030H,0B0H,0FFH,0FFH,0FFH,042H,0FFH ; AF BC (BC) - - - N - - DEFB 0FFH,044H,017H,0FFH,0FFH,0FFH,042H,0FFH ; - NN A - - - N - - DEFB 0FFH,032H,0B2H,0FFH,0FFH,0FFH,042H,0FFH ; - DE (DE) - - - N - - DEFB 041H,044H,034H,0FFH,0FFH,0FFH,042H,0FFH ; DIS NN HL - - - N - - DEFB 041H,034H,0C4H,0FFH,0FFH,0FFH,042H,0FFH ; DIS HL (NN) - - - N - - DEFB 041H,044H,017H,0FFH,0FFH,0FFH,042H,0FFH ; DIS NN A - - - N - - DEFB 041H,036H,0C4H,0FFH,0FFH,0FFH,042H,0FFH ; DIS SP (NN) - - - N - - - ; Befehle C0..FF ohne Praefix ED/CB - ; 2. Operand - - DEFB 0FFH,0FFH,044H,0FFH,044H,0FFH,042H,0FFH ; - - NN - NN - N - - DEFB 0FFH,0FFH,044H,0FFH,044H,0FFH,042H,0FFH ; - - NN *CB NN - N - - DEFB 0FFH,0FFH,044H,017H,044H,0FFH,0FFH,0FFH ; - - NN A NN - - - - DEFB 0FFH,0FFH,044H,0C2H,044H,0FFH,042H,0FFH ; - - NN (N) NN *DD N - - DEFB 0FFH,0FFH,044H,034H,044H,0FFH,0FFH,0FFH ; - - NN HL NN - - - - DEFB 0FFH,0FFH,044H,034H,044H,0FFH,0FFH,0FFH ; - - NN HL NN *ED - - - DEFB 0FFH,0FFH,044H,0FFH,044H,0FFH,0FFH,0FFH ; - - NN - NN - - - - DEFB 0FFH,034H,044H,0FFH,044H,0FFH,0FFH,0FFH ; - HL NN - NN *FD - - - -OP2TAB: ; Befehle 40..7F mit Praefix ED - ; 1. Operand - - DEFB 010H,091H,034H,0C4H,0FFH,0FFH,000H,01EH ; B (C) HL (NN) - - 0 I - DEFB 011H,091H,034H,030H,0FFH,0FFH,0FFH,01FH ; C (C) HL BC - - - R - DEFB 012H,091H,034H,0C4H,0FFH,0FFH,001H,017H ; D (C) HL (NN) - - 1 A - DEFB 013H,091H,034H,032H,0FFH,0FFH,002H,017H ; E (C) HL DE - - 2 A - DEFB 014H,091H,034H,0C4H,0FFH,0FFH,076H,0FFH ; H (C) HL - - - - - - DEFB 015H,091H,034H,0FFH,0FFH,0FFH,0FFH,0FFH ; L (C) HL - - - - - - DEFB 0FFH,0FFH,034H,0C4H,0FFH,0FFH,0FFH,0FFH ; - - HL (NN) - - - - - DEFB 017H,091H,034H,036H,0FFH,0FFH,0FFH,0FFH ; A (C) HL SP - - - - - - ; Befehle 40..7F mit Preafix ED - ; 2. Operand - - DEFB 091H,010H,030H,030H,0FFH,0FFH,0FFH,017H ; (C) B BC BC - - - A - DEFB 091H,011H,030H,0C4H,0FFH,0FFH,0FFH,017H ; (C) C BC (NN) - - - A - DEFB 091H,012H,032H,032H,0FFH,0FFH,0FFH,01EH ; (C) D DE DE - - - I - DEFB 091H,013H,032H,0C4H,0FFH,0FFH,0FFH,01FH ; (C) E DE (NN) - - - R - DEFB 091H,014H,034H,034H,0FFH,0FFH,0FFH,0FFH ; (C) H HL - - - - - - DEFB 091H,015H,034H,0FFH,0FFH,0FFH,0FFH,0FFH ; (C) L HL - - - - - - DEFB 0FFH,0FFH,036H,036H,0FFH,0FFH,0FFH,0FFH ; - - SP SP - - - - - DEFB 091H,017H,036H,0C4H,0FFH,0FFH,0FFH,0FFH ; (C) A SP (NN) - - - - - -CBMTAB: ; Tabelle der Mnemonics mit Praefix CB - DEFM 'RLC RRC ' - DEFM 'RL RR ' - DEFM 'SLA SRA ' - DEFM '????SRL ' - -NL: ; Null-terminiertes Newline fuers Terminal - DEFB 10,13,0 - -WRKS: DEFS 34 ; Workspace zur Aufbereitung einer Ausgabezeile -PRTMP: DEFS 2 ; temoraerer Speicher fuer Printposition -DADR: DEFS 2 ; Disassemblier-Adresse diff --git a/emu/z80pack-1.9/z80src/z80main.asm b/emu/z80pack-1.9/z80src/z80main.asm deleted file mode 100644 index 0bad2f8..0000000 --- a/emu/z80pack-1.9/z80src/z80main.asm +++ /dev/null @@ -1,28 +0,0 @@ - TITLE 'Test programm for Z80-Disassembler' - -;========================================================================== -; Test programm for Z80-Disassembler -;========================================================================== - - LD SP,STACK ; initialize stack for simulator - LD HL,Z80OPS ; start address for disassembler - LD (DADR),HL -LOOP: - CALL DISSCR ; disassemble one screen full - HALT ; stop simulation - JP LOOP ; next run - -PRTSTR: ; print 0 terminated string - LD A,(HL) ; next char -> A - OR A ; 0 ? - RET Z ; yes, done - OUT (0),A ; no, print it - INC HL ; increase pointer to string - JP PRTSTR ; process next char - - INCLUDE z80dis.asm - INCLUDE z80ops.asm - - DEFS 100H -STACK: - END diff --git a/emu/z80pack-1.9/z80src/z80ops.asm b/emu/z80pack-1.9/z80src/z80ops.asm deleted file mode 100644 index 937cf23..0000000 --- a/emu/z80pack-1.9/z80src/z80ops.asm +++ /dev/null @@ -1,704 +0,0 @@ - TITLE 'Z80 Instruction Set in alphabetical Order' - -IND EQU 5 -M EQU 10H -N EQU 20H -DIS EQU 30H - -Z80OPS: - ADC A,(HL) - ADC A,(IX+IND) - ADC A,(IY+IND) - ADC A,A - ADC A,B - ADC A,C - ADC A,D - ADC A,E - ADC A,H - ADC A,L - ADC A,N - ADC HL,BC - ADC HL,DE - ADC HL,HL - ADC HL,SP - ADD A,(HL) - ADD A,(IX+IND) - ADD A,(IY+IND) - ADD A,A - ADD A,B - ADD A,C - ADD A,D - ADD A,E - ADD A,H - ADD A,L - ADD A,N - ADD HL,BC - ADD HL,DE - ADD HL,HL - ADD HL,SP - ADD IX,BC - ADD IX,DE - ADD IX,IX - ADD IX,SP - ADD IY,BC - ADD IY,DE - ADD IY,IY - ADD IY,SP - AND (HL) - AND (IX+IND) - AND (IY+IND) - AND A - AND B - AND C - AND D - AND E - AND H - AND L - AND N - BIT 0,(HL) - BIT 0,(IX+IND) - BIT 0,(IY+IND) - BIT 0,A - BIT 0,B - BIT 0,C - BIT 0,D - BIT 0,E - BIT 0,H - BIT 0,L - BIT 1,(HL) - BIT 1,(IX+IND) - BIT 1,(IY+IND) - BIT 1,A - BIT 1,B - BIT 1,C - BIT 1,D - BIT 1,E - BIT 1,H - BIT 1,L - BIT 2,(HL) - BIT 2,(IX+IND) - BIT 2,(IY+IND) - BIT 2,A - BIT 2,B - BIT 2,C - BIT 2,D - BIT 2,E - BIT 2,H - BIT 2,L - BIT 3,(HL) - BIT 3,(IX+IND) - BIT 3,(IY+IND) - BIT 3,A - BIT 3,B - BIT 3,C - BIT 3,D - BIT 3,E - BIT 3,H - BIT 3,L - BIT 4,(HL) - BIT 4,(IX+IND) - BIT 4,(IY+IND) - BIT 4,A - BIT 4,B - BIT 4,C - BIT 4,D - BIT 4,E - BIT 4,H - BIT 4,L - BIT 5,(HL) - BIT 5,(IX+IND) - BIT 5,(IY+IND) - BIT 5,A - BIT 5,B - BIT 5,C - BIT 5,D - BIT 5,E - BIT 5,H - BIT 5,L - BIT 6,(HL) - BIT 6,(IX+IND) - BIT 6,(IY+IND) - BIT 6,A - BIT 6,B - BIT 6,C - BIT 6,D - BIT 6,E - BIT 6,H - BIT 6,L - BIT 7,(HL) - BIT 7,(IX+IND) - BIT 7,(IY+IND) - BIT 7,A - BIT 7,B - BIT 7,C - BIT 7,D - BIT 7,E - BIT 7,H - BIT 7,L - CALL C,NN - CALL M,NN - CALL NC,NN - CALL NN - CALL NZ,NN - CALL P,NN - CALL PE,NN - CALL PO,NN - CALL Z,NN - CCF - CP (HL) - CP (IX+IND) - CP (IY+IND) - CP A - CP B - CP C - CP D - CP E - CP H - CP L - CP N - CPD - CPDR - CPI - CPIR - CPL - DAA - DEC (HL) - DEC (IX+IND) - DEC (IY+IND) - DEC A - DEC B - DEC BC - DEC C - DEC D - DEC DE - DEC E - DEC H - DEC HL - DEC IX - DEC IY - DEC L - DEC SP - DI - DJNZ $+DIS - EI - EX (SP),HL - EX (SP),IX - EX (SP),IY - EX AF,AF' - EX DE,HL - EXX - HALT - IM 0 - IM 1 - IM 2 - IN A,(C) - IN A,(N) - IN B,(C) - IN C,(C) - IN D,(C) - IN E,(C) - IN H,(C) - IN L,(C) - INC (HL) - INC (IX+IND) - INC (IY+IND) - INC A - INC B - INC BC - INC C - INC D - INC DE - INC E - INC H - INC HL - INC IX - INC IY - INC L - INC SP - IND - INDR - INI - INIR - JP (HL) - JP (IX) - JP (IY) - JP C,NN - JP M,NN - JP NC,NN - JP NN - JP NZ,NN - JP P,NN - JP PE,NN - JP PO,NN - JP Z,NN - JR C,$+DIS - JR $+DIS - JR NC,$+DIS - JR NZ,$+DIS - JR Z,$+DIS - LD (BC),A - LD (DE),A - LD (HL),A - LD (HL),B - LD (HL),C - LD (HL),D - LD (HL),E - LD (HL),H - LD (HL),L - LD (HL),N - LD (IX+IND),A - LD (IX+IND),B - LD (IX+IND),C - LD (IX+IND),D - LD (IX+IND),E - LD (IX+IND),H - LD (IX+IND),L - LD (IX+IND),N - LD (IY+IND),A - LD (IY+IND),B - LD (IY+IND),C - LD (IY+IND),D - LD (IY+IND),E - LD (IY+IND),H - LD (IY+IND),L - LD (IY+IND),N - LD (NN),A - LD (NN),BC - LD (NN),DE - LD (NN),HL - LD (NN),IX - LD (NN),IY - LD (NN),SP - LD A,(BC) - LD A,(DE) - LD A,(HL) - LD A,(IX+IND) - LD A,(IY+IND) - LD A,(NN) - LD A,A - LD A,B - LD A,C - LD A,D - LD A,E - LD A,H - LD A,I - LD A,L - LD A,N - LD B,(HL) - LD B,(IX+IND) - LD B,(IY+IND) - LD B,A - LD B,B - LD B,C - LD B,D - LD B,E - LD B,H - LD B,L - LD B,N - LD BC,(NN) - LD BC,NN - LD C,(HL) - LD C,(IX+IND) - LD C,(IY+IND) - LD C,A - LD C,B - LD C,C - LD C,D - LD C,E - LD C,H - LD C,L - LD C,N - LD D,(HL) - LD D,(IX+IND) - LD D,(IY+IND) - LD D,A - LD D,B - LD D,C - LD D,D - LD D,E - LD D,H - LD D,L - LD D,N - LD DE,(NN) - LD DE,NN - LD E,(HL) - LD E,(IX+IND) - LD E,(IY+IND) - LD E,A - LD E,B - LD E,C - LD E,D - LD E,E - LD E,H - LD E,L - LD E,N - LD H,(HL) - LD H,(IX+IND) - LD H,(IY+IND) - LD H,A - LD H,B - LD H,C - LD H,D - LD H,E - LD H,H - LD H,L - LD H,N - LD HL,(NN) - LD HL,NN - LD I,A - LD IX,(NN) - LD IX,NN - LD IY,(NN) - LD IY,NN - LD L,(HL) - LD L,(IX+IND) - LD L,(IY+IND) - LD L,A - LD L,B - LD L,C - LD L,D - LD L,E - LD L,H - LD L,L - LD L,N - LD SP,(NN) - LD SP,HL - LD SP,IX - LD SP,IY - LD SP,NN - LDD - LDDR - LDI - LDIR - NEG - NOP - OR (HL) - OR (IX+IND) - OR (IY+IND) - OR A - OR B - OR C - OR D - OR E - OR H - OR L - OR N - OTDR - OTIR - OUT (C),A - OUT (C),B - OUT (C),C - OUT (C),D - OUT (C),E - OUT (C),H - OUT (C),L - OUT (N),A - OUTD - OUTI - POP AF - POP BC - POP DE - POP HL - POP IX - POP IY - PUSH AF - PUSH BC - PUSH DE - PUSH HL - PUSH IX - PUSH IY - RES 0,(HL) - RES 0,(IX+IND) - RES 0,(IY+IND) - RES 0,A - RES 0,B - RES 0,C - RES 0,D - RES 0,E - RES 0,H - RES 0,L - RES 1,(HL) - RES 1,(IX+IND) - RES 1,(IY+IND) - RES 1,A - RES 1,B - RES 1,C - RES 1,D - RES 1,E - RES 1,H - RES 1,L - RES 2,(HL) - RES 2,(IX+IND) - RES 2,(IY+IND) - RES 2,A - RES 2,B - RES 2,C - RES 2,D - RES 2,E - RES 2,H - RES 2,L - RES 3,(HL) - RES 3,(IX+IND) - RES 3,(IY+IND) - RES 3,A - RES 3,B - RES 3,C - RES 3,D - RES 3,E - RES 3,H - RES 3,L - RES 4,(HL) - RES 4,(IX+IND) - RES 4,(IY+IND) - RES 4,A - RES 4,B - RES 4,C - RES 4,D - RES 4,E - RES 4,H - RES 4,L - RES 5,(HL) - RES 5,(IX+IND) - RES 5,(IY+IND) - RES 5,A - RES 5,B - RES 5,C - RES 5,D - RES 5,E - RES 5,H - RES 5,L - RES 6,(HL) - RES 6,(IX+IND) - RES 6,(IY+IND) - RES 6,A - RES 6,B - RES 6,C - RES 6,D - RES 6,E - RES 6,H - RES 6,L - RES 7,(HL) - RES 7,(IX+IND) - RES 7,(IY+IND) - RES 7,A - RES 7,B - RES 7,C - RES 7,D - RES 7,E - RES 7,H - RES 7,L - RET - RET C - RET M - RET NC - RET NZ - RET P - RET PE - RET PO - RET Z - RETI - RETN - RL (HL) - RL (IX+IND) - RL (IY+IND) - RL A - RL B - RL C - RL D - RL E - RL H - RL L - RLA - RLC (HL) - RLC (IX+IND) - RLC (IY+IND) - RLC A - RLC B - RLC C - RLC D - RLC E - RLC H - RLC L - RLCA - RLD - RR (HL) - RR (IX+IND) - RR (IY+IND) - RR A - RR B - RR C - RR D - RR E - RR H - RR L - RRA - RRC (HL) - RRC (IX+IND) - RRC (IY+IND) - RRC A - RRC B - RRC C - RRC D - RRC E - RRC H - RRC L - RRCA - RRD - RST 0 - RST 10H - RST 18H - RST 20H - RST 28H - RST 30H - RST 38H - RST 8 - SBC A,(HL) - SBC A,(IX+IND) - SBC A,(IY+IND) - SBC A,A - SBC A,B - SBC A,C - SBC A,D - SBC A,E - SBC A,H - SBC A,L - SBC A,N - SBC HL,BC - SBC HL,DE - SBC HL,HL - SBC HL,SP - SCF - SET 0,(HL) - SET 0,(IX+IND) - SET 0,(IY+IND) - SET 0,A - SET 0,B - SET 0,C - SET 0,D - SET 0,E - SET 0,H - SET 0,L - SET 1,(HL) - SET 1,(IX+IND) - SET 1,(IY+IND) - SET 1,A - SET 1,B - SET 1,C - SET 1,D - SET 1,E - SET 1,H - SET 1,L - SET 2,(HL) - SET 2,(IX+IND) - SET 2,(IY+IND) - SET 2,A - SET 2,B - SET 2,C - SET 2,D - SET 2,E - SET 2,H - SET 2,L - SET 3,(HL) - SET 3,(IX+IND) - SET 3,(IY+IND) - SET 3,A - SET 3,B - SET 3,C - SET 3,D - SET 3,E - SET 3,H - SET 3,L - SET 4,(HL) - SET 4,(IX+IND) - SET 4,(IY+IND) - SET 4,A - SET 4,B - SET 4,C - SET 4,D - SET 4,E - SET 4,H - SET 4,L - SET 5,(HL) - SET 5,(IX+IND) - SET 5,(IY+IND) - SET 5,A - SET 5,B - SET 5,C - SET 5,D - SET 5,E - SET 5,H - SET 5,L - SET 6,(HL) - SET 6,(IX+IND) - SET 6,(IY+IND) - SET 6,A - SET 6,B - SET 6,C - SET 6,D - SET 6,E - SET 6,H - SET 6,L - SET 7,(HL) - SET 7,(IX+IND) - SET 7,(IY+IND) - SET 7,A - SET 7,B - SET 7,C - SET 7,D - SET 7,E - SET 7,H - SET 7,L - SLA (HL) - SLA (IX+IND) - SLA (IY+IND) - SLA A - SLA B - SLA C - SLA D - SLA E - SLA H - SLA L - SRA (HL) - SRA (IX+IND) - SRA (IY+IND) - SRA A - SRA B - SRA C - SRA D - SRA E - SRA H - SRA L - SRL (HL) - SRL (IX+IND) - SRL (IY+IND) - SRL A - SRL B - SRL C - SRL D - SRL E - SRL H - SRL L - SUB (HL) - SUB (IX+IND) - SUB (IY+IND) - SUB A - SUB B - SUB C - SUB D - SUB E - SUB H - SUB L - SUB N - XOR (HL) - XOR (IX+IND) - XOR (IY+IND) - XOR A - XOR B - XOR C - XOR D - XOR E - XOR H - XOR L - XOR N - -NN: DEFS 2