86DOS A86 86DOS A86 !86DOS A86"ASM A86#$%&'()*+,-./012P EQU 18 ;BP for SEARCH FIRST and SEARCH NEXT FIRCLUS EQU 20 ;First cluster of file LSTCLUS EQU 22 ;Last cluster accessed FIL ; INTBASE+14H: BIOS DISK READ ; INTBASE+18H: BIOS DISK WRITE ; INTBASE+40H: Long jump to CALL entry point ESCCH EQU 1BH ASM A863456789:;<=>?@ABASM A86wCDEFGHIJKLMNOPQBOOT A86RSTCHESS A86UVWXYZ[\]^_`abcdSIZ EQU 24 ;Size of file in records CLUSPOS EQU 26 ;Position of last cluster accessed FLSFLG EQU 28 ;Flush flag SIZCHG EQU 29CANCEL EQU "X"-"@" ;Cancel with Ctrl-X MAXCALL EQU 36 MAXCOM EQU 40 INTBASE EQU 80H INTTAB EQU 20H ENTRYPOINTSEG EQU 0CHCHESS A86efghijklmnopqrstCHESS A86uvwxyz{|}~CHESS A86CHESS A86? ;Size change flag NR EQU 32 ;Next record RR EQU 33 ;Random record ; Description of 16-byte directory entry (same as return ENTRYPOINT EQU INTBASE+40H CONTC EQU INTTAB+3 EXIT EQU INTBASE+8 LONGJUMP EQU 0EAH LONGCALL EQU 9AH SAVEXIT EQU 10 ; FCHESS DOCCOMMAND A864DOSIO A86DEDLIN A86H; QDOS High-performance operating system for the 8086 version 0.11 ; by Tim Paterson ; Interrupt Entry Points: ; INTBed by SEARCH FIRST ; and SEARCH NEXT, functions 17 and 18). ; ; Location bytes Description ; ; 0 11 File name and extenield definition for FCBs FNAME EQU 0 ;Drive code and name EXTENT EQU 12 ENTPOS EQU 16 ;Position of entry in directory DRVBHEX2BIN A86RDCPM A86SYS A86TRANS A86~ASE: ABORT ; INTBASE+4: COMMAND ; INTBASE+8: BASE EXIT ADDRESS ; INTBASE+C: CONTROL-C ABORT ; INTBASE+10H: FATAL ERROR ABORTsion ( 0E5H if empty) ; 11 2 First allocation unit ( < 4080 ) ; 13 3 File size, in bytes (LSB first, 24 bits max.) ; finitions BIOSSEG EQU 40H BIOSINIT EQU 0 ;Reserve room for jump to init code BIOSSTAT EQU 3 ;Console input status check SHFT EQU 3 ;Log2 of records/cluster FIRFAT EQU 4 ;Starting record of FATs FATSIZ EQU 6 ;Number of records occupied by FAT FAT MOV ES,AX LODB ;Get no. of drives & no. of I/O drivers CBW MOV CX,AX SEG CS MOV [NUMIO],AL MOV DI,AX SHL DI the OS. Entry 1 is reserved for ; future use. The first available allocation unit is assigned entry number ; two, and even th;Skip up to specified character DB "UH" ;Copy rest of template DB "HH" ;Kill line with no change in template (Ctrl-X) DB " ; The File Allocation Table uses a 12-bit entry for each allocation unit on ; the disk. These entries are packed, two for everBIOSIN EQU 6 ;Get console character BIOSOUT EQU 9 ;Output console character BIOSPRINT EQU 12 ;Output to printer BIOSAUXIN ECNT EQU 7 ;Number of FATs for this drive FIRDIR EQU 8 ;Starting record of directory DIRSIZ EQU 10 ;Number of records occupied MOV AH,DPBSIZ ;Size of DPB MUL AX,AH MOV BX,DRVTAB ADD DI,BX ;Point to first DPB ADD AX,DI MOV BP,AX ;Point to firsough it is the first, is called cluster 2. Entries of 0FFFH ; are end of file marks; entries of zero are unallocated. OtherwiseRM" ;Cancel line and update template DB "DD" ;Backspace (same as Ctrl-H) DB "P@" ;Enter Insert mode DB "QL" ;Exit Insert my three bytes. The contents ; of entry number N is found by 1) multiplying N by 1.5; 2) adding the result ; to the base addresQU 15 ;Get byte from auxilliary BIOSAUXOUT EQU 18 ;Output byte to auxilliary BIOSREAD EQU 21 ;Disk read BIOSWRITE EQU 24 ;Disby directory FIRREC EQU 11 ;First record of first cluster MAXCLUS EQU 13 ;Number of clusters on drive + 1 DIRTY EQU 15 ;Whetht FAT SEG CS MOV [FATBASE],AX PERDEV: SEG CS MOV [BX],DI ;Store DPB pointer to table entry INC BX INC BX MOV AL,, the ; contents of a FAT entry is the number of the next cluster in the file. ; Field definition for Drive Parameter Blocode DB 1BH,1BH ;Escape sequence to represent escape character DB ESCCH,ESCCH ESCTABLEN EQU $-ESCTAB HEADER DB 13,10,"86-s of the Allocation Table; 3) fetching the 16-bit word at ; this address; 4) If N was odd (so that N*1.5 was not an integer), sk write BIOSFLUSH EQU 27 ;Disk buffer flush ; Start of code ORG 0 PUT 100H JMP DOSINIT ESCTAB: DB "SC" ;Copyer FAT is dirty FAT EQU 16 ;Pointer to start of FAT DPBSIZ EQU 18 ;Size of the structure in bytes ; BOIS entry point deCH STOB ;DEVNUM LODW ;Get pointer to DPT PUSH SI ;Save INITTAB pointer MOV SI,AX ;Load DPT MOVB ;SECSIZ LODBk DEVNUM EQU 0 ;I/O driver number SECSIZ EQU 1 ;Size of physical sector in records CLUSMSK EQU 2 ;Records/cluster - 1 CLUSDOS version 0.11" DB 13,10 DB "Copyright 1980 Seattle Computer Products, Inc.",13,10,"$" DOSINIT: CLI CLD MOV AX,CShift the ; word right four bits; 5) mask to 12 bits (AND with 0FFF hex). Entry number ; zero is used as an end-of-file trap in one character from template DB "VN" ;Skip over one character in template DB "TA" ;Copy up to specified character DB "WB" DEC AL STOB ;CLUSMSK CBW FIGSHFT: INC AH SAR AL JNZ FIGSHFT MOV AL,AH STOB ;CLUSSHFT LODW STOW ;FIRFall entry point CMP AH,MAXCOM JBE SAVREGS BADCALL: MOV AL,0 IRET: IRET ENTRY: ;System call entry point and dispatcher [DMAADD],128 MOV [DMAADD+2],DX MOV AX,[DRVTAB] MOV [CURDRV],AX MOV CX,DX ;Start scanning just after DOS MOV BX,0FH PEN ;15 DW CLOSE DW SRCHFRST DW SRCHNXT DW DELETE DW SEQRD ;20 DW SEQWRT DW CREATE DW RENAME DW INUSE DW G5 ;True start of free space MOV CL,4 SHR BP,CL ;First free segment XOR AX,AX MOV DS,AX MOV ES,AX MOV DI,INTBASE PUSH BP PUSH DI PUSH SI PUSH DX PUSH CX PUSH BX PUSH AX MOV BL,AH MOV BH,0 SHL BX CLD SEG CS CALL [BX+AT MOV DX,AX LODB STOB ;FATSIZ MOV AH,AL PUSH AX LODB STOB ;FATCNT MUL AX,AH ADD AX,DX STOW ;FIRDIR POP AX ;IP from the long call at 5 POP AX ;Segment from the long call at 5 SEG CS POP [TEMP] ;IP from the CALL 5 PMEMSCAN: INC CX JZ SETEND MOV DS,CX MOV AL,[BX] NOT AL MOV [BX],AL CMP AL,[BX] NOT AL MOV [BX],AL JZ MEMSCANETDRV ;25 DW SETDMA DW GETFATPT DW GETFATPTDL DW GETRDONLY DW SETATTRIB ;30 DW GETDSKPT DW USERCODE DW RNDRD MOV AX,QUIT STOW ;Set abort address--displacement MOV AX,CS MOV B,[ENTRYPOINT],LONGJUMP MOV [ENTRYPOINT+1],ENTRY MOVDISPATCH] SEG CS MOV [AXSAVE],AL POP AX POP BX POP CX POP DX POP SI POP DI POP BP POP DS POP ES POP SS MOV DX,AX LODB STOB ;DIRSIZ CBW ADD AX,DX STOW ;FIRREC POP DX LODW INC AX STOW ;MAXCLUS XOR AL,AL STUSHF ;Start re-ordering the stack CLI PUSH AX ;Save segment SEG CS PUSH [TEMP] ;Stack now ordered as if INT had been SETEND: SEG CS MOV [ENDMEM],CX XOR CX,CX MOV DS,CX MOV [EXIT],100H MOV [EXIT+2],DX MOV [INTBASE+0CH],100H MODW RNDWRT DW FILESIZE ;35 DW SETRNDREC ; Extended Functions DW SETVECT DW NEWBASE DW BLKRD DW BLKWRT ;40 GETIO: [ENTRYPOINT+3],CS STOW STOW STOW MOV [INTBASE+4],COMMAND MOV DI,INTBASE+14H MOV AX,BIOSREAD STOW MOV AX,BIOSSEG SEG CS MOV SP,[SPSAVE] IRET ; Standard Functions DISPATCH DW ABORT ;0 DW CONIN DW CONOUT DW READER DW PUNCH DWOB POP SI LODW ;Allocation table displacement SEG CS ADD AX,[FATBASE] STOW ;FAT MOV DL,0 SHR DX ;FAT size in used CMP CL,MAXCALL ;This entry point doesn't get as many calls JA BADCALL MOV AH,CL SAVREGS: SEG CS MOV [SPSAVE],SPV [INTBASE+0EH],DX CALL SETMEM MOV SI,HEADER CALL OUTMES RET L QUIT: MOV AH,0 JP SAVREGS COMMAND: ;Interrupt c SETIO: GETVER: GETFATPTDL: GETRDONLY: SETATTRIB: USERCODE: MOV AL,0 RET READER: CALL BIOSAUXIN,BIOSSEG RET STOW STOW ;Add 2 to DI STOW MOV [INTBASE+18H],BIOSWRITE MOV DX,CS MOV DS,DX ADD DX,BP ;Next free segment MOV LIST ;5 DW RAWIO DW GETIO DW SETIO DW PRTBUF DW BUFIN ;10 DW CONSTAT DW GETVER DW DSKRESET DW SELDSK DW Obytes ADD AX,DX CMP AX,BP JBE SMFAT MOV BP,AX SMFAT: INC CH ;Next I/O device number DEC CL JNZ PERDEV ADD BP,1 SEG CS MOV [SSSAVE],SS INC SP INC SP SEG CS POP [TEMP] MOV SP,CS MOV SS,SP MOV SP,SSSAVE PUSH ES PUSH DS PUNCH: MOV AL,DL CALL BIOSAUXOUT,BIOSSEG RET UNPACK: ; Inputs: ; DS = CS ; BX = Cluster number ; BP = Base of d CMP AL,[BP+DIRSIZ] JB RDIRREC STC RET NEXTENT: Add BX,16 CMP BX,DIRBUF+127 JA RET CMP B,[BX],0E5H JZ NEXTENTny ; character. ; Outputs: ; Carry set if file not found ; ELSE ; BP = Base of drive parameters ; DS = CS ; ES = CS ; AXputs: ; DS, DX point to FCB ; Outputs: ; ES = CS ; If file name OK: ; BP has base of driver parameters ; [NAME1] has name ter to drive FAT ; Outputs: ; The data is stored in the FAT at the given cluster. ; BX,DX,DI all destroyed ; No other registRT XOR AL,AL RET RENAME: ;System call 23 CALL MOVNAME JC ERRET ADD SI,5 MOV DI,NAME2 CALL LODNAME CALL FINDrive parameters ; SI = Pointer to drive FAT ; Outputs: ; DI = Contents of FAT for given cluster ; Zero set means DI=0 (free MOV SI,BX MOV DI,NAME1 MOV CX,11 WILDCRD: REPE CMPB JZ RET CMP B,[DI-1],"?" JZ WILDCRD JP NEXTENT DELET = Directory record number ; BX = Pointer into directory buffer ; [DIRBUF] has directory record with match ; [NAME1] has filein upper case ; All registers except DX destroyed ; Carry set if bad file name or drive MOV AX,CS MOV ES,AX MOV DI,NAMers affected MOV DI,BX SHR BX ADD BX,SI ADD BX,DI SHR DI MOV DI,[BX] JNC ALIGNED SHL DX SHL DX SHL DX SHNAME JC ERRET SAVDREC: MOV AH,AL RENFIL: MOV DI,BX MOV SI,NAME2 MOV CX,11 NEWNAM: LODB CMP AL,"?" JZ SKIPLET cluster) ; No other registers affected. Fatal error if cluster too big. CMP BX,[BP+MAXCLUS] JA HURTFAT LEA DI,[SI+BX] E: ; System call 19 CALL GETNAME JC ERRET PUSH AX PUSH BX CALL LOADFAT POP BX DELFILE: MOV B,[BX],0E5H PUSH BX name ; All other registers destroyed. CALL MOVNAME JC RET FINDNAME: MOV AX,CS MOV DS,AX MOV AL,0 RDIRREC: PUE1 MOV SI,DX LODB SEG ES CMP [NUMIO],AL JC RET CBW XCHG AX,BP SHL BP MOV BP,[BP+CURDRV] LODNAME: ; This entrL DX AND DI,0FH JP PACKIN ALIGNED: AND DI,0F000H PACKIN: OR DI,DX MOV [BX],DI RET GETNAME: ; Inputs: ; DS MOV [DI],AL SKIPLET: INC DI LOOP NEWNAM CALL NEXTENT JZ RENFIL MOV AL,AH PUSH AX CALL DIRWRITE POP AX CALL SHR BX MOV DI,[DI+BX] JNC HAVCLUS SHR DI SHR DI SHR DI SHR DI STC HAVCLUS: RCL BX AND DI,0FFFH RET HURTFA MOV BX,[BX+11] MOV SI,[BP+FAT] OR BX,BX JZ DELNXT CMP BX,[BP+MAXCLUS] JA DELNXT CALL RELEASE DELNXT: POP BX CSH AX CALL DIRREAD POP AX MOV BX,DIRBUF-16 CONTSRCH: CALL NEXTENT JZ RET NDIRREC: INC AL ;Next directory record y point copies a file name from DS,SI ; to ES,DI converting to upper case. MOV CX,11 MOVCHK: LODB AND AL,7FH CMP AL,"a,DX point to FCB ; Function: ; Find file name in disk directory. First byte is ; drive number (0=current disk). "?" matches aNDIRREC JNC SAVDREC ;New record read, save current number XOR AL,AL RET ERRET: MOV AL,-1 RET MOVNAME: ; InT: MOV SI,BADFAT CALL OUTMES JMP ERROR PACK: ; Inputs: ; DS = CS ; BX = Cluster number ; DX = Data ; SI = PoinALL NEXTENT JZ DELFILE POP AX PUSH AX CALL DIRWRITE POP AX CALL NDIRREC PUSH AX JNC DELFILE POP AX CALL FATW"-1 JLE STOLET AND AL,5FH ;Convert to upper case STOLET: CMP AL," " JB RET STOB LOOP MOVCHK RET OPEN: ;Systemnchanged ; All other registers destroyed MOV B,[BP+DIRTY],0 CALL FIGFAT EACHFAT: PUSH DX PUSH CX PUSH BX PUSH AX JC BADCLOSE MOV CX,BX SUB CX,DIRBUF MOV AH,CL SEG ES CMP AX,[DI+ENTPOS] JNZ BADCLOSE SEG ES MOV CX,[DI+FIRCLUSG AL,AH MOV CL,5 REP STOB XCHG AL,AH PUSH AX PUSH BX CALL DIRWRITE POP BX POP AX JMP OPENNAM DIRREAD: CX PUSH BX PUSH AX CALL DREAD OR AL,AL POP AX POP BX POP CX POP DX JNZ FATERR SUB AL,[BP+FATCNT] JZ RET X,DIRBUF MOV CX,1 RET CREATE: ;System call 22 CALL MOVNAME JC ERRET3 MOV DI,NAME1 MOV CX,11 MOV AL,"?" REPN call 15 PUSH DX PUSH DS CALL GETNAME OPENNAM: POP ES POP DI JC ERRET MOV AH,[BP+DEVNUM] INC AH SEG ES MOV CALL DWRITE POP AX POP BX POP CX POP DX ADD DX,CX DEC AL JNZ EACHFAT OKRET: MOV AL,0 RET BADCLOSE: MO] MOV [BX+11],CX SEG ES MOV DX,[DI+FILSIZ] SHR DX MOV [BX+14],DX MOV DL,0 RCR DL MOV [BX+13],DL CALL DIRWRITE ; Inputs: ; DS = CS ; AL = Directory block number ; BP = Base of drive parameters ; Function: ; Read the directory block NEG AL JP FATWRT FATERR: ADD DX,CX DEC AL JNZ READFAT POP BP MOV SI,ALLBAD CALL HARDERR JP LOADFAT CLOSE: ;SE SCAB JZ ERRET3 PUSH DX PUSH DS MOV AX,CS MOV DS,AX XOR AX,AX RDIRREC2: PUSH AX CALL DIRREAD POP AX MOV [DI],AH SEG ES MOV [DI+EXTENT],0 ADD DI,16 MOV CX,BX SUB CX,DIRBUF MOV AH,CL STOW ;ENTPOS MOV AX,BP STOW ;V B,[BP+DIRTY],0 MOV AL,-1 RET FIGFAT: ; Loads registers with values needed to read or ; write a FAT. MOV AL,[BP+FA CHKFATWRT: ; Do FATWRT only if FAT is dirty TEST B,[BP+DIRTY],-1 JZ OKRET FATWRT: ; Inputs: ; DS = CS ; BP = Basinto DIRBUF. ; Outputs: ; AX,BP unchanged ; All other registers destroyed. CALL DIRCOMP DREAD: ; Inputs: ; BX,DS =ystem call 16 MOV DI,DX TEST B,[DI+FLSFLG],-1 JZ NOFLSH PUSH DI MOV BP,[DI+DRVBP] MOV AL,[BP+DEVNUM] CALL BIOSFLUSDI,DIRBUF-16 MOV CX,8 FNDFRE: ADD DI,16 CMP B,[DI],0E5H LOOPNE FNDFRE JZ FREESPOT INC AL CMP AL,[BP+DIRSIZ] JC DRVBP LEA SI,[BX+11] LODW STOW ;FIRCLUS STOW ;LSTCLUS LODB SHL AL LODW RCL AX STOW ;FILSIZ XOR AX,AX TCNT] MOV BX,[BP+FAT] MOV CL,[BP+FATSIZ] ;No. of records occupied by FAT MOV CH,0 MOV DX,[BP+FIRFAT] ;Record number of se of drive parameter table ; Function: ; Write the FAT back to disk and reset FAT ; dirty flag. ; Outputs: ; AL = 0 ; BP u Transfer address ; CX = Number of records ; DX = Absolute record number ; BP = Base of drive parameters ; Function: ; CallH,BIOSSEG POP DI NOFLSH: TEST B,[DI+SIZCHG],-1 JZ OKRET MOV DX,DI PUSH DX PUSH DS CALL GETNAME POP ES POP DI RDIRREC2 POP DS POP DX ERRET3: MOV AL,-1 RET FREESPOT: MOV BX,DI MOV SI,NAME1 MOV CX,5 MOVB REP MOVW XCH STOW ;CLUSPOS STOW ;FLSFLG, SIZCHG LOADFAT: TEST B,[BP+DIRTY],-1 JNZ RET CALL FIGFAT READFAT: PUSH DX PUSH tart of FATs RET DIRCOMP: ; Prepare registers for directory read or write CBW ADD AX,[BP+FIRDIR] MOV DX,AX MOV Bs BIOS to perform disk read. If BIOS reports ; errors, will call HARDERR for further action. ; BP preserved. All other registe CALL NOBUF XOR AX,AX MOV DS,AX MOV SI,EXIT MOV DI,EXITHOLD MOVW MOVW POP BP POP ES POP ES POP DS POP SS ERR: SUB DI,CX ADD DX,DI ;Next record to transfer CALL RECTOBYT ADD BX,DI ;Next location for transfer CALL OUTMES Ger ; BP = Base of drive parameters ; [RECCNT] = Record count ; [RECPOS] = Record position in file ; [FCB] = DX ; [NEXTADD] ; CX = Number of records ; DX = Absolute record number ; BP = Base of drive parameters ; Function: ; Calls BIOS to perform OAD JP FINBLK BLKWRT: ;System call 40 MOV DI,DX MOV AX,[DI+RR] CALL STORE FINBLK: MOV [CXSAVE],CX JCXZ FINRND rs destroyed. MOV AL,[BP+DEVNUM] PUSH BP PUSH BX PUSH CX PUSH DX CALL BIOSREAD,BIOSSEG POP DX POP DI POP BX MOV SP,[SPSAVE] MOV DS,[DSSAVE] SEG CS JMP L,[EXITHOLD] SEQRD: ;System call 20 CALL GETREC MOV CX,1 CALL LOAD ETRESP: CALL IN OR AL,20H ;To lower-case CMP AL,"a" JZ ERROR CMP AL,"r" JZ RET CMP AL,"i" JZ IGNORE CMP AL,"c= Displacement of disk transfer within segment ; [DSKERR] = 0 (no errors yet) ; [NUMTRNS] = 0 (No transfers yet) ; If SETUP ddisk write. If BIOS reports ; errors, will call HARDERR for further action. ; BP preserved. All other registers destroyed. INC AX FINRND: SEG ES MOV [DI+RR],AX SETNREX: MOV CX,AX AND AL,7FH SEG ES MOV [DI+NR],AL AND CL,80H ROL CX X POP BP JC DSKRDERR XOR AL,AL RET DSKRDERR: MOV SI,RDERR CALL HARDERR JP DREAD DIRWRITE: ; Inputs: ; DS = JCXZ SETNREX INC AX JP SETNREX SEQWRT: ;System call 21 CALL GETREC MOV CX,1 CALL STORE JCXZ SETNREX INC AX " JNZ GETRESP POP AX MOV AL,1 RET IGNORE: POP AX MOV AL,0 RET ABORT: SEG CS MOV DS,[TEMP] XOR AX,AX MOetects no records will be transfered, it returns 1 level up ; with CX = 0. MOV BP,[DI+DRVBP] MOV BX,DS MOV ES,BX MOV MOV AL,[BP+DEVNUM] MOV AH,0 CMP DX,[BP+FIRREC] RCR AH PUSH BP PUSH BX PUSH CX PUSH DX CALL BIOSWRITE,BIOSSEG CHG CL,CH SEG ES MOV [DI+EXTENT],CX MOV AL,[DSKERR] RET SETUP: ; Inputs: ; DS:DI point to FCB ; AX = Record posi CS ; AL = Directory block number ; BP = Base of drive parameters ; Function: ; Write the directory block into DIRBUF. ; OuJP SETNREX RNDRD: ;System call 33 MOV CX,1 MOV DI,DX MOV AX,[DI+RR] CALL LOAD JP FINRND RNDWRT: ;System call 34 V ES,AX MOV SI,SAVEXIT MOV DI,EXIT MOVW MOVW MOVW MOVW ERROR: MOV SP,BPSAVE MOV AX,CS MOV DS,AX MOV ES,AX BX,CS MOV DS,BX MOV [RECPOS],AX MOV [FCB],DX MOV BX,[DMAADD] MOV [NEXTADD],BX MOV B,[DSKERR],0 MOV [NUMTRNS],0 POP DX POP DI POP BX POP BP JC DSKWRERR XOR AL,AL RET DSKWRERR: MOV SI,WRERR CALL HARDERR JP DWRITE HARDtion in file of disk transfer ; CX = Record count ; Outputs: ; DS = CS ; ES:DI point to FCB ; CX = No. of records to transftputs: ; BP unchanged ; All other registers destroyed. CALL DIRCOMP DWRITE: ; Inputs: ; BX,DS = Transfer address MOV CX,1 MOV DI,DX MOV AX,[DI+RR] CALL STORE JP FINRND BLKRD: ;System call 39 MOV DI,DX MOV AX,[DI+RR] CALL LMOV SI,[BP+FAT] ADD BX,7FH ;See if there is any space left JC SEGEND AND BL,80H NEG BX ;These instructions divide by 12 CMP BX,0FFFH JNZ RDLP MOV B,[DSKERR],1 SETFCB: MOV AX,[CLUSNUM] MOV DI,[FCB] SEG ES MOV [DI+LSTCLUS],AX MOV Aead ; CX = No. of records read ; ES:DI point to FCB ; LSTCLUS, CLUSPOS fields in FCB set CALL SETUP SEG ES MOV BX,[DI DEC BX MOV CL,[BP+CLUSSHFT] SHR AX,CL SHR BX,CL MOV CX,AX MOV AX,BX CALL FNDCLUS SUB AX,DX ;Last cluster minus r ; DI destroyed. No other registers affected. SEG ES MOV BX,[DI+LSTCLUS] SEG ES MOV DX,[DI+CLUSPOS] OR BX,BX JZ AX,CL MOV CX,AX CALL FNDCLUS OR CX,CX JNZ ADDREC MOV DX,0FFFH MOV B,[BP+DIRTY],-1 MOV DI,[FCB] MOV AX,[RECPOS] 8 ROL BX XCHG BL,BH JNZ CHKMAX MOV BH,2 ;All 512 records OK CHKMAX: CMP CX,BX JBE SAVCNT MOV CX,BX MOV B,[DSKERX,[RECPOS] MOV BX,[NUMTRNS] ADD AX,BX SEG ES CMP AX,[DI+FILSIZ] JBE NOSZINC SEG ES MOV [DI+FILSIZ],AX SEG ES M+FILSIZ] SUB BX,AX JBE WRTERRJ CMP BX,CX JNB ENUF MOV B,[DSKERR],1 MOV [RECCNT],BX ENUF: MOV CL,[BP+CLUSSHFT] Scurrent cluster JCXZ HAVSTART ;See if no more data PUSH CX ;No. of clusters of first MOV CX,AX CALL ALLOCATE POP CX NOCLUS SUB CX,DX JNB FINDIT ADD CX,DX XOR DX,DX SEG ES MOV BX,[DI+FIRCLUS] FINDIT: JCXZ RET SKPCLP: CALL UNPAC SEG ES MOV [DI+FILSIZ],AX SEG ES MOV B,[DI+SIZCHG],-1 XOR CX,CX RET STORE: ; Inputs: ; DS:DI point to FCB ; R],2 ;Flag that trimming took place SAVCNT: MOV [RECCNT],CX RET SEGEND: MOV B,[DSKERR],2 MOV CX,0 POP BX RET OV B,[DI+SIZCHG],-1 NOSZINC: DEC AX MOV DX,AX MOV CL,[BP+CLUSSHFT] SHR DX,CL SEG ES MOV [DI+CLUSPOS],DX MOV CX,BXHR AX,CL MOV CX,AX CALL FNDCLUS OR CX,CX JNZ WRTERR MOV DL,[RECPOS] AND DL,[BP+CLUSMSK] MOV CX,[RECCNT] RDLP: C JC WRTERR DEC CX JZ NOSKIP CALL SKPCLP PUSH BX WRCLUS: POP BX NOSKIP: MOV DL,[RECPOS] AND DL,[BP+CLUSMSK] MOVK CMP DI,0FFFH JZ RET XCHG BX,DI INC DX LOOP SKPCLP RET NOCLUS: INC CX DEC DX RET LOAD: ; Inputs: ; AX = Position in file of disk transfer ; CX = Record count ; Outputs: ; AX = Position of last record written ; CX = No. of rFNDCLUS: ; Inputs: ; DS = CS ; CX = No. of clusters ; BP = Base of drive parameters ; SI = FAT pointer ; ES:DI point to RET WRTERRJ: JP WRTERR HAVSTART: MOV CX,AX PUSH BX CALL FNDCLUS JCXZ WRCLUS CALL ALLOCATE POP BX JNC NOSKALL OPTIMIZE PUSH DI PUSH AX PUSH DS MOV DS,[DMAADD+2] CALL DREAD POP DS POP CX POP BX JCXZ SETFCB MOV DL,0 CX,[RECCNT] WRTLP: CALL OPTIMIZE PUSH DI PUSH AX PUSH DS MOV DS,[DMAADD+2] CALL DWRITE POP DS POP CX POP BX DS:DI point to FCB ; AX = Position in file to read ; CX = No. of records to read ; Outputs: ; AX = Position of last record records written ; ES:DI point to FCB ; LSTCLUS, CLUSPOS fields in FCB set CALL SETUP JCXZ WRTEOF MOV BX,CX ADD BX,AX FCB ; Outputs: ; BX = Last cluster skipped to ; CX = No. of clusters remaining (0 unless EOF) ; DX = Position of last clusteIP WRTERR: MOV B,[DSKERR],1 ADDREC: MOV AX,[RECPOS] XOR CX,CX MOV DI,[FCB] RET WRTEOF: MOV CL,[BP+CLUSSHFT] SHR MOV DL,0 OR CX,CX JNZ WRTLP CALL SETFCB SEG ES MOV B,[DI+FLSFLG],-1 RET OPTIMIZE: ; Inputs: ; DS = CS ; determined by EXTENT and NR fields ; DS:DI point to FCB ; No other registers affected. MOV DI,DX MOV AL,[DI+NR] MOV BUM],BX ;Last cluster accessed SUB DX,CX ;Number of records still needed MOV AX,DX MOV BX,CX XCHG BL,BH ROR BX MOV S LOOP ALLOC MOV DX,0FFFH CALL PACK MOV B,[BP+DIRTY],-1 POP BX CALL UNPACK XCHG BX,DI OR DI,DI JNZ RET MOV DI,,AL SUB AL,DL ;AL = Number of records left in first cluster MOV DX,CX MOV SI,[BP+FAT] MOV CX,0 OPTCLUS: ;AL has numbe is fully updated including dirty flag ; FIRCLUS field of FCB set if file was null ; SI,BP unchanged. All other registers destBX = Physical cluster ; CX = No. of records ; DL = record within cluster ; BP = Base of drives parameters ; [NEXTADD] = tranX,[DI+EXTENT] SHL AL SHR BX RCR AL MOV AH,BL RET ALLOCATE: ; Inputs: ; DS = CS ; ES = Segment of FCB ; BX =I,[NEXTADD] ADD BX,SI ;Adjust by size of transfer MOV [NEXTADD],BX ADD [NUMTRNS],CX POP DX POP BX PUSH CX MOV CL,[FCB] SEG ES MOV [DI+FIRCLUS],BX OR [SI],0FFFH RET RELEASE: ; Inputs: ; DS = CS ; BX = Cluster in file ; SI =r of records available in current cluster ;AH has number of records available in next cluster ;BX has current physical clusterroyed. PUSH BX MOV AX,BX ALLOC: MOV DX,BX FINDFRE: INC BX CMP BX,[BP+MAXCLUS] JL TRYOUT CMP AX,1 JG TRYIN sfer address ; Outputs: ; AX = No. of records remaining ; BX = Transfer address ; CX = No. or records to be transferred ; D Last cluster of file (0 if null file) ; CX = No. of clusters to allocate ; DX = Position of cluster BX ; BP = Base of drive [BP+CLUSSHFT] DEC DX DEC DX SHL DX,CL OR DL,BL ADD DX,[BP+FIRREC] POP CX MOV BX,SI RET BLKDON: MOV CX,DX ;Ma FAT pointer ; BP = Base of drive parameters ; Function: ; Frees cluster chain starting with [BX] ; AX,BX,DX,DI all destroye ;CX has number of sequential records found so far ;DX has number of records left to transfer ;SI has FAT pointer CALL UNPAPOP BX MOV DX,0FFFH CALL RELBLKS OR [SI],0FFFH STC RET TRYOUT: CALL UNPACK JZ HAVFRE TRYIN: DEC AX JLE FINX = Physical record address ; DI = Next cluster ; [CLUSNUM] = Last cluster accessed ; [NEXTADD] updated ; BP unchanged. Noteparameters ; SI = FAT pointer ; [FCB] = Displacement of FCB within segment ; Outputs: ; IF insufficient space ; THEN ; Cke the total equal to the request JP FINCLUS GETREC: ; Inputs: ; DS:DX point to FCB ; Outputs: ; AX = Record numberd. Other registers unchanged. XOR DX,DX RELBLKS: ; Enter here with DX=0FFFH to put an end-of-file mark ; in the first cluCK ADD CL,AL ADC CH,0 CMP CX,DX JAE BLKDON MOV AL,AH INC BX CMP DI,BX JZ OPTCLUS DEC BX FINCLUS: MOV [CLUSNDFRE XCHG AX,BX CALL UNPACK JZ HAVFRE XCHG AX,BX JP FINDFRE HAVFRE: XCHG BX,DX MOV AX,DX CALL PACK MOV BX,AX that segment of transfer not set. PUSH DX PUSH BX MOV AL,[BP+CLUSMSK] INC AL ;Number of records per cluster MOV AHarry set ; CX = max. no. of records that could be added to file ; ELSE ; Carry clear ; BX = First cluster allocated ; FATster and free the rest in the chain. CALL UNPACK JZ RET MOV AX,DI CALL PACK CMP AX,0FFFH MOV BX,AX JNZ RELEASE ROV [BXSAVE],BX RET DSKRESET: ;System call 13 SEG CS MOV [DMAADD+2],DS MOV AX,CS MOV DS,AX MOV [DMAADD],80H MO RCL AX ;Round to nearest record STOW MOV AL,0 RCL AL STOB RET SETDMA: ;System call 26 SEG CS MOV [DMAADD] MOV BL,CH EDITON: MOV DL,AL DEC DX NEWLIN: SEG CS MOV AL,[CARPOS] SEG CS MOV [STARTPOS],AL PUSH SI MOV DI,INs starting at the disk transfer address. MOV SI,BX LES DI,[DMAADD] MOV CX,8 REP MOVW MOV AL,0 RET KILLSRCH: M: RCL BX LOOP CHKUSE MOV AL,BL RET SETRNDREC: ;System call 36 CALL GETREC MOV [DI+RR],AX MOV AL,0 JZ BIGRR ET GETEOF: ; Inputs: ; BX = Cluster in a file ; SI = Base of drive FAT ; DS = CS ; Outputs: ; BX = Last cluster in V AX,[DRVTAB] MOV [CURDRV],AX NOBUF: MOV CL,[NUMIO] MOV CH,0 MOV SI,DRVTAB WRTFAT: LODW PUSH CX PUSH SI MOV BP,DX SEG CS MOV [DMAADD+2],DS RET GETFATPT: ;System call 27 MOV AX,CS MOV DS,AX MOV [DSSAVE],CS MOV BP,[CURDRV] BUF MOV AH,CH MOV BH,CH MOV DH,CH GETCH: CALL IN CMP AL,7FH JZ BACKSP CMP AL,8 JZ BACKSP CMP AL,13 JZ ENDLIOV AL,-1 MOV [SRCHDON],AL RET SRCHNXT: ;System call 18 MOV AX,CS MOV ES,AX MOV DS,AX MOV AL,[SRCHDON] CMP AL, INC AL BIGRR: MOV [DI+RR+2],AL RET SELDSK: ;System call 14 MOV DH,0 MOV BX,DX PUSH CS POP DS CMP BL,[NUMIOthe file ; DI destroyed. No other registers affected. CALL UNPACK CMP DI,0FFFH JZ RET MOV BX,DI JP GETEOF SRCH,AX CALL CHKFATWRT POP SI POP CX LOOP WRTFAT MOV AL,-1 CALL BIOSFLUSH,BIOSSEG RET GETDRV: ;System call 25 S CALL LOADFAT MOV BX,[BP+FAT] MOV AL,[BP+CLUSMSK] INC AL MOV DX,[BP+MAXCLUS] DEC DX MOV B,[BP+DIRTY],-1 MOV [BXSAN CMP AL,10 JZ PHYCRLF CMP AL,CANCEL JZ KILNEW CMP AL,27 JZ ESC SAVCH: CMP DH,DL JNB GETCH STOB INC DH CA-1 JZ RET MOV BX,[PDIR] MOV BP,[SRCHBP] CALL CONTSRCH JP SAVPLCE FILESIZE: ;System call 35 PUSH DI PUSH DX ] JGE RET SHL BX MOV AX,[BX+DRVTAB] MOV [CURDRV],AX RET BUFIN: ;System call 10 MOV AX,CS MOV ES,AX MOV SI,DX FRST: ;System call 17 CALL GETNAME SAVPLCE: ; Search-for-next enters here to save place and report ; findings. JC KILLSRCEG CS MOV BP,[CURDRV] MOV AL,[BP+0] RET INUSE: ;System call 24 MOV AX,CS MOV DS,AX MOV CL,[NUMIO] MOV CH,0 VE],BX MOV [DXSAVE],DX RET GETDSKPT: ;System call 31 SEG CS MOV [DSSAVE],CS SEG CS MOV BX,[CURDRV] SEG CS MLL OUT OR AH,AH JNZ GETCH CMP BH,BL JAE GETCH INC SI INC BH JP GETCH ESC: CALL IN MOV CL,ESCTABLEN PUSH DCALL GETNAME POP DI POP ES MOV AL,-1 JC RET ADD DI,33 ;Write size in RR field LEA SI,[BX+13] LODB SHL AL LODW MOV CH,0 LODW OR AL,AL JZ RET MOV BL,AH MOV BH,CH CMP AL,BL JBE NOEDIT CMP B,[BX+SI],0DH JZ EDITON NOEDIT: H MOV [SRCHDON],AL MOV [PDIR],BX MOV [SRCHBP],BP ;Information in directory entry must be copied into the first ; 16 byteMOV SI,CX SHL SI ADD SI,CURDRV MOV BX,0 STD CHKUSE: LODW MOV BP,AX TEST B,[BP+DIRTY],-1 JZ SETBIT STC SETBITI MOV DI,ESCTAB REPNE SCAB POP DI AND CL,0FEH MOV BP,CX JMP [BP+ESCFUNC] ENDLIN: STOB CALL OUT POP DI MI,SI INC DI REPNE SCAB POP DI POP ES JNZ NOTFND NOT CL ADD CL,BL SUB CL,BH RET NOTFND: POP BP JMP GETCHAVCH COPYLIN: MOV CL,BL SUB CL,BH JP COPYEACH COPYSTR: CALL FINDOLD JP COPYEACH COPYONE: MOV CL,1 COPYEACHOS CMP AL,8 JZ BACKPOS CMP AL,9 JZ TAB PUSH AX MOV AL,"^" CALL OUT POP AX OR AL,40H JP OUT ZERPOS: SEG MP GETCH BAKTAB: PUSH DI DEC DI STD MOV CL,DH MOV AL," " PUSH BX MOV BL,7 JCXZ FIGTAB FNDPOS: SCAB JNA CHKSOUT,BIOSSEG SEG CS TEST B,[PFLAG],-1 JZ STATCHK CALL BIOSPRINT,BIOSSEG STATCHK: CALL BIOSSTAT,BIOSSEG JZ RET INOV [DI-1],DH INC DH COPYNEW: MOV BP,ES MOV BX,DS MOV ES,BX MOV DS,BP MOV SI,INBUF MOV CL,DH REP MOVB RET C REEDIT: MOV AL,"@" CALL OUT POP DI PUSH DI PUSH ES PUSH DS CALL COPYNEW POP DS POP ES POP SI MOV BL,DH: CMP DH,DL JZ GETCH2 CMP BH,BL JZ GETCH2 LODB STOB CALL OUT INC BH INC DH LOOP COPYEACH GETCH2: JMP GETCCS MOV B,[CARPOS],0 JP OUTCH BACKPOS: SEG CS DEC B,[CARPOS] JP OUTCH TAB: MOV AL,0 SEG CS XCHG AL,[CARPOS]CNT SEG ES CMP B,[DI+1],9 JZ HAVTAB DEC BL CHKCNT: LOOP FNDPOS FIGTAB: SEG CS SUB BL,[STARTPOS] HAVTAB: SUB BCHK: CALL BIOSIN,BIOSSEG CMP AL,'S'-'@' JNZ NOSTOP CALL BIOSIN,BIOSSEG ;Eat Cntrl-S NOSTOP: CMP AL,'P'-'@' JZ PRINTRLF: MOV AL,13 CALL OUT MOV AL,10 JMP OUT PHYCRLF: CALL CRLF JP GETCH KILNEW: MOV AL,"\" CALL OUT POP SI JMP PUTNEW ENTERINS: MOV AH,-1 JMP GETCH EXITINS: MOV AH,0 JMP GETCH ESCFUNC DW GETCH DW TWOESC DW EXITIH SKIPONE: CMP BH,BL JZ GETCH2 INC BH INC SI JMP GETCH SKIPSTR: CALL FINDOLD ADD SI,CX ADD BH,CL JMP GET OR AL,0F8H NEG AL PUSH CX MOV CL,AL MOV CH,0 TABLP: MOV AL," " CALL OUTCH LOOP TABLP POP CX RET CONSTL,DH ADD CL,BL AND CL,7 CLD POP BX POP DI JZ OLDBAK TABBAK: CALL BACKMES LOOP TABBAK JP OLDBAK BACKUP: DEON CMP AL,'N'-'@' JZ PRINTOFF CMP AL,'C'-'@' JNZ RET INT CONTC ;Execute user Ctrl-C handler RET PRINTON: SEG C PUTNEW: CALL CRLF JMP NEWLIN BACKSP: OR DH,DH JZ OLDBAK CALL BACKUP SEG ES MOV AL,[DI] CMP AL," " JAE OLDNS DW ENTERINS DW BACKSP DW REEDIT DW KILNEW DW COPYLIN DW SKIPSTR DW COPYSTR DW SKIPONE DW COPYONE CONOUT:CH FINDOLD: CALL IN MOV CL,BL SUB CL,BH JZ NOTFND DEC CX JZ NOTFND PUSH ES PUSH DS POP ES PUSH DI MOV DAT: ;System call 11 CALL BIOSSTAT,BIOSSEG JZ RET OR AL,-1 RET CONIN: ;System call 1 CALL INCHK PUSH AX CALL OC DH DEC DI BACKMES: MOV AL,8 CALL OUT MOV AL," " CALL OUTCH MOV AL,8 JMP OUTCH TWOESC: MOV AL,ESCCH JMP SS MOV B,[PFLAG],1 RET PRINTOFF: SEG CS MOV B,[PFLAG],0 RET CTRLOUT: CMP AL,10 JZ OUTCH CMP AL,13 JZ ZERPBAK CMP AL,9 JZ BAKTAB CALL BACKMES OLDBAK: OR AH,AH JNZ GETCH1 OR BH,BH JZ GETCH1 DEC BH DEC SI GETCH1: J ;System call 2 MOV AL,DL OUT: CMP AL,20H JB CTRLOUT CMP AL,7FH JZ OUTCH SEG CS INC B,[CARPOS] OUTCH: CALL BIOUT POP AX RET IN: CALL INCHK JZ IN RET RAWIO: ;System call 6 MOV AL,DL CMP AL,-1 JNZ RAWOUT CALL BIOSS DI RET ;***** DATA AREA ***** BADFAT DB 13,10,"Bad FAT",13,10,"$" ALLBAD DB 13,10,"All FATs on disk are bad",13,10,"$"rom INT 23H) ; DX,BP unchanged. All other registers destroyed. XOR CX,CX MOV DS,CX MOV ES,DX MOV SI,EXIT MOV DI,SAVN: EQU 15 CLOSE: EQU 16 DELETE: EQU 19 READ: EQU 20 SETDMA: EQU 26 MAKE: EQU 22 SEQWRT: EQU 21 ;The following equates dBASE: ; Interrupt call 38 MOV ES,DX SEG CS MOV DS,[TEMP] XOR SI,SI MOV DI,SI MOV CX,80H REP MOVW SETMEM: ;S DS 2 DS 50 AXSAVE DS 2 BXSAVE DS 2 CXSAVE DS 2 DXSAVE DS 2 SISAVE DS 2 DISAVE DS 2 BPSAVE DS 2 DSSAVE DS 2 ESSAVE DTAT,BIOSSEG JZ RET CALL BIOSIN,BIOSSEG RET RAWOUT: CALL BIOSOUT,BIOSSEG RET LIST: ;System call 5 MOV AL,DL CAL RDERR DB 13,10,"Disk read error",13,10,"$" WRERR DB 13,10,"Disk write error",13,10,"$" CARPOS DB 0 STARTPOS DB 0 PFLAG DB EXIT MOVW MOVW MOVW MOVW SEG CS MOV CX,[ENDMEM] SEG ES MOV [2],CX SUB CX,DX CMP CX,0FFFH JBE HAVDIF MOV efine some token values returned by GETSYM UNDEFID:EQU 0 ;Undefined identifier (including no nearby RET) CONST: EQU 1 ;Constan Inputs: ; AX = Size of memory in paragraphs ; DX = Segment ; Function: ; Completely prepares a program base at the ; specS 2 SSSAVE DS 2 SPSAVE DS 2 CURDRV DS 2 DRVTAB: ;Address of start of DPBs L BIOSPRINT,BIOSSEG RET PRTBUF: ;System call 9 MOV SI,DX OUTSTR: LODB CMP AL,"$" JZ RET CALL OUT JP OUTSTR 0 SRCHDON DB -1 PDIR DS 2 SRCHBP DS 2 EXITHOLD DS 4 ENDMEM DS 2 FATBASE DS 2 INBUF DS 255 DIRBUF DS 128 NUMIO DS 1 ;NuCX,0FFFH HAVDIF: MOV BX,ENTRYPOINTSEG SUB BX,CX SHL CX SHL CX SHL CX SHL CX MOV DS,DX MOV [6],CX MOV [8],BX t (including $) REG: EQU 2 ;8-bit register XREG: EQU 3 ;16-bit register (except segment registers) SREG: EQU 4 ;Segment regisified segment. ; Outputs: ; DS = DX ; ES = DX ; [0] has INT 20H ; [2] = First unavailable segment ([ENDMEM]) ; [5] to [9] ; Seattle Computer Products 8086 Assembler version 2.00 ; by Tim Paterson ; Runs on the 8086 under 86-DOS FCB: EQU 5CH OUTMES: ;String output for internal messages SEG CS LODB CMP AL,"$" JZ RET CALL OUT JP OUTMES SETVECT: ; Interrmber of disk tables NAME1 DS 11 ;File name buffer NAME2 DS 11 ;File name buffer DMAADD DS 4 ;User's disk transfer address MOV [0],20CDH ;"INT INTTAB" MOV B,[5],LONGCALL RET RECTOBYT: SHL DI SHL DI SHL DI SHL DI SHL DI SHL DI SHLter ORG 100H PUT 100H JMP BEGIN CPYRHT: DB 'Copyright 1979 by Seattle Computer Products, Inc.' DB 13,10,13,10,'$'form a long call to the entry point ; [10] to [13] have exit address (from INT 22H) ; [14] to [17] have ctrl-C exit address (fEOL: EQU 13 ;ASCII carriage return OBJECT: EQU 100H ;DEFAULT "PUT" ADDRESS ;System call function codes PRINTMES: EQU 9 OPEupt call 37 XOR BX,BX MOV ES,BX MOV BL,AL SHL BX SHL BX SEG ES MOV [BX],DX SEG ES MOV [BX+2],DS RET NEW(disp/seg) TEMP DS 2 DSKERR DS 1 FCB DS 2 ;Address of user FCB RECPOS DS 2 NEXTADD DS 2 RECCNT DS 2 CLUSNUM DS 2 NUMTRN BEGIN: MOV SP,STACK MOV DX,HEADER MOV CL,PRINTMES CALL SYSTEM MOV DX,CPYRHT CALL SYSTEM MOV AL,[FCB+17] MOV been read yet MOV [SYM],AL CALL ASMLIN ;Assemble the line MOV AL,[SYM] CMP AL,-1 ;Any tokens found on line? JNZ L00V [BASE],BX ;POINTER TO ROOT OF ID TREE=NIL MOV [RETPT],BX ;Pointer to last RET record DEC BX MOV [LSTRET],BX ;Location of ADDEXT: MOV DX,FCB+9 MOV BX,EXTEND ;Set extension to ASM MOV CX,7 UP MOV SI,BX MOV DI,DX REP MOVB MOV DX,D? JZ NOPRN CALL CHKDSK NOPRN: MOV [LSTFCB],AL CALL ADDEXT MOV DX,FCB MOV CL,OPEN CALL SYSTEM MOV BX,NOFILE IN over comments for linefeed JP GETEOL ABORT: MOV BX,NOMEM PRERR: XCHG DX,BX MOV CL,PRINTMES CALL SYSTEM JMP 0 [SYMFLG],AL ;Save symbol table request flag MOV BX,FCB+9 ;Point to file extension MOV AL,[BX] ;Get source drive letter CA02 CALL GETSYM ;If no tokens read yet, read first one L0002: CMP AL,';' JZ ENDLN CMP AL,EOL JZ ENDLN MOV AL,14H last RET MOV BX,[6] ;HL=END OF MEMORY MOV [HEAP],BX ;BACK END OF SYMBOL TABLE SPACE MOV AL,4 MOV [BCOUNT],AL ;CODE BYTI MOV BX,SI RET CHKDSK: SUB AL,' ' ;If not present, set zero flag JZ RET SUB AL,20H JZ DSKERR ;Must be in rangeC AL JNZ $+5 JMP PRERR XOR AL,AL MOV [FCB+32],AL ;Zero Next Record field MOV DX,HEXFCB CALL MAKFIL MOV DX,LSTFCB MAKFIL: MOV SI,DX LODB ;Get drive select byte CMP AL,20H ;If not valid, don't make file JNC RET PUSH DX INC DX LL CHKDSK ;Valid drive? OR AL,AL JZ DEFAULT ;If no extension, use existing drive spec MOV [FCB],AL DEFAULT: INC BX ;Garbage at end of line error JP ENDLIN ENDJ: JMP END ENDLN: XOR AL,AL ;Flag no errors on line ENDLIN: ;AL = error coES PER RELOCATION BYTE XOR AL,AL MOV [IFFLG],AL ;NOT WITHIN IF/ENDIF MOV [CHKLAB],AL ;LOOKUP ALL LABELS ;Assemble each A-W CMP AL,'X'-'@' JC RET DSKERR: MOV BX,BADDSK JP PRERR ERROR: MOV AL,CL JMP ENDLIN NEXTCHR: XCHG BX,[HL] CALL MAKFIL MOV BX,0FFH XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] MOV BX,START+1 ;POINTER TO NEXT BYTE OF INTERMEDIATE C MOV BX,FCB+1 MOV CX,8 UP MOV SI,BX MOV DI,DX REP MOVB ;Copy source file name MOV DX,DI MOV BX,SI POP DX MMOV AL,[BX] ;Get HEX file drive letter CMP AL,'Z' ;Suppress HEX file? JZ L0000 CALL CHKDSK L0000: MOV [HEXFCB],AL de for line. Stack depth unknown MOV SP,STACK CALL NEXLIN JP LOOP NEXLIN: MOV CH,0C0H ;Put end of line marker and erline of code LOOP: CALL NEXTCHR ;Get first character on line CMP AL,1AH JZ ENDJ MOV AL,-1 ;Flag that no tokens have XCHG DX,[DE] XCHG CX,[BC] INC BL JNZ GETCH ;Buffer empty so refill it MOV DX,80H MOV CL,SETDMA CALL SYSTEM XCHODE MOV [CODE],BX MOV [IY],START ;POINTER TO CURRENT RELOCATION BYTE MOV BX,0 MOV [PC],BX ;DEFAULT PROGRAM COUNTER MOOV CL,DELETE CALL SYSTEM MOV CL,MAKE CALL SYSTEM MOV BX,NOSPAC INC AL ;Success? JZ PRERR MOV CL,OPEN JMP SYSTEMINC BX MOV AL,[BX] ;Get PRN file drive letter CMP AL,'Z' ;Suppress PRN file? JZ NOPRN CMP AL,'X' ;PRN file to consoleror code (AL) CALL PUTCD CALL GEN1 MOV AL,[CHR] GETEOL: CMP AL,10 JZ RET CMP AL,1AH JZ ENDJ CALL NEXTCHR ;ScanG DX,BX MOV DX,FCB MOV CL,READ CALL SYSTEM OR AL,AL MOV AL,1AH ;Possibly signal End of File JNZ NOMOD ;If nothing er move OP code MOV AL,UNDEFID CMP AL,DH ;Check if source is memory JZ LOAD CMP AL,BH ;Check if destination is memory r length (1=16 bits) OR AL,CH ;Or in to OP code CALL PUT ;And write it POP CX ;Dump return address MOV AL,BL ADD ALk byte/word operation AND AL,1 OR AL,CH POP CX ;Dump return address JMP PUTADD ;Write the address NOTAC: MOV AL,Band is immediate MOV CL,26 CMP AL,BH JZ ERROR ;Error if so POP CX ;Restore type flags CMP AL,DH ;If second operand operation JNZ XRG MOV DH,22 TEST CL,1 ;See if 8-bit operation is OK JZ MRERR XRG: MOV AL,DL SUB AL,6 ;Check for read GETCH: MOV AL,[BX] NOMOD: XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] MOV [CHR],AL RET MROPS: ; Get two op JZ STORE MOV AL,XREG SUB AL,DH ;Check if source is 16-bit register JZ RR ;If so, AL must be zero AND CH,0FDH ;Chang,AL ;Rotate register number into middle position ADD AL,AL ADD AL,AL OR AL,0C0H ;Set register-to-register mode OR AL,DH AND AL,1 ;Get byte/word bit AND AL,CL ;But don't use it in word-only operations OR AL,CH ;Combine with OP code CALLis immediate, then done JZ RET MOV AL,UNDEFID ;Check for memory reference CMP AL,BH JZ STORE ;Is destination memory? R/M mode 6 and register 0 OR AL,BL ; meaning direct load/store of accumulator JNZ NOTAC TEST CL,8 ;See if direct load/erands and check for certain types, according to flag byte ; in CL. OP code in CH. Returns only if immediate operation. PUSe direction XCHG DX,BX ;Flip which operand is first and second MOV AL,XREG SUB AL,DH ;Let RR perform finish the test JL ;Combine with other register number JMP PUT SEGCHK: ;Come here if at least one operand is a segment register POP CX PUT MOV AL,BL ADD AL,AL ;Rotate to middle position ADD AL,AL ADD AL,AL OR AL,DL ;Combine register field POP CX ;CMP AL,DH JZ LOAD ;Is source memory? RCR SI TEST CL,1 ;Check if register-to-register operation OK RCL SI MOV CL,27 store of accumulator JZ NOTAC ; means anything in this case ; Process direct load/store of accumulator MOV AL,CH AND AH CX ;Save type flags CALL GETOP PUSH DX ;Save first operand CALL GETOP2 POP BX ;First op in BX, second op in DX MOP RR STORE: TEST CL,004H ;Check if storing is OK JNZ STERR XCHG DX,BX ;If so, flip operands AND CH,0FDH ; and ze;Restore flags RCR SI TEST CL,8 ;Check if segment register OK RCL SI MOV CL,22 JZ ERR1 MOV CX,8E03H ;Segment registDump return address JMP PUTADD ;Write the address STERR: MOV DH,29 MRERR: MOV CL,DH ERR1: JMP ERROR GETOP2: ;G JZ ERROR MOV AL,DH CMP AL,BH ;Registers must be of same length RR: MOV CL,22 JNZ ERROR RR1: AND AL,1 ;Get registeL,2 ;Preserve direction bit only XOR AL,2 ; but flip it OR AL,0A0H ;Combine with OP code MOV CH,AL MOV AL,BH ;ChecV AL,SREG ;Check for a segment register CMP AL,BH JZ SEGCHK CMP AL,DH JZ SEGCHK MOV AL,CONST ;Check if the first operro direction bit LOAD: MOV DH,25 CMP AL,BH ;Check if memory-to-memory JZ MRERR MOV AL,BH CMP AL,REG ;Check if 8-bitet the second operand: look for a comma and drop into GETOP MOV AL,[SYM] CMP AL,',' MOV CL,21 JNZ ERR1 GETOP: ; USH DX CALL GETSYM POP DX MOV AL,DH RET MEM: CALL GETSYM MOV AL,1 CALL GETVAL MOV AL,[SYM] CMP AL,']' MOV C GETOP1: ;Enter here if we don't need a GETSYM first CMP AL,'[' ;Memory reference? JZ MEM CMP AL,5 ;Flag ("B", "W", et JNZ L046A JMP L0597 L046A: CMP AL,'"' JNZ L0471 L046E: JMP L0648 L0471: CMP AL,"'" JZ L046E CMP AL,3 MOV CL, to be added to this, a pointer to ; its information fields is in ALABEL, otherwise ALABEL is zero. ; ; AL=DH=1 Value. The co ; be added to this, a pointer to its information fields will be found in ; UNDEF. LAHF XCHG AX,BP SAHF PUSH BX MGet one operand. Operand may be a memory reference in brackets, a register, ; or a constant. If a flag (such as "B" for byte opL,24 JNZ ERR1 CALL GETSYM MOV BX,[CON] MOV [ADDR],BX MOV BX,[UNDEF] MOV [ALABEL],BX MOV DL,CH MOV DH,UNDEFID Mc.)? JZ FLG CMP AL,REG ;8-Bit register? JZ NREG CMP AL,XREG ;16-Bit register? JZ NREG CMP AL,SREG ;Segment regist14H JNZ ERR2 LAHF XCHG AX,BP SAHF RCR SI TEST AL,1 RCL SI MOV CL,1 JZ ERR2 LAHF XCHG AX,BP SAHF MOV ALonstant part is in DATA. If an undefined label needs ; to be added to this, a pointer to its information fields is in DLABEL, OV BX,0 MOV [CON],BX MOV [UNDEF],BX POP BX MOV AL,[SYM] CMP AL,'+' JZ PLSMNS CMP AL,'-' JZ PLSMNS MOV CH,'+' eration) is encountered, ; it is noted and processing continues to find the operand. ; ; On exit, AL (=DH) has the type of opOV AL,DH RET FLG: CALL GETSYM CMP AL,',' JZ GETOP JP GETOP1 GETVAL: ; Expression analyzer. On entry, if AL=0 er? JZ NREG VAL: ;Must be immediate XOR AL,AL ;No addressing modes allowed VAL1: CALL GETVAL MOV BX,[CON] ;Defined,DL MOV CL,3 CMP AL,3 JZ L04C6 SUB AL,5 JZ L04D7 DEC AL MOV CL,4 JZ L04B5 DEC AL JZ L04A6 MOV CL,2 ERR2: ; otherwise DLABEL is zero. "$" and "RET" are in this class. ; ; AL=DH=2 8-bit Register. DL has the register number. ; ; AL PUSH CX JP L045C PLSMNS: LAHF XCHG AH,AL PUSH AX XCHG AH,AL LAHF XCHG AX,BP SAHF LAHF OR AL,4 ;Flag that erand. Other information depends ; on the actual operand: ; ; AL=DH=0 Memory Reference. DL has the address mode properly prthen do not allow base or index ; registers. If AL=1, we are analyzing a memory reference, so allow base ; and index registers part MOV [DATA],BX MOV BX,[UNDEF] ;Undefined part MOV [DLABEL],BX MOV DL,CH MOV DH,CONST MOV AL,DH RET NREG: PJMP ERROR L04A6: LAHF XCHG AX,BP SAHF RCR SI TEST AL,10H RCL SI JNZ ERR2 OR AL,30H JP L04E4 L04B5: LAHF =DH=3 16-bit Register. DL has the register number. ; ; AL=DH=4 Segment Register. DL has the register number. CALL GETSYMa sign was found SAHF LAHF XCHG AX,BP SAHF CALL GETSYM L045C: CMP AL,1 JNZ L0463 JMP L0578 L0463: CMP AL,0 epared in ; the 8086 R/M format (middle bits zero). The constant part of the address ; is in ADDR. If an undefined label needs, and compute addressing mode when done. The constant ; part of the expression will be found in CON. If an undefined label is tXCHG AX,BP SAHF RCR SI TEST AL,10H RCL SI JNZ ERR2 LAHF OR AL,10H SAHF JP L04E4 L04C6: LAHF XCHG AX,BP r. Used only in the operand field. Returns with the token ; in SYM and AL, sometimes with additional info in BX or DX. ; ; ALMOV CH,6 JNC RET RCL AL JC L0523 INC CH JP L0523 L0578: MOV BX,[CON] POP AX XCHG AH,AL SAHF CMP AL,'-' ],CONST CALL READID LAHF DEC BX SAHF MOV AL,[BX] MOV CL,7 MOV BX,0 CMP AL,'h' JNZ $+5 JMP HEX INC CL MOV RCL SI RCL AL JZ NOIND CMC RCL CH RCL AL RCL CH RCL AL RCL CH L0523: MOV BX,[UNDEF] MOV AL,BH OR AL,BLthe character. Note that this may ; never be a letter or number. CALL GETSY MOV AL,[SYM] RET SCANB: MOV AL,[CHR] SAHF RCR SI TEST AL,80H RCL SI JNZ ERR2 LAHF OR AL,80H SAHF JP L04E4 L04D7: LAHF XCHG AX,BP SAHF RCR SI=SYM=0 Undefined label. BX has pointer to information fields. ; ; AL=SYM=1 Constant (or defined label). DX has value. ; ; JNZ L058D SBB BX,DX L0586: MOV [CON],BX JMP L04F1 L058D: LAHF ADD BX,DX RCR SI SAHF RCL SI JP L0586 L0597 [IX],ID DEC: MOV SI,[IX] MOV AL,[SI] INC [IX] CMP AL,'9'+1 JC $+5 ERR3: JMP ERROR SUB AL,'0' MOV DX,BX SHL BX LAHF OR CH,80H SAHF JNZ RET3 MOV BX,[CON] CALL L055B JNZ RET3 LAHF AND CH,7FH SAHF LAHF OR CH,40H SAHSCANT: CMP AL,' ' JZ NEXB CMP AL,9 JNZ RET NEXB: CALL NEXTCHR JP SCANT DOLLAR: MOV DX,[OLDPC] MOV AL,CONST TEST AL,80H RCL SI JNZ ERR2 OR AL,0C0H L04E4: LAHF XCHG AX,BP SAHF POP AX XCHG AH,AL SAHF CMP AL,'-' MAL=SYM=2,3,4 8-bit register, 16-bit register, or segment register, ; respectively. DL has register number. ; ; AL=SYM=5 A m: LAHF XCHG AX,BP SAHF MOV CL,6 RCR SI TEST AL,8 RCL SI JNZ L05B5 LAHF OR AL,8 XCHG AX,BP SAHF MOV [UN SHL BX ADD BX,DX SHL BX MOV DL,AL MOV DH,0 ADD BX,DX DEC CH JNZ DEC XCHG DX,BX RET L0648: MOV CH,AL F MOV AL,BH OR AL,BL JNZ RET3 MOV AL,CH AND AL,7 MOV CH,AL CMP AL,6 JNZ RET3 LAHF OR CH,40H SAHF RET3: RE MOV [SYM],AL NEXTCHJ: JMP NEXTCHR GETSY: CALL SCANB CMP AL,'$' JZ DOLLAR MOV [SYM],AL OR AL,20H CMP AL,'z'+1 OV CL,5 JZ ERR2 L04F1: LAHF XCHG AX,BP SAHF LAHF OR AL,4 SAHF LAHF XCHG AX,BP SAHF CALL GETSYM CMP AL,'ode flag (such as "B" for byte operation). Type of flag in DL ; and also stored in FLAG: -1=no flags, 0=B, 1=W, 2=S, 3=L, 4=T. DEF],BX POP AX XCHG AH,AL SAHF CMP AL,'+' MOV CL,5 L05B5: JNZ ERR3 JMP L04F1 GETSYM: ; The lexical scanneMOV AL,[CHR] CMP AL,CH MOV CL,'#' MOV DL,AL MOV DH,0 JNZ L065A CALL L0690 L065A: CALL L0698 LAHF XCHG AX,BP T L055B: MOV AL,BH OR AL,AL JZ L0565 INC AL JNZ RET L0565: MOV AL,BL XOR AL,BH AND AL,80H RET NOIND: JNC NEXTCHJ CMP AL,'a' JC $+5 JMP LETTER CMP AL,'9'+1 JNC NEXTCHJ CMP AL,'0' JC NEXTCHJ MOV BX,SYM MOV B,[BX+' JNZ L0505 L0502: JMP PLSMNS L0505: CMP AL,'-' JZ L0502 LAHF XCHG AX,BP SAHF MOV CH,0 RCR SI TEST AL,10H ; ; AL=SYM=6 8087 floating point register, ST(n) or ST. DL has register number. ; ; All other values are the ASCII code of SAHF MOV CL,'%' TEST AL,2 JZ ERR3 TEST AL,4 MOV CL,'&' JNZ ERR3 LAHF XCHG AX,BP SAHF L066F: MOV AL,DL CM MOV CL,[BX] LAHF INC BX SAHF MOV AL,[BX] MOV BX,REGTAB MOV DH,XREG MOV DL,0 CMP AL,'x' JZ SCANREG MOV DH, AL,CL RET LETTER: CALL READID MOV AL,CH DEC AL JNZ NOFLG MOV AL,[ID] CMP AL,'l' MOV CL,0 MOV DX,L1A98 JZ80H SAHF MOV DX,RETSTR+2 CHKRET: MOV SI,DX LODB CMP AL,[BX] JNZ LOOKIT LAHF DEC BX SAHF LAHF DEC DX SAHBX ADD BL,AL DEC CH JNZ HEX1 XCHG DX,BX RET ERR4: JMP ERROR GETLET: CALL SCANB CMP AL,EOL STC JZ RET CSEGTAB: DB 'dsce' LOOK: MOV CH,[BX] LAHF INC BX SAHF MOV DX,ID CALL CPSLP JZ RET XOR AL,80H MOV CL,AL LAHP AL,13 MOV CL,"'" JZ ERR3 CALL PUT MOV AL,[DATSIZ] OR AL,AL JNZ L0686 MOV AL,DH CALL PUT L0686: MOV AL,[CHR]REG CMP AL,'l' JZ SCANREG MOV DL,4 CMP AL,'h' JZ SCANREG MOV DH,SREG MOV DL,0 MOV BX,SEGTAB CMP AL,'s' JZ SC SAVFLG CMP AL,'b' MOV DX,FLAG JZ SAVFLG CMP AL,'w' MOV CL,1 JZ SAVFLG XOR AL,AL NOFLG: DEC AL PUSH BX JNZ F DEC CH JNZ CHKRET MOV DX,[LSTRET] MOV AL,DL AND AL,DH INC AL JZ ALLRET MOV BX,[PC] SBB BX,DX CALL L055B MP AL,';' STC JZ RET MOV CL,10 OR AL,20H CMP AL,'a' JC ERR4 CMP AL,'z'+1 JNC ERR4 READID: MOV BX,ID MOV CH,F DEC BX SAHF MOV AL,[BX] XOR AL,80H CMP AL,CL JNC SMALL INC CH INC CH SMALL: MOV DL,CH MOV DH,0 LAHF A MOV DL,AL CALL L0698 JP L066F L0690: CALL NEXTCHR CMP AL,CH JNZ ERR3 RET L0698: CALL NEXTCHR CMP AL,CH ANREG MOV DH,XREG CMP AL,'p' JZ PREG CMP AL,'i' JNZ RET MOV DL,6 MOV AL,CL CMP AL,'s' JZ RET INC DL CMP ALL0004 CALL REGCHK L0004: POP BX MOV AL,DH JZ SYMSAV CALL LOOKRET SYMSAV: MOV [SYM],AL RET SAVFLG: XCHG DX,MOV AL,1 JZ RET ALLRET: MOV BX,[RETPT] MOV AL,BH OR AL,BL MOV AL,0 JNZ RET MOV BX,[HEAP] LAHF DEC BX SAHF 0 MOREID: MOV [BX],AL INC CH LAHF INC BX SAHF CALL NEXTCHR CMP AL,'0' JC NOMORE OR AL,20H CMP AL,'z'+1 JNDD BX,DX RCR SI SAHF RCL SI MOV DL,[BX] LAHF INC BX SAHF MOV DH,[BX] MOV AL,DH OR AL,DL STC JZ RET XCH JNZ RET CALL NEXTCHR CMP AL,CH JZ RET POP BX JMP L0578 HEX: MOV DX,ID DEC CH HEX1: MOV SI,DX LODB INC ,'d' RET PREG: MOV DL,4 MOV AL,CL CMP AL,'s' JZ RET INC DL CMP AL,'b' RET SCANREG: MOV AL,CL MOV CX,4 UPBX MOV AL,[BX] INC AL MOV [BX],CL MOV CL,32 JZ L0760 JMP ERROR L0760: MOV AL,5 JP SYMSAV REGCHK: MOV BX,ID LAHF DEC BX SAHF LAHF DEC BX SAHF MOV [HEAP],BX XOR AL,AL MOV [BX],AL MOV [RETPT],BX RET LOOKUP: LAHF C NOMORE CMP AL,'9'+1 JC MOREID CMP AL,'a' JNC MOREID NOMORE: MOV CL,AL MOV AL,CH MOV [LENID],AL OR AL,AL MOVG DX,BX JP LOOK LOOKRET: MOV AL,CH CMP AL,3 ;RET has 3 letters JNZ LOOKUP LAHF DEC BX SAHF LAHF OR B,[BX],0DX SUB AL,'0' CMP AL,10 JC GOTIT CMP AL,'g'-'0' JNC ERR4 SUB AL,'a'-10-'0' GOTIT: SHL BX SHL BX SHL BX SHL MOV DI,BX REPNZ SCAB MOV BX,DI JNZ RET MOV AL,CL ADD AL,DL MOV DL,AL XOR AL,AL RET REGTAB: DB 'bdca' DEC BX SAHF LAHF OR B,[BX],080H SAHF LOOKIT: MOV BX,[BASE] MOV AL,BH OR AL,BL JZ EMPTY CALL LOOK JC ENTER4 XCHG DX,BX NILIFY: MOV [BX],CL ;Zero left and right links INC BX DEC CH JNZ NILIFY XOR AL,AL ;Set zero flag M been defined), DX points ; to start of new node, and BX points to data field of new node. MOV AL,[LENID] ADD AL,8 ;StorADD AL,AL MOV BX,OPTAB MOV DL,AL MOV DH,0 LAHF ADD BX,DX RCR SI SAHF RCL SI MOV DL,[BX] LAHF INC BX SAHFID with ; bit 7 of the last character set to one. The length of the identifier is ; in LENID, which is ID-1. ; ; Node formatAB] OR AL,AL JZ $+5 JMP GETLET CALL LOOKUP MOV CL,11 JNZ ERR5 MOV DX,[PC] MOV B,[BX],1 LAHF INC BX SAHF MOV DX,4 LAHF ADD BX,DX RCR SI SAHF RCL SI MOV AL,[BX] OR AL,AL JZ RET LAHF INC BX SAHF MOV DL,[BX] OV [BX],AL ;Zero defined flag POP DX ;Restore pointer to node RET CPSLP: MOV SI,DX LODB CMP AL,[BX] LAHF INC age needed for the node MOV BX,[HEAP] MOV DL,AL MOV DH,0 SBB BX,DX ;Heap grows downward MOV [HEAP],BX XCHG DX,BX MOV DH,[BX] XCHG DX,BX INC CH MOV CL,CH MOV AL,[BX] LAHF INC BX SAHF OR AL,AL JZ OPERR FINDOP: MOV CH,CL: ; 1. Length of identifier (1 byte) ; 2. Identifier (1-80 bytes) ; 3. Left link (2-byte pointer to alphabetically smaller idMOV [BX],DL MOV [LABPT],BX LAHF INC BX SAHF MOV [BX],DH JMP GETLET ERR5: JMP ERROR ASMLIN: MOV BX,[PC] MOV LAHF INC BX SAHF MOV DH,[BX] RET ENTER: PUSH BX ;Save pointer to link field CALL CREATE ;Add the node POP SIDX INC BX SAHF JNZ RET DEC CH JNZ CPSLP RET GETLAB: MOV BX,0 MOV [LABPT],BX MOV AL,-1 MOV [FLAG],AL MOVMOV BX,[CODE] ;Check to make sure there's enough SBB BX,DX JB $+5 JMP ABORT PUSH DX MOV BX,LENID MOV CL,[BX] INC C LAHF XCHG AX,BP ;Save count of opcodes in BP SAHF MOV DX,ID+1 CALL CPSLP JZ HAVOP MOV DH,0 MOV DL,CH INC DL entifiers) ; 4. Right link (0 if none larger) ; 5. Data field: ; a. Defined flag (0=undefined, 1=defined) ; b. Value ( [OLDPC],BX CALL GETLAB JNC $+5 JMP ENDLN MOV BX,LENID MOV AL,[BX] MOV CL,12 SUB AL,2 MOV CH,AL JC ERR5 CMP XCHG SI,BX PUSH SI MOV [BX],DH ;Link new node LAHF DEC BX SAHF MOV [BX],DL POP BX RET ;Zero was set by CRE [L1A98],AL MOV DH,0 MOV AL,[CHR] CMP AL,' '+1 JC NOT1 LAHF OR DH,001H SAHF NOT1: CALL GETLET JC RET CMP ALL MOV CH,0 UP MOV SI,BX MOV DI,DX REP MOVB ;Move identifier and length into node MOV DX,DI MOV BX,SI MOV CH, INC DL LAHF ADD BX,DX RCR SI SAHF RCL SI LAHF XCHG AX,BP SAHF DEC AL JNZ FINDOP OPERR: MOV CL,12 JMP 2 bytes) ; ; This routine returns with AL=zero and zero flag set (which indicates ; on return from LOOKUP that it has not yetAL,5 JNC ERR5 LAHF INC BX SAHF MOV AL,[BX] SUB AL,'a' MOV CL,AL ADD AL,AL ADD AL,AL ADD AL,CL ADD AL,CH ATE EMPTY: CALL CREATE MOV [BASE],DX RET CREATE: ; Add a new node to the identifier tree. The identifier is at ,':' JNZ LABCHK CALL NEXTCHR JP LABEL LABCHK: OR AL,AL RCR SI TEST DH,001H RCL SI JZ RET LABEL: MOV AL,[CHKLERROR HAVOP: MOV DL,[BX] LAHF INC BX SAHF MOV DH,[BX] LAHF INC BX SAHF MOV AL,[BX] ;Get opcode XCHG DX,BATA] as code. If defined, ;two bytes of pure code will be produced. Otherwise, appropriate intermediate ;code will be generateCL CH RCL AL RCL CH RCL AL MOV [RELOC],AL MOV BX,BCOUNT DEC B,[BX] JNZ RET MOV B,[BX],4 MOV BX,RELOC MOV AL, ;or two-byte displacement will be added, as described by [ADDR] and [ALABEL]. PUSH CX PUSH DX PUSH BX MOV CH,0 MOV CLMOV AL,[FLAG] CALL IMM CALL PUTADD JP FINIMM IMM: AND AL,1 OR AL,CL MOV CL,AL CALL PUT MOV AL,CH AND AL,38HCALL GEN JP PRET SMPUT: CALL PUTCD CALL GEN1 PRET: POP BX POP DX POP CX RET NOUNDEF: MOV AL,BL MOV CL,BH X JMP BX GRP1: MOV CX,8A09H CALL MROPS MOV CX,0C6H MOV AL,BH CMP AL,UNDEFID JNZ L0006 CALL STIMM L0006: Ad. PUSH CX MOV CH,80H PUSH DX PUSH BX JP PUTBW PUTBYT: ;Same as PUTWOR, above, but for byte value. PUSH CX MOV[BX] MOV B,[BX],0 MOV DI,[IY] MOV [DI],AL MOV BX,[CODE] PUSH BX POP [IY] LAHF INC BX SAHF MOV [CODE],BX RE,AL CALL GEN ;Save the addressing mode as pure code MOV AL,CL MOV CH,80H AND AL,0C7H CMP AL,6 JZ TWOBT ;Direct add OR AL,BL RET PUT: ;Save byte in AL as pure code, with intermediate code bits 00. AL and ;DI destroyed, no other regist PUSH CX MOV CH,0 CALL GEN POP CX MOV AL,CL RCR SI TEST CH,080H RCL SI MOV CH,0 JZ PRETJ CALL GEN PRETJ: JND AL,1 JZ BYTIMM MOV AL,0B8H OR AL,BL CALL PUT JMP PUTWOR BYTIMM: MOV AL,0B0H OR AL,BL CALL PUT PUTBJ: JMP CH,40H PUSH DX PUSH BX MOV BX,[DLABEL] MOV AL,BH OR AL,BL JNZ PUTBW MOV BX,[DATA] OR AL,BH JZ PUTBW INC BH T PUTINC: PUSH BX MOV BX,[PC] LAHF INC BX SAHF MOV [PC],BX JP PUTCD1 PUTCD: PUSH BX PUTCD1: MOV BX,[CODE] ress? AND AL,0C0H JZ PRET ;Indirect through reg, no displacement? CMP AL,0C0H JZ PRET ;Register to register operation?ers affected. PUSH BX PUSH CX MOV CH,0 ;Flag as pure code CALL GEN POP CX POP BX RET GEN: ;Save byte of code P PRET PUTADD: ;Save complete addressing mode. Addressing mode is in AL; if this is a register ;operation (>=C0), then the PUTBYT IMMED: MOV AL,BH CMP AL,UNDEFID JZ STIMM MOV AL,BL OR AL,AL JZ RET MOV AL,BH CALL IMM OR AL,0C0H C JZ PUTBW MOV CL,31 JMP ERROR PUTBW: MOV DX,[DLABEL] MOV BX,[DATA] PUTCHK: MOV AL,DH OR AL,DL JZ NOUNDEF MOV MOV [BX],AL LAHF INC BX SAHF MOV [CODE],BX POP BX RET PUTWOR: ;Save the word value described by [DLABEL] and [D MOV CH,AL ;Save whether one- or two-byte displacement TWOBT: MOV BX,[ADDR] MOV DX,[ALABEL] JP PUTCHK GRP2: CALL in AL, given intermediate code bits in bits 7&8 of CH. CALL PUTINC ;Save it and bump code pointer GEN1: MOV AL,[RELOC] Rone byte will be saved as pure code. Otherwise, ;the details of the addressing mode will be investigated and the optional one- ALL PUT FINIMM: MOV AL,CL POP CX RCR SI TEST AL,1 RCL SI JZ PUTBJ CMP AL,83H JZ PUTBJ JMP PUTWOR STIMM: AL,DL CALL PUTCD MOV AL,DH CALL PUTCD MOV AL,BL CALL PUTINC MOV AL,BH RCR SI TEST CH,080H RCL SI JZ SMPUT GETOP MOV CX,0FF30H CMP AL,UNDEFID JZ PMEM MOV CH,50H CMP AL,XREG JZ PXREG MOV CH,6 CMP AL,SREG JNZ $+5 JMP DX,BX MOV BX,[LABPT] MOV AL,BH OR AL,BL MOV CL,34 JZ ERR7 MOV [BX],DL LAHF INC BX SAHF MOV [BX],DH RET ORYT GRP5: LAHF XCHG AH,AL PUSH AX XCHG AH,AL CALL GETOP CMP AL,CONST JNZ ERR6 MOV BX,[DLABEL] MOV AL,BH OR AL,AL JNZ ERRJ1 MOV AL,DH CMP AL,XREG JZ G10 CMP AL,REG ERRJ1: JNZ ERR8 G10: LAHF XCHG AH,AL PUSH AX XCHG AAL,BL OR AL,AL JZ EXACC XCHG DX,BX MOV AL,BL OR AL,AL MOV AL,BH JZ EXACC CALL RR1 EXACC: MOV AL,90H OR AL,D CALL GETOP ONE: MOV CL,26 CMP AL,CONST JZ ERR7 CMP AL,SREG MOV CL,22 JZ ERR7 POP CX CMP AL,UNDEFID JZ MOP PACKREG MOV CL,20 JMP ERROR PMEM: MOV AL,CH CALL PUT MOV AL,CL OR AL,DL JMP PUTADD PXREG: MOV AL,CH OR AG: MOV [PC],BX MOV AL,-2 NEWLOC: CALL PUTCD MOV AL,BL CALL PUTCD MOV AL,BH CALL PUTCD MOV CH,0C0H JMP GEN1 G AL,BL MOV CL,30 JNZ ERR6 MOV BX,[DATA] POP AX XCHG AH,AL SAHF OR AL,AL JZ ORG DEC AL JZ DSJ DEC AL JZ EH,AL CALL GETOP POP AX XCHG AH,AL SAHF AND AL,1 MOV [FLAG],AL MOV AL,DH ONEJ: JP ONE GRP11: CALL PUT MOV AL,L JMP PUT EXMEM: XCHG DX,BX EXMEM1: CMP AL,BH JZ ERR6 MOV CL,1 ;Flag word as OK CALL NOTAC ;NOTAC never returns AND AL,1 JZ ROP RCR SI TEST CL,001H RCL SI JZ ROP MOV AL,CL AND AL,0F8H OR AL,DL JMP PUT MOP: MOV AL,[FLAGL,DL JMP PUT GRP3: CALL GETOP PUSH DX CALL GETOP2 POP BX MOV CX,8614H MOV AL,SREG CMP AL,BH JZ ERR6 CMP ARP6: MOV CH,AL MOV CL,4 CALL MROPS MOV CL,23 ERR7: JMP ERROR GRP7: MOV CH,AL MOV CL,1 CALL MROPS MOV CL,80H QU DEC AL JZ $+5 JMP IF PUTOP: MOV AL,-3 JP NEWLOC ALIGN: MOV AL,[PC] AND AL,1 JZ RET MOV BX,1 DSJ: XCHG 0AH JMP PUT GRP12: MOV CL,AL MOV CH,0D0H PUSH CX CALL GETOP MOV AL,[SYM] CMP AL,',' MOV AL,DH JNZ ONEJ PUSH ERR6: JMP ERROR GRP4: LAHF XCHG AH,AL PUSH AX XCHG AH,AL CALL GETOP POP CX CMP AL,CONST JZ FIXED SUB AL,XR] AND AL,1 OR AL,CH CALL PUT MOV AL,CL AND AL,38H OR AL,DL JMP PUTADD ROP: OR AL,CH CALL PUT MOV AL,CL ANL,DH JZ ERR6 MOV AL,CONST CMP AL,BH JZ ERR6 CMP AL,DH JZ ERR6 MOV AL,UNDEFID CMP AL,BH JZ EXMEM CMP AL,DH MOV DX,[DLABEL] MOV AL,DH OR AL,DL JNZ ACCJ XCHG DX,BX MOV BX,[DATA] CALL L055B XCHG DX,BX JNZ ACCJ LAHF OR DX,BX MOV BX,[PC] LAHF ADD BX,DX RCR SI SAHF RCL SI MOV [PC],BX XCHG DX,BX MOV AL,-4 JP NEWLOC EQU: XCHG DX CALL GETOP SUB AL,REG MOV CL,20 DEC DL OR AL,DL JNZ ERR8 POP DX MOV AL,DH POP CX LAHF OR CH,002H SAHEG DEC DL DEC DL OR AL,DL MOV CL,20 JNZ ERR6 MOV AL,CH OR AL,8 JMP PUT FIXED: MOV AL,CH CALL PUT JMP PUTBD AL,38H OR AL,0C0H OR AL,DL JMP PUT GRP10: MOV CL,AL MOV CH,0F6H PUSH CX CALL GETOP MOV CL,20 MOV AL,DL ORJZ EXMEM1 MOV AL,BH CMP AL,DH MOV CL,22 JNZ ERR6 CMP AL,XREG JZ L0008 CALL RR1 L0008: ;RR1 never returns MOV CL,002H SAHF ACCJ: JMP ACCIMM GRP8: MOV CL,AL MOV CH,0FEH JP ONEOP GRP9: MOV CL,AL MOV CH,0F6H ONEOP: PUSH CX F PUSH CX JMP ONE GRP13: MOV CH,AL MOV CL,1 CALL MROPS MOV CL,80H ACCIMM: CALL IMMED OR CH,004H AND CH,0FDH CMP AL,',' JNZ L0011 CALL GETSYM L0011: JP GETSP NODEC: ;Return is intra-segment (short) without add to SP. ;Record JNZ ERR8 JMP PUTWOR GRP16: ;RET mnemonic LAHF XCHG AH,AL PUSH AX XCHG AH,AL CALL GETSYM CMP AL,5 JZ LONGR R10 MOV CH,26H PACKREG: MOV AL,DL ADD AL,AL ADD AL,AL ADD AL,AL OR AL,CH JMP PUT GRP22: CALL GETOP MOV CX,8FND AL,38H OR AL,DL MOV CH,AL MOV AL,[L1A98] OR AL,AL MOV AL,CH JZ PUTADDJ ;If so, do inter-segment AND AL,0F7H ;MOV BX,[DATA] CALL L055B JZ RET MOV CL,31 ERR10: JMP ERROR RET GRP18: CALL GETOP CMP AL,CONST MOV CL,20 JNZ ER AIMM: MOV AL,BH AND AL,1 LAHF XCHG AH,AL PUSH AX XCHG AH,AL OR AL,CH CALL PUT POP AX XCHG AH,AL SAHF JN position for RET symbol. MOV BX,[PC] MOV [LSTRET],BX XCHG DX,BX MOV BX,[RETPT] MOV AL,BH OR AL,BL JZ DORET MOV CMP AL,EOL JZ NODEC CMP AL,';' JZ NODEC GETSP: CALL GETOP1 POP CX CMP AL,CONST MOV CL,20 JNZ ERR9 MOV AL,CH 00H CMP AL,UNDEFID JNZ $+5 JMP PMEM MOV CH,58H CMP AL,XREG JNZ $+5 JMP PXREG MOV CH,7 CMP AL,SREG JZ PACKREGConvert to intra-segment PUTADDJ: JMP PUTADD DIRECT: MOV AL,[SYM] CMP AL,',' JZ LONGJ POP AX XCHG AH,AL SAHF DR10 MOV BX,[DLABEL] MOV AL,BH OR AL,BL JNZ GENINT MOV BX,[DATA] MOV DX,3 SBB BX,DX JNZ GENINT MOV AL,0CCH JMZ $+5 JMP PUTBYT JMP PUTWOR ERR8: JMP ERROR GRP14: ;JMP and CALL mnemonics LAHF XCHG AH,AL PUSH AX XCHG AH,ALB,[BX],1 LAHF INC BX SAHF MOV [BX],DL LAHF INC BX SAHF MOV [BX],DH MOV BX,0 MOV [RETPT],BX DORET: POP AX AND AL,0FEH CALL PUT JMP PUTWOR LONGR: MOV AL,[L1A98] OR AL,AL ;Is flag "L"? JNZ NOTLON POP AX XCHG AH,AL SA MOV CL,20 ERR11: JMP ERROR GRP23: MOV [DATSIZ],AL GETDAT: CALL GETSYM MOV AL,2 CALL VAL1 MOV AL,[SYM] CMP AL,'EC AL CMP AL,0E9H JZ GOTOP MOV AL,0E8H GOTOP: CALL PUT MOV BX,[DATA] MOV DX,[PC] INC DX INC DX SUB BX,DX MOP PUT GENINT: MOV AL,0CDH CALL PUT JMP PUTBYT GRP19: ;ESC opcode MOV CX,0D800H JMP ONEOP GRP20: MOV CH,AL M CALL GETOP CMP AL,CONST JZ DIRECT MOV CL,20 CMP AL,REG JZ ERR8 CMP AL,SREG JZ ERR8 CMP AL,XREG JNZ NOTRG XCHG AH,AL SAHF JMP PUT GRP17: CALL PUT CALL GETOP CMP AL,CONST MOV CL,20 ERR9: JNZ ERR10 MOV BX,[DATA] MOHF OR AL,8 LAHF XCHG AH,AL PUSH AX XCHG AH,AL NOTLON: CALL GETSYM CMP AL,EOL JZ DORET CMP AL,';' JZ DORET ,' MOV AL,[DATSIZ] JNZ ENDDAT CALL SAVDAT JP GETDAT ENDDAT: CMP AL,2 JNZ SAVDAT MOV BX,[DATA] LAHF OR BL,080HV [DATA],BX JMP PUTWOR LONGJ: POP AX XCHG AH,AL SAHF CALL PUT CALL PUTWOR CALL GETOP MOV CL,20 CMP AL,CONST OV CL,1 CALL MROPS MOV CL,0F6H CALL IMMED MOV CH,0A8H JMP AIMM GRP21: CALL GETOP CMP AL,SREG MOV CL,28 JNZ EROR DL,40H OR DL,80H NOTRG: ;Indirect jump. DL has addressing mode. MOV AL,0FFH CALL PUT POP AX XCHG AH,AL SAHF AV DX,[PC] LAHF INC DX SAHF SBB BX,DX MOV [DATA],BX CALL PUTBYT MOV BX,[DLABEL] MOV AL,BH OR AL,BL JNZ RET SAHF MOV [DATA],BX SAVDAT: OR AL,AL JZ $+5 JMP PUTBYT JMP PUTWOR IF: MOV AL,BH OR AL,BL MOV AL,1 JZ SKIPCLL LIST CALL LIST CALL LIST DEC CH JNZ BLNK NOFIL: CALL OUTLIN POP BX MOV AL,[BX] PUSH BX CALL REPERR MOV At NEXT RECORD field to zero MOV [COUNT],AL CALL STRTLIN MOV BX,START L1069: MOV CH,4 MOV CL,[BX] LAHF INC BX SA SAHF MOV CH,[BX] XCHG DX,BX MOV DL,[BX] LAHF INC BX SAHF MOV DH,[BX] XCHG DX,BX LAHF ADD BX,CX RCR SI ********** END: MOV CL,4 WREND: MOV CH,0FFH MOV AL,CH CALL GEN DEC CL JNZ WREND MOV AL,[LSTFCB] CMP AL,'Z' 8 INC AL JZ L1128 L111E: MOV AL,101 MOV [ERR],AL L1123: MOV AL,DL JMP L107D L1128: MOV AL,[COUNT] DEC AL JND MOV [IFFLG],AL RET SKIPCD: MOV [CHKLAB],AL SKIPLP: XOR AL,AL CALL NEXLIN CALL NEXTCHR CMP AL,1AH JZ END L,[ERR] CALL REPERR CALL STRTLIN POP BX POP CX JP L1080 OUTLIN: CALL LIST MOV AL,[LSTFCB] CMP AL,'Z' JZ RETHF L1070: RCL CL JC L1087 RCL CL JNC L107B JMP L1108 L107B: MOV AL,[BX] L107D: CALL L13BB L1080: INC BX DESAHF RCL SI POP CX XCHG DX,BX OR AL,AL JNZ RET1 MOV AL,64H MOV [ERR],AL MOV DX,0 RET1: RET STRTLIN: XOR AL JZ L1033 CALL ADDEXT MOV DX,FCB MOV CL,OPEN CALL SYSTEM MOV BX,0FFH XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] L10Z L1123 MOV AL,[L1B10] CMP AL,0EBH JZ L111E AND AL,0FCH CMP AL,0E0H JZ L111E AND AL,0F0H CMP AL,70H JZ L111E CALL GETLAB JC SKIPLP MOV BX,LENID MOV DX,IFEND MOV CH,[BX] INC CH CALL CPSLP JNZ SKIPLP XOR AL,AL MOV [CHKLAB2 MOV BX,L1B0F MOV AL,[BX] MOV B,[BX],0FFH OR AL,AL JNZ CRLF OUTLN: CALL NEXTCHR CALL LIST CMP AL,10 JNZ OUTLC CH JNZ L1070 JP L1069 L1087: RCL CL JC L108E JMP L1144 L108E: MOV AL,[BX] CMP AL,-10 JB L1097 JMP L1214 L,AL MOV [ERR],AL MOV [L1B0F],AL MOV BX,[PC] MOV AL,BH CALL PHEX MOV AL,BL PHEXB: CALL PHEX MOV AL,' ' LIST: 33: MOV AL,-5 MOV [HEXCNT],AL ;FLAG HEX BUFFER AS EMPTY MOV [L1B0E],AL MOV BX,HEXBUF MOV [HEXPNT],BX MOV BX,LSTBUF JP L1123 L1144: CALL L1151 MOV AL,DL CALL L13BB MOV AL,DH JMP L107D L1151: PUSH CX MOV DL,[BX] LAHF INC],AL RET ENDIF: MOV BX,IFFLG MOV AL,[BX] MOV B,[BX],0 MOV CL,36 OR AL,AL JZ ERR11 RET ;*******************N RET2: RET PRTCNT: MOV BX,ERCNTM CALL PRINT MOV BX,[ERRCNT] CALL L1362 CALL L1384 CRLF: MOV AL,13 CALL LIST 1097: PUSH CX PUSH BX MOV BX,COUNT MOV AL,6 SUB AL,[BX] MOV B,[BX],0 MOV CH,AL MOV AL,' ' JZ NOFIL BLNK: CALAHF XCHG AH,AL PUSH AX XCHG AH,AL MOV AL,[LSTFCB] CMP AL,'Z' JZ L11ED CMP AL,'X' JZ L11F2 POP AX XCHG AH,AL MOV [LSTPNT],BX MOV BX,0 MOV [ERRCNT],BX MOV [PC],BX MOV BX,OBJECT MOV [HEXADD],BX XOR AL,AL MOV [FCB+20H],AL ;Se BX SAHF MOV DH,[BX] LAHF INC BX SAHF XCHG DX,BX MOV AL,[BX] LAHF INC BX SAHF MOV CL,[BX] LAHF INC BX ************************************************** ; ; PASS 2 ; ;*********************************************************** MOV AL,10 JMP LIST L1108: CALL L1151 XCHG DX,BX CALL L055B XCHG DX,BX JZ L1123 MOV AL,DH OR AL,AL JZ L112 SAHF LAHF XCHG AH,AL PUSH AX XCHG AH,AL AND AL,7FH PUSH BX MOV BX,[LSTPNT] MOV [BX],AL CALL L1546 MOV [LSCNT EXIT: JMP 0 RET L12D6: MOV AX,[LSTPNT] CMP AX,LSTBUF JZ RET MOV AL,1AH CALL LIST JP L12D6 L12E5: XCHGSH CX MOV AL,'0' CALL PUTCHR POP CX DEC CH JNZ L1276 CALL L14F4 JZ L1289 CALL L13B3 L1289: CALL L13B3 MOV C L1384: XCHG DX,BX MOV CH,10H MOV AL,CL CALL L13A0 MOV AL,BH CALL L13AE MOV AL,BH CALL L13A0 MOV AL,BL CALF INC BX SAHF MOV DH,[BX] PUSH BX INC AL JZ L1253 INC AL JZ L124D MOV BX,[PC] LAHF ADD BX,DX RCR SI SA INC BX SAHF PUSH BX LAHF INC BX SAHF LAHF INC BX SAHF LAHF INC BX SAHF LAHF INC BX SAHF MOV AL,[TPNT],BX JNZ L11EC MOV BX,LSTBUF MOV [LSTPNT],BX PUSH DX XCHG DX,BX PUSH CX MOV CL,SETDMA CALL 5 MOV DX,LSTFCB DX,BX PUSH BX MOV DL,[BX] MOV DH,0 LAHF INC BX SAHF LAHF ADD BX,DX RCR SI SAHF RCL SI MOV DL,[BX] LAHL,CLOSE MOV DX,HEXFCB CALL SYSTEM SYMDMP: MOV AL,[SYMFLG] CMP AL,'S' JNZ L12B4 MOV BX,SYMMES CALL PRINT MOV DX,L L13AE MOV AL,BL MOV CH,0 L13A0: CALL LHALF L13A3: CMP AL,30H JZ L13A9 MOV CH,0 L13A9: SUB AL,CH JMP LIST HF RCL SI MOV [PC],BX MOV BX,[HEXADD] LAHF ADD BX,DX RCR SI SAHF RCL SI MOV [HEXADD],BX JP L1257 L124D: MBX] CALL PHEX LAHF DEC BX SAHF MOV AL,[BX] CALL PHEX CALL CRLF POP BX MOV DL,[BX] LAHF INC BX SAHF MOV MOV CL,SEQWRT CALL 5 POP CX POP DX L11EC: POP BX L11ED: POP AX XCHG AH,AL SAHF RET L11F2: POP AX XCHG F INC BX SAHF MOV DH,[BX] MOV AL,DL OR AL,DH JZ L1307 CALL L12E5 L1307: POP BX MOV CH,[BX] LAHF INC BX [BASE] MOV AL,DH OR AL,DL JZ EXIT MOV BX,[HEAP] MOV SP,BX CALL L12E5 L12B4: MOV AL,[LSTFCB] CMP AL,'X' JZ EXI L13AE: CALL UHALF JP L13A3 L13B3: MOV AL,1AH CALL PUTCHR JNZ L13B3 RET L13BB: MOV [L1B10],AL PUSH BX PUOV [HEXADD],DX JP L1257 L1253: MOV [PC],DX L1257: POP BX JMP L1080 L125B: CALL PRTCNT MOV AL,[HEXFCB] CMP AL,'Z DH,[BX] MOV AL,DH OR AL,DL JNZ L12E5 RET L1362: MOV CH,10H MOV DX,0 L1367: LAHF ADD BX,BX RCR SI SAHF AH,AL SAHF LAHF XCHG AH,AL PUSH AX XCHG AH,AL CALL OUT POP AX XCHG AH,AL SAHF RET PHEX: MOV CH,AL CALSAHF MOV AL,0AH SUB AL,CH JNB L1315 MOV AL,1 L1315: MOV DH,AL L1317: MOV AL,[BX] LAHF INC BX SAHF CALL LIST CMP AL,'Z' JZ L12CA CALL L12D6 MOV DX,LSTFCB MOV CL,CLOSE CALL 5 L12CA: MOV AL,'X' MOV [LSTFCB],AL CALL PRTSH CX LAHF XCHG AH,AL PUSH AX XCHG AH,AL PUSH DX CALL L144E POP DX MOV BX,COUNT INC B,[BX] MOV AL,[BX] CMP' JZ SYMDMP MOV AL,[HEXCNT] CMP AL,-5 JZ L126F CALL ENHEXL L126F: MOV AL,':' CALL PUTCHR MOV CH,10 L1276: PU RCL SI MOV AL,DL ADC AL,AL DAA MOV DL,AL MOV AL,DH ADC AL,AL DAA MOV DH,AL RCL CL DEC CH JNZ L1367 RET L UHALF CALL LIST MOV AL,CH CALL LHALF JMP LIST L1214: INC AL JZ L125B LAHF INC BX SAHF MOV DL,[BX] LAHT DEC CH JNZ L1317 MOV CH,DH INC CH MOV AL,20H L1329: CALL LIST DEC CH JNZ L1329 LAHF INC BX SAHF LAHF AL,7 JNZ L13E9 MOV B,[BX],1 MOV AL,20H CALL OUTLIN MOV AL,20H MOV CH,5 L13E2: CALL LIST DEC CH JNZ L13E2 L1X],AL MOV AL,-6 MOV [HEXCNT],AL MOV AL,[CHKSUM] ADD AL,CH NEG AL CALL HEXBYT L14F4: MOV AL,13 CALL PUTCHR M [CHKSUM],AL MOV BX,[HEXPNT] MOV [HEXLEN],BX CALL HEXBYT MOV AL,[HEXADD+1] CALL HEXBYT MOV AL,[HEXADD] CALL HEXBYTd' DW GRP11 DB 0D5H A5: DB 1 DB 'lign' DW ALIGN DB 0 C3: DB 7 DB 'mp' DW GRP7 DB 3AH DB 'lc' DW PUT LAHF INC BX SAHF JP PRINT OUT: MOV DL,AL MOV CL,2 SYSTEM: PUSH CX PUSH DX PUSH BX CALL 5 POP BX POP UF+128 JZ RET CMP BX,L1B9B+128 JNZ RET MOV BX,HEXBUF RET NONE: DB 0 ; 8086 MNEMONIC TABLE ; This table is act3E9: POP AX XCHG AH,AL SAHF CALL PHEXB POP CX MOV BX,[PC] LAHF INC BX SAHF MOV [PC],BX MOV BX,[HEXADD] LOV AL,10 PUTCHR: MOV BX,[HEXPNT] MOV [BX],AL CALL L1546 MOV [HEXPNT],BX JNZ RET PUSH BX MOV BX,L1B0E MOV AL,[ XOR AL,AL CALL HEXBYT AFHEX: POP AX XCHG AH,AL SAHF HEXBYT: MOV CH,AL MOV BX,CHKSUM ADD AL,[BX] MOV [BX],ALDB 0F8H DB 'ld' DW PUT DB 0FCH DB 'li' DW PUT DB 0FAH DB 'mc' DW PUT DB 0F5H DB 'bw' DW PUT DB 98H DB DX POP CX RET L144E: LAHF XCHG AH,AL PUSH AX XCHG AH,AL MOV AL,[HEXFCB] CMP AL,'Z' JNZ L145E JMP L11ED Lually a sequence of subtables, each starting with a label. ; The label signifies which mnemonics the subtable applies to--A3, fAHF INC BX SAHF MOV [HEXADD],BX POP BX RET REPERR: OR AL,AL ;Did an error occur? JZ RET LAHF XCHG AH,AL BX] MOV B,[BX],0 POP BX OR AL,AL JNZ RET MOV CL,SETDMA XCHG DX,BX CALL SYSTEM MOV DX,HEXFCB MOV CL,SEQWRT CA MOV AL,CH CALL UHALF CALL PUTCHR MOV AL,CH CALL LHALF CALL PUTCHR MOV BX,HEXCNT INC B,[BX] MOV AL,[BX] CMP 'wd' DW PUT DB 99H C4: DB 3 DB 'all' DW GRP14 DB 9AH DB 'mpb' DW PUT DB 0A6H DB 'mpw' DW PUT DB 0A7H D145E: MOV DX,[LASTAD] MOV BX,[HEXADD] MOV [LASTAD],BX LAHF INC DX SAHF MOV AL,[HEXCNT] CMP AL,-5 JZ NEWLIN Oor example, ; means all 3-letter mnemonics beginning with A. A3: DB 7 DB 'dd' DW GRP7 DB 2 DB 'nd' DW GRP13 DBPUSH AX XCHG AH,AL MOV BX,ERRMES ;Print "ERROR" CALL PRINT POP AX XCHG AH,AL SAHF CALL PHEX MOV BX,HEXSUF CALLLL SYSTEM XCHG DX,BX OR AL,AL JZ RET MOV BX,WRTERR JMP PRERR UHALF: RCR AL RCR AL RCR AL RCR AL LHALF: AAL,26 JNZ RET ENHEXL: MOV BX,[HEXLEN] MOV CH,AL CALL UHALF MOV [BX],AL CALL L1546 MOV AL,CH CALL LHALF MOV [B2: DB 5 DB 'b' DW GRP23 DB 1 DB 'w' DW GRP23 DB 0 DB 'm' DW GRP23 DB 2 DB 's' DW GRP5 DB 1 DB 'i' R AL,AL SBB BX,DX JZ AFHEX CALL ENHEXL NEWLIN: MOV AL,':' CALL PUTCHR MOV AL,-4 MOV [HEXCNT],AL XOR AL,AL MOV 22H DB 'dc' DW GRP7 DB 12H DB 'aa' DW PUT DB 37H DB 'as' DW PUT DB 3FH DB 'am' DW GRP11 DB 0D4H DB 'a PRINT MOV BX,[ERRCNT] LAHF INC BX SAHF MOV [ERRCNT],BX RET PRINT: MOV AL,[BX] CALL LIST OR AL,AL JS RET ND AL,0FH OR AL,30H CMP AL,'9'+1 JC RET ADD AL,7 RET: RET L1546: INC BX CMP BX,HEXBUF+128 JZ RET CMP BX,LSTBDW PUT DB 0FAH D3: DB 4 DB 'ec' DW GRP8 DB 49H DB 'iv' DW GRP10 DB 30H DB 'aa' DW PUT DB 27H DB 'as' DW GRP17 DB 7CH DB 'nae' DW GRP17 DB 72H DB 'nbe' DW GRP17 DB 77H DB 'nle' DW GRP17 DB 7FH L3: DB 3 DBB 75H DB 'ne' DW GRP17 DB 75H DB 'nl' DW GRP17 DB 7DH DB 'ge' DW GRP17 DB 7DH DB 'nb' DW GRP17 DB 73H 6 DB 'et' DW GRP16 DB 0C3H DB 'ep' DW PUT DB 0F3H DB 'ol' DW GRP12 DB 0 DB 'or' DW GRP12 DB 8 DB 'cl' 0CCH I4: DB 4 DB 'mul' DW GRP10 DB 28H DB 'div' DW GRP10 DB 38H DB 'ret' DW PUT DB 0CFH DB 'nto' DW PUB 0A4H DB 'ovw' DW PUT DB 0A5H N3: DB 3 DB 'ot' DW GRP9 DB 10H DB 'eg' DW GRP9 DB 18H DB 'op' DW PUT DW PUT DB 2FH D4: DB 1 DB 'own' DW PUT DB 0FDH E2: DB 1 DB 'i' DW PUT DB 0FBH E3: DB 3 DB 'qu' DW GRP 'ea' DW GRP6 DB 8DH DB 'ds' DW GRP6 DB 0C5H DB 'es' DW GRP6 DB 0C4H L4: DB 5 DB 'oop' DW GRP17 DB 0E2HDB 'ae' DW GRP17 DB 73H DB 'nc' DW GRP17 DB 73H DB 'ng' DW GRP17 DB 7EH DB 'le' DW GRP17 DB 7EH DB 'na' DW GRP12 DB 10H DB 'cr' DW GRP12 DB 18H R4: DB 2 DB 'epz' DW PUT DB 0F3H DB 'epe' DW PUT DB 0F3H R5: T DB 0CEH J2: DB 10 DB 'p' DW GRP17 DB 0EBH DB 'z' DW GRP17 DB 74H DB 'e' DW GRP17 DB 74H DB 'l' DW GDB 90H O2: DB 1 DB 'r' DW GRP13 DB 0AH O3: DB 2 DB 'ut' DW GRP4 DB 0E6H DB 'rg' DW GRP5 DB 0 O4: DB 25 DB 2 DB 'sc' DW GRP19 DB 0D8H DB 'nd' DW END DB 0 E5: DB 1 DB 'ndif' DW ENDIF DB 0 H3: DB 1 DB 'lt DB 'odb' DW PUT DB 0ACH DB 'odw' DW PUT DB 0ADH DB 'ahf' DW PUT DB 9FH DB 'ock' DW PUT DB 0F0H L5: D DW GRP17 DB 76H DB 'be' DW GRP17 DB 76H DB 'pe' DW GRP17 DB 7AH DB 'np' DW GRP17 DB 7BH DB 'po' DW GRP DB 2 DB 'epnz' DW PUT DB 0F2H DB 'epne' DW PUT DB 0F2H S3: DB 11 DB 'ub' DW GRP7 DB 2AH DB 'bb' DW GRPRP17 DB 7CH DB 'b' DW GRP17 DB 72H DB 'a' DW GRP17 DB 77H DB 'g' DW GRP17 DB 7FH DB 'o' DW GRP17 DB 70 DB 'utb' DW GRP4 DB 0E6H DB 'utw' DW GRP4 DB 0E7H P3: DB 2 DB 'op' DW GRP22 DB 8FH DB 'ut' DW GRP5 D' DW PUT DB 0F4H H4: DB 1 DB 'alt' DW PUT DB 0F4H I2: DB 2 DB 'n' DW GRP4 DB 0E4H DB 'f' DW GRP5 DB B 2 DB 'oope' DW GRP17 DB 0E1H DB 'oopz' DW GRP17 DB 0E1H L6: DB 2 DB 'oopne' DW GRP17 DB 0E0H DB 'oopnz'17 DB 7BH DB 'no' DW GRP17 DB 71H DB 'ns' DW GRP17 DB 79H J4: DB 5 DB 'cxz' DW GRP17 DB 0E3H DB 'nge' 7 DB 1AH DB 'bc' DW GRP7 DB 1AH DB 'tc' DW PUT DB 0F9H DB 'td' DW PUT DB 0FDH DB 'ti' DW PUT DB 0FBH H DB 's' DW GRP17 DB 78H DB 'c' DW GRP17 DB 72H J3: DB 17 DB 'mp' DW GRP14 DB 0EAH DB 'nz' DW GRP17 DB 3 P4: DB 2 DB 'ush' DW GRP2 DB 0FFH DB 'opf' DW PUT DB 9DH P5: DB 1 DB 'ushf' DW PUT DB 9CH R3: DB 4 I3: DB 4 DB 'nc' DW GRP8 DB 41H DB 'nb' DW GRP4 DB 0E4H DB 'nw' DW GRP4 DB 0E5H DB 'nt' DW GRP18 DB DW GRP17 DB 0E0H M3: DB 2 DB 'ov' DW GRP1 DB 88H DB 'ul' DW GRP10 DB 20H M4: DB 2 DB 'ovb' DW PUT D DB 'hl' DW GRP12 DB 20H DB 'hr' DW GRP12 DB 28H DB 'al' DW GRP12 DB 20H DB 'ar' DW GRP12 DB 38H DB 'eg' NONE DW NONE DW I2 ;I DW I3 DW I4 DW NONE DW NONE DW J2 ;J DW J3 DW J4 DW NONE DW NONE DW NONE ;K DW of the first ; letter of the mnemonic and its length, then add a new subsection to ; the mnemonic table in alphabetical order.FILE: DB 13,10,'File not found',13,10,'$' WRTERR: DB 13,10,'Disk write error',13,10,'$' BADDSK: DB 13,10,'Bad disk specifier',ting letter of the mnemonic), there are 5 entries. Each entry ; corresponds to a mnemonic whose length is 2, 3, 4, 5, and 6 chaNE DW NONE DW NONE ;V DW NONE DW NONE DW NONE DW NONE DW NONE ;W DW NONE DW W4 DW NONE DW NONE DW NONE ; DW GRP21 DB 26H S4: DB 5 DB 'cab' DW PUT DB 0AEH DB 'caw' DW PUT DB 0AFH DB 'tob' DW PUT DB 0AAH DB NONE DW NONE DW NONE DW NONE DW NONE ;L DW L3 DW L4 DW L5 DW L6 DW NONE ;M DW M3 DW M4 DW NONE DW NONE DW NONE DW A3 DW NONE DW A5 DW NONE DW NONE ;B DW NONE DW NONE DW NONE DW NONE DW NONE ;C DW C3 DW 13,10,'$' ERCNTM: DM 13,10,13,10,'Error Count =' SYMMES: DM 13,10,'Symbol Table',13,10,13,10 EXTEND: DB 'ASM',0,0,0,0 IFEND:racters ; long, respectively. If there are no mnemonics for a given combination ; of first letter and length (such as A-2), thX DW X3 DW X4 DW NONE DW NONE DW NONE ;Y DW NONE DW NONE DW NONE DW NONE DW NONE ;Z DW NONE DW NONE DW'tow' DW PUT DB 0ABH DB 'ahf' DW PUT DB 9EH T4: DB 1 DB 'est' DW GRP20 DB 84H U2: DB 1 DB 'p' DW PUT DW NONE ;N DW N3 DW NONE DW NONE DW NONE DW O2 ;O DW O3 DW O4 DW NONE DW NONE DW NONE ;P DW P3 DW P4 C4 DW NONE DW NONE DW D2 ;D DW D3 DW D4 DW NONE DW NONE DW E2 ;E DW E3 DW NONE DW E5 DW NONE DW NONE ; DB 5,'endif' RETSTR: DM 'ret' HEXFCB: DB 0,' HEX',0,0,0,0 DS 16 DB 0 LSTFCB: DB 0,' PRN',0,0,0,0 DS 16 en the corresponding entry ; points to NONE. Otherwise, it points to a place in the mnemonic table ; for that type. ; This NONE DW NONE HEADER: DB 13,10,'Seattle Computer Products 8086 Assembler Version 2.00',13,10,'$' ERRMES: DM '***** ERROR n DB 0FCH W4: DB 1 DB 'ait' DW PUT DB 9BH X3: DB 1 DB 'or' DW GRP13 DB 32H X4: DB 2 DB 'chg' DW GRP3 D DW P5 DW NONE DW NONE ;Q DW NONE DW NONE DW NONE DW NONE DW NONE ;R DW R3 DW R4 DW R5 DW NONE DW NONE F DW NONE DW NONE DW NONE DW NONE DW NONE ;G DW NONE DW NONE DW NONE DW NONE DW NONE ;H DW H3 DW H4 DW DB 0 PC: DS 2 OLDPC: DS 2 LABPT: DS 2 FLAG: DS 1 L1A98: DS 1 ADDR: DS 2 ALABEL: DS 2 DATA: DS 2 DLABEL: DS 2 CON: DS table only needs to be modified if a mnemonic is added to a group ; previously marked NONE. Change the NONE to a label made up o. ' NOSPAC: DB 13,10,'No directory space',13,10,'$' HEXSUF: DM 'H',13,10 NOMEM: DB 13,10,'Insufficient memory',13,10,'$' NOB 86H DB 'lat' DW PUT DB 0D7H OPTAB: ; Table of pointers to mnemonics. For each letter of the alphabet (the ; star;S DW S3 DW S4 DW NONE DW NONE DW NONE ;T DW NONE DW T4 DW NONE DW NONE DW U2 ;U DW NONE DW NONE DW NO2 UNDEF: DS 2 LENID: DS 1 ID: DS 80 CHR: DS 1 SYM: DS 1 BASE: DS 2 HEAP: DS 2 SYMFLG: DS 1 CODE: DS 2 DATSIZ: DS 1 REctors to load BOOTER: EQU 200H ;"B" command puts booter here ;**************************************************************ll begin exection at its load address (which ;must be a 16-byte boundary) with the Instruction ;Pointer set to zero. ; VariLL ROL AL JNC DONE ENDIF IF CROMEMCO ROR AL JC DONE ENDIF INB DISK+3 STOB LOOP READ GETSTAT: INB DISK WAITBYTE:EQU 0A1H ENDIF ORG BOOTER PUT 100H XOR AX,AX MOV DS,AX MOV ES,AX MOV SS,AX UP MOV DI,LOAD MOVLOC: DS 1 BCOUNT: DS 1 COUNT: DS 1 ERR: DS 1 HEXPNT: DS 2 HEXLEN: DS 2 HEXADD: DS 2 LASTAD: DS 2 HEXCNT: DS 1 CHKSUM: D CROMEMCO: EQU CROMEMCOLARGE+CROMEMCOSMALL TARBELL: EQU TARBELLSINGLE+TARBELLDOUBLE WD1771: EQU CROMEMCO+TARBELLSINGLE Wations are available for the Cromemco 4FDC with ; large disks, the 4FDC with small disks, the Tarbell ; single-density control+4 IF TARBELL ROL AL JC GETSTAT ENDIF IF CROMEMCO ROR AL JNC GETSTAT ENDIF DONE: IN DISK AND AL,9CH ;This is a disk boot routine for the 1771/1791 type disk ;controllers. It would normally reside on track 0, ;sector 1, to be DX,SECTOR MOV BL,2 SECT: MOV AL,BL OUTB DISK+2 MOV CX,128 IF TARBELL INB DISK ;Get head load status ENDIF S 1 L1B0E: DS 1 L1B0F: DS 1 L1B10: DS 1 IFFLG: DS 1 CHKLAB: DS 1 LSTPNT: DS 2 ERRCNT: DS 2 LSTRET: DS 2 RETPT: DS 2 HED1791: EQU TARBELLDOUBLE SMALL: EQU CROMEMCOSMALL LARGE: EQU CROMEMCOLARGE+TARBELL IF SMALL MAXSECT:EQU 18 ENDIF ler, and the Tarbell double- ; density controller. Select one. CROMEMCOSMALL: EQU 0 CROMEMCOLARGE: EQU 1 TARBELLSINGLE: EQ JNZ SECT DEC DX JZ BOOT INC BL CMP BL,MAXSECT+1 JNZ SECT XOR BL,BL INC DX MOV AL,58H ;Step in with update OUloaded by the "B" command of the ;monitor at address 200H. By changing the equates ;below, it may be configured to load any s IF CROMEMCO INB DISK+4 ;Get head load status ENDIF TEST AL,20H MOV AL,READCOM JNZ OUTCOM MOV AL,READCOM+4 OUTCOXBUF: DS 128 L1B9B: DS 128 LSTBUF: DS 128 BC: DS 2 DE: DS 2 HL: DS 2 IX: DS 2 IY: DS 2 DS 50 STACK: EQU $ START: EQU IF LARGE MAXSECT:EQU 26 ENDIF IF TARBELL DISK: EQU 78H ENDIF IF CROMEMCO DISK: EQU 30H ENDIF IF WD1771 REAU 0 TARBELLDOUBLE: EQU 0 LOAD: EQU 400H ;Address to load program SEG: EQU 40H ;LOAD/10H SECTOR: EQU 51 ;No. of 128-byte seTB DISK JP GETSTAT BOOT: MOV AX,SEG MOV SS,AX MOV ES,AX MOV DS,AX JMP 0,SEG ize of ;program at any address. The program is assumed to ;occupy consecutive sectors starting at track 0, sector ;2, and wiM: OUTB DISK IF CROMEMCO MOV AL,WAITBYTE OUT DISK+4 ;Turn on hardware wait ENDIF READ: INB DISK+4 IF TARBE$ DCOM:EQU 88H ENDIF IF WD1791 READCOM:EQU 80H ENDIF IF CROMEMCOLARGE WAITBYTE:EQU 0B1H ENDIF IF CROMEMCOSMALL PLYRMV ; ; ARGUMENTS: None ;*********************************************************** DRIVER: MOV SP,STS ;*********************************************************** ; PAWN: EQU 1 KNIGHT: EQU 2 BISHOP: EQU 3 ROOK: EQU 4 QUEE: CALL CPTRMV ; Do computer move MOV BX,MOVENO INC B,[BX] ; Increment move number JP DR20 ; Back to player move ;***gned ; and coded by Dan and Kathe Spracklen. Copyright 1978. All ; rights reserved. No part of this publication may be ; rebtract Ascii constant JB DR15 ; Under minimum - prompt again CMP AL,6 ; Over maximum of 6 ? JNB DR15 ; Yes - prompt agaACK ; Set stack pointer MOV DX,CLRMSG ; Request color choice MOV CL,PRINTBUF CALL SYSTEM MOV CL,INCHAR ; Accept responseN: EQU 5 KING: EQU 6 WHITE: EQU 0 BLACK: EQU 80H BPAWN: EQU BLACK+PAWN ORG 100H PUT 100H ;********************************************************************************* ; TABLES SECTION ;***************************************************produced without the prior written permission. ;*********************************************************** ;***************in INC AL ; Increment by one MOV [PLYMAX],AL ; Set desired depth MOV DX,CRLF ; Output CRLF MOV CL,PRINTBUF CALL SYST CALL SYSTEM CMP AL,57H ; Did player request white ? JZ DR05 ; Yes - branch CMP AL,42H ; Did player request black ? ********************************** ; MAIN PROGRAM DRIVER ;*********************************************************** ; FUNCT******** ORG 200H ; Start at 200H START: ORG START+80H PUT START+80H TBASE: EQU START+100H ;********************************************************************** ; SYSTEM EQUATES ;*********************************************************** INEM XOR AL,AL MOV [COLOR],AL ; Set color to white INC AL MOV [MOVENO],AL ; Set move number to 1 CALL INITBD ; Init boa JNZ DRIVER ; No - error XOR AL,AL JP DR10 ; Jump DR05: MOV AL,BLACK ; Set computers color to black DR10: MOV [KOLOR],ALION: -- To coordinate the game moves. ; ; CALLED BY: -- None ; ; CALLS: -- INITBD ; CPTRMV ; ******************************** ; DIRECT -- Direction Table. Used to determine the dir- ; ection of movement oCHAR EQU 1 PRINTBUF EQU 9 INBUF EQU 10 SYSTEM EQU 5 ;*********************************************************** ; EQUATErd MOV AL,[KOLOR] ; Get color OR AL,AL ; Computer move ? JZ DR25 ; Yes - jump DR20: CALL PLYRMV ; Do player move DR25;*********************************************************** ; ; SARGON ; ; Sargon is a computer chess playing program desi DR15: MOV DX,PLYDEP ; Request depth of search MOV CL,PRINTBUF CALL SYSTEM MOV CL,INCHAR CALL SYSTEM SUB AL,31H ; Suf each piece. ;*********************************************************** DIRECT: EQU $-TBASE DB +09,+11,-11,-09 DB +10,- ; FFFFFFFFFFFFFFFFFFFF ; FFFFFFFFFFFFFFFFFFFF ; FF0402030506030204FF ; FF01********************************** ; PIECES -- The initial arrangement of the first rank of ; pieces on the boar 5 -- Queen ; 6 -- King ; 7 -- Not used ; 0 -- Empty Square ;**Used to determine ; the number of directions of movement for any ; given piece. ;******************** the board array are as ; follows: ; Bit 7 -- Color of the piece ; 1 -- Black ; 10,+01,-01 DB -21,-12,+08,+19 DB +21,+12,-08,-19 DB +10,+10,+11,+09 DB -10,-10,-11,-09 ;*******************************01010101010101FF ; FF0000000000000000FF ; FF0000000000000000FF ; FF0000000000000060FF ; d. Use to set up the board ; for the start of the game. ;****************************************************************************************************************** BOARD: EQU $-TBASE BOARDA: DS 120 ;********************************************************************* DCOUNT: EQU $-TBASE DB 4,4,8,4,4,8,8 ;******************************************** 0 -- White ; Bit 6 -- Not used ; Bit 5 -- Not used ; Bit 4 --Castle f**************************** ; DPOINT -- Direction Table Pointer. Used to determine ; where to begin in the dire FF0000000000000000FF ; FF8181818181818181FF ; FF8482838586838284FF ; FFFFFFFF** PIECES: EQU $-TBASE DB 4,2,3,5,6,3,2,4 ;*********************************************************** ; BOARD -- Boar***************************** ; ATKLIST -- Attack List. A two part array, the first ; half for white and the second*************** ; PVALUE -- Point Value. Gives the point value of each ; piece, or the worth of each piece. ;**lag for Kings only ; Bit 3 -- Piece has moved flag ; Bits 2-0 Piece type ; 1 -- Pction table for any ; given piece. ;*********************************************************** DPOINT: EQU $-TBAFFFFFFFFFFFF ; FFFFFFFFFFFFFFFFFFFF ; The values of FF form the border of the ; board, and Array. Used to hold the current position ; of the board during play. The board itself ; looks like: half for black. ; It is used to hold the attackers of any given ; square in the order of their value. ********************************************************* PVALUE: EQU $-TBASE-1 DB 1,3,3,5,9,10 ;*************************awn ; 2 -- Knight ; 3 -- Bishop ; 4 -- Rook ; SE DB 20,16,8,0,4,0,0 ;*********************************************************** ; DCOUNT -- Direction Table Counter. d are used to indicate when a piece ; moves off the board. The individual bits of ; the other bytes in; ; WACT -- White Attack Count. This is the first ; byte of the array and tells how many pieces are ; ; PLYIX -- Ply Table. Contains pairs of pointers, a pair ; for each ply. The first pointer points to the ; POSK,but for queens. ;*********************************************************** POSK: DB 24,95 POSQ: DB 14,94 DB -1 ;*ch tells ; which pair of pointers are in current use. ; ; MLPTRJ -- Pointer into the move list to the move thatn from the pinned ; piece to the attacker. ;*********************************************************** PLIST: EQ*********************************************** ; TABLE INDICES SECTION ; ; M1-M4 -- Working indices used to index into ; in the white portion of the attack list. ; ; BACT -- Black Attack Count. This is the eighth byte of ; the arr top of the list of possible moves at that ply. ; The second pointer points to which move in the ; ********************************************************** ; SCORE -- Score Array. Used during Alpha-Beta pruning to ; is ; currently being processed. ; ; SCRIX -- Score Index. Pointer to the score table for ; the pU $-TBASE-1 PLISTD: EQU PLIST+10 PLISTA: DW 0,0,0,0,0,0,0,0,0,0 ;********************************************************** the board array. ; ; T1-T3 -- Working indices used to index into Direction ; Count, Direction Valay and does the same for black. ;*********************************************************** ATKLST: DW 0,0,0,0,0,0,0 WACT: E list is the one currently being considered. ;*********************************************************** PLYIX: DW 0,0,0,0 hold the scores at each ply. It includes two ; "dummy" entries for ply -1 and ply 0. ;********************ly being examined. ; ; BESTM -- Pointer into the move list for the move that ; is currently considered the bes* ; POSK -- Position of Kings. A two byte area, the first ; byte of which hold the position of the white ; ue, and Piece Value tables. ; ; INDX1 -- General working indices. Used for various ; INDX2 purposes. ; ; NPINS -QU ATKLST BACT: EQU ATKLST+7 ;*********************************************************** ; PLIST -- Pinned Piece Array.,0,0,0,0,0,0 DW 0,0,0,0,0,0,0,0,0,0 ;*********************************************************** ; STACK -- Contains th*************************************** SCORE: DW 0,0,0,0,0,0 ;*********************************************************** t by the ; Alpha-Beta pruning process. ; ; MLLST -- Pointer to the previous move placed in the move ; king and the second holding the position of ; the black king. ; ; POSQ -- Position of Queens. Like - Number of Pins. Count and pointer into the ; pinned piece list. ; ; MLPTRI -- Pointer into the ply table whi This is a two part array. ; PLISTA contains the pinned piece position. ; PLISTD contains the directioe stack for the program. ;*********************************************************** ORG START+2FFH STACK: ;************ list. Used during generation of the move list. ; ; MLNXT -- Pointer to the next available space in the move ; h could be won ; through an exchange by the player not on the ; move. ; ; PTSW2 -- The second higndicates the king is in check. ; ; MATEF -- A zero value indicates no legal moves. ; ; VALM -- The score of the curre0 BMOVES: DB 35,55,10H DB 34,54,10H DB 85,65,10H DB 84,64,10H ;*******************************************************80H. ; ; COLOR -- Indicates color of the side with the move. ; ; P1-P3 -- Working area to hold the contents of the boae piece has ; just moved itself into a losing exchange of ; material. ; ; BMOVES -- Our very tiny list. ; ;*********************************************************** ORG START+0 PUT START+0 M1: DW TBASE M2: DW TBhest number of points which could ; be won through a different exchange by the player ; not on the movnt move being examined. ; ; BRDC -- A measure of mobility equal to the total number ; of squares white can mo**** ; MOVE LIST SECTION ; ; MLIST -- A 2048 byte storage area for generated moves. ; This area must be largerd ; array for a given square. ; ; PMATE -- The move number at which a checkmate is ; discovered book of openings. Determines ; the first move for the computer. ; ;**********************************************ASE M3: DW TBASE M4: DW TBASE T1: DW TBASE T2: DW TBASE T3: DW TBASE INDX1: DW TBASE INDX2: DW TBASE NPINS: DW TBASE MLe. ; ; MTRL -- A measure of the difference in material ; currently on the board. It is the total value of ; ve to minus the number ; black can move to. ; ; PTSL -- The maximum number of points which could be lost ; enough to hold all ; the moves for a single leg of the move tree. ; ; MLEND -- The address of the last availaduring look ahead. ; ; MOVENO -- Current move number. ; ; PLYMAX -- Maximum depth of search using Alpha-Beta ; ************* KOLOR: DB 0 COLOR: DB 0 P1: DB 0 P2: DB 0 P3: DB 0 PMATE: DB 0 MOVENO: DB 0 PLYMAX: DB 2 NPLY: DB 0 CKFLPTRI: DW PLYIX MLPTRJ: DW 0 SCRIX: DW 0 BESTM: DW 0 MLLST: DW 0 MLNXT: DW MLIST ;*************************************** the white pieces minus the total value of the ; black pieces. ; ; BC0 -- The value of board cont through an exchange by the player not on the ; move. ; ; PTSW1 -- The maximum number of points whicble location ; in the move list. ; ; MLPTR -- The Move List is a linked list of individual ; move pruning. ; ; NPLY -- Current ply number during Alpha-Beta ; pruning. ; ; CKFLG -- A non-zero value iG: DB 0 MATEF: DB 0 VALM: DB 0 BRDC: DB 0 PTSL: DB 0 PTSW1: DB 0 PTSW2: DB 0 MTRL: DB 0 BC0: DB 0 MV0: DB 0 PTSCK: DB ******************** ; VARIABLES SECTION ; ; KOLOR -- Indicates computer's color. White is 0, and ; Black is rol(BRDC) at ply 0. ; ; MV0 -- The value of material(MTRL) at ply 0. ; ; PTSCK -- A non-zero value indicates that ths each of which is 6 bytes in length. The ; move list pointer(MLPTR) is the link field ; within a move**************************** ; PROGRAM CODE SECTION ;*********************************************************** ; BOARD SETUed at ; least once. ; Bits 2-0 Describe the captured piece. A ; ******************************************************* ; FUNCTION: To generate a single possible move for a given ; 1 -- Black ; Bit 6 -- Double move flag (set for castling and ; en passant pawn capturees MOV [SI+21],AL ; White pieces LAHF OR AL,080H SAHF ; Change to black MOV [SI+91],AL ; Black pieces MOV B,[SI+31. ; ; MLFRP -- The field in the move entry which gives the ; board position from which the piece is moving. ;P ROUTINE ;*********************************************************** ; FUNCTION: To initialize the board array, setting thzero value indicates no capture. ; ; MLVAL -- The field in the move entry which contains the ; score assigned piece along its current path of motion including: ; Fetching the contents of the board at the new ; s) ; Bit 5 -- Pawn Promotion flag; set when pawn ; promotes. ; Bit 4 -- Wh],PAWN ; White Pawns MOV B,[SI+81],BPAWN ; Black Pawns MOV B,[SI+41],0 ; Empty squares MOV B,[SI+51],0 MOV B,[SI+61],0 ; MLTOP -- The field in the move entry which gives the ; board position to which the piece is moving. ; ; MLe ; pieces in their initial positions for the ; start of the game. ; ; CALLED BY: DRIVER ; ; CALLto the move. ; ;*********************************************************** ORG START+300H PUT START+300H MLIST: DS 2048 position, and setting a flag describing the ; contents: ; 0 -- New positien set, this flag indicates that ; this is the first move for the ; piece on the MOV B,[SI+71],0 INC SI DEC CH JNZ IB2 MOV SI,POSK ; Init King/Queen position list MOV B,[SI+0],25 MOV B,[SI+1],95 FLG -- A field in the move entry which contains flag ; information. The meaning of each bit is as ; S: None ; ; ARGUMENTS: None ;*********************************************************** INITBD: MOV CX,60 ; Pre-fill MLEND: EQU MLIST+2040 MLPTR: EQU 0 MLFRP: EQU 2 MLTOP: EQU 3 MLFLG: EQU 4 MLVAL: EQU 5 ;*******************************on is empty ; 1 -- Encountered a piece of the ; opposite color ; move. ; Bit 3 -- This flag is set is there is a piece ; captured, and that piece has mov MOV B,[SI+2],24 MOV B,[SI+3],94 RET ;*********************************************************** ; PATH ROUTINE ;**** follows: ; Bit 7 -- The color of any captured piece ; 0 -- White ; board with -1's MOV DI,BOARDA MOV AX,-1 REP STOW MOV CH,8 MOV SI,BOARDA IB2: MOV AL,[SI-8] ; Fill non-border squar 2 -- Encountered a piece of the ; same color ; e MOV DI,[T1] ; Load index to DCOUNT/DPOINT MOV CH,[DI+DCOUNT] ; Get direction count MOV AL,[DI+DPOINT] ; Get direction pe all the possible legal moves for a ; given piece. ; ; CALLED BY: GENMOV ; ; CALLS: PATH ; 15 ; No - jump MOV AL,[M2] ; Get "to" position CMP AL,91 ; Promote white Pawn ? JNC MP25 ; Yes - Jump CMP AL,29 ; Pn border area ? JZ PA2 ; Yes - jump MOV [P2],AL ; Save piece MOV AH,AL ; Save piece in register AND AL,7 ; Clear flaAL,[T1] ; Piece type CMP AL,KING ; King ? JZ MP15 ; Yes - Jump CMP AL,BISHOP ; Bishop, Rook, or Queen ? JNC MP10 ; Y 3 -- New position is off the ; board ; ; CALLED BY: MPIECE ; ATTACK ; ointer MOV [INDX2],AL ; Save as index to direct MOV DI,[INDX2] ; Load index MP5: MOV CL,[DI+DIRECT] ; Get move direction ADMOVE ; CASTLE ; ENPSNT ; ; ARGUMENTS: The piece to be moved. ;**********************************romote black Pawn ? JNC MP26 ; No - Jump MP25: OR B,[P2],020H ; Set promote flag MP26: CALL ADMOVE ; Add to move list INgs MOV [T2],AL ; Save piece type JZ RET ; Return if empty XOR AH,[P1] ; Compare with moving piece SHL AH ; Set flag es - Jump MP15: INC DI ; Increment direction index DEC CH JNZ MP5 ; Decr. count-jump if non-zerc MOV AL,[T1] ; Piece t PINFND ; ; CALLS: None ; ; ARGUMENTS: Direction from the direction array giving the ; constant MOV AL,[M1] ; From position MOV [M2],AL ; Initialize to position MP10: CALL PATH ; Calculate next position CMP AL,2 ; R************************* MPIECE: XOR AL,[BX] ; Piece to move AND AL,87H ; Clear flag bit CMP AL,BPAWN ; Is it a black PaC DI ; Adjust to two square move DEC CH TEST B,[P1],008H ; Check Pawn moved flag, has it moved before ? JZ MP10 ; No - J MOV AL,2 SBB AL,0 RET ; Return PA2: MOV AL,3 ; Set off board flag RET ;******************************************ype CMP AL,KING ; King ? JNZ RET JMP CASTLE ; Yes - Try Castling ; ***** PAWN LOGIC ***** MP20: MOV AL,CH ; Counter fto be added for the new position. ;*********************************************************** PATH: ADD [M2],CL ; Add directeady for new direction ? JNC MP15 ; Yes - Jump AND AL,AL ; Test for empty square PUSHF MOV AL,[T1] ; Get piece moved wn ? JNZ MP1 ; No-Skip DEC AL ; Decrement for black Pawns MP1: AND AL,7 ; Get piece type MOV [T1],AL ; Save piece typump JMP MP15 ; Jump MP30: POPF JNZ MP15 ; No - Jump MP31: CALL ADMOVE ; Add to move list JMP MP15 ; Jump MP35: POPF***************** ; PIECE MOVER ROUTINE ;*********************************************************** ; FUNCTION: To generator direction CMP AL,3 ; On diagonal moves ? JC MP35 ; Yes - Jump JZ MP30 ; -or-jump if on 2 square move POPF JNZ MPion constant to previous position MOV SI,[M2] ; Load board index MOV AL,[SI+BOARD] ; Get contents of board CMP AL,-1 ; I CMP AL,PAWN+1 ; Is it a Pawn ? JC MP20 ; Yes - Jump CALL ADMOVE ; Add move to list POPF JNZ MP15 ; No - Jump MOV JZ MP36 ; Yes - Jump MOV AL,[M2] ; Get "to" position CMP AL,91 ; Promote white Pawn ? JNC MP37 ; Yes - Jump CMP A0 ? JNZ RET ; No - return OR B,[P2],040H ; Set double move flag CALL ADMOVE ; Add Pawn move to move list MOV AL,[M1] iece ? JZ RET ; No - return MOV AL,[SI+MLTOP] ; Get "to" position MOV [M4],AL ; Store as index to board MOV SI,[M4] ;****************************************************** ; CASTLE ROUTINE ;*****************************************************-- ADMOVE ; ADJPTR ; ; ARGUMENTS: -- None ;*********************************************************** Elink around ; second move in double move. ; ; CALLED BY: -- ENPSNT ; CASTLE ; L,29 ; Black Pawn promotion ? JNC MP31 ; No- Jump MP37: OR B,[P2],020H ; Set promote flag JP MP31 ; Jump MP36: CALL ENP; Save initial Pawn position MOV [M3],AL MOV AL,[M4] ; Set "from" and "to" positions ; for dummy move MOV [M1],AL Load board index MOV AL,[SI+BOARD] ; Get piece moved MOV [P3],AL ; Save it AND AL,7 ; Get piece type CMP AL,PAWN ; I****** ; FUNCTION: -- To determine whether castling is legal ; (Queen side, King side, or both) and add it NPSNT: MOV AL,[M1] ; Set position of Pawn TEST B,[P1],080H ; Check color, is it white ? JZ EP5 ; Yes - skip ADD AL,10 ; (This mini-routine is not really called, ; but is jumped to to save time.) ; ; CALLS: -- None ; SNT ; Try en passant capture JMP MP15 ; Jump ;*********************************************************** ; EN PASSANT RMOV [M2],AL MOV AL,[P3] ; Save captured Pawn MOV [P2],AL CALL ADMOVE ; Add Pawn capture to move list MOV AL,[M3] ; Res it a Pawn ? JNZ RET ; No - return MOV AL,[M4] ; Get "to" position MOV BX,M2 ; Get present "to" position SUB AL,[BX] ; to the move list if it is. ; ; CALLED BY: -- MPIECE ; ; CALLS: -- ATTACK ; ADMOV Add 10 for black EP5: CMP AL,61 ; On en passant capture rank ? JC RET ; No - return CMP AL,69 ; On en passant capture r; ARGUMENTS: -- None ;*********************************************************** ADJPTR: MOV BX,[MLLST] ; Get list pointer OUTINE ;*********************************************************** ; FUNCTION: -- To test for en passant Pawn capture and store "from" position MOV [M1],AL ;*********************************************************** ; ADJUST MOVE LIST POINTER ; Find difference JNS EP10 ; Positive ? Yes - Jump NEG AL ; Else take absolute value EP10: CMP AL,10 ; Is difference 1E ; ADJPTR ; ; ARGUMENTS: -- None ;*********************************************************** CASTLE: ank ? JNC RET ; No - return MOV SI,[MLPTRJ] ; Get pointer to previous move TEST B,[SI+MLFLG],010H ; First move for that p SUB BX,6 ; Back up list pointer MOV [MLLST],BX ; Save list pointer MOV [BX],0 ; Zero out link RET ; Return ;***** ; to add it to the move list if it is ; legal. ; ; CALLED BY: -- MPIECE ; ; CALLS: FOR DOUBLE MOVE ;*********************************************************** ; FUNCTION: -- To adjust move list pointer to TEST B,[P1],008H ; Has king moved ? JNZ RET ; Yes - return MOV AL,[CKFLG] ; Fetch Check Flag AND AL,AL ; Is the King in Restore King position MOV [M1],AL ; Store CA20: MOV AL,CH ; Scan Index CMP AL,1 ; Done ? JZ RET ; Yes - return MOV SUB AL,CH MOV [M2],AL ; Save it MOV BX,P2 ; Address of flags MOV B,[BX],40H ; Set double move flag CALL ADMOVE ; Putove position STOB MOV AL,[P2] ; Store move flags/capt. piece STOB XOR AL,AL ; Store initial move value STOB MOV [M ; No - Jump MOV AL,[M3] ; Current position CMP AL,22 ; White Queen Knight square ? JZ CA15 ; Yes - Jump CMP AL,92 ;BX,MLEND ; Address of list end SUB BX,DX ; Calculate difference JC AM10 ; Jump if out of space MOV BX,[MLLST] ; Addr of check ? JNZ RET ; Yes - Return MOV CX,0FF03H ; Initialize King-side values CA5: ADD CL,[M1] ; Rook position MOV AL,CL CX,01FCH ; Set Queen-side initial values JMP CA5 ; Jump ;*********************************************************** ; A king move in list MOV BX,M1 ; Addr of King "from" position MOV AL,[BX] ; Get King's "from" position MOV [BX],CL ; StorLNXT],DI ; Save address for next move MOV DI,DX RET ; Return AM10: MOV [BX],0 ; Abort entry on table ovflow RET ;** Black Queen Knight square ? JZ CA15 ; Yes - Jump CALL ATTACK ; Look for attack on square AND AL,AL ; Any attackers ? prev. list area MOV [MLLST],DX ; Save next as previous MOV [BX],DX ; Store link address TEST B,[P1],008H ; Has moved piec MOV [M3],AL ; Store as board index MOV SI,[M3] ; Load board index MOV AL,[SI+BOARD] ; Get contents of board AND AL,7FHDMOVE ROUTINE ;*********************************************************** ; FUNCTION: -- To add a move to the move list ;e Rook "from" position SUB AL,CH ; Get Rook "to" position MOV [M2],AL ; Store Rook "to" position XOR AL,AL ; Zero MOV********************************************************* ; GENERATE MOVE ROUTINE ;******************************************* JNZ CA20 ; Yes - Jump MOV AL,[M3] ; Current position CA15: ADD AL,CH ; Next position MOV [M3],AL ; Save as board indexe moved before ? JNZ AM5 ; Yes - jump OR B,[P2],010H ; Set first move flag AM5: XCHG DX,DI ; Address of move area XOR A ; Clear color bit CMP AL,ROOK ; Has Rook ever moved ? JNZ CA20 ; Yes - Jump MOV AL,CL ; Restore Rook position JP CA ; CALLED BY: -- MPIECE ; ENPSNT ; CASTLE ; ; CALLS: -- None ; ; ARGUMENT: -- N [P2],AL ; Zero move flags CALL ADMOVE ; Put Rook move in list CALL ADJPTR ; Re-adjust move list pointer MOV AL,[M3] ;**************** ; FUNCTION: -- To generate the move set for all of the ; pieces of a given color. ; ; CALL MOV BX,M1 ; King position CMP AL,[BX] ; Reached King ? JNZ CA10 ; No - jump SUB AL,CH ; Determine King's position X,AX ; Store zero in link address CLD STOW MOV AL,[M1] ; Store "from" move position STOB MOV AL,[M2] ; Store "to" m15 ; Jump CA10: MOV SI,[M3] ; Load board index MOV AL,[SI+BOARD] ; Get contents of board AND AL,AL ; Empty ? JNZ CA20 one ;*********************************************************** ADMOVE: MOV DX,[MLNXT] ; Addr of next loc in move list MOV ED BY: -- FNDMOV ; ; CALLS: -- MPIECE ; INCHK ; ; ARGUMENTS: -- None ;******************************on AND AL,AL ; White ? JZ IC5 ; Yes - Skip INC BX ; Addr of black King position IC5: MOV AL,[BX] ; Fetch King positio****************************************************** ; CHECK ROUTINE ;****************************************************** bishop is then said to be transparent to the ; queen, since both participate in the ; attack.L,[SI+BOARD] ; Fetch board contents AND AL,AL ; Is it empty ? JZ GM10 ; Yes - Jump CMP AL,-1 ; Is it a border square ? quare, or a piece is found that ; doesn't attack that square, or the edge ; of the board is re***************************** GENMOV: CALL INCHK ; Test for King in check MOV [CKFLG],AL ; Save attack count as flag MOV Dn MOV [M3],AL ; Save MOV SI,[M3] ; Load board index MOV AL,[SI+BOARD] ; Fetch board contents MOV [P1],AL ; Save AND***** ; FUNCTION: -- To determine whether or not the ; King is in check. ; ; CALLED BY: -- GENMOV ; ; ; In the case where this routine is called ; by CASTLE or INCHK, the routine is ; JZ GM10 ; Yes - Jump MOV [P1],AL ; Save piece MOV BX,COLOR ; Address of color of piece XOR AL,[BX] ; Test color of piached. ; ; In determining which pieces attack ; a square, this routine also takes into ; X,[MLNXT] ; Addr of next avail list space MOV BX,[MLPTRI] ; Ply list pointer index INC BX ; Increment to next ply INC BX AL,7 ; Get piece type MOV [T1],AL ; Save ;*********************************************************** ; ATTACK ROUTINE FNDMOV ; EVAL ; ; CALLS: -- ATTACK ; ; ARGUMENTS: -- Color of King ;**************** terminated as soon as an attacker of the ; opposite color is encountered. ; ; CALLED BY: -- POINTSece TEST AL,080H ; Match ? JNZ GM10 CALL MPIECE ; Yes - call Move Piece GM10: MOV AL,[M1] ; Fetch current board positi account the ability of certain pieces to ; attack through another attacking piece. (For ; MOV [BX],DX ; Save move list pointer INC BX INC BX MOV [MLPTRI],BX ; Save new index MOV [MLLST],BX ; Last pointer for ;*********************************************************** ; FUNCTION: -- To find all attackers on a given square ; ******************************************* INCHK: MOV AL,[COLOR] ; Get color INCHK1: MOV BX,POSK ; Addr of white King positi ; PINFND ; CASTLE ; INCHK ; ; CALLS: -- ATKADJ ; ATon INC AL ; Incr to next board position CMP AL,99 ; End of board array ? JNZ GM5 ; No - Jump RET ; Return ;***** example a queen lined up behind a bishop ; of her same color along a diagonal.) The ; chain init. MOV AL,21 ; First position on board GM5: MOV [M1],AL ; Save as index MOV SI,[M1] ; Load board index MOV A by scanning outward from the square ; until a piece is found that attacks ; that sKOUT ; ; ARGUMENTS: -- None ;*********************************************************** ATTACK: PUSH CX ; Save Register The piece under attack. The attacker. ;*********************************************************** ATKADJ: MOV CX,8 ; 8 dirck for a Bishop CALL ATKOUT ; Scan outwards MOV AH,ROOK ; Check for a Rook CALL ATKOUT ; Scan outwards XOR AL,AL ; N ; Bitmask for color flags XCHG AX,BX ; Save AX LODB ; Get direction byte CBW ; Convert to word XCHG AX,BX ; Save piece at +9 AND AL,87H ; Clear flag bit CMP AL,BPAWN ; Black Pawn ? JNZ AT10 ; No - jump OR [BP+9],AH ; Turn on bit 5 ***** ; ATTACK OUTWARD SCAN ROUTINE ;*********************************************************** ; FUNCTION: -- To scan foCX MOV BP,[M3] ; Get piece index ADD BP,BOARD ; Add board pointer to it MOV DH,0 ; Init. scan count/flags MOV SI,DIRECections to scan AA5: XCHG AX,BX ; Save AX LODB ; Get direction byte CBW ; Convert to word XCHG AX,BX ; Save directio attackers POP CX ; Restore CX reg RET ; Return ;*********************************************************** ; ATTACdirection and restore AX MOV DI,BP ; Load pointer to piece AO10: ADD DI,BX ; Add direction constant MOV AL,[DI] ; Get at AT10: MOV AL,[BP-11] ; Get piece at -11 AND AL,87H ; Clear flag bit CMP AL,PAWN ; White Pawn ? JNZ AT15 ; No - jump r a specified attacker outwards ; from the piece under attack, until found ; or edge of the boT+TBASE ; Load direction table MOV AH,KING ; Check for a King CALL ATKADJ ; Scan adjacent squares MOV AH,KNIGHT ; Check on and restore AX MOV DI,BP ; Load pointer to piece ADD DI,BX ; Add direction constant MOV AL,[DI] ; Get attacking piecK ADJACENT SCAN ROUTINE ;*********************************************************** ; FUNCTION: -- To scan for a specifiedtacking piece AND AL,27H ; Get piece type and bit 5 JZ AO10 ; No piece, keep going CMP AL,AH ; Same as what we want ? OR [BP-11],AH ; Turn on bit 5 AT15: MOV AL,[BP-9] ; Get piece at -9 AND AL,87H ; Clear flag bit CMP AL,PAWN ; White Pawn ard is reached. ; ; CALLED BY: -- ATTACK ; ; CALLS: -- ATKCHK ; ; ARGUMENTS: -- The piece under attack. The attafor a Knight CALL ATKADJ ; Scan adjacent squares MOV AH,20H ; Bit 5 set MOV AL,[BP+11] ; Get piece at +11 AND AL,87H e AND AL,7 ; Get piece type CMP AL,AH ; Same as what we want ? JNZ AA10 ; No - jump CALL ATKCHK ; Check and save att attacker on adjacent ; squares. ; ; CALLED BY: -- ATTACK ; ; CALLS: -- ATKCHK ; ; ARGUMENTS: -- JZ AO22 ; Yes - jump CMP AL,QUEEN ; Queen ? JZ AO20 ; Yes - jump CMP AL,PAWN+20H ; Pawn with bit 5 ? JZ AO21 ; Yes -? JNZ AT20 ; No - jump OR [BP-9],AH ; Turn on bit 5 AT20: MOV SI,DIRECT+TBASE ; Load direction table MOV AH,BISHOP ; Checker. ;*********************************************************** ATKOUT: MOV CL,4 ; 4 directions to scan AO5: MOV DX,0C0H ; Clear flag bit CMP AL,BPAWN ; Black Pawn ? JNZ AT5 ; No - jump OR [BP+11],AH ; Turn on bit 5 AT5: MOV AL,[BP+9] ; Get acker AA10: LOOP AA5 ; Go check for next direction RET ; Return ;****************************************************** jump AO15: LOOP AO5 ; Go check for next direction RET ; Return AO20: INC DH ; Set Queen found flag AO21: AND B,[DI],0D ACK5 ; Yes, jump AND [BP+9],AH ; Remove bit 5 for piece ACK5: CMP [BP+11],AL ; Is +11 border ? JZ ACK6 ; Yes - jump ANite color is encountered. ; ; CALLED BY: -- ATTACK ; ; CALLS: -- None ; ; ARGUMENTS: -- The attacking piece. TheDI POP CX RET ; Return to ATTACK ACK25: POP AX ; Restore AX ACK26: MOV CL,AL ; Put piece in CL AND CL,7 ; Get piecethe target ; square and save the attacking piece value ; in the attack list. ; ; r in AX SUB AX,BOARDA ; Minus BOARDA for position MOV DI,PLISTA ; Pin list address ACK15: OR AL,AL ; Set flags for REP RFH ; Remove bit 5 for piece AO22: MOV AL,[DI] ; Get piece ADD AL,80H ; CY if back, NC if white RCR AL ; Bit 7 set if blaD [BP+11],AH ; Remove bit 5 for piece ACK6: CMP [BP-9],AL ; Is -9 border ? JZ ACK7 ; Yes - jump AND [BP-9],AH ; Remove bit piece under attack. ;*********************************************************** ATKCHK: MOV AL,[DI] ; Get piece CMP B,[T1 type MOV DI,PVALUE+TBASE ; PVALUE list address ADD DI,CX ; Point to piece value MOV CL,[DI] ; Get point value of piece The pin piece list is checked for the ; attacking piece, and if found there, the ; piece EPZ SCAB ; Search list for position JNZ ACK25 ; Continue if not found OR AH,AH ; Is this the first find ? JNZ ACK20 ck, bit 6 if white AND DL,AL ; Keep only bits 6 and 7 JZ AO15 ; Nothing, next direction CALL ATKCHK ; Check and save at 5 for piece ACK7: CMP [BP-11],AL ; Is -11 border ? JZ ACK8 ; Yes - jump AND [BP-11],AH ; Remove bit 5 for piece ACK8: MO],7 ; Call from POINTS ? JZ ACK10 ; Yes - jump XOR AL,[BP] ; Attacker and target same color ? JNS RET ; Yes - return MOV DI,ATKLST ; Init address of attack list TEST AL,80H ; Is it white ? JZ ACK30 ; Yes - jump ADD DI,7 ; Attack list is not included in the attack list. ; ; In the case where ATTACK is called by ; CASTLE or INC ; No - jump MOV AH,[DI+9] ; Get direction CMP AH,BL ; Same as attacking direction ? JZ ACK15 ; Yes - jump NEG AH ; Otack JP AO10 ; Keeping going that direction ;*********************************************************** ; ATTACK CHECK AV AL,1 ; Set attacker found flag POP CX ; Restore CX reg RET ; Return from ATTACK ACK10: PUSH CX ; Save regs PUSH DIPOP AX POP AX ; Set SP level to ATTACK MOV AX,0DFFFH ; FF (border) in AL and DF in AH CMP [BP+9],AL ; Is +9 border ? JZaddress ACK30: OR DH,DH ; Queen found this scan ? JZ ACK31 ; No - jump MOV AL,QUEEN ; Use Queen slot in attack list ACK3HK, control is returned to ; the aforementioned routines as soon as an ; attacker of the oppospposite direction ? CMP AH,BL ; Same as attacking direction ? JZ ACK15 ; Yes - jump ACK20: POP AX ; Restore regs. POP ND SAVE ROUTINE ;*********************************************************** ; FUNCTION: -- To check if a piece can attack MOV CL,[NPINS] ; Number of pinned pieces JCXZ ACK26 ; No pins - jump PUSH AX ; Save AX MOV AX,DI ; Load piece pointe1: AND AL,7 ; Attacking piece type INC B,[DI] ; Increment list count XCHG AL,CL ; Save point value in AL ADD DI,CX ; A[INDX2] PF2: MOV AL,[M3] ; Get King/Queen position MOV [M2],AL ; Save XOR AL,AL MOV [M4],AL ; Clear pinned piece savedn count MOV [NPINS],AL MOV DX,POSK ; Addr of King/Queen pos list PF1: MOV BP,DX MOV AL,[BP] ; Get position of royal pieump PUSH CX ; Save regs. PUSH DX PUSH DI XOR AX,AX ; Zero out attack list MOV CX,7 MOV BX,ATKLST XCHG DI,BX CL******************************************************** ; PIN FIND ROUTINE ;*************************************************5 ; Non-diagonal direction ? JC PF10 ; Yes - jump MOV AL,BL ; Piece type CMP AL,BISHOP ; Bishop ? JNZ PF25 ; No - juttack list slot address MOV CH,[DI] ; Get data already there TEST CH,0FH ; Is first slot empty ? JZ ACK40 ; Yes - jump pos MOV CL,[DI+DIRECT] ; Get direction of scan PF5: CALL PATH ; Compute next position AND AL,AL ; Is it empty ? JZ PF5ce AND AL,AL ; Is it on board ? JNZ PF1A ; Yes- continue JMP PF26 PF1A: CMP AL,-1 ; At end of list ? JZ RET ; Yes rD REP STOW XCHG DI,BX MOV AL,7 ; Set attack flag MOV [T1],AL CALL ATTACK ; Find attackers/defenders MOV BX,WACT ********** ; FUNCTION: -- To produce a list of all pieces pinned ; against the King or Queen, for both whitmp JMP PF20 ; Jump JPF25: JMP PF25 PF10: MOV AL,BL ; Piece type CMP AL,ROOK ; Rook ? JNZ PF25 ; No - jump JMP PF20 TEST CH,0F0H ; Is second slot empty ? JZ ACK35 ; Yes - jump INC DI ; Increment to King slot MOV CH,[DI] ; Get byte ; Yes - jump CMP AL,3 ; Off board ? JZ JPF25 ; Yes - jump CMP AL,2 ; Piece of same color MOV AL,[M4] ; Load pinnedeturn MOV [M3],AL ; Save position as board index MOV SI,[M3] ; Load index to board MOV AL,[SI+BOARD] ; Get contents of b ; White queen attackers MOV DX,BACT ; Black queen attackers TEST B,[P1],080H ; Is queen white ? JZ PF19A ; Yes - skip e ; and black. ; ; CALLED BY: -- FNDMOV ; EVAL ; ; CALLS: -- PATH ; ; Jump PF15: AND AL,AL ; Possible pin ? JNZ PF25 ; No - jump MOV AL,[M2] ; Save possible pin position MOV [M4],AL XCHG AL,CH ; Byte to AL, point value to CH ACK35: SHL AL ; Lower bits to upper SHL AL SHL AL SHL AL OR AL,CH ; Comb piece position JZ PF15 ; Yes - jump AND AL,AL ; Possible pin ? JZ JPF25 ; No - jump MOV AL,[T2] ; Piece type encounoard MOV [P1],AL ; Save MOV CH,8 ; Init scan direction count XOR AL,AL MOV [INDX2],AL ; Init direction index MOV DI, XCHG DX,BX ; Reverse for black PF19A: MOV AL,[BX] ; Number of defenders XCHG DX,BX ; Reverse for attackers SUB AL,[BX] ATTACK ; ; ARGUMENTS: -- None ;*********************************************************** PINFND: XOR AL,AL ; Zero piJMP PF5 ; Jump PF19: MOV AL,[P1] ; Load King or Queen AND AL,7 ; Clear flags CMP AL,QUEEN ; Queen ? JNZ PF20 ; No - jine with point value ACK40: MOV [DI],AL ; Put back into attack list POP DI ; Restore regs POP CX RET ; Return ;***tered CMP AL,QUEEN ; Queen ? JZ PF19 ; Yes - jump MOV BL,AL ; Save piece type MOV AL,CH ; Direction counter CMP AL, ; Defenders minus attackers DEC AL ; Less 1 POP DI ; Restore regs. POP DX POP CX JNS PF25 ; Jump if pin not valid JNZ XC10 JMP RET ; Return if none XC10: MOV BL,AL ; Save attacker value CALL NEXTAD ; Get next defender JZ XC18 ; JuAddr of black attkrs/dfndrs TEST AL,080H ; Is piece white ? JZ XC5 ; Yes - jump XCHG DX,BX ; Swap list pointers XC5: Mddresses. ; Side flag ; Attack list counts ;******************************************************************************* ; FUNCTION: -- To determine the exchange value of a ; piece on a given squarF JZ RET ; Return if none MOV CH,BL ; Prev attckr becomes defender JMP XC10 ; Jump ;******************************** PF20: MOV BX,NPINS ; Address of pinned piece count INC B,[BX] ; Increment MOV SI,[NPINS] ; Load pin list index MOV [SI+Pmp if none LAHF CMP CH,BL ; Attacked less than attacker ? JNC XC19 ; No - jump XC15: CMP AL,BL ; Defender less than atOV CH,[BX] ; Init list counts XCHG DX,BX MOV CL,[BX] XCHG DX,BX XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Restore r********** NEXTAD: INC CL ; Increment side flag XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Swap registers XCHG CH,CL ;e by examining all ; attackers and defenders of that piece. ; ; CALLED BY: -- POINTS ; ; CALLS: -- *************************** ; NEXT ATTACKER/DEFENDER ROUTINE ;*********************************************************** ; FLISTD],CL ; Save direction of pin MOV AL,[M4] ; Position of pinned piece MOV [SI+PLIST],AL ; Save in list PF25: INC DI ; tacker ? JC RET ; Yes - return CALL NEXTAD ; Retrieve next attacker value JZ RET ; Return if none MOV BL,AL ; Save aegs. MOV CL,0 ; Init attacker/defender flag MOV DL,0 ; Init points lost count MOV SI,[T3] ; Load piece value index MO Swap list counts XCHG DX,BX ; Swap list pointers XOR AL,AL CMP AL,CH ; At end of list ? JZ NX6 ; Yes - jump DEC CHNEXTAD ; ; ARGUMENTS: -- None. ;*********************************************************** XCHNG: XCHG BX,[HL] XCHG DX,UNCTION: -- To retrieve the next attacker or defender ; piece value from the attack list, and delete ; Increment direction index DEC CH JZ PF26 ; Done ? Yes - Continue JMP PF2 PF26: INC DX ; Incr King/Queen pos index JMPttacker value CALL NEXTAD ; Retrieve next defender value JNZ XC15 ; Jump if none XC18: LAHF XC19: TEST CL,001H ; AttackV DH,[SI+PVALUE] ; Get attacked piece value SAL DH ; Double it MOV CH,DH ; Save CALL NEXTAD ; Retrieve first attacker ; Decrement list count NX5: INC BX ; Increment list pointer CMP AL,[BX] ; Check next item in list JZ NX5 ; Jump if emp[DE] XCHG CX,[BC] ; Swap regs. MOV AL,[P1] ; Piece attacked MOV BX,WACT ; Addr of white attkrs/dfndrs MOV DX,BACT ; that piece from the list. ; ; CALLED BY: -- XCHNG ; ; CALLS: -- None ; ; ARGUMENTS: -- Attack list a PF1 ; Jump ;*********************************************************** ; EXCHANGE ROUTINE ;*****************************er or defender ? JZ XC20 ; Jump if defender NEG CH ; Negate value for attacker XC20: ADD DL,CH ; Total points lost SAHty MOV AL,[BX] ; Get value from list MOV AH,AL SHR AH SHR AH SHR AH SHR AH MOV [BX],AH AND AL,0FH DEC BX ; Dtling TEST B,[BX],080H ; Check piece color JZ PT6D ; Jump if white MOV AL,-6 ; Bonus for black castling JP PT6D ; JumPT25 ; Yes - jump PT5A: MOV BX,P1 ; Save piece, if any MOV [BX],AL AND AL,7 ; Save piece type, if any MOV [T3],AL CM3 ; No - Jump DEC DH ; Deduct half a Pawn value MOV AL,[P1] ; Get piece under attack XOR AL,[COLOR] ; Compare color of LIMIT ; ; ARGUMENTS: -- None ;*********************************************************** POINTS: XOR AL,STOW XCHG DI,BX CALL ATTACK ; Build attack list for square MOV BX,BACT ; Get black attacker count addr MOV AL,[WACT] ;ecrement list pointer ADD AL,AL ; Double it NX6: XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Restore regs. RET ; Returp PT6A: TEST B,[BX],008H ; Has piece moved yet ? JZ PT6X ; No - jump JP PT6C ; Jump PT6B: TEST B,[BX],008H ; Has piece mP AL,KNIGHT ; Less than a Knight (Pawn) ? JC PT6X ; Yes - Jump CMP AL,ROOK ; Rook, Queen or King ? JC PT6B ; No - jump side just moved with piece TEST AL,080H ; Do colors match ? MOV AL,DL ; Points lost JNZ PT20 ; Jump if no match MOV BAL ; Zero out variables MOV [MTRL],AL MOV [BRDC],AL MOV [PTSL],AL MOV [PTSW1],AL MOV [PTSW2],AL MOV [PTSCK],AL MO Get white attacker count SUB AL,[BX] ; Compute count difference MOV BX,BRDC ; Address of board control ADD AL,[BX] ; An ;*********************************************************** ; POINT EVALUATION ROUTINE ;********************************oved yet ? JNZ PT6X ; Yes - jump PT6C: MOV AL,-2 ; Two point penalty for white TEST B,[BX],080H ; Check piece color JZ CMP AL,KING ; Is it a King ? JZ PT6AA ; Yes - jump MOV AL,[MOVENO] ; Get move number CMP AL,7 ; Less than 7 ? JC PTX,PTSL ; Previous max points lost CMP AL,[BX] ; Compare to current value JC PT23 ; Jump if greater than MOV [BX],DL ; V BX,T1 ; Set attacker flag MOV B,[BX],7 MOV AL,21 ; Init to first square on board PT5: MOV [M3],AL ; Save as board indeccum board control score MOV [BX],AL ; Save MOV AL,[P1] ; Get piece on current square AND AL,AL ; Is it empty ? JZ PT*************************** ;FUNCTION: -- To perform a static board evaluation and ; derive a score for a giPT6D ; Jump if white MOV AL,+2 ; Two point penalty for black PT6D: MOV BX,BRDC ; Get address of board control ADD [BX],A6A ; Yes - Jump JMP PT6X ; Jump PT6AA: TEST B,[BX],010H ; Castled yet ? JZ PT6A ; No - jump MOV AL,+6 ; Bonus for casStore new value as max lost MOV SI,[MLPTRJ] ; Load pointer to this move MOV AL,[M3] ; Get position of lost piece CMP AL,[x MOV SI,[M3] ; Load board index MOV AL,[SI+BOARD] ; Get piece from board CMP AL,-1 ; Off board edge ? JNZ PT5A JMP 25 ; Yes - jump CALL XCHNG ; Evaluate exchange, if any XOR AL,AL ; Check for a loss CMP AL,DL ; Points lost ? JZ PT2ven board position ; ; CALLED BY: -- FNDMOV ; EVAL ; ; CALLS: -- ATTACK ; XCHNG ;L ; Add on penalty/bonus points PT6X: XOR AX,AX ; Zero out attack list MOV CX,7 MOV BX,ATKLST XCHG DI,BX CLD REP SI+MLTOP] ; Is it the one moving ? JNZ PT23 ; No - jump MOV [PTSCK],AL ; Save position as a flag JP PT23 ; Jump PT20: M ; Net material on board ADD AL,[BX] ; Add exchange adjustments MOV BX,MV0 ; Material at ply 0 SUB AL,[BX] ; Subtract s lost AND AL,AL ; Is it zero ? JZ PT26 ; Yes - jump DEC AL ; Decrement it PT26: MOV CH,AL ; Save it MOV AL,[PTSW1]UTINE ;*********************************************************** ; FUNCTION: -- To limit the magnitude of a given value BX,MTRL ; Get addrs of material total ADD AL,[BX] ; Add new value MOV [BX],AL ; Store PT25: MOV AL,[M3] ; Get current b DH,AL ; Save limited value MOV AL,DL ; Get material points ADD AL,AL ; Multiply by 4 ADD AL,AL ADD AL,DH ; Add boarOV BX,PTSW1 ; Previous maximum points won CMP AL,[BX] ; Compare to current value JC PT21 ; Jump if greater than MOV AL,[from current MOV CH,AL ; Save MOV AL,30 ; Load material limit CALL LIMIT ; Limit to plus or minus value MOV DL,AL ; ; Max,points won AND AL,AL ; Is it zero ? JZ PT27 ; Yes - jump MOV AL,[PTSW2] ; 2nd max points won AND AL,AL ; Is it; to another given value. ; ; CALLED BY: -- POINTS ; ; CALLS: -- None ; ; ARGUMENTS: -- Input -oard position INC AL ; Increment CMP AL,99 ; At end of board ? JZ PT25AA JMP PT5 ; No - jump PT25AA: MOV AL,[PTSCK] d control TEST B,[COLOR],080H ; Is color of side just moved white ? JNZ PT30 ; No - jump NEG AL ; Negate for white PT30BX] ; Load previous max value MOV [BX],DL ; Store new value as max won PT21: MOV BX,PTSW2 ; Previous 2nd max points won CSave limited value MOV AL,[BRDC] ; Get board control points MOV BX,BC0 ; Board control at ply zero SUB AL,[BX] ; Get dif zero ? JZ PT27 ; Yes - jump DEC AL ; Decrement it SHR AL ; Divide it by 2 PT27: SUB AL,CH ; Subtract points lost T Value, to be limited in the CH ; register. ; - Value to limit to in the AL re; Moving piece lost flag AND AL,AL ; Was it lost ? JZ PT25A ; No - jump MOV AL,[PTSW2] ; 2nd max points won MOV [PTSW1: ADD AL,80H ; Rescale score (neutral = 80H) MOV [VALM],AL ; Save score MOV SI,[MLPTRJ] ; Load move list pointer MOV [SI+MP AL,[BX] ; Compare to current value JC PT23 ; Jump if greater than MOV [BX],AL ; Store as new 2nd max lost PT23: TEST ference MOV CH,AL ; Save MOV AL,[PTSCK] ; Moving piece lost flag AND AL,AL ; Is it zero ? JZ PT29 ; Yes - jump MOV EST B,[COLOR],080H ; Is color of side just moved white ? JZ PT28 ; Yes - jump NEG AL ; Negate for black PT28: MOV BX,MTRLgister ; Output - Limited value in the AL register. ;*********************************************************],AL ; Store as max points won XOR AL,AL ; Zero out 2nd max points won MOV [PTSW2],AL PT25A: MOV AL,[PTSL] ; Get max pointMLVAL],AL ; Save score in move list RET ; Return ;*********************************************************** ; LIMIT ROB,[P1],080H ; Test piece color MOV AL,DH ; Value of piece JZ PT24 ; Jump if white NEG AL ; Negate for black PT24: MOV CH,0 ; Zero board control points PT29: MOV AL,6 ; Load board control limit CALL LIMIT ; Limit to plus or minus value MOV** LIMIT: TEST CH,080H ; Is value negative ? JZ LIM10 ; No - jump NEG AL ; Make positive CMP AL,CH ; Compare to limitmove ? JNZ MV40 ; Yes - jump MOV AL,DH ; Get captured piece, if any AND AL,7 CMP AL,QUEEN ; Was it a queen ? JNZ RETLoad "from" pos board index MOV DL,[SI+BOARD] ; Get piece moved TEST DH,020H ; Test Pawn promotion flag JNZ MV15 ; Jump utine, ; thereby restoring the board array to its ; previous position. ; ; CALLED BY: -- V EVAL ; FNDMOV ; VALMOV ; ; CALLS: -- None ; ; ARGUMENTS: -- None ;**],AL ; Save JMP MV5 ; Jump MV30: MOV BX,POSK ; Get saved King position TEST DH,020H ; Castling ? JZ MV21 ; No - jump JNC RET ; Return if outside limit MOV AL,CH ; Output value as is RET ; Return LIM10: CMP AL,CH ; Compare to limit ; No - return MOV BX,POSQ ; Addr of saved Queen position TEST DH,080H ; Is Queen white ? JZ MV10 ; Yes - jump INC Bif set MOV AL,DL ; Piece moved AND AL,7 ; Clear flag bits CMP AL,QUEEN ; Is it a queen ? JZ MV20 ; Yes - jump CMP AALMOV ; EVAL ; FNDMOV ; ASCEND ; ; CALLS: -- None ; ; ARGUMENTS: -********************************************************* MOVE: MOV BX,[MLPTRJ] ; Load move list pointer INC BX ; Increment OR DL,010H ; Set King castled flag JMP MV21 ; Jump MV40: MOV BX,[MLPTRJ] ; Get move list pointer ADD BX,8 ; Increment JC RET ; Return if outside limit MOV AL,CH ; Output value as is RET ; Return ;**************************************X ; Increment to black Queen pos MV10: XOR AL,AL ; Set saved position to zero MOV [BX],AL RET ; Return MV15: OR DL,004L,KING ; Is it a king ? JZ MV30 ; Yes - jump MV5: MOV DI,[M2] ; Load "to" pos board index OR DL,008H ; Set piece moved - None ;*********************************************************** UNMOVE: MOV BX,[MLPTRJ] ; Load move list pointer INC BXpast link bytes INC BX MV1: MOV AL,[BX] ; "From" position MOV [M1],AL ; Save INC BX ; Increment pointer MOV AL,[BX] to next move JMP MV1 ; Jump (2nd part of dbl move) ;*********************************************************** ; UN-MOV********************* ; MOVE ROUTINE ;*********************************************************** ; FUNCTION: -- To executH ; Change Pawn to a Queen JMP MV5 ; Jump MV20: MOV BX,POSQ ; Addr of saved Queen position MV21: TEST DL,080H ; Is Queenflag MOV [DI+BOARD],DL ; Insert piece at new position MOV B,[SI+BOARD],0 ; Empty previous position TEST DH,040H ; Double ; Increment past link bytes INC BX UM1: MOV AL,[BX] ; Get "from" position MOV [M1],AL ; Save INC BX ; Increment poin ; "To" position MOV [M2],AL ; Save INC BX ; Increment pointer MOV DH,[BX] ; Get captured piece/flags MOV SI,[M1] ; E ROUTINE ;*********************************************************** ; FUNCTION: -- To reverse the process of the move roe a move from the move list on the ; board array. ; ; CALLED BY: -- CPTRMV ; PLYRMV ; white ? JZ MV22 ; Yes - jump INC BX ; Increment to black Queen pos MV22: MOV AL,[M2] ; Get new Queen position MOV [BXter MOV AL,[BX] ; Get "to" position MOV [M2],AL ; Save INC BX ; Increment pointer MOV DH,[BX] ; Get captured piece/fr castled flag JMP UM21 ; Jump UM40: MOV BX,[MLPTRJ] ; Load move list pointer ADD BX,8 ; Increment to next move JMP UM1e RET ; Return UM15: AND DL,0FBH ; Restore Queen to Pawn JMP UM5 ; Jump UM16: AND DL,0F7H ; Clear piece moved flag I,DX ; Transfer move pointer MOV AL,[VALM] ; Get new move value CMP AL,[SI+MLVAL] ; Less than list value ? JNC SR30 ; No AL,DH ; Get captured piece, if any AND AL,8FH ; Clear flags MOV [SI+BOARD],AL ; Return to board TEST DH,040H ; Was it SR5: MOV BH,CH MOV BL,CL MOV CL,[BX] ; Link to next move INC BX MOV CH,[BX] MOV [BX],DH ; Store to link in list lags MOV SI,[M2] ; Load "to" pos board index MOV DL,[SI+BOARD] ; Get piece moved TEST DH,020H ; Was it a Pawn promotion ; Jump (2nd part of dbl move) ;*********************************************************** ; SORT ROUTINE ;**************JMP UM6 ; Jump UM20: MOV BX,POSQ ; Addr of saved Queen position UM21: TEST DL,080H ; Is Queen white ? JZ UM22 ; Yes - ju - jump SR25: MOV [BX],CH ; Link new move into list DEC BX MOV [BX],CL JMP SR5 ; Jump SR30: XCHG DX,BX ; Swap pointera double move ? JNZ UM40 ; Yes - jump MOV AL,DH ; Get captured piece, if any AND AL,7 ; Clear flag bits CMP AL,QUEEN DEC BX MOV [BX],DL XOR AL,AL ; End of list ? CMP AL,CH JZ RET ; Yes - return SR10: MOV [MLPTRJ],CX ; Save list pointe? JNZ UM15 ; Yes - jump MOV AL,DL ; Get piece moved AND AL,7 ; Clear flag bits CMP AL,QUEEN ; Was it a Queen ? JZ U********************************************* ; FUNCTION: -- To sort the move list in order of ; increasingmp INC BX ; Increment to black Queen pos UM22: MOV AL,[M1] ; Get previous position MOV [BX],AL ; Save JMP UM5 ; Jump s JMP SR15 ; Jump ;*********************************************************** ; EVALUATION ROUTINE ;*******************; Was it a Queen ? JNZ RET ; No - return MOV BX,POSQ ; Address of saved Queen pos TEST DH,080H ; Is Queen white ? JZ r CALL EVAL ; Evaluate move MOV BX,[MLPTRI] ; Begining of move list MOV CX,[MLPTRJ] ; Restore list pointer SR15: MOV DL,M20 ; Yes - jump CMP AL,KING ; Was it a King ? JZ UM30 ; Yes - jump UM5: TEST DH,010H ; Is this 1st move for piece ? move value scores. ; ; CALLED BY: -- FNDMOV ; ; CALLS: -- EVAL ; ; ARGUMENTS: -- None ;*********************** UM30: MOV BX,POSK ; Address of saved King pos TEST DH,040H ; Was it a castle ? JZ UM21 ; No - jump AND DL,0EFH ; Clea**************************************** ; FUNCTION: -- To evaluate a given move in the move list. ; It firUM10 ; Yes - jump INC BX ; Increment to black Queen pos UM10: MOV AL,[M2] ; Queen's previous position MOV [BX],AL ; Sav[BX] ; Next move for compare INC BX MOV DH,[BX] XOR AL,AL ; At end of list ? CMP AL,DH JZ SR25 ; Yes - jump MOV SJNZ UM16 ; Yes - jump UM6: MOV DI,[M1] ; Load "from" pos board index MOV [DI+BOARD],DL ; Return to previous board pos MOV************************************ SORTM: MOV CX,[MLPTRI] ; Move list begin pointer MOV DX,0 ; Initialize working pointersst makes the move on the board, then if ; the move is legal, it evaluates it, and then ; resto MOV BX,PLYIX-2 MOV [MLPTRI],BX MOV AL,[KOLOR] ; Initialize color MOV [COLOR],AL MOV BX,SCORE ; Initialize score index ; GENMOV ; SORTM ; ASCEND ; UNMOVE ; ; ARGUMENTS: -- NonAL,AL ; End of move list ? JNZ FM15A JMP FM25 ; Yes - jump FM15A: MOV [MLPTRJ],DX ; Save current move pointer MOV BX,[MFND ; Compile pinned list CALL POINTS ; Assign points to move JMP UNMOVE ; Restore board array ;********************** INC B,[BX] ; Increment ply count XOR AL,AL ; Initialize mate flag MOV [MATEF],AL CALL GENMOV ; Generate list of moves res the board position. ; ; CALLED BY: -- SORT ; ; CALLS: -- MOVE ; INCHK ; PINFND MOV [SCRIX],BX MOV AL,[PLYMAX] ; Get max ply number ADD AL,2 ; Add 2 MOV CH,AL ; Save as counter XOR AL,AL ; Zero oe ;*********************************************************** FNDMOV: MOV AL,[MOVENO] ; Current move number CMP AL,1 ; FirLPTRI] ; Save in ply pointer list MOV [BX],DL INC BX MOV [BX],DH MOV AL,[NPLY] ; Current ply counter MOV BX,PLYMAX ; M************************************* ; FIND MOVE ROUTINE ;*********************************************************** ; FUNC MOV AL,[NPLY] ; Current ply counter MOV BX,PLYMAX ; Address of maximum ply number CMP AL,[BX] ; At max ply ? JNC L0004 ; POINTS ; UNMOVE ; ; ARGUMENTS: -- None ;**********************************************ut score table FM1: MOV [BX],AL INC BX DEC CH JNZ FM1 MOV [BC0],AL ; Zero ply 0 board control MOV [MV0],AL ; Zero plyst move ? JNZ L0003 CALL BOOK ; Yes - execute book opening L0003: XOR AL,AL ; Initialize ply number to zero MOV [NPLYaximum ply number ? CMP AL,[BX] ; Compare JC FM18 ; Jump if not max CALL MOVE ; Execute move on board array CALL INCHTION: -- To determine the computer's best move by ; performing a depth first tree search using ; CALL SORTM ; No - call sort L0004: MOV BX,[MLPTRI] ; Load ply index pointer MOV [MLPTRJ],BX ; Save as last move pointer ************* EVAL: CALL MOVE ; Make move on the board array CALL INCHK ; Determine if move is legal AND AL,AL ; Legal m 0 material CALL PINFND ; Compile pin list CALL POINTS ; Evaluate board at ply 0 MOV AL,[BRDC] ; Get board control point],AL MOV BX,0 ; Initialize best move to zero MOV [BESTM],BX MOV BX,MLIST ; Initialize ply list pointers MOV [MLNXT],BX K ; Check for legal move AND AL,AL ; Is move legal JZ FM16 ; Yes - jump CALL UNMOVE ; Restore board position JMP FM1 the techniques of alpha-beta pruning. ; ; CALLED BY: -- CPTRMV ; ; CALLS: -- PINFND ; POINTS FM15: MOV BX,[MLPTRJ] ; Load last move pointer MOV DL,[BX] ; Get next move pointer INC BX MOV DH,[BX] MOV AL,DH AND ove ? JZ EV5 ; Yes - jump XOR AL,AL ; Score of zero MOV [VALM],AL ; For illegal move JMP UNMOVE ; Jump EV5: CALL PINs MOV [BC0],AL ; Save MOV AL,[MTRL] ; Get material count MOV [MV0],AL ; Save FM5: MOV BX,NPLY ; Address of ply counter 5 ; Jump FM16: MOV AL,[NPLY] ; Get ply counter MOV BX,PLYMAX ; Max ply number CMP AL,[BX] ; Beyond max ply ? JZ FM17 te move CALL UNMOVE ; Restore board position MOV AL,[VALM] ; Get value of move FM36: OR B,[MATEF],001H ; Set mate flag Mate) MOV AL,[MOVENO] ; Get move number MOV [PMATE],AL ; Save MOV AL,0FFH ; Pre-set checkmate score JMP FM36 ; Jump FM**** ; ASCEND TREE ROUTINE ;*********************************************************** ; FUNCTION: -- To adjust all necessmp INC B,[MOVENO] ; Increment move number FM20: MOV BX,[SCRIX] ; Load score table pointer MOV AL,[BX] ; Get score two plysESTM],BX ; Save as best move pointer MOV AL,[SCORE+1] ; Get best move score CMP AL,0FFH ; Was it a checkmate ? JNZ JFM15 JMP FM35 ; Yes - jump FM17: MOV AL,[COLOR] ; Get current color XOR AL,80H ; Get opposite color CALL INCHK1 ; Determine iOV BX,[SCRIX] ; Load score table pointer FM37: CMP AL,[BX] ; Compare to score 2 ply above JC FM40 ; Jump if less JZ FM40 30: MOV AL,[NPLY] ; Get ply counter CMP AL,1 ; At top of tree ? JZ RET ; Yes - return CALL ASCEND ; Ascend one ply in tary parameters to ; ascend one ply in the tree. ; ; CALLED BY: -- FNDMOV ; ; CALLS: -- UNMOVE ; ; AR above INC BX ; Increment to current ply MOV [SCRIX],BX ; Save it INC BX MOV [BX],AL ; Save score as initial value J ; No - jump MOV BX,PLYMAX ; Get maximum ply number SUB B,[BX],2 ; Subtract 2 MOV AL,[KOLOR] ; Get computer's color TESTf King is in check AND AL,AL ; In check ? JZ FM35 ; No - jump JMP FM19 ; Jump (One more ply for check) FM18: MOV SI,[M ; Jump if equal NEG AL ; Negate score INC BX ; Incr score table pointer CMP AL,[BX] ; Compare to score 1 ply above Jree MOV BX,[SCRIX] ; Load score table pointer INC BX ; Increment to current ply INC BX MOV AL,[BX] ; Get score DEC BGUMENTS: -- None ;*********************************************************** ASCEND: XOR B,[COLOR],80H ; Toggle color, is neMP FM5 ; Jump FM25: MOV AL,[MATEF] ; Get mate flag AND AL,AL ; Checkmate or stalemate ? JNZ FM30 ; No - jump MOV AL,[C AL,080H ; Is it white ? JZ RET ; Yes - return MOV BX,PMATE ; Checkmate move number DEC B,[BX] ; Decrement RET ; ReLPTRJ] ; Load move pointer MOV AL,[SI+MLVAL] ; Get move score AND AL,AL ; Is it zero (illegal move) ? JZ FM15 ; Yes - juC JFM15 ; Jump if less than JZ JFM15 ; Jump if equal MOV [BX],AL ; Save as new score 1 ply above MOV AL,[NPLY] ; Get cuX ; Restore pointer DEC BX JMP FM37 ; Jump JFM15: JMP FM15 FM35: CALL PINFND ; Compile pin list CALL POINTS ; Evaluaw color white ? JNS AC5 ; Yes - jump DEC B,[MOVENO] ; Decrement move number AC5: DEC [SCRIX] ; Decrement score table indeKFLG] ; Get check flag AND AL,AL ; Was King in check ? MOV AL,80H ; Pre-set stalemate score JZ FM36 ; No - jump (stalemturn FM40: CALL ASCEND ; Ascend one ply in tree JMP FM15 ; Jump ;*******************************************************mp CALL MOVE ; Execute move on board array FM19: XOR B,[COLOR],80H ; Toggle color, is new color white ? JS FM20 ; No - jurrent ply counter CMP AL,1 ; At top of tree ? JNZ JFM15 ; No - jump MOV BX,[MLPTRJ] ; Load current move pointer MOV [Bx DEC B,[NPLY] ; Decrement ply counter MOV BX,[MLPTRI] ; Load ply list pointer DEC BX ; Load pointer to move list top rn to CPTRMV ;*********************************************************** ; COMPUTER MOVE ROUTINE ;************************T ; Return BM5: ADD B,[BX],6 ; Increment to black moves MOV SI,[MLPTRJ] ; Pointer to opponents 1st move MOV AL,[SI+MLFRP]; Convert to Ascii MOV [MVEMSG],BX ; Put in move message MOV DX,MVEMSG ; Output move MOV CL,PRINTBUF CALL SYSTEM CP1C: BY: -- FNDMOV ; ; CALLS: -- None ; ; ARGUMENTS: -- None ;*******************************************************ve list pointer variable MOV [MLPTRJ],BX ; Pointer to move data MOV AL,[SCORE+1] ; To check for mates CMP AL,1 ; Mate agaDEC BX MOV DX,[BX] MOV [MLNXT],DX ; Update move list avail ptr DEC BX ; Get ptr to next move to undo DEC BX MOV DX,[B*********************************** ; FUNCTION: -- To control the search for the computers move ; and the d ; Get "from" position CMP AL,22 ; Is it a Queen Knight move ? JZ BM9 ; Yes - Jump CMP AL,27 ; Is it a King Knight moveMOV AL,[COLOR] ; Should computer call check ? MOV CH,AL XOR AL,80H ; Toggle color MOV [COLOR],AL CALL INCHK ; Check fo**** BOOK: POP AX MOV B,[SCORE+1],0 ; Zero out score table MOV [BESTM],BMOVES-2 ; Init best move ptr to book MOV BX,BESTMinst computer ? JNZ CP0C ; No - jump MOV CL,1 ; Computer mate flag CALL FCDMAT ; Full checkmate ? CP0C: CALL MOVE ; PX] MOV [MLPTRI],BX ; Save new ply list pointer MOV [MLPTRJ],DX ; Save next move pointer JMP UNMOVE ; Restore board to preisplay of that move on the board ; and in the move list. ; ; CALLED BY: -- DRIVER ; ; CALLS: -- FND ? JZ BM9 ; Yes - jump CMP AL,34 ; Is it a Queen Pawn ? JZ BM9 ; Yes - jump JC RET ; If Queen side Pawn opening - r check AND AL,AL ; Is enemy in check ? MOV AL,CH ; Restore color MOV [COLOR],AL JZ CP24 ; No - return MOV DX,CKMSG ; Initialize address of pointer MOV AL,[KOLOR] ; Get computer's color AND AL,AL ; Is it white ? JNZ BM5 ; No - jump Mroduce move on board array MOV SI,[MLPTRJ] ; Get pointer to move MOV DH,[SI+MLTOP] ; "To" position of the move CALL BITASNvious ply ;*********************************************************** ; ONE MOVE BOOK OPENING ; **************************MOV ; FCDMAT ; MOVE ; BITASN ; INCHK ; ; ARGUMENTS: -- N ; return (P-K4) CMP AL,35 ; Is it a King Pawn ? JZ RET ; Yes - return (P-K4) BM9: ADD B,[BX],3 ; (P-Q4) RET ; Retu ; Output "check" MOV CL,PRINTBUF CALL SYSTEM CP24: MOV AL,[SCORE+1] ; Check again for mates CMP AL,0FFH ; Player mated OV AL,0 ; Load random number (0) TEST AL,001H ; Test random bit JZ RET ; Return if zero (P-K4) ADD B,[BX],3 ; P-Q4 RE ; Convert to Ascii MOV [MVEMSG+3],BX ; Put in move message MOV DH,[SI+MLFRP] ; "From" position of the move CALL BITASN ******************************** ; FUNCTION: -- To provide an opening book of a single ; move. ; ; CALLEDone ;*********************************************************** CPTRMV: CALL FNDMOV ; Select best move MOV BX,[BESTM] ; Mo? JNZ RET ; No - return MOV CL,0 ; Set player mate flag CALL FCDMAT ; Full checkmate ? RET ; Return ;************************************************* ; BOARD INDEX TO ASCII SQUARE NAME ;***************************************************g for who is mated RCL AH JZ FM04 ; Jump if player MOV DX,CKMSG ; Print "CHECK" MOV CL,PRINTBUF CALL SYSTEM MOV DX,ED BY: -- DRIVER ; ; CALLS: -- ASNTBI ; VALMOV ; ; ARGUMENTS: -- None ;*************************PTRMV ; ; CALLS: -- None ; ; ARGUMENTS: -- The only value passed in a register is the ; flag which e DEC DH ; Get rank on 1-8 basis ADD AL,60H ; Convert file to Ascii (a-h) MOV BL,AL ; Save MOV AL,DH ; Rank ADD AL************************************************ ; FORCED MATE HANDLING ;************************************************************* ; FUNCTION: -- To translate a hexadecimal index in the ; board array into an ascii description ; UWIN ; Output "YOU WIN" MOV CL,PRINTBUF CALL SYSTEM JP FM08 ; Jump FM04: MOV DX,CKMSG ; Print "CHECK" MOV CL,PRINTBUF********************************** PLYRMV: MOV DX,BUFFER ; Ask for input MOV CL,INBUF CALL SYSTEM MOV DX,CRLF ; Output Ctells FCDMAT whether the computer ; or the player is mated. ;*************************************************,30H ; Convert rank to Ascii (1-8) MOV BH,AL ; Save RET ; Return ;********************************************************* ; FUNCTION: -- To examine situations where there exits ; a forced mate and determine whether or ; of the square in algebraic chess notation. ; ; CALLED BY: -- CPTRMV ; ; CALLS: -- DIVIDE ; ; ARGUM CALL SYSTEM MOV DX,IWIN ; Output "I WIN" MOV CL,PRINTBUF CALL SYSTEM FM08: POP BX ; Remove return addresses POP BXRLF MOV CL,PRINTBUF CALL SYSTEM MOV BX,BUFFER+1 ; Point to input length MOV AL,[BX] ; Get input length OR AL,AL ; Em********** FCDMAT: MOV AL,[MOVENO] ; Current move number MOV CH,AL ; Save MOV AL,[PMATE] ; Move number where mate occurs ******** ; PLAYERS MOVE ANALYSIS ;*********************************************************** ; FUNCTION: -- To accept and not the current move is checkmate. If it is, ; a losing player is offered another game, ; ENTS: -- Board index input in register DH and the ; Ascii square name is output in register BX. ;*********** MOV CL,INCHAR ; Input any char to play again CALL SYSTEM JMP DRIVER ; Jump (Rest of game init) ;*********************pty ? JZ PLYRMV ; Jump if empty MOV CH,AL ; Save length LAHF INC BX ; Point to actual buffer SAHF MOV AL,[BX] ; SUB AL,CH ; Number of moves till mate AND AL,AL ; Checkmate ? JNZ RET ; No - return RCR AH TEST CL,001H ; Check fla validate the players move ; Also allows player to resign the game by ; entering R. ; ; CALL while a loss for the computer signals the ; King to tip over in resignation. ; ; CALLED BY: -- C************************************************ BITASN: SUB AL,AL ; Get ready for division MOV DL,10 CALL DIVIDE ; DividGet first char CMP AL,"R" ; Restart game ? JNZ PL05 ; Jump if not restart JMP DRIVER PL05: MOV AL,CH ; Get input lengt MOV CL,AL ADD AL,AL ADD AL,AL ADD AL,CL ADD AL,CH ; 10 * rank + file INC BX ; Increment pointer ADD AL,21 RET e board index in register AL. ; CF = 0 if ok. CF = 1 if invalid. ;******************************************** "To" position CMP AL,[SI+MLTOP] ; Is it in list ? JZ VA7 ; Yes - jump VA6: MOV DL,[SI+MLPTR] ; Pointer to next list move ;*********************************************************** ; ASCII SQUARE NAME TO BOARD INDEX ;*********************************** VALMOV: MOV BX,[MLPTRJ] ; Save last move pointer PUSH BX ; Save register MOV AL,[KOLOR] ; Computers color XORh CMP AL,5 ; Long enough ? JC PL08 ; Jump if less than 5 chars CALL ASNTBI ; Convert "from" to a board index JC PL08 ; Return ;*********************************************************** ; VALIDATE MOVE SUBROUTINE ;************************************** ATBINX: INC BX ; Increment pointer to skip a char ASNTBI: MOV AL,[BX] ; Ascii file letter (a - h) INC BX MOV DH,[SI+MLPTR+1] XOR AL,AL ; At end of list ? CMP AL,DH JZ VA10 ; Yes - jump PUSH DX ; Move to SI register POP********************************** ; FUNCTION: -- To convert an algebraic square name in ; Ascii to a hexad AL,80H ; Toggle color MOV [COLOR],AL ; Store MOV BX,PLYIX-2 ; Load move list index MOV [MLPTRI],BX MOV BX,MLIST+1024 ; ; Jump if invalid MOV [MVEMSG],AL ; Move list "from" position CALL ATBINX ; Convert "to" to a board index JC PL08 ; Jum************************************ ; FUNCTION: -- To check a players move for validity. ; ; CALLED BY: -- PLYRMV ; ; SUB AL,41H ; File 1 - 8 JC RET ; Not file letter CMP AL,8 ; Check upper bound CMC JC RET ; Invalid MOV CH,AL MO SI JP VA5 ; Jump VA7: MOV [MLPTRJ],SI ; Save opponents move pointer CALL MOVE ; Make move on board array CALL INCHK ;ecimal board index. ; This routine also checks the input for ; validity. ; ; CALLED BY: -- Next available list pointer MOV [MLNXT],BX CALL GENMOV ; Generate opponents moves MOV SI,MLIST+1024 ; Index to start of p if invalid MOV [MVEMSG+1],AL ; Move list "to" position CALL VALMOV ; Determines if a legal move OR AL,AL ; Legal ? J CALLS: -- GENMOV ; MOVE ; INCHK ; UNMOVE ; ; ARGUMENTS: -- ReturnsV AL,[BX] SUB AL,31H ; Rank 1 - 8 JC RET CMP AL,8 ; Check upper bound CMC JC RET ADD AL,AL ; Multiply rank by 10 Was it a legal move ? AND AL,AL JNZ VA9 ; No - jump VA8: POP BX ; Restore saved register RET ; Return VA9: CALL UNM PLYRMV ; ; CALLS: -- None ; ; ARGUMENTS: -- Accepts the square name in pointer BX ; and outputs thmoves VA5: MOV AL,[MVEMSG] ; "From" position CMP AL,[SI+MLFRP] ; Is it in list ? JNZ VA6 ; No - jump MOV AL,[MVEMSG+1] ;Z RET ; Yes - return PL08: MOV DX,INVAL ; Output "INVALID MOVE--TRY AGAIN" MOV CL,PRINTBUF CALL SYSTEM JP PLYRMV ; Jump flag in register AL, 0 for valid ; and 1 for invalid move. ;*************************************************OVE ; Un-do move on board array VA10: MOV AL,1 ; Set flag for invalid move POP BX ; Restore saved register MOV [MLPTRJ],will consider 1. All of his possible moves 2. All of your responses to those moves. 3. All of his possible replies to youreft-hand corner (from White's viewpoint) is a1. Moves are entered as ff-tt (f=from, t=to), so to play the white king's pawnor 35 (CTRL-C) INT 33 GETCOM: MOV CL,GETDRV CALL SYSTEM ADD AL,"A" MOV CL,OUTCH MOV DL,AL CALL SYSTEM ;Print dri3,10,"$" IWIN: DB "I win" CRLF: DB 13,10,"$" INVAL: DB "INVALID MOVE--TRY AGAIN",13,10,"$" BUFFER: DB 7 DS 6 IX: DS 2 UF EQU 9 OUTCH EQU 2 INBUF EQU 10 RR EQU 33 SYSTEM EQU 5 ORG 100H PUT 100H MOV SP,STACK CLD MOV DL,0 ;Start wBX ; Save move pointer RET ; Return ;*********************************************************** ; POSITIVE INTEGER DIVI responses. Start at ply depth 2 to get the feel for it. A move of "R" will restart the game.  up two squares you would enter E2-E4. You must enter your file letters in upper case, while the computer will always use lowerve letter MOV DL,":" MOV CL,OUTCH CALL SYSTEM ;Print : MOV DX,LINBUF MOV CL,INBUF CALL SYSTEM MOV DL,10 MOV CL,IY: DS 2 BC: DS 2 DE: DS 2 HL: DS 2 ith A: SETDRV: MOV CL,SELDRV CALL SYSTEM COMMAND: MOV SP,STACK CLD MOV AX,CS MOV SS,AX MOV ES,AX MOV DS,AX MSION ;*********************************************************** DIVIDE: PUSH CX MOV CH,8 DD04: SAL DH RCL AL SUB AL,D case. To castle, enter only the king's move. The computer castles the same way. To capture En Passant, enter your pawn's acOUTCH CALL SYSTEM ;New line MOV CH,0 MOV SI,FILIFO ;8 spaces MOV DI,ID CALL FILLBUF MOV DI,FCB CALL FILLBUF MOVOV CX,[6] SUB CX,TPA AND CL,80H ;Round down ROL CX XCHG CH,CL MOV [NUMREC],CX ;Number of records each time MOV DX,CL JS DD05 INC DH JP DD06 DD05: ADD AL,DL DD06: DEC CH JNZ DD04 POP CX RET CLRMSG: DB 13,10,"Choose your color (FCB EQU 5CH DSKRESET EQU 13 SETBASE EQU 38 SRCHFRST EQU 17 SRCHNXT EQU 18 RENAM EQU 23 INCHAR EQU 1 GETFAT EQU 27 OPEN Etual move. Ply depth is the number of half-turns the computer looks ahead. For example, with a ply depth of 3, the computer SI,LINBUF+2 MOV DI,ID CALL FILEDRV ;Get COM drive MOV [SPECDRV],AL MOV CX,8 CALL COPYNAM ;Copy file name MOV AL,9This chess game uses algebraic chess notation. The files are lettered "a" to "h" and the ranks are numbered 1 to 8. The lower lRLF MOV CL,PRINTBUF CALL SYSTEM MOV DX,COMMAND MOV AX,2522H ;Set vector 34 (terminate) INT 33 MOV AX,2523H ;Set vectW/B): $" PLYDEP: DB 13,10,"Ply depth (1-6): $" MVEMSG: DB " ",13,10,"$" CKMSG: DB "CHECK",13,10,"$" UWIN: DB "You win",1QU 15 CLOSE EQU 16 MAKE EQU 22 DELETE EQU 19 RDBLK EQU 39 WRBLK EQU 40 SETDMA EQU 26 SELDRV EQU 14 GETDRV EQU 25 PRINTB SUB AL,CL MOV [IDLEN],AL MOV DI,81H MOV CX,0 PUSH SI COMTAIL: LODB STOB ;Move command tail to 80H CMP AL,13 CMP AL,";" JZ RET CMP AL,9 ;Check for TAB character RET FILEDRV: CALL NEXTCHR JZ FILEDRV ;Skip delim CMP AL,13 MOV CX,512 ;512 records MOV AH,RDBLK INT 33 MOV DS,BX MOV ES,BX MOV SS,BX MOV SP,40H MOV AX,0 PUSH AX MOV SYSTEM ;Print new line MOV CL,SRCHNXT JP EACHFILE OUTCNT: LODB PUSH CX PUSH SI MOV DL,AL MOV CL,OUTCH CALL SYSV DRVCHK: DEC DL ;Adjust for correct drive number DEC AL ;Check if anything else is on line JZ SETDRV1 EXTERNAL: MOV JP FILLBUF DIR: CMP B,[FCB+1]," " JNZ HASNAME MOV SI,FCBFIL MOV DI,FCB+1 CALL FILLBUF ;Fill 11 bytes with "?" H LOOPNZ COMTAIL NOT CL MOV [80H],CL POP SI MOV DI,FCB CALL PARSENAM MOV DI,FCB+10H CALL PARSENAM MOV AL,[IDLEN] JZ NOMATCH CMP B,[SI],":" JNZ NOMATCH SUB AL,40H ;A => 1, B => 2 INC SI RET PARSENAM: CALL NEXTCHR JZ ISDELIAX,100H PUSH BX PUSH AX MOV CL,SETDMA MOV DX,80H CALL SYSTEM RET L BADCOM: MOV DX,BADNAM MOV CL,PRINTBUF CALLTEM POP SI POP CX LOOP OUTCNT RET RENAME: MOV CL,RENAM MOV DX,FCB JMP 5 ERASE: MOV CL,DELETE MOV DX,FCB AL,[SPECDRV] MOV [IDLEN],AL PUSH DS MOV DX,TPA ADD DX,0FH ;Round to next paragraph SHR DX SHR DX SHR DX SHR DXASNAME: MOV DX,LINBUF+2+1 MOV CL,SETDMA CALL SYSTEM MOV CL,SRCHFRST MOV DX,FCB EACHFILE: CALL SYSTEM INC AL ;FF MOV DL,[SPECDRV] OR DL,DL ;Check if drive was specified JNZ DRVCHK DEC AL ;Check for null command JZ GETCOM MOV SIM CMP AL,13 JNZ PARSENAM DEC SI ISDELIM: CALL FILEDRV STOB MOV CX,11 CALL COPYNAM ADD DI,CX CMP CX,3 JB RET SYSTEM JMP COMMAND NEXTCHR: ;Convert lower case input to upper case LODB CMP AL,"a"-1 JB DELIM CMP AL,"z" JA DE JMP 5 CREATE: MOV CL,MAKE MOV DX,FCB JMP 5 TYPE: MOV DX,TPA MOV CL,SETDMA CALL SYSTEM MOV DX,FCB MOV AH, ;Divide 16 MOV CX,CS ADD DX,CX ;New segment MOV DS,DX MOV AH,SETBASE INT 33 MOV DX,100H MOV CL,SETDMA CALL SY= file not found JZ RET MOV SI,LINBUF+2+1 MOV CX,8 CALL OUTCNT ;Print 8 chars (name) MOV CL,OUTCH MOV DL," " CALL,COMTAB FINDCOM: MOV DI,IDLEN MOV CL,[SI] JCXZ EXTERNAL REPE CMPB LAHF ADD SI,CX ;Bump to next position without SUB DI,3 CMP AL,"." JNZ NOMATCH MOV CX,3 COPYNAM: CALL NEXTCHR JZ NOMATCH CMP AL,13 JZ NOMATCH CMP AL,"." LIM SUB AL,20H ;Lower-case changed to upper-case DELIM: CMP AL," " JZ RET CMP AL,"=" JZ RET CMP AL,"," JZ RET OPEN INT 33 OR AL,AL JNZ RET ; Not found MOV [FCB+RR],0 MOV CX,512 MOV AH,RDBLK INT 33 MOV SI,TPA OUTLP: LODSTEM MOV BX,DS ;New segment into BX POP DS MOV DX,IDLEN MOV AH,OPEN INT 33 OR AL,AL JNZ BADCOM MOV [IDLEN+RR],0 SYSTEM ;Print space MOV SI,LINBUF+2+9 MOV CX,3 CALL OUTCNT ;Print 3 chars (ext) MOV DX,CRLF MOV CL,PRINTBUF CALL affecting flags SAHF LODW ;Get address of command JNZ FINDCOM CALL AX ;Call command JMP COMMAND SETDRV1: JMP SETDRJZ RET STOB LOOP COPYNAM NOMATCH: XOR AL,AL DEC SI RET FILLBUF: LODB MOV CL,AL JCXZ RET LODB REP STOB B CMP AL,1AH ;Is EOF? JZ RET MOV CL,OUTCH MOV DL,AL CALL SYSTEM JP OUTLP RET CLEAR: MOV DX,ERAMES MOV CL,PC: DS 2 IDLEN: DS 1 ID: DS 8 COM: DB "COM" DSTFCB: DS 36 LINBUF: DB 80H,1,13 DS 80H FILIFO: DB 8," " DB 0 DB 1[NUMREC] MOV AH,RDBLK INT 33 JCXZ CPYDONE MOV DX,DSTFCB MOV AH,WRBLK INT 33 OR AL,AL JZ CPYBLK MOV DX,NOSPCE table may be defined CUSTOM: EQU 0 ; If Tarbell disk controller, select one-sided or two-sided drives ; and single or doubl,FCBFIL MOV DI,FCB+1 CALL FILLBUF MOV DX,FCB MOV CL,DELETE CALL SYSTEM ;Delete all files MOV CL,DSKRESET JMP 5 RINTBUF CALL SYSTEM ;Confirm erase MOV CL,INCHAR CALL SYSTEM CMP AL,"Y" JZ DOCLEAR CMP AL,"y" JZ DOCLEAR RET D2," ",4,0 DB 12," ",8,0 DB 0 COMTAB: DB 4,"DIR" DW DIR DB 7,"RENAME" DW RENAME DB 6,"ERASE" DW ERASE DB 7,"CR MOV AH,PRINTBUF INT 33 CPYDONE: MOV DX,DSTFCB MOV AH,CLOSE INT 33 RET NOSRC: MOV DX,NOTFND MOV AH,PRINTBUF INe density controller DOUB1SIDE:EQU 0 DOUB2SIDE:EQU 0 SNGL1SIDE:EQU 0 ; If Cromemco disk controller, select drive configura COPY: MOV SI,FCB+10H MOV DI,DSTFCB MOVB CMP B,[SI]," " ;Has file name? JNZ HASDSTNAM MOV SI,FCB+1 HASDSTNAM: MOOCLEAR: MOV DL,[FCB] OR DL,DL JZ CLRDSK DEC DL MOV CL,SELDRV CALL SYSTEM CLRDSK: MOV CL,GETFAT CALL SYSTEM MOEATE" DW CREATE DB 5,"TYPE" DW TYPE DB 6,"CLEAR" DW CLEAR DB 5,"COPY" DW COPY DB 0 TPA: T 33 RET DS 40 STACK: BADNAM: DB "Bad command or file name" CRLF: DB 13,10,"$" ERAMES: DB "Erase all files (Y/N)? $"tion SMALLCRO:EQU 0 ;3 small drives COMBCRO:EQU 1 ;2 large drives and 1 small one LARGECRO:EQU 0 ;4 large drives WD1791VB MOV CX,7 REP MOVW MOV DX,FCB MOV AH,OPEN INT 33 OR AL,AL JNZ NOSRC MOV DX,DSTFCB MOV AH,DELETE INT 33 ; I/O System for 86-DOS. ; Assumes a CPU Support card at F0 hex for character I/O, ; with disk drivers for Tarbell or CromemV CX,DX INC DX SHR DX ADD CX,DX MOV AX,DS MOV ES,AX MOV DI,BX MOV AX,0FFFFH STOW STOB ;Fill first 3 bytes wit NOTFND: DB "Source file not found$" NOSPCE: DB "Insufficient disk space$" FCBFIL: DB 11,"?" DB 0 SPECDRV: DS 1 NUMRE: EQU DOUB1SIDE+DOUB2SIDE WD1771: EQU CROMEMCO+SNGL1SIDE IF WD1791 READCOM:EQU 80H WRITECOM:EQU 0A0H ENDIF IF WD177 MOV AH,MAKE INT 33 MOV DX,TPA MOV AH,SETDMA INT 33 MOV [FCB+RR],0 MOV [DSTFCB+RR],0 CPYBLK: MOV DX,FCB MOV CX,co controllers. ; Select disk controller here TARBELL:EQU 0 CROMEMCO:EQU 1 ; For either disk controller, a custom drive h FF INC AX ;AX = 0 SHR CX JNC DOFILL STOB ;Odd byte DOFILL: REP STOW MOV AX,CS MOV DS,AX MOV ES,AX MOV SI1 READCOM:EQU 88H WRITECOM:EQU 0A8H ENDIF IF TARBELL DONEBIT:EQU 80H DISK: EQU 78H ENDIF IF CROMEMCO DONEBIT:EQSI,128 LOOP WRTLP OR AL,AL RET L ERROR: SEG CS MOV B,[DI],-1 RET L SEEK: ; Inputs: ; AL = Drive number ; AL,DAV RET L AUXIN: INP: IN STAT AND AL,DAV JZ INP IN DATA AND AL,7FH RET L AUXOUT: OUTP: PUSH AX OUTLPDI] ;Xchange current track with desired track OUT DISK+1 ;Inform controller chip of current track CMP AL,DL JZ ONTRK M,FCB MOV AH,15 INT 21H OR AL,AL JNZ COMERR MOV [FCB+33],0 MOV CX,200H MOV AH,39 ;Load file INT 21H JCXZ COMER ;Set auto-wait bit ENDIF MOV AH,AL ;Save for later XCHG AX,DX MOV DL,26 ;26 sectors per track IF CROMEMCO TEU 1 DISK: EQU 30H ENDIF DOSSEG: EQU 80H ORG 0 PUT 100H BASE: EQU 0F0H STAT: EQU BASE+7 DAV: EQU 2 TBMT: EQU 1 BX = Disk transfer address in DS ; CX = Number of sectors to transfer ; DX = Logical record number of transfer ; Function: ;: IN STAT AND AL,TBMT JZ OUTLP POP AX OUT DATA RET L PRINT: PUSH AX PRINLP: IN PSTAT AND AL,TBMT JZ PRINOV BH,3 ;Seek retry count CMP AL,-1 ;Head position known? JNZ NOHOME ;If not, home head TRYSK: CALL HOME NOHOME: MOR CMP AL,1 JNZ COMERR MOV DS,BX MOV ES,BX MOV SS,BX MOV SP,40H XOR AX,AX PUSH AX MOV DX,80H MOV AH,26 INT ST DH,10H ;Check if small disk JNZ BIGONE MOV DL,18 ;18 sectors on small disk track BIGONE: ENDIF DIV AL,DL ;Compu DATA: EQU BASE+6 PSTAT: EQU BASE+0DH PDATA: EQU BASE+0CH JMP INIT JMP STATUS JMP INP JMP OUTP JMP PRINT JMP AUX Seeks to proper track. ; Outputs: ; AH = Drive select byte ; DL = Track number ; DH = Sector number ; SI = Disk transfer aLP POP AX OUT PDATA RET L READ: CALL SEEK RDLP: PUSH CX CALL READSECT POP CX JC ERROR INC DH ADD SI,128 V AL,DL OUT DISK+3 MOV AL,1CH CALL MOVHEAD AND AL,98H JZ ONTRK DEC BH JNZ TRYSK STC ONTRK: RET SETUP: 21H PUSH BX MOV AX,100H PUSH AX RET L COMERR: MOV DX,BADCOM MOV AH,9 ;Print string INT 21H EI STALL: JP STALLte track and sector XCHG AX,DX INC DH ;First sector is 1, not zero SEG CS MOV BL,[BX+TRKPT] ;Get this drive's displacemIN JMP AUXOUT JMP READ JMP WRITE JMP RETL ;Flush buffers INIT: MOV AX,CS MOV DS,AX MOV SS,AX MOV SP,STACK Mddress in DS ; DI = pointer to drive's track counter in CS ; CX unchanged. MOV SI,BX ; Save transfer address CBW MOV LOOP RDLP OR AL,AL RETL: RET L WRITE: CALL SEEK WRTLP: PUSH CX CALL WRITESECT POP CX JC ERROR INC DH ADD IF CROMEMCO TEST AH,10H ;Check for small disk JNZ CHKSTP CMP DH,18 ;Only 18 sectors/track on small ones JA STEP CHKST BADCOM: DB 13,10,"Bad or missing Command Interpreter",13,10,"$" FCB: DB 1,"COMMAND COM" DS 24 STATUS: IN STAT AND ent into track table ADD BX,TRKTAB ;BX now points to track counter for this drive MOV DI,BX MOV AL,DL SEG CS XCHG AL,[OV SI,INITTAB CALL 0,DOSSEG MOV DX,100H MOV AH,26 ;Set DMA address INT 21H MOV BX,DS MOV AX,CS MOV DS,AX MOV DXBX,AX ; Prepare to index on drive number SEG CS MOV AL,[BX+DRVTAB] OUT DISK+4 ; Select drive IF CROMEMCO OR AL,80HP: ENDIF CMP DH,26 ;Check for overflow onto next track JBE PUTSEC STEP: INC DL MOV DH,1 MOV AL,58H ;Step in witK MOV AL,50 DELAY: DEC AL JNZ DELAY ;Delay 100 microseconds GETSTAT: IN DISK+4 TEST AL,DONEBIT IF TARBELL JNZ ENDIF IF CROMEMCO JNZ WRDONE ENDIF LODB OUT DISK+3 LOOP WRLOOP WRDONE: POP SI CALL GETSTAT AND AL,09CHB 0,40H,10H,50H TRKPT: DB 0,0,1,1 TRKTAB: DB -1,-1 ENDIF IF SNGL1SIDE DRVTAB: DB 0F2H,0E2H,0D2H,0C0H TRKPT: DB 0,1,2,3ET READSECT: CALL SETUP JC RET MOV BL,10 RDAGN: OR AL,READCOM OUT DISK PUSH SI RLOOP: IN DISK+4 TEST AL,DONWAIT MOV AL,7FH OUT 4 MOV AL,0 RET ENDIF DS 20H STACK: LFAT: EQU 300H SFAT: EQU 200H CURDRV: DS 1 LDRIVh update, no verify CALL DCOM SEG CS INC B,[DI] ;Update track counter PUTSEC: MOV AL,DH OUT DISK+2 MOV CX,80H GETSTAT ENDIF IF CROMEMCO JZ GETSTAT ENDIF IN DISK RET IF CROMEMCO RESTORE: MOV AL,0C4H ;READ ADDRESS c JZ RET MOV AL,0 DEC BL JNZ WRTAGN STC RET HOME: IF CROMEMCO TEST AH,10H ;Check 8" (PerSci) bit JNZ RESTOR TRKTAB: DB -1,-1,-1,-1 ENDIF IF TARBELL INITTAB:DB 4 ;Number of drives DW LDRIVE DW FAT0 DW LDRIVE DW FAT1 DWEBIT IF TARBELL JZ RDONE ENDIF IF CROMEMCO JNZ RDONE ENDIF IN DISK+3 MOV [SI],AL INC SI LOOP RLOOP RDE: DB 1 ;Records/sector DB 4 ;Records/cluster DW 52 ;Reserved records DB 6 ;FAT size (records) DB 2 ;Number of FATs IF TARBELL IN DISK ;Get head load bit ENDIF IF CROMEMCO IN DISK+4 ;Get head load bit XCHG AL,AH OUT DISK+4 ;Turommand to keep head loaded OUT DISK MOV AL,77H OUT 4 CHKRES: IN 4 AND AL,40H JZ RESDONE IN DISK+4 TEST AL,DONEBE ENDIF MOV BL,3 TRYHOM: MOV AL,0CH CALL DCOM AND AL,98H JZ RET MOV AL,58H ;Step in with update CALL DCOM D LDRIVE DW FAT2 DW LDRIVE DW FAT3 ORG 0 FAT0: DS LFAT FAT1: DS LFAT FAT2: DS LFAT FAT3: DS LFAT ENDIF ; CromeONE: POP SI CALL GETSTAT AND AL,9CH JZ RET MOV AL,0 DEC BL JNZ RDAGN STC RET WRITESECT: CALL SETUP JC RDB 8 ;Number of directory records DW 482 ;Number of clusters on drive SDRIVE: DB 1 DB 2 DW 54 DB 4 DB 2 DB 8 n on auto-wait XCHG AL,AH ENDIF NOT AL AND AL,20H ;Check head load status JZ CHKDRV MOV AL,4 CHKDRV: ; Turn on IT JZ CHKRES IN DISK JP RESTORE ;Reload head RESDONE: MOV AL,7FH OUT 4 CALL GETSTAT MOV AL,0 OUT DISK+1 ;TellEC BL JNZ TRYHOM RET MOVHEAD: IF CROMEMCO TEST AH,10H ;Check 8" (PerSci) bit JNZ FASTSK ENDIF DCOM: OUT DISmco drive select byte is derived as follows: ; Bit 7 = 0 ; Bit 6 = X (unassigned) ; Bit 5 = 1 (motor on) ; Bit 4 = 0 for 5",ET MOV BL,10 WRTAGN: OR AL,WRITECOM OUT DISK PUSH SI WRLOOP: IN DISK+4 TEST AL,DONEBIT IF TARBELL JZ WRDONEDW 330 IF DOUB1SIDE DRVTAB: DB 0,10H,20H,30H TRKPT: DB 0,1,2,3 TRKTAB: DB -1,-1,-1,-1 ENDIF IF DOUB2SIDE DRVTAB: D15ms head load delay if selecting a different drive SEG CS CMP AH,[CURDRV] SEG CS MOV [CURDRV],AH JZ RET OR AL,4 R 1771 we're now on track 0 RET FASTSK: MOV AL,6FH OUT 4 MOV AL,18H CALL DCOM SKWAIT: IN 4 TEST AL,40H JNZ SK 1 for 8" drives ; Bit 3 = 1 for drive 3 ; Bit 2 = 1 for drive 2 ; Bit 1 = 1 for drive 1 ; Bit 0 = 1 for drive 0 IF LARGT ENDIF  MOV [LAST],CX MOV DI,START-1 TEST B,[HAVEOF],-1 JNZ SAVEND CALL NUMRECS MOV [FCB+RR],0 MOV DX,FCB MOV AH,RDBLK W FAT2 ORG 0 FAT0: DS LFAT FAT1: DS LFAT FAT2: DS SFAT ENDIF IF SMALLCRO ; Table for 3 small drives DRVTAB: DB 21T 33 HAVFIL: MOV SI,FCB MOV DI,FCB2 MOV CX,9 REP MOVB MOV SI,BAK MOVW MOVB MOV AH,DELFIL MOV DX,FCB2 INT ECRO ; Table for four large drives DRVTAB: DB 31H,32H,34H,38H TRKPT: DB 0,0,1,1 TRKTAB: DB -1,-1 INITTAB:DB 4 ;Number of drFCB EQU 5CH RENAM EQU 23 OPEN EQU 15 CLOSE EQU 16 MAKE EQU 22 DELFIL EQU 19 RDBLK EQU 39 WRBLK EQU 40 SETDMA EQU 26 PRI INT 33 CMP AL,2 JZ TOOBIG JCXZ SAVEND ROR CX XCHG CL,CH ADD DI,CX ;Point to last byte DOWN MOV AL,1AH REPNE H,22H,24H TRKPT: DB 0,1,2 TRKTAB: DB -1,-1,-1 INITTAB:DB 3 DW SDRIVE DW FAT0 DW SDRIVE DW FAT1 DW SDRIVE DW FAT2 33 MOV AL,"$" MOV DI,FCB2+9 STOB STOB STOB MOV AH,DELFIL INT 33 ;Create .$$$ file to make sure directory has rooives DW LDRIVE DW FAT0 DW LDRIVE DW FAT1 DW LDRIVE DW FAT2 DW LDRIVE DW FAT3 ORG 0 FAT0: DS LFAT FAT1: DS NTBUF EQU 9 OUTCH EQU 2 INBUF EQU 10 RR EQU 33 PROMPT EQU "*" ORG 100H PUT 100H MOV SP,STACK MOV DX,BREAK MO SCAB JNZ NOTEOF REPE SCAB INC DI SAVEND: CLD INC DI MOV B,[DI],1AH MOV [ENDTXT],DI MOV B,[COMBUF],128 MOV ORG 0 FAT0: DS SFAT FAT1: DS SFAT FAT2: DS SFAT ENDIF IF CUSTOM ; Table for 2 large drives DRVTAB: DB 31H,32H TRm MOV AH,MAKE INT 33 OR AL,AL JZ SETUP MOV DX,NODIR JMP ERROR NOTBAK: MOV DX,NOBAK JMP ERROR TOOBIG: MOV DX,LFAT FAT2: DS LFAT FAT3: DS LFAT ENDIF IF COMBCRO ; Table for two large drives and one small one DRVTAB: DB 31H,32H,24V AX,2523H INT 33 MOV SI,BAK MOV DI,FCB+9 MOV CX,3 ;File must not have .BAK extension REPE CMPB JZ NOTBAK ;Ope B,[EDITBUF],255 MOV [POINTER],START MOV [CURRENT],1 COMMAND: MOV SP,STACK MOV AL,PROMPT CALL OUT MOV DX,COMBUF KPT: DB 0,1 TRKTAB: DB -1,-1 INITTAB:DB 2 DW LDRIVE DW FAT0 DW LDRIVE DW FAT1 ORG 0 FAT0: DS LFAT FAT1: DS LFATOBIG JMP ERROR NOTEOF: MOV DX,NOEOF JMP ERROR SETUP: MOV DX,START MOV AH,SETDMA INT 33 MOV CX,[6] SUB CX,80H H TRKPT: DB 0,0,1 TRKTAB: DB -1,-1 INITTAB:DB 3 ;Number of drives DW LDRIVE DW FAT0 DW LDRIVE DW FAT1 DW SDRIVE Dn input file MOV AH,OPEN MOV DX,FCB INT 33 MOV [HAVEOF],AL OR AL,AL JZ HAVFIL MOV DX,NEWFIL MOV AH,PRINTBUF IN MOV AH,INBUF INT 33 MOV AL,10 CALL OUT MOV [PARAM2],0 MOV B,[QFLG],0 MOV SI,2+COMBUF CALL GETNUM MOV [PARAM1],DCXZ RET REPNE SCAB INC DX CMP BX,DX JNZ FINLIN RET SHOWNUM: ; Inputs: ; BX = Line number to be displayed ;W ENDED DW INSERT DW LIST DW DELETE DW COMERR DW COMERR FINDLIN: ; Inputs ; BX = Line number to be located in bY MOV DI,21 JP DISPLAY DISPONE: MOV DI,1 DISPLAY: ; Inputs: ; BX = Line number ; SI = Pointer to text buffer NUMLP: CMP AL,"0" JB RET CMP AL,"9" JA RET SUB AL,"0" MOV BX,DX SHL DX SHL DX ADD DX,BX SHL DX CBW ADD HG AL,AH ADC AL,AL DAA XCHG AL,AH ADC DL,DL LOOP CONV MOV BL,"0"-" " XCHG AX,DX CALL LDIG MOV AL,DH CALL DIGX CALL SKIP1 CMP AL,"," JNZ CHKNXT INC SI CHKNXT: DEC SI CALL GETNUM MOV [PARAM2],DX CALL SKIP1 CMP AL,"?" Function: ; Displays line number on terminal in 8-character ; format, suppressing leading zeros. ; AX, CX, DX destroyed. No uffer (0 means last line) ; Outputs: ; DX = Actual line found ; DI = Pointer to start of line DX ; Zero set if BX = DX ; AL ; DI = No. of lines ; Function: ; Ouputs specified no. of line to terminal, each ; with leading line number. ; Outputs: ; DX,AX LODB JP NUMLP CURLIN: MOV DX,[CURRENT] LODB RET MAXLIN: MOV DX,-1 LODB RET COMTAB DB "SFDLIE",13 ITS MOV AL,DL DIGITS: MOV DH,AL SHR AL SHR AL SHR AL SHR AL CALL LDIG MOV AL,DH LDIG: AND AL,0FH JZ ZERDIGJNZ DISPATCH MOV [QFLG],AL CALL SKIP DISPATCH: AND AL,5FH MOV DI,COMTAB MOV CX,NUMCOM REPNE SCAB JNZ COMERR Mother registers affected. PUSH BX MOV AL," " CALL OUT CALL CONV10 MOV AL,":" CALL OUT MOV AL," " CALL OUT PO,CX destroyed. No other registers affected. MOV DX,[CURRENT] MOV DI,[POINTER] CMP BX,DX JZ RET JA FINDIT MOV DX,1 BX = Last line output. ; All registers destroyed. MOV CX,[ENDTXT] SUB CX,SI JZ RET MOV BP,[CURRENT] DISPLN: PUSH C NUMCOM EQU $-COMTAB ;-----------------------------------------------------------------------; ; Carefull changing the ord MOV BL,0 ZERDIG: ADD AL,"0" SUB AL,BL JMP OUT LIST: MOV BX,[PARAM1] OR BX,BX JNZ CHKP2 MOV BX,[CURRENT] OV BX,CX SHL BX CALL [BX+TABLE] JMP COMMAND SKIP: LODB SKIP1: CMP AL," " JZ SKIP RET COMERR: MOV DX,BADCOP BX RET CONV10: ;Inputs: ; BX = Binary number to be displayed ; Function: ; Ouputs binary number. Five digits with MOV DI,START CMP BX,DX JZ RET FINDIT: MOV CX,[ENDTXT] SUB CX,DI MOV AL,10 OR AL,AL ;Clear zero flag FINLIN: JX CALL SHOWNUM POP CX OUTLN: LODB CALL OUT CMP AL,10 LOOPNZ OUTLN JCXZ RET DEC DI JZ RET CMP BX,BP LAHF er of the next two tables. They are ; linked and chnges should be be to both. TABLE DW NOCOM ;No command--edit line D SUB BX,10 JA CHKP2 MOV BX,1 CHKP2: CALL FINDLIN JNZ RET MOV SI,DI MOV DI,[PARAM2] INC DI SUB DI,BX JA DISPLAM MOV AH,PRINTBUF INT 33 JP COMMAND GETNUM: CALL SKIP CMP AL,"." JZ CURLIN CMP AL,"#" JZ MAXLIN MOV DX,0 leading ; zero suppression. Zero prints 5 blanks. XOR AX,AX MOV DL,AL MOV CX,16 CONV: SHL BX ADC AL,AL DAA XC INC BX SAHF JZ OUTLF CMP BX,BP JNZ DISPLN OUTLF: MOV AL,10 CALL OUT JP DISPLN RET: RET NOCOM: MOV BX,[PAR CX,CX JP REPLACE GETTEXT: ; Inputs: ; SI points into command line buffer ; DI points to result buffer ; Function: ADD AX,CX CMP AX,[LAST] JAE MEMERR XCHG AX,[ENDTXT] MOV CX,AX SUB CX,SI CMP SI,DI JA DOMOV ADD SI,CX ADD DI, MOV [POINTER],DI MOV [CURRENT],BX MOV SI,BP INC SI MOV CX,[LAST] SUB CX,BP REP MOVB DEC DI MOV [ENDTXT],DI CXZ RET MOV DL,[OLDLEN] MOV DH,0 MOV SI,2+EDITBUF MOV DI,[POINTER] REPLACE: ; Inputs: ; CX = Length of new text LL FINDLIN MOV CX,[ENDTXT] ;Get End-of-text marker MOV SI,CX SUB CX,DI ;Calculate number of bytes to copy INC CX MORAM1] OR BX,BX JNZ HAVLIN MOV BX,[CURRENT] INC BX ;Default is current line plus one HAVLIN: CALL FINDLIN MOV SI,DI ; Moves [SI] to [DI] until ctrl-Z (1AH) or ; RETURN (0DH) is found. Termination char not moved. ; Outputs: ; AL = TerminatiCX STD DOMOV: INC CX REP MOVB CLD POP CX POP DI POP SI COPYIN: REP MOVB RET DELETE: MOV BX,[PARAMRET ENDED: ;Write text out to .$$$ file MOV DI,[ENDTXT] MOV CX,128 MOV AL,1AH REP STOB MOV CX,[ENDTXT] CALL NU; DX = Length of original text ; SI = Pointer to new text ; DI = Pointer to old text in buffer ; Function: ; New text replacV DI,[LAST] DOWN REP MOVB XCHG SI,DI UP INC DI MOV BP,SI MOV BX,DX INLP: CALL SHOWNUM MOV DX,EDITBUF MOV MOV [CURRENT],DX MOV [POINTER],SI JNZ RET CMP SI,[ENDTXT] JZ RET MOV DI,2+EDITBUF MOV CX,254 MOV DL,-1 LOADLP: on character ; CX = No of characters moved. ; SI points one past termination character ; DI points to next free location 1] OR BX,BX JNZ DELFIN1 MOV BX,[CURRENT] DELFIN1: CALL FINDLIN JNZ RET MOV [CURRENT],BX MOV [POINTER],DI PUSH DMRECS INC CX MOV [FCB2+RR],0 MOV DX,FCB2 MOV AH,WRBLK INT 33 OR AL,AL JNZ WRTERR ;Close .$$$ file MOV AH,CLOSE es old text in buffer and buffer ; size is adjusted. CX or DX may be zero. ; CX, SI, DI all destroyed. No other registers affeAH,INBUF INT 33 MOV AL,10 CALL OUT MOV SI,EDITBUF+2 CMP B,[SI],1AH JZ ENDINS MOV CL,[SI-1] MOV CH,0 MOV DX,SI LODB STOB INC DL CMP AL,13 LOOPNZ LOADLP MOV [EDITBUF+1],DL MOV [OLDLEN],DL MOV SI,[POINTER] CALL DISPONE CAXOR CX,CX GETIT: LODB CMP AL,1AH JZ RET CMP AL,0DH JZ RET STOB INC CX JP GETIT MEMERR: MOV DX,MEMFUL MI MOV BX,[PARAM2] OR BX,BX JNZ DELFIN2 MOV BX,DX DELFIN2: INC BX CALL FINDLIN MOV DX,DI POP DI SUB DX,DI XO INT 33 MOV SI,FCB LEA DI,[SI+16] MOV DX,SI MOV CX,9 REP MOVB MOV SI,BAK MOVW MOVB ;Rename original file .BActed. CMP CX,DX JZ COPYIN PUSH SI PUSH DI PUSH CX MOV SI,DI ADD SI,DX ADD DI,CX MOV AX,[ENDTXT] SUB AX,DX ADD DX,CX INC DX CMP DX,BP ;Will it fit? JNC MEMERR REP MOVB MOVB MOV AL,10 STOB INC BX JP INLP ENDINS: LL SHOWNUM MOV AH,INBUF ;Get input buffer MOV DX,EDITBUF INT 33 MOV AL,10 CALL OUT MOV CL,[EDITBUF+1] MOV CH,0 JOV AH,PRINTBUF INT 33 JMP COMMAND INSERT: MOV BX,[PARAM1] OR BX,BX JNZ INS MOV BX,[CURRENT] INC BX INS: CAK MOV AH,RENAM INT 33 MOV SI,FCB MOV DI,FCB2+16 MOV CX,6 REP MOVW ;Rename .$$$ file to original name MOV DX,FCBnt MOV CL,AL MOV CH,0 JCXZ DONE CALL GETBYT ;Get high byte of load address MOV BH,AL CALL GETBYT ;Get low byte of SE: EQU 16 CREATE: EQU 22 DELETE: EQU 19 BLKWRT: EQU 40 BUFFER: EQU 80H BUFSIZ: EQU 128 ORG 100H PUT 100H HEX2BIN:TDMA INT 33 MOV CX,BP SUB CX,START-7FH AND CL,80H JCXZ EXIT ROL CX XCHG CL,CH MOV AH,BLKWRT MOV DX,FCB INT 3d$" MEMFUL: DB 13,10,"Memory full",13,10,"$" BADCOM: DB "Entry error",13,10,"$" NEWFIL: DB "New file",13,10,"$" FCB2: DS 36 MOV SI,BUFFER NOREAD: LODB CMP AL,1AH JZ DONE RET GETBYT: CALL HEXDIG MOV BL,AL CALL HEXDIG SHL BL SHL B2 INT 33 JMP 0 WRTERR: MOV DX,DSKFUL ERROR: MOV AH,PRINTBUF INT 33 JMP 0 NUMRECS: SUB CX,START AND CL,8load address MOV BL,AL ADD BX,START-100H ;Add in offset MOV DI,BX CALL GETBYT ;Throw away type byte READLN: CMP DI,[ MOV DI,FCB+9 CMP B,[DI]," " JNZ HAVEXT MOV SI,HEX MOVB MOVW HAVEXT: ;Get load offset (default is -100H) MOV AH,3 MOV AH,CLOSE INT 33 EXIT: INT 32 NOROOM: MOV DX,DIRFUL JMP QUIT HEX: DB "HEX" COM: DB "COM" ERRMES: DB "Err PARAM1: DS 2 PARAM2: DS 2 QFLG: DS 1 HAVEOF: DS 1 OLDLEN: DS 1 CURRENT: DS 2 POINTER: DS 2 LAST: DS 2 ENDTXT: DS 2 COML SHL BL SHL BL OR AL,BL RET HEXDIG: CALL GETCH SUB AL,"0" JC ERROR CMP AL,9 JBE RET SUB AL,"A"-"0"-10 0H ROL CX XCHG CL,CH RET OUT: PUSH DX XCHG AX,DX MOV AH,OUTCH INT 33 XCHG AX,DX POP DX RET BREAK: IR6] JAE ADERR CMP DI,START JB ADERR CALL GETBYT ;Get data byte STOB LOOP READLN CMP DI,BP ;Check if this is the lOPEN MOV DX,FCB INT 33 OR AL,AL JNZ NOFIL MOV B,[FCB+32],0 MOV AH,READ MOV BP,START MOV SI,BUFFER+BUFSIZ ;Flag ior in HEX file--conversion aborted$" NOFILE: DB "File not found$" ADDR: DB "Address out of range--conversion aborted$" DIRFULBUF: DS 2+128 EDITBUF: DS 2+255 DS 40 ALIGN STACK: START: JC ERROR CMP AL,15 JBE RET ERROR: MOV DX,ERRMES MOV AH,9 INT 33 DONE: MOV DI,FCB+9 MOV SI,COM MOVB MOVW MOET BAK: DB "BAK" NOBAK: DB "Cannot edit .BAK file--rename file$" NODIR: DB "No room in directory for file$" TOBIG: DB "Fargest address so far JBE READHEX MOV BP,DI ;Save new largest JP READHEX NOFIL: MOV DX,NOFILE QUIT: MOV AH,9 INnput buffer as empty READHEX: CALL GETCH CMP AL,":" ;Search for : to start line JNZ READHEX CALL GETBYT ;Get byte cou: DB "Disk directory full$" START: ; HEX2BIN ; Converts Intel hex format files to straight binary FCB: EQU 5CH READ: EQU 20 SETDMA: EQU 26 OPEN: EQU 15 CLOV DX,FCB MOV AH,DELETE INT 33 MOV AH,CREATE INT 33 OR AL,AL JNZ NOROOM MOV W,[FCB+33],0 MOV DX,START MOV AH,SEile too big to fit into memory$" NOEOF: DB "No end-of-file mark found in file$" DSKFUL: DB "Disk full--file write not completeT 33 INT 32 ADERR: MOV DX,ADDR JMP ERROR GETCH: CMP SI,BUFFER+BUFSIZ JNZ NOREAD INT 33 OR AL,AL JNZ ERROR DEC AX CMP AL,[DRIVE] JZ BADPARM MOV CL,DELETE MOV DX,DSTFCB CALL SYSTEM MOV CL,MAKE MOV DX,DSTFCB CALL SYSTEM JZ NONAME XOR AL,AL XCHG AL,[FCB] OR AL,AL JNZ HASDRV MOV CL,GETDRV CALL SYSTEM INC AX HASDRV: DEC AX MOV DONE: MOV CL,CLOSE MOV DX,DSTFCB CALL SYSTEM JMP 0 ;Read allocation block READSEC: XOR DX,DX MOV BX,[BP+SPT] AH,0 TEST B,[BP+DSISIZ+1],0FFH JZ SMALDSK MOV AH,[SI] ;Big disk, use words instead INC SI DEC CX SMALDSK: OR AX MOV CL,SETDMA MOV DX,SECBUF CALL SYSTEM BEGDIR: XOR AX,AX MOV BX,[BP+NUMENT] READDIR: MOV DI,DIRBUF PUSH AX [DRIVE],AL CMP AL,15 JA INVSRC ;Invalid drive number CBW MOV BX,AX SHL BX MOV BP,[BX+CPMTAB] OR BP,BP JZ INVSRDIV AX,BX ADD AX,[BP+RESTRK] MOV CX,DX MUL AX,BX ;Tracks in sectors MOV DX,AX OR BH,BH ;Check for >255 sectors per tFCB EQU 5CH FCB2 EQU 6CH OPEN EQU 15 CLOSE EQU 16 MAKE EQU 22 DELETE EQU 19 SEQWRT EQU 21 SETDMA EQU 26 GETDRV EQU 25 P,AX JZ DONE PUSH CX MOV CH,0 PUSH SI MOV CL,[BP+BLKSFT] SHL AX,CL RDALOC: PUSH AX OR AL,CH PUSH CX MOV DI PUSH BX CALL READSEC POP BX POP AX MOV SI,DIRBUF ENUMDIR: MOV DI,FCB MOV CX,13 REPE CMPB JZ RDENTRY ADD C MOV SI,FCB2 MOV DI,DSTFCB MOVB CMP B,[FCB2+1]," " JNZ HASDST MOV SI,FCB+1 HASDST: MOV CX,11 REP MOVB ;Crack JNZ BIGTRK ;Use words instead of bytes for xlat table MOV AX,CX MOV BX,[BP+XLTTBL] XLAT ADD DX,AX ;Logical sectRINTBUF EQU 9 SYSTEM EQU 5 ORG 100H PUT 100H JMP RDCPM CPMTAB: DW IBM,IBM,IBM,IBM DW 0,0,0,0 DW 0,0,0,0 DW,SECBUF CALL READSEC MOV CL,SEQWRT MOV DX,DSTFCB CALL SYSTEM POP CX POP AX INC CH CMP CH,[BP+BLKMSK] JBE RDALOSI,CX ADD SI,19 ;Point to next entry DEC BX JS DONE CMP SI,DIRBUF+128 JB ENUMDIR INC AX JP READDIR BADPARM: opy file name MOV AL,[DSTFCB] OR AL,AL JNZ DSTDRV MOV CL,GETDRV CALL SYSTEM ;Use default drive INC AX DSTDRV: or number READABS: MOV CX,1 MOV BX,DI MOV AL,[DRIVE] PUSH BP INT 37 POP AX POP BP JNC RDDONE MOV DX,DSKERR 0,0,0,0 INVSRC: MOV DX,BADSRC JMP EXIT NONAME: MOV DX,BADFN JMP EXIT RDCPM: MOV SP,100H CMP B,[FCB+1]," " C POP SI POP CX LOOP RDNXTAL INC B,[FCB+12] ;Increment extent counter JMP BEGDIR ;Scan from beginning of directory MOV DX,SAMDSK JMP EXIT RDENTRY: ADD SI,3 ;Point to AL array MOV CX,16 ;16 AL bytes per entry RDNXTAL: LODB MOV EXIT: MOV CL,PRINTBUF CALL SYSTEM JMP 0 ;Translation table made up of WORDs BIGTRK: MOV BX,CX SHL BX ADD BX,[L JZ BADDRV DEC AL JZ BADDRV MOV [FCB],AL MOV CX,[SECS] MOV DX,0 MOV BX,END MOV AL,0 INT 37 JC RDERR POPF ,0 DW 0,0,0,0 DW 0,0,0,0 DW 0,0,0,0 D: EQU 20 WRITE: EQU 21 PRNBUF: EQU 9 MOV SP,STACK MOV DX,HEADER MOV CL,9 CALL SYSTEM MOV BX,FCB+12 XOR AL,AL MOhe definition for standard single-density 8" drives IBM: DW 26 ;Sectors per track DB 3 ;Block shift DB 7 ;Block mask BP+XLTTBL] ADD DX,[BX] JP READABS RDDONE: RET DSKERR: DB 13,10,"HARD DISK ERROR",13,10,"$" SAMDSK: DB 13,10,"Source MOV CX,[SECS] MOV DX,0 MOV BX,END MOV AL,[FCB] MOV AH,1 INT 38 JC WRERR MOV DX,SYSOK JP QUIT RDERR: MOV DV CH,4 CLRFCB: MOV [BX],AL INC BX DEC CH JNZ CLRFCB MOV [FCB+32],AL MOV BX,FCB MOV DX,PUTFCB MOV CX,16 UP MDB 0 ;Extent mask DW 242 ;Disk size - 1 DW 63 ;Directory entries - 1 DB 0C0H ;Directory allocation bitmap 0 DB 0 ;Direct and destination drives must not be the same",13,10,"$" BADSRC: DB 13,10,"Bad source drive",13,10,"$" BADFN: DB 13,10,"Bad filX,ERREAD QUIT: MOV AH,9 INT 33 INT 32 WRERR: MOV DX,ERWRIT JP QUIT BADDRV: MOV DX,DRVBAD JP QUIT SYSOKOV SI,BX MOV DI,DX REP MOVB MOV DX,DI MOV BX,SI MOV [PUTFCB+32],AL MOV BX,"A"+5300H ;"AS" MOV [PUTFCB+9],BX MOory allocation bitmap 1 DW 16 ;Directory check vector size DW 2 ;Tracks to skip DW MOD6 ;Modulo-6 sector translate table ; Z80 to 8086 Translator version 2.0 ; Runs on the 8086 under 86-DOS ; by Tim Paterson ; ORG 100H EOF: EQU 1AH ;End of fe name",13,10,"$" DRIVE: DS 1 DSTFCB: DS 32 DB 0 DIRBUF: DS 128 SECBUF: DS 128 SPT EQU 0 BLKSFT EQU 2 BLKMSK EQU 3 E: DB "System transfered$" ERREAD: DB "Disk read error$" ERWRIT: DB "Disk write error$" DRVBAD: DB "Bad drive specification" FCB EQU 5CH ORG 100H PUT 100H JMP START SECS: DW 52 ;Patch for different configs START: MOV AL,[FCB] OR AL,AV AL,'M' MOV [PUTFCB+11],AL MOV DX,FCB MOV CL,OPEN CALL SYSTEM INC AL MOV DX,NOFILE JZ ABORTJ MOV DX,PUTFCB MO MOD6: DB 0,6,12,18,24 DB 4,10,16,22 DB 2,8,14,20 DB 1,7,13,19,25 DB 5,11,17,23 DB 3,9,15,21 CPMTAB2: DW 0,0,0ile EOL: EQU 0DH FCB: EQU 5CH SYSTEM: EQU 5 OPEN: EQU 15 CLOSE: EQU 16 SETDMA: EQU 26 CREATE: EQU 22 DELETE: EQU 19 REAXTMSK EQU 4 DSISIZ EQU 5 NUMENT EQU 7 ALBMP0 EQU 9 ALBMP1 EQU 10 DIRCKS EQU 11 RESTRK EQU 13 XLTTBL EQU 15 ;Below is t END: V CL,DELETE CALL SYSTEM MOV DX,PUTFCB MOV CL,CREATE CALL SYSTEM INC AL MOV DX,NOROOM ABORTJ: JZ ABORT MOV DX,PU MOV DX,GETBUF ; Set `DMA address'. MOV CL,SETDMA CALL SYSTEM MOV DX,FCB ; Read the next record from source file. MOV CX,[PUTPT] MOV [BX],AL LAHF INC BX SAHF MOV [PUTPT],BX CMP BX,PUTBUF+80H JNZ POPRET MOV DX,PUTBUF MOV [PUTPT],DAL LAHF XCHG AX,BP SAHF MOV B,[BX],']' JP NEXCH NOTRIT: MOV [BX],AL CMP AL,'''' JZ EATQUO CALL IDCHK JNC GEV CH,127 MOV AL,1AH FILL: CALL PUTCH DEC CH JNZ FILL MOV DX,PUTFCB MOV CL,CLOSE CALL SYSTEM MOV DX,ENDMES ABORCALL PUTCH LOADOP: MOV BX,OPCODE EATEM: CALL DELIM JZ EATEM LOADLP: CALL IDCHK JNC $+5 JMP OPERR MOV [BX],AL TFCB MOV CL,OPEN CALL SYSTEM MOV BX,PUTBUF MOV [PUTPT],BX MOV BX,GETBUF+80H MOV [GETPT],BX TRANLN: XOR AL,AL MOL,READ CALL SYSTEM OR AL,AL ; Entire record read OK? MOV AL,EOF ; Force end-of-file character in case JNZ TESEND ; tX MOV CL,SETDMA CALL SYSTEM MOV DX,PUTFCB MOV CL,WRITE CALL SYSTEM OR AL,AL MOV DX,WRTERR JNZ ABORT POPRET: PTID NEXCH: INC BX CALL GETCH IDRET: CALL DELCHK JNZ OPCHAR CMP AL,' ' JZ OPCHAR RET EATQUO: INC BX CALL GETT: MOV CL,PRNBUF CALL SYSTEM JMP 0 DELIM: CALL GETCH DELCHK: CMP AL,EOL JZ DOLIN CMP AL,EOF JZ DOLIN CMP AL,INC BX CALL DELIM JNZ LOADLP MOV B,[BX],0 CMP AL,':' JNZ RET MOV BX,OPCODE CALL TRANS JP ENLAB GETOP: XOR AL,V [OP1],AL MOV [OP2],AL MOV BX,OPCODE CALL LOAD MOV BX,OP1 CALL GETOP MOV B,[BX],0 MOV BX,OP2 CALL GETOP DOLIN:here is nothing in the record. MOV BX,GETBUF ; Reset buffer pointer. GETIT: MOV AL,[BX] ; Get next character from buffer. OP AX XCHG AH,AL SAHF NOTAF: POP CX POP DX POP BX RET ; ; Get character from source file. ; GETCH: PUSH BX CH MOV [BX],AL CMP AL,';' JZ L0000 CALL DELCHK L0000: CMP AL,'''' JNZ EATQUO JP NEXCH IDCHK: CMP AL,'0' JC ';' JZ DOLIN CMP AL,' ' JZ RET CMP AL,':' JZ RET CMP AL,',' JZ RET CMP AL,9 RET HEX: AND AL,0FH ADD AL,90AL LAHF XCHG AX,BP SAHF GETLP: CALL DELIM JZ GETLP OPCHAR: CMP AL,'(' JNZ NOTLEF LAHF XCHG AX,BP SAHF IN MOV B,[BX],0 CALL FINDOP ENLIN: MOV SP,STACK MOV AL,[CHAR] CMP AL,';' JNZ NOCOM MOV AL,9 CALL PUTCH MOV AL,' LAHF INC BX ; Point to next character. SAHF MOV [GETPT],BX ; Save new pointer. TESEND: MOV [CHAR],AL JP NOTAF ; PPUSH DX PUSH CX MOV BX,[GETPT] ; Get buffer pointer. CMP BX,GETBUF+80H ; Past end-of-buffer? JNZ GETIT ; Jump if not. RET CMP AL,'9'+1 CMC JNC RET CMP AL,40H JC RET AND AL,5FH CMP AL,'A' JC RET CMP AL,'Z'+1 CMC RET GETID: H DAA ADC AL,40H DAA PUTCH: PUSH BX PUSH DX PUSH CX LAHF XCHG AH,AL PUSH AX XCHG AH,AL AND AL,7FH MOV BC AL LAHF XCHG AX,BP SAHF MOV B,[BX],'[' JP NEXCH NOTLEF: CMP AL,')' JNZ NOTRIT LAHF XCHG AX,BP SAHF DEC ;' NOCOM: CALL PUTCH PUTLIN: CMP AL,EOF JZ END CALL GETCH CALL PUTCH CMP AL,10 JNZ PUTLIN JP TRANLN END: MOop registers and return. LOAD: CALL DELIM JZ LOADOP EATLAB: CALL PUTCH CALL DELIM JNZ EATLAB ENLAB: MOV AL,':' MOV [BX],AL MOV CH,1 LODID: INC BX CALL GETCH CALL IDCHK JC RWCHK MOV [BX],AL INC CH JP LODID RWCHK: LAHF [BX] MOV BX,[BX+2] JMP DX NEXOP: RCR SI TEST B,[BX],080H RCL SI LAHF INC BX SAHF JZ NEXOP MOV DX,4 LAHF MOV BX,DI JNZ OPERR MOV AL,4 SUB AL,CL JZ RET DEC AL JZ OPERR MOV CL,AL DEC BX DEC BX OR B,[BX],080H MO XCHG DX,BX MOV BX,OP2 JZ GETPORT MOV BX,SAVEAX CALL OUTSTR CALL OUTSTR MOV BX,OP2 CALL GETPORT MOV BX,MOV0 C SAHF JMP IDRET HAVRW: POP BX INC CL MOV [BX],CL INC BX POP DX PUSH BX MOV AL,CL MOV BX,IXSI CMP AL,RSI CMP AL,20H ;Could be immediate? MOV AL,9 JC L0001 CALL BFLAG ;Add "B," L0001: CALL TRAN1 JP TRNOP2 TWOOPS: C XCHG AH,AL PUSH AX XCHG AH,AL PUSH BX DEC BX DEC CH MOV DL,CH JZ LOOKRW MOV DL,[BX] DEC BX DEC CH JNZ NOR ADD BX,DX RCR SI SAHF RCL SI JP LOOKOP OPERR: MOV BX,OPCODE CALL OUTSTR CALL TWOOPS MOV BX,OPCDER CALL OUTSTV AL,[OPCODE] SUB AL,'A' JC OPERR ADD AL,AL MOV DL,AL MOV DH,0 MOV BX,OPTAB LAHF ADD BX,DX RCR SI SAHF RCLALL ONEOP MOV AL,',' CALL PUTCH MOV AL,RAL CALL TRNTOK IODONE: MOV BX,RESTAX JMP OUTSTR OUT: MOV AL,[OP2] XCHG JZ IXIY MOV BX,IYDI CMP AL,RDI JNZ NORW IXIY: LAHF XCHG AX,BP SAHF JZ NOTENC LAHF XCHG AX,BP SAHF CALL OALL TRNOP1 TRNOP2: MOV AL,',' TRAN2: MOV BX,OP2 PTRANS: CALL PUTCH TRANS: MOV AL,[BX] LAHF INC BX SAHF OR ALW LOOKRW: MOV AL,[BX] MOV DH,AL PUSH BX MOV BX,RWTAB MOV CX,LENRW RWLK: UP MOV DI,BX REPNZ SCAB MOV BX,DI R JMP ENLIN LD: CALL OUTSTR MOV BX,OP1 MOV DX,OP2+1 CALL LCHECK JNZ $+5 JMP LDAX XCHG DX,BX DEC BX INC DX SI MOV DL,[BX] INC BX MOV DH,[BX] XCHG DX,BX MOV AL,9 CALL PUTCH LOOKOP: MOV AL,[BX] OR AL,AL JZ OPERR MOV DX,BX MOV BX,OP1 CMP AL,RAL JZ GETOUT MOV BX,SAVEAX CALL OUTSTR MOV BX,MOVAL CALL OUTSTR CALL TRNOP2 MOV BX,CUTSTR JP NORW NOTENC: LAHF XCHG AX,BP SAHF POP BX DEC BX MOV B,[BX],'[' INC BX ADD AL,RIX-1 MOV [BX],AL I,AL JZ RET CALL TRNTOK JP TRANS LCHECK: MOV AL,[BX] CMP AL,RAL JNZ RET MOV SI,DX LODB CMP AL,RCX JZ RET C JNZ NOTRW PUSH BX PUSH CX MOV CX,LENRW-1 LAHF ADD BX,CX RCR SI SAHF RCL SI MOV AL,[BX] POP CX POP BX C CALL LCHECK JNZ $+5 JMP STAX ;If immediate move, check for byte memory reference MOV AL,[OP1] CMP AL,'[' ;Memory refe DX,OPCODE+1 MOV CH,CL LOOKLP: MOV SI,DX LODB CMP AL,[BX] JNZ NEXOP INC DX INC BX DEC CH JNZ LOOKLP MOV DX,RLFTB CALL OUTSTR MOV BX,OP1 CALL GETOUT JP IODONE GETPORT: MOV AL,[BX] CMP AL,'[' JNZ NOBRAK LAHF INC BX SNC BX MOV B,[BX],']' INC BX JP ENDRW RET FINDOP: MOV BX,OPCODE MOV CX,5 XOR AL,AL UP MOV DI,BX REPNZ SCABMP AL,RDX RET ONEOP: CALL OUTSTR TRNOP1: MOV AL,9 TRAN1: MOV BX,OP1 JP PTRANS IN: MOV AL,[OP1] CMP AL,RAL MP AL,DL JZ HAVRW MOV AL,CL OR AL,AL MOV AL,DH JNZ RWLK NOTRW: POP BX NORW: POP BX ENDRW: POP AX XCHG AH,ALrence? JNZ TWOOPS MOV AL,[OP1+1] ;Referencing IX as a word? CMP AL,RIX JZ TWOOPS CMP AL,RIY JZ TWOOPS MOV AL,[OP2]AHF PUSH BX MOV CX,80 MOV AL,']' UP MOV DI,BX REPNZ SCAB MOV BX,DI LAHF DEC BX SAHF MOV B,[BX],0 POP B CALL OUTSTR XCHG DX,BX MOV BX,OPCODE-1 CALL ONEOP XCHG DX,BX OUTSTRJ: JMP OUTSTR JUMP: MOV AL,[OP1] CMP AL,'['STR MOV BX,BLMOVE JP OUTSTR CPDR: CALL OUTSTR MOV BX,CMPREP JP OUTSTR ADD: MOV AL,[OP1] CMP AL,RBX JZ DAD ARI MOV AL,[OP1+1] CMP AL,STP JZ XTHL MOV BX,XCHG CALL OUTSTR JMP TWOOPS XTHL: MOV BX,XTHL1 CALL OUTSTR CALL TRNOP ADD BX,CX RCR SI SAHF RCL SI LAHF ADD BX,CX RCR SI SAHF RCL SI MOV AL,[BX] CALL PUTCH INC BX MOV AL,[[OP2+2],BX JP DIRECT ONEOPJ1: JMP ONEOP DOCALL: MOV AL,[OP2] OR AL,AL JZ ONEOPJ1 CALL FIXCON DEC AL XOR AL,1 X NOBRAK: MOV AL,[BX] CMP AL,RGCL JNZ FIXPOR MOV BX,IO1 CALL OUTSTR XCHG DX,BX CALL OUTSTR MOV AL,RDX CALL TR JNZ DIRECT MOV AL,[OP1+1] MOV [OP1],AL XOR AL,AL MOV [OP1+1],AL DIRECT: MOV AL,[OP2] OR AL,AL JZ ONEOPJ CALLTH: CALL OUTSTR MOV AL,[OP2] OR AL,AL JZ $+5 JMP TWOOPS MOV AL,9 CALL PUTCH MOV AL,RAL CALL TRNTOK MOV AL,',2 MOV BX,XTHL2 OUTSTRJ1: JMP OUTSTR PSEUDO: CALL ONEOP MOV AL,[OP2] OR AL,AL JZ RET JMP TRNOP2 RET BITSET: BX] POP CX POP BX OR AL,AL JZ RET JMP PUTCH PUSH: MOV DX,PUSHAF JP AFCHK POP: MOV DX,POPAF AFCHK: MOV AL,[O INC AL MOV BX,LABEL CALL OUTCON MOV BX,OPCODE-1 CALL OUTSTR MOV AL,[OP2] OR AL,AL MOV AL,9 MOV BX,OP2 JZ L000NTOK MOV BX,IO2 JMP OUTSTR GETOUT: CALL GETPORT JNC RET MOV BX,BADIO JMP OUTSTR FIXPOR: XCHG DX,BX CALL OUTSTR FIXCON MOV BX,OP2 OUTCON: MOV CH,AL MOV AL,'J' CALL PUTCH MOV AL,CH CALL TRNTOK MOV AL,9 CALL PTRANS MOV AL,' JMP TRAN1 ACCUM: CALL OUTSTR MOV AL,9 CALL PUTCH MOV AL,RAL JMP TRNTOK ONEOPJ: JMP ONEOP DAD: MOV BX,DAD1 CMOV CL,0 JP SETRES RES: MOV CL,-1 SETRES: CALL OUTSTR PUSH BX MOV AL,[OP2] CMP AL,'[' MOV AL,9 JNZ L0004 CALP1] CMP AL,RAX JNZ ONEOPJ XCHG DX,BX OUTSTR: MOV AL,[BX] OR AL,AL JNZ L0002 CALL NEWOP L0002: CALL PUTCH IN3 CALL PTRANS L0003: MOV BX,CRLF CALL OUTSTR CALL TRANS CALL OUTSTR MOV BX,LABEL+4 NEXLAB: INC [BX] MOV AL,[B XCHG DX,BX JMP TRANS LDAX: MOV BX,LDAX1 LSAX: CALL OUTSTR MOV SI,DX LODB CALL TRNTOK JP OUTSTR STAX: MOV BCH CMP AL,ODDPAR MOV BX,WARNPA JZ OUTSTRJ CMP AL,EVEPAR JZ OUTSTRJ RET FIXCON: MOV AL,[OP1] CMP AL,RGCL JNZ RALL OUTSTR CALL TWOOPS MOV BX,DAD2 JP OUTSTR INCDEC: MOV AL,[OP1] CMP AL,RCX+1 ;16-bit? JNC ONEOPJ MOV BX,LAHF L BFLAG L0004: CALL TRAN2 MOV AL,',' CALL PUTCH CALL GETBIT MOV BX,BITERR JNC L0005 CALL OUTSTR L0005: POP BC BX ADD AL,AL JNC OUTSTR RET NEWOP: MOV AL,13 CALL PUTCH MOV AL,10 CALL PUTCH MOV AL,9 RET LDDR: CALL OUTX] CMP AL,'9'+1 JNZ RET MOV B,[BX],'0' LAHF DEC BX SAHF JP NEXLAB EX: MOV AL,[OP1] CMP AL,RAX JZ OUTSTRJ1 X,STAX1 JP LSAX TRNTOK: CMP AL,' ' JC $+5 JMP PUTCH PUSH BX PUSH CX MOV CL,AL MOV CH,0 MOV BX,TOKTAB-2 LAHFET MOV AL,CY RET RETURN: MOV AL,[OP1] OR AL,AL JZ OUTSTRJ MOV BX,'R'+4500H ;"RE" MOV [OP2],BX MOV BX,'T' MOV X JMP OUTSTR BFLAG: CALL PUTCH MOV AL,'B' CALL PUTCH MOV AL,',' RET GETBIT: MOV AL,[OP1+1] OR AL,AL STC CODE DB 0 OOPS: DM 'R' DW ARITH,OPCODE DM 'UT' DW OUT,OUTB DM 'RG' DW ONEOP,OPCODE DB 0 POPS: DM 'OP' DW PEOPS: DM 'X' DW EX,EXAF DM 'I' DW OUTSTR,OPCODE DM 'XX' DW OUTSTR,EXX DM 'QU' DW ONEOP,OPCODE DM 'NDIF' DW OOVB',0,'MOV',9,'DX,DI' DM 0,'MOV',9,'BX,SI' CPIR: DB 'UP' CMPREP: DB 0,'MOV',9,'DI,BX',0,'REPNZ',0,'SCAB' DM 0,'MOV',9,'BXDC' DW ARITH,OPCODE DM 'ND' DW ARITH,OPCODE DB 0 BOPS: DM 'IT' DW BITSET,TESBIT DB 0 COPS: DM 'ALL' DW DOCALEOP,SAR DM 'RL' DW ONEOP,SHR DM 'CF' DW OUTSTR,STC DM 'ET' DW BITSET,SETBIT DB 0 TOPS: DB 0 UOPS: DB 0 VOPS JNZ RET MOV AL,[OP1] SUB AL,'0' JC RET CMP AL,8 CMC JC RET MOV CH,AL INC CH XOR AL,AL STC SHFT: RCL AL OP,OPCODE DM 'USH' DW PUSH,OPCODE DB 0 QOPS: DB 0 ROPS: DM 'ET' DW RETURN,OPCODE DM 'LA' DW ACCUM,RCL DM 'RAUTSTR,OPCODE DB 0 FOPS: DB 0 GOPS: DB 0 HOPS: DM 'ALT' DW OUTSTR,HLT DB 0 IOPS: DM 'NC' DW INCDEC,OPCODE D,DI' DAD1: DM 'LAHF',0,'ADD' DAD2: DM 0,'RCR',9,'SI',0,'SAHF',0,'RCL',9,'SI' LAHF: DM 'LAHF' DM 0,'SAHF' DJNZ: DB 'DEC',9,L,OPCODE DM 'P' DW ARITH,CMP DM 'PL' DW ACCUM,NOT DM 'PIR' DW OUTSTR,CPIR DM 'PDR' DW CPDR,DOWN DM 'CF' DW O: DB 0 WOPS: DB 0 XOPS: DM 'OR' DW ARITH,OPCODE DB 0 YOPS: DB 0 ZOPS: DB 0 LDAX1: DM 9,'SI,' DM 0,'LODB' S DEC CH JNZ SHFT XOR AL,CL MOV CH,AL MOV AL,'0' CALL PUTCH MOV AL,CH RCR AL RCR AL RCR AL RCR AL CALL HEX' DW ACCUM,RCR DM 'LCA' DW ACCUM,ROL DM 'RCA' DW ACCUM,ROR DM 'L' DW ONEOP,RCL DM 'R' DW ONEOP,RCR DM 'LC' M 'N' DW IN,INB DM 'F' DW ONEOP,OPCODE DB 0 JOPS: DM 'R' DW JUMP,JR DM 'P' DW JUMP,JMP DB 0 KOPS: DB 0 LO'CH',13,10 DB '; *** WARNING: DJNZ does not affect flags - DEC does.',0 DM 'JNZ' WARNPA: DM 13,10,'; *** WARNING: Parity flUTSTR,CMC DB 0 DOPS: DM 'EC' DW INCDEC,OPCODE DM 'JNZ' DW ONEOP,DJNZ DM 'AA' DW OUTSTR,OPCODE DM 'I' DW OUTSTTAX1: DM 9,'DI,' DM 0,'STOB' PUSHAF: DB 'LAHF',0,'XCHG',9,'AH,AL',0,'PUSH',9,'AX',0 DM 'XCHG',9,'AH,AL' POPAF: DM 'POP',9, MOV AL,CH CALL HEX MOV AL,'H' JMP PUTCH OPTAB: DW AOPS,BOPS,COPS,DOPS,EOPS DW FOPS,GOPS,HOPS,IOPS,JOPS DW KOPS,L DW ONEOP,ROL DM 'RC' DW ONEOP,ROR DM 'ES' DW RES,RESBIT DM 'ETI' DW OUTSTR,IRET DM 'ETN' DW OUTSTR,IRET DM 'SPS: DM 'D' DW LD,MOV DM 'DIR' DW OUTSTR,UP DM 'DDR' DW LDDR,DOWN DB 0 MOPS: DB 0 NOPS: DM 'EG' DW ACCUM,OPag not always same as Z80.' IO1: DB 'MOV',9,'DI,DX',0,'MOV',9,'DL,CL',0 DM 'XOR',9,'DH,DH',13,10,9 IO2: DM 0,'MOV',9,'DX,DI'R,OPCODE DM 'W' DW PSEUDO,OPCODE DM 'B' DW PSEUDO,OPCODE DM 'M' DW PSEUDO,OPCODE DM 'S' DW ONEOP,OPCODE DB 0 'AX',0,'XCHG',9,'AH,AL',0,'SAHF' DOWN: DM 'DOWN' UP: DB 'UP' BLMOVE: DB 0,'MOV',9,'SI,BX',0,'MOV',9,'DI,DX' DB 0,'REP',0,'MOPS,MOPS,NOPS,OOPS DW POPS,QOPS,ROPS,SOPS,TOPS DW UOPS,VOPS,WOPS,XOPS,YOPS DW ZOPS AOPS: DM 'DD' DW ADD,OPCODE DM 'T' DW ONEOP,CALL DB 0 SOPS: DM 'UB' DW ARITH,OPCODE DM 'BC' DW ARITH,SBB DM 'LA' DW ONEOP,SAL DM 'RA' DW ON BADIO: DM 13,10,'; *** WARNING: Flags not same as Z80.' BITERR: DM 13,10,' *** ERROR: Cannot determine bit number.' SETBIT: U $ ORG 1 ;This is really just for equates without EQU RSI: DS 1 RDI: DS 1 ODDPAR: DS 1 EVEPAR: DS 1 DS 5 ;MINUS,PLUS,NO: DB 13,10,'Z80 to 8086 Translator version 2.0',13,10,'$' NOROOM: DB 13,10,'Insufficient directory space to create file',13,10CHG: DM 'XCHG' JMP: DM 'JMP' JR: DM 'JP' RCL: DM 'RCL' RCR: DM 'RCR' ROL: DM 'ROL' ROR: DM 'ROR' SAL: DM 'SAL' SAR: DM 'DM 'LAHF',0,'OR' DM 0,'SAHF' RESBIT: DM 'LAHF',0,'AND' DM 0,'SAHF' TESBIT: DM 'RCR',9,'SI',0,'TEST' DM 0,'RCL',9,'SI' XT ZERO,ZERO,NOT CARRY CY: DS 1 RAX: DS 1 STP: DS 1 RBX: DS 1 RDX: DS 1 RCX: DS 1 RBL: DS 1 RBH: DS 1 RDL: DS 1 RDH: DS,'$' NOFILE: DB 13,10,'File not found',13,10,'$' ENDMES: DB 13,10,'Translation complete',13,10,'$' WRTERR: DB 13,10,'Out of dSAR' SHR: DM 'SHR' STC: DM 'STC' IRET: DM 'IRET' HLT: DM 'HLT' CMC: DM 'CMC' NOT: DM 'NOT' MOV0: DB 0 MOV: DM 'MOV' CMPTHL1: DM 'POP',9,'SI',0,'XCHG',9,'SI' XTHL2: DM 0,'PUSH',9,'SI' EXX: DB 'XCHG',9,'BX,[HL]',0,'XCHG',9,'DX,[DE]',0 DM 'XCHG', 1 RGCL: DS 1 RCH: DS 1 RAL: DS 1 RIX: DS 1 RIY: DS 1 isk space',13,10,'$' OPCDER: DM 13,10,'*** Opcode Error ' CRLF: DM 13,10 LABEL: DB 'L0000',0 DM ':',9 PUTPT: DS 2 GETPT: : DM 'CMP' SBB: DM 'SBB' CALL: DM 'CALL' TOKTAB: DB 'SIDI' DB 'PEPOS',0,'NSNZZ',0,'NCC',0 DB 'AXSPBXDXCX' DB 'BLBHDLD9,'CX,[BC]' EXAF: DM 'LAHF',0,'XCHG',9,'AX,BP',0,'SAHF' MOVAL: DM 0,'MOV',9,'AL' IXSI: DM 9,'MOV',9,'SI,[IX]',13,10 IYDI: DMDS 2 CHAR: DS 1 DB 0 OPCODE: DS 80 OP1: DS 80 OP2: DS 80 PUTBUF: DS 128 GETBUF: DS 128 PUTFCB: DS 33 DS 50 STACK: EQHCLCHALIXIY' RWTAB: DB 'ABCDEHLBDHSACNZNPMPPII' LENRW: EQU $-RWTAB DB 0,0,0,0,0,0,0,'CELPF',0,'C',0,'Z',0,0,'OEYX' HEADER 9,'MOV',9,'DI,[IY]',13,10 RESTAX: DB 0 SAVEAX: DM 'XCHG',9,'AX,SI' CRLFTB: DM 13,10,9 INB: DM 'INB',9 OUTB: DM 'OUTB',9 X