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 A86bCDEFGHIJKLMNOBOOT A86PQRCHESS A86STUVWXYZ[\]^_`abSIZ 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 A86cdefghijklmnopqrCHESS A86stuvwxyz{|}~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,SAVction codes PRINTMES: EQU 9 OPEN: EQU 15 CLOSE: EQU 16 DELETE: EQU 19 READ: EQU 20 SETDMA: EQU 26 MAKE: EQU 22 SEQWRT: EBASE: ; 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 QU 21 ;The following equates define some token values returned by GETSYM UNDEFID:EQU 0 ;Undefined identifier (including no n 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 earby RET) CONST: EQU 1 ;Constant (including $) REG: EQU 2 ;8-bit register XREG: EQU 3 ;16-bit register (except 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 SYMWID: EQU 10OUTMES: ;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 SHLters) SREG: EQU 4 ;Segment register ORG 100H PUT 100H JMP BEGIN CPYRHT: DB 'Copyright 1979 by Seattle Computer Proform a long call to the entry point ; [10] to [13] have exit address (from INT 22H) ; [14] to [17] have ctrl-C exit address (f FCB: EQU 5CH BUFSIZ: EQU 128 EOL: EQU 13 ;ASCII carriage return OBJECT: EQU 100H ;DEFAULT "PUT" ADDRESS ;System call funupt 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 NUMTRNducts, Inc.' DB 13,10,13,10,'$' BEGIN: MOV SP,STACK MOV DX,HEADER MOV CL,PRINTMES CALL SYSTEM MOV DX,CPYRHT CAL AL,-1 ;Flag that no tokens have been read yet MOV [SYM],AL CALL ASMLIN ;Assemble the line MOV AL,[SYM] CMP AL,-1 ;AnBX ;DEFAULT PROGRAM COUNTER MOV [BASE],BX ;POINTER TO ROOT OF ID TREE=NIL MOV [RETPT],BX ;Pointer to last RET record DEC OV DX,FCB+9 MOV BX,EXTEND ;Set extension to ASM MOV CX,7 UP MOV SI,BX MOV DI,DX REP MOVB MOV DX,DI MOV BX,SI CMP AL,'X' ;PRN file to console? JZ NOPRN CALL CHKDSK NOPRN: MOV [LSTFCB],AL CALL ADDEXT MOV DX,FCB MOV CL,OPEN for linefeed JP GETEOL ABORT: MOV BX,NOMEM PRERR: XCHG DX,BX MOV CL,PRINTMES CALL SYSTEM JMP 0 MAKFIL: MOV L SYSTEM MOV AL,[FCB+17] MOV [SYMFLG],AL ;Save symbol table request flag MOV BX,FCB+9 ;Point to file extension MOV AL,[By tokens found on line? JNZ L0002 CALL GETSYM ;If no tokens read yet, read first one L0002: CMP AL,';' JZ ENDLN CMPBX MOV [LSTRET],BX ;Location of last RET MOV BX,[6] ;HL=END OF MEMORY MOV [HEAP],BX ;BACK END OF SYMBOL TABLE SPACE MOV RET CHKDSK: SUB AL,' ' ;If not present, set zero flag JZ RET SUB AL,20H JZ DSKERR ;Must be in range A-W CMP AL,' CALL SYSTEM MOV BX,NOFILE INC AL JNZ $+5 JMP PRERR XOR AL,AL MOV [FCB+32],AL ;Zero Next Record field MOV DX,HEXFCSI,DX LODB ;Get drive select byte CMP AL,20H ;If not valid, don't make file JNC RET PUSH DX INC DX MOV BX,FCB+1 X] ;Get source drive letter CALL CHKDSK ;Valid drive? OR AL,AL JZ DEFAULT ;If no extension, use existing drive spec M AL,EOL JZ ENDLN MOV AL,14H ;Garbage at end of line error JP ENDLIN ENDJ: JMP END ENDLN: XOR AL,AL ;Flag no errors AL,4 MOV [BCOUNT],AL ;CODE BYTES PER RELOCATION BYTE XOR AL,AL MOV [IFFLG],AL ;NOT WITHIN IF/ENDIF MOV [CHKLAB],AL ;LOOX'-'@' JC RET DSKERR: MOV BX,BADDSK JP PRERR ERROR: MOV AL,CL JMP ENDLIN NEXTCHR: XCHG BX,[HL] XCHG DX,[DE]B CALL MAKFIL MOV DX,LSTFCB CALL MAKFIL MOV BX,0FFH XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] MOV BX,START+1 ;POINT MOV CX,8 UP MOV SI,BX MOV DI,DX REP MOVB ;Copy source file name MOV DX,DI MOV BX,SI POP DX MOV CL,DELETE OV [FCB],AL DEFAULT: INC BX MOV AL,[BX] ;Get HEX file drive letter CMP AL,'Z' ;Suppress HEX file? JZ L0000 CALL CHK on line ENDLIN: MOV SP,STACK CALL NEXLIN JP LOOP NEXLIN: MOV CH,0C0H ;Put end of line marker and error code (AL) KUP ALL LABELS ;Assemble each line of code LOOP: CALL NEXTCHR ;Get first character on line CMP AL,1AH JZ ENDJ MOV XCHG CX,[BC] INC BL JNZ GETCH ;Buffer empty so refill it MOV DX,80H MOV CL,SETDMA CALL SYSTEM XCHG DX,BX MOV DER TO NEXT BYTE OF INTERMEDIATE CODE MOV [CODE],BX MOV [IY],START ;POINTER TO CURRENT RELOCATION BYTE MOV BX,0 MOV [PC],CALL SYSTEM MOV CL,MAKE CALL SYSTEM MOV BX,NOSPAC INC AL ;Success? JZ PRERR MOV CL,OPEN JMP SYSTEM ADDEXT: MDSK L0000: MOV [HEXFCB],AL INC BX MOV AL,[BX] ;Get PRN file drive letter CMP AL,'Z' ;Suppress PRN file? JZ NOPRN CALL PUTCD CALL GEN1 MOV AL,[CHR] GETEOL: CMP AL,10 JZ RET CMP AL,1AH JZ ENDJ CALL NEXTCHR ;Scan over comments X,FCB MOV CL,READ CALL SYSTEM OR AL,AL MOV AL,1AH ;Possibly signal End of File JNZ NOMOD ;If nothing read GETCH: SUB AL,DH ;Check if source is 16-bit register JZ RR ;If so, AL must be zero AND CH,0FDH ;Change direction XCHG DX,BX ber into middle position ADD AL,AL ADD AL,AL OR AL,0C0H ;Set register-to-register mode OR AL,DL ;Combine with other reord bit AND AL,CL ;But don't use it in word-only operations OR AL,CH ;Combine with OP code CALL PUT MOV AL,BL ADD AL JZ RET MOV AL,UNDEFID ;Check for memory reference CMP AL,BH JZ STORE ;Is destination memory? CMP AL,DH JZ LOAD ;Is OR AL,BL ; meaning direct load/store of accumulator JNZ NOTAC TEST CL,8 ;See if direct load/store of accumulator JZMOV AL,[BX] NOMOD: XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] MOV [CHR],AL RET MROPS: PUSH CX ;Save type flags ;Flip which operand is first and second MOV AL,XREG SUB AL,DH ;Let RR perform finish the test JP RR STORE: TEST CL,gister number JMP PUT SEGCHK: ;Come here if at least one operand is a segment register POP CX ;Restore flags RCR SI ,AL ;Rotate to middle position ADD AL,AL ADD AL,AL OR AL,DL ;Combine register field POP CX ;Dump return address JMPsource memory? RCR SI TEST CL,1 ;Check if register-to-register operation OK RCL SI MOV CL,27 JZ ERROR MOV AL,DH C NOTAC ; means anything in this case ; Process direct load/store of accumulator MOV AL,CH AND AL,2 ;Preserve direction CALL GETOP PUSH DX ;Save first operand CALL GETOP2 POP BX ;First op in BX, second op in DX MOV AL,SREG ;Check for a s004H ;Check if storing is OK JNZ STERR XCHG DX,BX ;If so, flip operands AND CH,0FDH ; and zero direction bit LOAD: TEST CL,8 ;Check if segment register OK RCL SI MOV CL,22 JZ ERR1 MOV CX,8E03H ;Segment register move OP code MOV AL, PUTADD ;Write the address STERR: MOV DH,29 MRERR: MOV CL,DH ERR1: JMP ERROR GETOP2: ;Get the second operand: loMP AL,BH ;Registers must be of same length RR: MOV CL,22 JNZ ERROR RR1: AND AL,1 ;Get register length (1=16 bits) ORbit only XOR AL,2 ; but flip it OR AL,0A0H ;Combine with OP code MOV CH,AL MOV AL,BH ;Check byte/word operation Aegment register CMP AL,BH JZ SEGCHK CMP AL,DH JZ SEGCHK MOV AL,CONST ;Check if the first operand is immediate MOV CL MOV DH,25 CMP AL,BH ;Check if memory-to-memory JZ MRERR MOV AL,BH CMP AL,REG ;Check if 8-bit operation JNZ XRG MOUNDEFID CMP AL,DH ;Check if source is memory JZ LOAD CMP AL,BH ;Check if destination is memory JZ STORE MOV AL,XREG ok for a comma and drop into GETOP MOV AL,[SYM] CMP AL,',' MOV CL,21 JNZ ERR1 GETOP: CALL GETSYM GETOP1: ;Enter AL,CH ;Or in to OP code CALL PUT ;And write it POP CX ;Dump return address MOV AL,BL ADD AL,AL ;Rotate register numND AL,1 OR AL,CH POP CX ;Dump return address JMP PUTADD ;Write the address NOTAC: MOV AL,BH AND AL,1 ;Get byte/w,26 CMP AL,BH JZ ERROR ;Error if so POP CX ;Restore type flags CMP AL,DH ;If second operand is immediate, then done V DH,22 TEST CL,1 ;See if 8-bit operation is OK JZ MRERR XRG: MOV AL,DL SUB AL,6 ;Check for R/M mode 6 and register 0 here if we don't need a GETSYM first CMP AL,'[' ;Memory reference? JZ MEM CMP AL,5 ;Flag ("B", "W", etc.)? JZ FLG Check for SI MOV CL,4 JZ SIJ DEC AL ;Check for DI JZ DIJ MOV CL,2 ;Invalid base/index register ERR2: JMP ERROR DIJ:SAHF LAHF XCHG AX,BP SAHF CALL GETSYM OPERATE: CMP AL,CONST JNZ $+5 JMP CVAL CMP AL,UNDEFID JNZ $+5 JMP UVAZ PJ LAHF XCHG AX,BP SAHF MOV CH,0 RCR SI TEST AL,010H ;Test INDEX bit RCL SI RCL AL ;BASE bit (zero flag not CALL GETSYM MOV BX,[CON] MOV [ADDR],BX MOV BX,[UNDEF] MOV [ALABEL],BX MOV DL,CH MOV DH,UNDEFID MOV AL,DH RET Fr BX SAHF JP LPCHK BPJ: LAHF XCHG AX,BP SAHF RCR SI TEST AL,080H ;Check if already seen base register RCL SI MP AL,REG ;8-Bit register? JZ NREG CMP AL,XREG ;16-Bit register? JZ NREG CMP AL,SREG ;Segment register? JZ NREG VA LAHF XCHG AX,BP SAHF RCR SI TEST AL,10H ;Check if already seen index register RCL SI JNZ ERR2 OR AL,30H ;FlagL CMP AL,'"' JNZ $+5 STRINGJ:JMP STRING CMP AL,"'" JZ STRINGJ CMP AL,XREG ;Only 16-bit register may index MOV CL,2affected) JZ NOIND ;Jump if not indexed, with BASE bit in carry CMC RCL CH RCL AL ;BP bit RCL CH RCL AL ;DI bit LG: CALL GETSYM CMP AL,',' JZ GETOP JP GETOP1 GETVAL: LAHF XCHG AX,BP SAHF PUSH BX MOV BX,0 MOV [CON],B JNZ ERR2 OR AL,0C0H ;Flag seeing base register BP LPCHK: LAHF XCHG AX,BP SAHF POP AX ;Get operator XCHG AH,AL L: ;Must be immediate XOR AL,AL ;No addressing modes allowed VAL1: CALL GETVAL MOV BX,[CON] ;Defined part MOV [DATA seeing index register DI JP LPCHK SIJ: LAHF XCHG AX,BP SAHF RCR SI TEST AL,010H ;Check if already seen index regi0 JNZ ERR2 LAHF XCHG AX,BP SAHF RCR SI TEST AL,1 ;Check to see if indexing is OK RCL SI MOV CL,1 JZ ERR2 LA RCL CH ;The low 3 bits now have indexing mode MODE: MOV BX,[UNDEF] MOV AL,BH OR AL,BL LAHF OR CH,080H ;If undefineX MOV [UNDEF],BX POP BX MOV AL,[SYM] CMP AL,'+' JZ PLSMNS CMP AL,'-' JZ PLSMNS MOV CH,'+' PUSH CX JP OPERATESAHF CMP AL,'-' ;Can't subtract a register MOV CL,5 JZ ERR2 NEXTER: LAHF XCHG AX,BP SAHF LAHF OR AL,4 ;Flag t],BX MOV BX,[UNDEF] ;Undefined part MOV [DLABEL],BX MOV DL,CH MOV DH,CONST MOV AL,DH RET NREG: PUSH DX CALL GETster RCL SI JNZ ERR2 LAHF OR AL,010H ;Flag seeing index register SI SAHF JP LPCHK BXJ: LAHF XCHG AX,BP SAHF HF XCHG AX,BP SAHF MOV AL,DL MOV CL,3 CMP AL,3 ;Check for BX JZ BXJ SUB AL,5 ;Check for BP JZ BPJ DEC AL ;Cd label, force 16-bit displacement SAHF JNZ RET MOV BX,[CON] CALL SIGNEXT ;Check if 8-bit with sign extended JNZ RET PLSMNS: LAHF XCHG AH,AL PUSH AX XCHG AH,AL LAHF XCHG AX,BP SAHF LAHF OR AL,4 ;Flag that a sign was found hat a term was processed SAHF LAHF XCHG AX,BP SAHF CALL GETSYM CMP AL,'+' JNZ $+5 PJ: JMP PLSMNS CMP AL,'-' JSYM POP DX MOV AL,DH RET MEM: CALL GETSYM MOV AL,1 CALL GETVAL MOV AL,[SYM] CMP AL,']' MOV CL,24 JNZ ERR1 RCR SI TEST AL,080H ;Check if already seen base register RCL SI JNZ ERR2 LAHF OR AL,080H ;Flag seeing base registe ;If not, use 16-bit displacement LAHF AND CH,07FH ;Reset 16-bit displacement SAHF LAHF OR CH,040H ;Set 8-bit displaX],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 MO only be added MOV CL,5 ERR30: JNZ ERR3 JMP NEXTER GETSYM: CALL GETSY MOV AL,[SYM] RET SCANB: MOV AL,[CHR] HL BX SHL BX ADD BL,AL DEC CH JNZ HEX1 XCHG DX,BX RET ERR4: JMP ERROR GETLET: CALL SCANB CMP AL,EOL STC C CH ;If not, must be BX JP MODE CVAL: MOV BX,[CON] POP AX XCHG AH,AL SAHF CMP AL,'-' JNZ ADDCON SBB BX,DX AL,DL CMP AL,EOL MOV CL,39 JZ ERR3 CALL PUT MOV AL,[DATSIZ] OR AL,AL JNZ BYTSIZ MOV AL,DH CALL PUT BYTSIZ: cement SAHF MOV AL,BH OR AL,BL JNZ RET ;Use it if not zero displacement MOV AL,CH AND AL,7 ;Specify no displacemenV [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 B SCANT: CMP AL,' ' JZ NEXB CMP AL,9 JNZ RET NEXB: CALL NEXTCHR JP SCANT DOLLAR: MOV DX,[OLDPC] MOV AL,CONST JZ RET CMP AL,';' STC JZ RET MOV CL,10 OR AL,20H CMP AL,'a' JC ERR4 CMP AL,'z'+1 JNC ERR4 READID: MOV BX,SETCON: MOV [CON],BX JMP NEXTER ADDCON: LAHF ADD BX,DX RCR SI SAHF RCL SI JP SETCON UVAL: LAHF XCHG AX,BMOV AL,[CHR] MOV DL,AL CALL GETCHR JP STRGDAT ZERLEN: CALL NEXTCHR CMP AL,CH JNZ ERR3 RET GETCHR: CALL NEXTCHRt MOV CH,AL CMP AL,6 ;Check for BP+0 addressing mode JNZ RET LAHF OR CH,040H ;If BP+0, use 8-bit displacement SAHFX SHL BX ADD BX,DX SHL BX MOV DL,AL MOV DH,0 ADD BX,DX DEC CH JNZ DEC XCHG DX,BX RET STRING: MOV CH,AL MOV [SYM],AL NEXTCHJ: JMP NEXTCHR GETSY: CALL SCANB CMP AL,'$' JZ DOLLAR MOV [SYM],AL OR AL,20H CMP AL,'z'+1ID MOV CH,0 MOREID: MOV [BX],AL INC CH LAHF INC BX SAHF CALL NEXTCHR CMP AL,'0' JC NOMORE OR AL,20H CMP AP SAHF MOV CL,6 RCR SI TEST AL,008H ;Check if undefined label has been seen RCL SI JNZ ERR30 LAHF OR AL,008H ; CMP AL,CH JNZ RET CALL NEXTCHR CMP AL,CH JZ RET POP BX JMP CVAL HEX: MOV DX,ID DEC CH HEX1: MOV SI,DX RET SIGNEXT: MOV AL,BH OR AL,AL JZ HIZERO INC AL JNZ RET HIZERO: MOV AL,BL XOR AL,BH AND AL,80H RET MOV AL,[CHR] CMP AL,CH MOV CL,35 MOV DL,AL MOV DH,0 JNZ L0003 CALL ZERLEN L0003: CALL GETCHR LAHF XCHG AX, 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,[BL,'z'+1 JNC NOMORE CMP AL,'9'+1 JC MOREID CMP AL,'a' JNC MOREID NOMORE: MOV CL,AL MOV AL,CH MOV [LENID],AL ORFlag seeing undefined label XCHG AX,BP SAHF MOV [UNDEF],BX POP AX XCHG AH,AL SAHF CMP AL,'+' ;Undefined label may LODB INC DX SUB AL,'0' CMP AL,10 JC GOTIT CMP AL,'g'-'0' JNC ERR4 SUB AL,'a'-10-'0' GOTIT: SHL BX SHL BX SNOIND: MOV CH,6 ;Try direct address mode JNC RET ;If no base register, that's right RCL AL ;Check BP bit JC MODE INBP SAHF MOV CL,37 TEST AL,002H JZ ERR3 TEST AL,004H MOV CL,38 JNZ ERR3 LAHF XCHG AX,BP SAHF STRGDAT: MOV AL,AL MOV AL,CL RET LETTER: CALL READID MOV AL,CH DEC AL JNZ NOFLG MOV AL,[ID] CMP AL,'l' MOV CL,0 MOV D080H SAHF MOV DX,RETSTR+2 CHKRET: MOV SI,DX LODB CMP AL,[BX] JNZ LOOKIT LAHF DEC BX SAHF LAHF DEC DX SA SEGTAB: DB 'dsce' LOOK: MOV CH,[BX] LAHF INC BX SAHF MOV DX,ID CALL CPSLP JZ RET XOR AL,80H MOV CL,AL LAV BX,[HEAP] MOV DL,AL MOV DH,0 SBB BX,DX ;Heap grows downward MOV [HEAP],BX XCHG DX,BX MOV BX,[CODE] ;Check to make,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 STER 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,[BXX,LONG JZ BWFLAG CMP AL,'b' MOV DX,FLAG JZ BWFLAG CMP AL,'w' MOV CL,1 JZ BWFLAG XOR AL,AL NOFLG: DEC AL PUSHF DEC CH JNZ CHKRET MOV DX,[LSTRET] MOV AL,DL AND AL,DH INC AL JZ ALLRET MOV BX,[PC] SBB BX,DX CALL SIGNEXTHF 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 sure there's enough SBB BX,DX JB $+5 JMP ABORT PUSH DX MOV BX,LENID MOV CL,[BX] INC CL MOV CH,0 UP MOV SI,BCANREG 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 A] LAHF INC BX SAHF MOV DH,[BX] RET ENTER: PUSH BX ;Save pointer to link field CALL CREATE ;Add the node POPH BX JNZ L0004 CALL REGCHK L0004: POP BX MOV AL,DH JZ SYMSAV CALL LOOKRET SYMSAV: MOV [SYM],AL RET BWFLAG: 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 SAHADD 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 XCX MOV DI,DX REP MOVB ;Move identifier and length into node MOV DX,DI MOV BX,SI MOV CH,4 XCHG DX,BX NILIFY: MOL,'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 U SI 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 XCHG DX,BX MOV AL,[BX] INC AL MOV [BX],CL MOV CL,32 JZ $+5 JMP ERROR MOV AL,5 JP SYMSAV REGCHK: MOV BX,IF LAHF DEC BX SAHF LAHF DEC BX SAHF MOV [HEAP],BX XOR AL,AL MOV [BX],AL MOV [RETPT],BX RET LOOKUP: LAHG 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],V [BX],CL ;Zero left and right links INC BX DEC CH JNZ NILIFY XOR AL,AL ;Set zero flag MOV [BX],AL ;Zero defined flP 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' CREATE EMPTY: CALL CREATE MOV [BASE],DX RET CREATE: MOV AL,[LENID] ADD AL,8 ;Storage needed for the node MOD 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 DHHF DEC BX SAHF LAHF OR B,[BX],080H SAHF LOOKIT: MOV BX,[BASE] MOV AL,BH OR AL,BL JZ EMPTY CALL LOOK JC ENag POP DX ;Restore pointer to node RET CPSLP: MOV SI,DX LODB CMP AL,[BX] LAHF INC DX INC BX SAHF JNZ RET6H MOV AL,BH CMP AL,UNDEFID JNZ L0006 CALL STIMM L0006: AND AL,1 JZ BYTIMM MOV AL,0B8H OR AL,BL CALL PUT J INC CH MOV CL,CH MOV AL,[BX] LAHF INC BX SAHF OR AL,AL JZ OPERR FINDOP: MOV CH,CL LAHF XCHG AX,BP SAHF ,[CODE] MOV [BX],AL LAHF INC BX SAHF MOV [CODE],BX POP BX RET PUTWOR: PUSH CX MOV CH,80H PUSH DX PUSH B LAHF INC BX SAHF MOV [BX],DH JMP GETLET ERR5: JMP ERROR ASMLIN: MOV BX,[PC] MOV [OLDPC],BX CALL GETLAB J ;Flag as pure code CALL GEN POP CX POP BX RET GEN: CALL PUTINC ;Save it and bump code pointer GEN1: MOV AL,[R DEC CH JNZ CPSLP RET GETLAB: MOV BX,0 MOV [LABPT],BX MOV AL,-1 MOV [FLAG],AL MOV [LONG],AL MOV DH,0 MOV MP PUTWOR BYTIMM: MOV AL,0B0H OR AL,BL CALL PUT PUTBJ: JMP PUTBYT IMMED: MOV AL,BH CMP AL,UNDEFID JZ STIMM MOV DX,ID+1 CALL CPSLP JZ HAVOP MOV DH,0 MOV DL,CH INC DL INC DL LAHF ADD BX,DX RCR SI SAHF RCL SI LAHFX JP PUTBW PUTBYT: PUSH CX MOV CH,40H PUSH DX PUSH BX MOV BX,[DLABEL] MOV AL,BH OR AL,BL JNZ PUTBW MOV BXNC $+5 JMP ENDLN MOV BX,LENID MOV AL,[BX] MOV CL,12 SUB AL,2 MOV CH,AL JC ERR5 CMP AL,5 JNC ERR5 LAHF INC ELOC] RCL 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 AL,[CHR] CMP AL,' '+1 JC NOT1 LAHF OR DH,001H SAHF NOT1: CALL GETLET JC RET CMP AL,':' JNZ LABCHK CALL NEXTMOV AL,BL OR AL,AL JZ RET MOV AL,BH CALL IMM OR AL,0C0H CALL PUT FINIMM: MOV AL,CL POP CX RCR SI TEST AL,00 XCHG AX,BP SAHF DEC AL JNZ FINDOP OPERR: MOV CL,12 JMP ERROR HAVOP: MOV DL,[BX] LAHF INC BX SAHF MOV ,[DATA] OR AL,BH JZ PUTBW INC BH JZ PUTBW MOV CL,31 JMP ERROR PUTBW: MOV DX,[DLABEL] MOV BX,[DATA] PUTCHK: MBX SAHF MOV AL,[BX] SUB AL,'a' MOV CL,AL ADD AL,AL ADD AL,AL ADD AL,CL ADD AL,CH ADD AL,AL MOV BX,OPTAB MO MOV AL,[BX] MOV B,[BX],0 MOV DI,[IY] MOV [DI],AL MOV BX,[CODE] PUSH BX POP [IY] LAHF INC BX SAHF MOV [CODECHR JP LABEL LABCHK: OR AL,AL RCR SI TEST DH,001H RCL SI JZ RET LABEL: MOV AL,[CHKLAB] OR AL,AL JZ $+5 JMP1H RCL SI JZ PUTBJ CMP AL,83H JZ PUTBJ JMP PUTWOR STIMM: MOV AL,[FLAG] CALL IMM CALL PUTADD JP FINIMM IMDH,[BX] LAHF INC BX SAHF MOV AL,[BX] ;Get opcode XCHG DX,BX JMP BX GRP1: MOV CX,8A09H CALL MROPS MOV CX,0COV AL,DH OR AL,DL JZ NOUNDEF MOV AL,DL CALL PUTCD MOV AL,DH CALL PUTCD MOV AL,BL CALL PUTINC MOV AL,BH RCR SV DL,AL MOV DH,0 LAHF ADD BX,DX RCR SI SAHF RCL SI MOV DL,[BX] LAHF INC BX SAHF MOV DH,[BX] XCHG DX,BX ],BX RET PUTINC: PUSH BX MOV BX,[PC] LAHF INC BX SAHF MOV [PC],BX JP PUTCD1 PUTCD: PUSH BX PUTCD1: MOV BX GETLET CALL LOOKUP MOV CL,11 JNZ ERR5 MOV DX,[PC] MOV B,[BX],1 LAHF INC BX SAHF MOV [BX],DL MOV [LABPT],BX M: AND AL,1 OR AL,CL MOV CL,AL CALL PUT MOV AL,CH AND AL,38H OR AL,BL RET PUT: PUSH BX PUSH CX MOV CH,0I TEST CH,080H RCL SI JZ SMPUT CALL GEN JP PRET SMPUT: CALL PUTCD CALL GEN1 PRET: POP BX POP DX POP CX RP4: LAHF XCHG AH,AL PUSH AX XCHG AH,AL CALL GETOP POP CX CMP AL,CONST JZ FIXED SUB AL,XREG DEC DL DEC DL L,CONST CMP AL,BH JZ ERR6 CMP AL,DH JZ ERR6 MOV AL,UNDEFID CMP AL,BH JZ EXMEM CMP AL,DH JZ EXMEM1 MOV AL,BH AL,DH OR AL,DL JNZ ACCJ XCHG DX,BX MOV BX,[DATA] CALL SIGNEXT XCHG DX,BX JNZ ACCJ LAHF OR CL,002H SAHF ACCJether one- or two-byte displacement TWOBT: MOV BX,[ADDR] MOV DX,[ALABEL] JP PUTCHK GRP2: CALL GETOP MOV CX,0FF30H LAHF ADD BX,DX RCR SI SAHF RCL SI MOV [PC],BX XCHG DX,BX MOV AL,-4 JP NEWLOC EQU: XCHG DX,BX MOV BX,[LABPT]ET NOUNDEF: MOV AL,BL MOV CL,BH PUSH CX MOV CH,0 CALL GEN POP CX MOV AL,CL RCR SI TEST CH,080H RCL SI M OR AL,DL MOV CL,20 JNZ ERR6 MOV AL,CH OR AL,8 JMP PUT FIXED: MOV AL,CH CALL PUT JMP PUTBYT GRP5: LAHF X CMP AL,DH MOV CL,22 JNZ ERR6 CMP AL,XREG JZ L0008 CALL RR1 L0008: ;RR1 never returns MOV AL,BL OR AL,AL JZ : JMP ACCIMM GRP8: MOV CL,AL MOV CH,0FEH JP ONEOP GRP9: MOV CL,AL MOV CH,0F6H ONEOP: PUSH CX CALL GETOP ONE: CMP AL,UNDEFID JZ PMEM MOV CH,50H CMP AL,XREG JZ PXREG MOV CH,6 CMP AL,SREG JNZ $+5 JMP PACKREG MOV CL,20 MOV AL,BH OR AL,BL MOV CL,34 JZ ERR7 MOV [BX],DL LAHF INC BX SAHF MOV [BX],DH RET ORG: MOV [PC],BX MOVOV CH,0 JZ PRETJ CALL GEN PRETJ: JP PRET PUTADD: PUSH CX PUSH DX PUSH BX MOV CH,0 MOV CL,AL CALL GEN ;Save CHG AH,AL PUSH AX XCHG AH,AL CALL GETOP CMP AL,CONST JNZ ERR6 MOV BX,[DLABEL] MOV AL,BH OR AL,BL MOV CL,30 JEXACC XCHG DX,BX MOV AL,BL OR AL,AL MOV AL,BH JZ EXACC CALL RR1 EXACC: MOV AL,90H OR AL,DL JMP PUT EXMEM: MOV CL,26 CMP AL,CONST JZ ERR7 CMP AL,SREG MOV CL,22 JZ ERR7 POP CX CMP AL,UNDEFID JZ MOP AND AL,1 JZ ROP JMP ERROR PMEM: MOV AL,CH CALL PUT MOV AL,CL OR AL,DL JMP PUTADD PXREG: MOV AL,CH OR AL,DL JMP PUT GRP3 AL,-2 NEWLOC: CALL PUTCD MOV AL,BL CALL PUTCD MOV AL,BH CALL PUTCD MOV CH,0C0H JMP GEN1 GRP6: MOV CH,AL MOVthe addressing mode as pure code MOV AL,CL MOV CH,80H AND AL,0C7H CMP AL,6 JZ TWOBT ;Direct address? AND AL,0C0H NZ ERR6 MOV BX,[DATA] POP AX XCHG AH,AL SAHF OR AL,AL JZ ORG DEC AL JZ DSJ DEC AL JZ EQU DEC AL JZ $+5 XCHG DX,BX EXMEM1: CMP AL,BH JZ ERR6 MOV CL,1 ;Flag word as OK CALL NOTAC ;NOTAC never returns ERR6: JMP ERROR GR RCR SI TEST CL,001H RCL SI JZ ROP MOV AL,CL AND AL,0F8H OR AL,DL JMP PUT MOP: MOV AL,[FLAG] AND AL,1 OR AL: CALL GETOP PUSH DX CALL GETOP2 POP BX MOV CX,8614H MOV AL,SREG CMP AL,BH JZ ERR6 CMP AL,DH JZ ERR6 MOV A CL,4 CALL MROPS MOV CL,23 ERR7: JMP ERROR GRP7: MOV CH,AL MOV CL,1 CALL MROPS MOV CL,80H MOV DX,[DLABEL] MOV JZ PRET ;Indirect through reg, no displacement? CMP AL,0C0H JZ PRET ;Register to register operation? MOV CH,AL ;Save wh JMP IF PUTOP: MOV AL,-3 JP NEWLOC ALIGN: MOV AL,[PC] AND AL,1 JZ RET MOV BX,1 DSJ: XCHG DX,BX MOV BX,[PC] ,CH CALL PUT MOV AL,CL AND AL,38H OR AL,DL JMP PUTADD ROP: OR AL,CH CALL PUT MOV AL,CL AND AL,38H OR AL,0C0JMP PUTWOR LONGJ: POP AX XCHG AH,AL SAHF CALL PUT CALL PUTWOR CALL GETOP MOV CL,20 CMP AL,CONST JNZ ERR8 JM,20 CMP AL,REG JZ ERR8 CMP AL,SREG JZ ERR8 CMP AL,XREG JNZ NOTRG OR DL,040H OR DL,080H NOTRG: MOV AL,0FFH CATA] CALL SIGNEXT JZ RET MOV CL,31 ERR10: JMP ERROR RET GRP18: CALL GETOP CMP AL,CONST MOV CL,20 JNZ ERR10 MUB AL,REG MOV CL,20 DEC DL OR AL,DL JNZ ERR8 POP DX MOV AL,DH POP CX LAHF OR CH,002H SAHF PUSH CX JMP ON JP GETSP NODEC: MOV BX,[PC] MOV [LSTRET],BX XCHG DX,BX MOV BX,[RETPT] MOV AL,BH OR AL,BL JZ DORET MOV B,[BX],H OR AL,DL JMP PUT GRP10: MOV CL,AL MOV CH,0F6H PUSH CX CALL GETOP MOV CL,20 MOV AL,DL OR AL,AL JNZ ERRJ1 P PUTWOR GRP16: LAHF XCHG AH,AL PUSH AX XCHG AH,AL CALL GETSYM CMP AL,5 JZ LONGR CMP AL,EOL JZ NODEC CMP ALALL PUT POP AX XCHG AH,AL SAHF AND AL,38H OR AL,DL MOV CH,AL MOV AL,[LONG] OR AL,AL MOV AL,CH JZ PUTADDJ AOV BX,[DLABEL] MOV AL,BH OR AL,BL JNZ GENINT MOV BX,[DATA] MOV DX,3 SBB BX,DX JNZ GENINT MOV AL,0CCH JMP PUT E GRP13: MOV CH,AL MOV CL,1 CALL MROPS MOV CL,80H ACCIMM: CALL IMMED OR CH,004H AND CH,0FDH AIMM: MOV AL,BH 1 LAHF INC BX SAHF MOV [BX],DL LAHF INC BX SAHF MOV [BX],DH MOV BX,0 MOV [RETPT],BX DORET: POP AX XCHG MOV AL,DH CMP AL,XREG JZ G10 CMP AL,REG ERRJ1: JNZ ERR8 G10: LAHF XCHG AH,AL PUSH AX XCHG AH,AL CALL GETOP ,';' JZ NODEC GETSP: CALL GETOP1 POP CX CMP AL,CONST MOV CL,20 JNZ ERR9 MOV AL,CH AND AL,0FEH CALL PUT JMP ND AL,0F7H PUTADDJ: JMP PUTADD DIRECT: MOV AL,[SYM] CMP AL,',' JZ LONGJ POP AX XCHG AH,AL SAHF DEC AL CMP ALGENINT: MOV AL,0CDH CALL PUT JMP PUTBYT GRP19: ;ESC opcode MOV CX,0D800H JMP ONEOP GRP20: MOV CH,AL MOV CL,1 AND AL,1 LAHF XCHG AH,AL PUSH AX XCHG AH,AL OR AL,CH CALL PUT POP AX XCHG AH,AL SAHF JNZ $+5 JMP PUTBYT AH,AL SAHF JMP PUT GRP17: CALL PUT CALL GETOP CMP AL,CONST MOV CL,20 ERR9: JNZ ERR10 MOV BX,[DATA] MOV DX,[PC]POP AX XCHG AH,AL SAHF AND AL,1 MOV [FLAG],AL MOV AL,DH ONEJ: JP ONE GRP11: CALL PUT MOV AL,0AH JMP PUT GRP12PUTWOR LONGR: MOV AL,[LONG] OR AL,AL JNZ NOTLON POP AX XCHG AH,AL SAHF OR AL,8 LAHF XCHG AH,AL PUSH AX XC,0E9H JZ GOTOP MOV AL,0E8H GOTOP: CALL PUT MOV BX,[DATA] MOV DX,[PC] INC DX INC DX SUB BX,DX MOV [DATA],BX CALL MROPS MOV CL,0F6H CALL IMMED MOV CH,0A8H JMP AIMM GRP21: CALL GETOP CMP AL,SREG MOV CL,28 JNZ ERR10 M JMP PUTWOR ERR8: JMP ERROR GRP14: LAHF XCHG AH,AL PUSH AX XCHG AH,AL CALL GETOP CMP AL,CONST JZ DIRECT MOV CL LAHF INC DX SAHF SBB BX,DX MOV [DATA],BX CALL PUTBYT MOV BX,[DLABEL] MOV AL,BH OR AL,BL JNZ RET MOV BX,[D: MOV CL,AL MOV CH,0D0H PUSH CX CALL GETOP MOV AL,[SYM] CMP AL,',' MOV AL,DH JNZ ONEJ PUSH DX CALL GETOP SHG AH,AL NOTLON: CALL GETSYM CMP AL,EOL JZ DORET CMP AL,';' JZ DORET CMP AL,',' JNZ L0011 CALL GETSYM L0011: OV 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,8F00H CNEXT RECORD field to zero MOV [COUNT],AL CALL STRTLIN MOV BX,START NEXBT: MOV CH,4 MOV CL,[BX] ;Get flag byte LAHF*** END: MOV CL,4 WREND: MOV CH,0FFH MOV AL,CH CALL GEN DEC CL JNZ WREND MOV AL,[LSTFCB] CMP AL,'Z' JZ NOR CALL CONV10 CALL PRNT10 CRLF: MOV AL,13 CALL LIST MOV AL,10 JMP LIST DEFBYT: CALL FIXUP XCHG DX,BX CALL SIG [IFFLG],AL RET SKIPCD: MOV [CHKLAB],AL SKIPLP: XOR AL,AL CALL NEXLIN CALL NEXTCHR CMP AL,1AH JZ END CALL GELL LIST CALL LIST CALL LIST DEC CH JNZ BLNK NOFIL: CALL OUTLIN POP BX MOV AL,[BX] PUSH BX CALL REPERR MOV AMP AL,UNDEFID JNZ $+5 JMP PMEM MOV CH,58H CMP AL,XREG JNZ $+5 JMP PXREG MOV CH,7 CMP AL,SREG JZ PACKREG MOV INC BX ;Point to code SAHF CDLP: RCL CL ;Get high bit JC TESTTYP ;Word fixup or special RCL CL JNC $+5 JMP DEEOPN CALL ADDEXT MOV DX,FCB MOV CL,OPEN CALL SYSTEM MOV BX,0FFH XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] NOREOPN:NEXT ;See if in range +127 to -128 XCHG DX,BX JZ OBJBTE ;If so, it's always OK MOV AL,DH OR AL,AL ;Check for range +2TLAB JC SKIPLP MOV BX,LENID MOV DX,IFEND MOV CH,[BX] INC CH CALL CPSLP JNZ SKIPLP XOR AL,AL MOV [CHKLAB],AL L,[ERR] CALL REPERR CALL STRTLIN POP BX POP CX JP NEXCD OUTLIN: CALL LIST MOV AL,[LSTFCB] CMP AL,'Z' JZ RETCL,20 ERR11: JMP ERROR GRP23: MOV [DATSIZ],AL GETDAT: CALL GETSYM MOV AL,2 CALL VAL1 MOV AL,[SYM] CMP AL,',' MOFBYT ;Byte fixup MOV AL,[BX] OBJBT: CALL SAVCD NEXCD: INC BX DEC CH ;Still have codes left? JNZ CDLP JP NEXBT T MOV AL,-5 MOV [HEXCNT],AL ;FLAG HEX BUFFER AS EMPTY MOV [SKPFLG],AL MOV BX,HEXBUF MOV [HEXPNT],BX MOV BX,LSTBUF M55 to -256 JZ CHKJMP INC AL JZ CHKJMP RNGERR: MOV AL,101 ;Value out of range MOV [ERR],AL OBJBTE: MOV AL,DL JMPRET ENDIF: MOV BX,IFFLG MOV AL,[BX] MOV B,[BX],0 MOV CL,36 OR AL,AL JZ ERR11 RET ;************************** MOV BX,LINFLG MOV AL,[BX] MOV B,[BX],-1 OR AL,AL JNZ CRLF ;Output line only if first time OUTLN: CALL NEXTCHR CV AL,[DATSIZ] JNZ ENDDAT CALL SAVDAT JP GETDAT ENDDAT: CMP AL,2 JNZ SAVDAT MOV BX,[DATA] LAHF OR BL,080H SAHFESTTYP: RCL CL JC $+5 JMP DEFWRD MOV AL,[BX] CMP AL,-10 JC $+5 JMP SPCFUN PUSH CX PUSH BX MOV BX,COUNT MOVOV [LSTPNT],BX MOV BX,0 MOV [ERRCNT],BX MOV [PC],BX MOV BX,OBJECT MOV [HEXADD],BX XOR AL,AL MOV [FCB+20H],AL ;Set OBJBT CHKJMP: ;Check for short jump. If so, we're out of range; otherwise we're OK MOV AL,[COUNT] DEC AL ;Only one other******************************************* ; ; PASS 2 ; ;******************************************************************ALL LIST CMP AL,10 ;Output until linefeed found JNZ OUTLN RET PRTCNT: MOV BX,ERCNTM CALL PRINT MOV BX,[ERRCNT] MOV [DATA],BX SAVDAT: OR AL,AL JZ $+5 JMP PUTBYT JMP PUTWOR IF: MOV AL,BH OR AL,BL MOV AL,1 JZ SKIPCD MOV AL,6 SUB AL,[BX] MOV B,[BX],0 MOV CH,AL MOV AL,' ' JZ NOFIL BLNK: ;Put in 3 blanks for each byte not present CA byte on line? JNZ OBJBTE ;Can't be short jump if not MOV AL,[PREV] ;Get the first byte of this line CMP AL,0EBH ;DirectCHG AH,AL CALL OUTA POP AX XCHG AH,AL SAHF RET PHEX: MOV CH,AL CALL UHALF CALL LIST MOV AL,CH CALL LHALF TFCB] CMP AL,'Z' JZ OUTRET CMP AL,'X' JZ LSTCON POP AX XCHG AH,AL SAHF LAHF XCHG AH,AL PUSH AX XCHG AH,AL BX,[HEAP] MOV SP,BX CALL NODE ENDSYM: MOV AL,[LSTFCB] CMP AL,'X' JZ EXIT CMP AL,'Z' JZ ERRCON ;Print error countX,BX MOV DL,[BX] ;Get constant part LAHF INC BX SAHF MOV DH,[BX] XCHG DX,BX LAHF ADD BX,CX ;Add symbol value t POP BX JMP NEXCD FINI: CALL PRTCNT MOV AL,[HEXFCB] CMP AL,'Z' JZ SYMDMP MOV AL,[HEXCNT] CMP AL,-5 JZ L0012 short jump? JZ RNGERR AND AL,0FCH CMP AL,0E0H ;LOOP or JCXZ instruction? JZ RNGERR AND AL,0F0H CMP AL,70H ;Condit JMP LIST SPCFUN: INC AL ;End of file? JZ FINI LAHF INC BX SAHF MOV DL,[BX] ;Get address LAHF INC BX SAH AND AL,7FH PUSH BX MOV BX,[LSTPNT] MOV [BX],AL CALL INCBUF MOV [LSTPNT],BX JNZ HAVSPC MOV BX,LSTBUF MOV [LSTPN to console CALL LSTEOF MOV DX,LSTFCB MOV CL,CLOSE CALL 5 ERRCON: MOV AL,'X' MOV [LSTFCB],AL CALL PRTCNT EXIT: Jo constant part RCR SI SAHF RCL SI POP CX XCHG DX,BX OR AL,AL ;See if symbol got defined JNZ RET MOV AL,100 ;U CALL ENHEXL L0012: MOV AL,':' CALL PUTCHR MOV CH,10 HEXEND: PUSH CX MOV AL,'0' CALL PUTCHR POP CX DEC CH ional jump? JZ RNGERR JP OBJBTE DEFWRD: CALL FIXUP MOV AL,DL CALL SAVCD MOV AL,DH JMP OBJBT FIXUP: PUSH CXF MOV DH,[BX] PUSH BX INC AL ;ORG? JZ DORG INC AL ;PUT? JZ DPUT DDS: ;Handle DS pseudo-op MOV BX,[PC] LAHF T],BX PUSH DX XCHG DX,BX PUSH CX MOV CL,SETDMA CALL 5 MOV DX,LSTFCB MOV CL,SEQWRT CALL 5 POP CX POP DX HAVSMP 0 RET LSTEOF: MOV AX,[LSTPNT] CMP AX,LSTBUF JZ RET MOV AL,1AH CALL LIST JP LSTEOF NODE: XCHG DX,BX PUSHndefined - flag error MOV [ERR],AL MOV DX,0 RET STRTLIN: XOR AL,AL MOV [ERR],AL MOV [LINFLG],AL MOV BX,[PC] MJNZ HEXEND CALL HEXCRLF JZ L0013 CALL HEXEOF L0013: CALL HEXEOF MOV CL,CLOSE MOV DX,HEXFCB CALL SYSTEM SYMDMP: MOV DL,[BX] ;Get pointer to symbol LAHF INC BX SAHF MOV DH,[BX] LAHF INC BX SAHF XCHG DX,BX MOV AL,[BX] ; ADD BX,DX RCR SI SAHF RCL SI MOV [PC],BX MOV BX,[HEXADD] LAHF ADD BX,DX RCR SI SAHF RCL SI MOV [HEXADD],BPC: POP BX OUTRET: POP AX XCHG AH,AL SAHF RET LSTCON: POP AX XCHG AH,AL SAHF LAHF XCHG AH,AL PUSH AX X BX MOV DL,[BX] MOV DH,0 LAHF INC BX SAHF LAHF ADD BX,DX RCR SI SAHF RCL SI MOV DL,[BX] LAHF INC BX OV AL,BH CALL PHEX MOV AL,BL PHEXB: CALL PHEX MOV AL,' ' LIST: LAHF XCHG AH,AL PUSH AX XCHG AH,AL MOV AL,[LS MOV AL,[SYMFLG] CMP AL,'S' JNZ ENDSYM MOV BX,SYMMES CALL PRINT MOV DX,[BASE] MOV AL,DH OR AL,DL JZ EXIT MOV Whether symbol was defined LAHF INC BX SAHF MOV CL,[BX] ;Get symbol value LAHF INC BX SAHF MOV CH,[BX] XCHG DX JP SPEND DPUT: ;Handle PUT pseudo-op MOV [HEXADD],DX JP SPEND DORG: ;Handle ORG pseudo-op MOV [PC],DX SPEND: SAHF MOV DH,[BX] MOV AL,DL OR AL,DH JZ L0014 CALL NODE L0014: POP BX MOV CH,[BX] LAHF INC BX SAHF MOV ALXT: POP AX XCHG AH,AL SAHF CALL PHEXB POP CX MOV BX,[PC] LAHF INC BX SAHF MOV [PC],BX MOV BX,[HEXADD] LA' JZ SUPZ MOV CH,0 ;Turn off zero suppression if not zero SUPZ: SUB AL,CH ;Convert leading zeros to blanks JMP LIST XCHG AH,AL SAHF HEXBYT: MOV CH,AL MOV BX,CHKSUM ADD AL,[BX] MOV [BX],AL MOV AL,CH CALL UHALF CALL PUTCHR MOV MOV AL,DH OR AL,DL JNZ NODE RET CONV10: MOV CH,16 MOV DX,0 CONVLP: LAHF ADD BX,BX RCR SI SAHF RCL SI XCHG AH,AL PUSH AX XCHG AH,AL MOV AL,[HEXFCB] CMP AL,'Z' JNZ $+5 JMP OUTRET MOV DX,[LASTAD] MOV BX,[HEXADD] M,SYMWID SUB AL,CH JNC LENOK MOV AL,1 LENOK: MOV DH,AL WRTSYM: MOV AL,[BX] LAHF INC BX SAHF CALL LIST DEC CHF INC BX SAHF MOV [HEXADD],BX POP BX RET REPERR: OR AL,AL JZ RET LAHF XCHG AH,AL PUSH AX XCHG AH,AL HIDIG: CALL UHALF JP DIGIT HEXEOF: MOV AL,1AH CALL PUTCHR JNZ HEXEOF RET SAVCD: MOV [PREV],AL PUSH BX AL,CH CALL LHALF CALL PUTCHR MOV BX,HEXCNT INC B,[BX] MOV AL,[BX] CMP AL,26 JNZ RET ENHEXL: MOV BX,[HEXLEN] 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 CONVLP RET PRNT10OV [LASTAD],BX LAHF INC DX SAHF MOV AL,[HEXCNT] CMP AL,-5 JZ NEWLIN OR AL,AL SBB BX,DX JZ AFHEX CALL ENHEXL H JNZ WRTSYM MOV CH,DH INC CH MOV AL,' ' OUTB: CALL LIST DEC CH JNZ OUTB LAHF INC BX SAHF LAHF INC BX MOV BX,ERRMES CALL PRINT POP AX XCHG AH,AL SAHF CALL PHEX MOV BX,ENDMES CALL PRINT MOV BX,[ERRCNT] LAHF INC PUSH CX LAHF XCHG AH,AL PUSH AX XCHG AH,AL PUSH DX CALL CODBYT POP DX MOV BX,COUNT INC B,[BX] MOV AL,[BX] MOV CH,AL CALL UHALF MOV [BX],AL CALL INCBUF MOV AL,CH CALL LHALF MOV [BX],AL MOV AL,-6 MOV [HEXCNT],AL MOV AL: XCHG DX,BX MOV CH,'0'-' ' ;Enable leading zero suppression MOV AL,CL CALL LODIG MOV AL,BH CALL HIDIG MOV AL,BH NEWLIN: MOV AL,':' CALL PUTCHR MOV AL,-4 MOV [HEXCNT],AL XOR AL,AL MOV [CHKSUM],AL MOV BX,[HEXPNT] MOV [HEXLEN] SAHF PUSH BX LAHF INC BX SAHF LAHF INC BX SAHF LAHF INC BX SAHF LAHF INC BX SAHF MOV AL,[BX] CALLBX SAHF MOV [ERRCNT],BX RET PRINT: MOV AL,[BX] CALL LIST OR AL,AL JS RET LAHF INC BX SAHF JP PRINT OCMP AL,7 JNZ NOEXT MOV B,[BX],1 MOV AL,' ' CALL OUTLIN MOV AL,' ' MOV CH,5 TAB: CALL LIST DEC CH JNZ TAB NOE,[CHKSUM] ADD AL,CH NEG AL CALL HEXBYT HEXCRLF: MOV AL,13 CALL PUTCHR MOV AL,10 PUTCHR: MOV BX,[HEXPNT] MO CALL LODIG MOV AL,BL CALL HIDIG MOV AL,BL MOV CH,0 ;Don't suppress last digit LODIG: CALL LHALF DIGIT: CMP AL,'0,BX CALL HEXBYT MOV AL,[HEXADD+1] CALL HEXBYT MOV AL,[HEXADD] CALL HEXBYT XOR AL,AL CALL HEXBYT AFHEX: POP AX PHEX LAHF DEC BX SAHF MOV AL,[BX] CALL PHEX CALL CRLF POP BX MOV DL,[BX] LAHF INC BX SAHF MOV DH,[BX] UTA: MOV DL,AL MOV CL,2 SYSTEM: PUSH CX PUSH DX PUSH BX CALL 5 POP BX POP DX POP CX RET CODBYT: LAHF V [BX],AL CALL INCBUF MOV [HEXPNT],BX JNZ RET PUSH BX MOV BX,SKPFLG MOV AL,[BX] MOV B,[BX],0 ;Buffer filled, don'tW GRP19 DB 0D8H DB 'nd' DW END DB 0 E5: DB 1 DB 'ndif' DW ENDIF DB 0 H3: DB 1 DB 'lt' DW PUT DB 0F4H C4: DB 3 DB 'all' DW GRP14 DB 9AH DB 'mpb' DW PUT DB 0A6H DB 'mpw' DW PUT DB 0A7H D2: DB 5 DB 'b' DDB 'be' DW GRP17 DB 76H DB 'pe' DW GRP17 DB 7AH DB 'np' DW GRP17 DB 7BH DB 'po' DW GRP17 DB 7BH DB 'no' NONE: DB 0 ; 8086 MNEMONIC TABLE A3: DB 7 DB 'dd' DW GRP7 DB 2 DB 'nd' DW GRP13 DB 22H DB 'dc' DW GR DW GRP17 DB 72H DB 'a' DW GRP17 DB 77H DB 'g' DW GRP17 DB 7FH DB 'o' DW GRP17 DB 70H DB 's' DW GRP17 skip next time POP BX OR AL,AL ;Both buffers filled? JNZ RET MOV CL,SETDMA XCHG DX,BX CALL SYSTEM MOV DX,HEXFCB H4: DB 1 DB 'alt' DW PUT DB 0F4H I2: DB 2 DB 'n' DW GRP4 DB 0E4H DB 'f' DW GRP5 DB 4 I3: DB 4 DB 'ncW GRP23 DB 1 DB 'w' DW GRP23 DB 0 DB 'm' DW GRP23 DB 2 DB 's' DW GRP5 DB 1 DB 'i' DW PUT DB 0FAH D3: DW GRP17 DB 71H DB 'ns' DW GRP17 DB 79H J4: DB 5 DB 'cxz' DW GRP17 DB 0E3H DB 'nge' DW GRP17 DB 7CH DP7 DB 12H DB 'aa' DW PUT DB 37H DB 'as' DW PUT DB 3FH DB 'am' DW GRP11 DB 0D4H DB 'ad' DW GRP11 DB 0D5 DB 78H DB 'c' DW GRP17 DB 72H J3: DB 17 DB 'mp' DW GRP14 DB 0EAH DB 'nz' DW GRP17 DB 75H DB 'ne' DW G MOV CL,SEQWRT CALL SYSTEM XCHG DX,BX OR AL,AL JZ RET MOV BX,WRTERR JMP PRERR UHALF: RCR AL RCR AL RCR AL ' DW GRP8 DB 41H DB 'nb' DW GRP4 DB 0E4H DB 'nw' DW GRP4 DB 0E5H DB 'nt' DW GRP18 DB 0CCH I4: DB 4 DB DB 4 DB 'ec' DW GRP8 DB 49H DB 'iv' DW GRP10 DB 30H DB 'aa' DW PUT DB 27H DB 'as' DW PUT DB 2FH D4: B 'nae' DW GRP17 DB 72H DB 'nbe' DW GRP17 DB 77H DB 'nle' DW GRP17 DB 7FH L3: DB 3 DB 'ea' DW GRP6 DB 8H A5: DB 1 DB 'lign' DW ALIGN DB 0 C3: DB 7 DB 'mp' DW GRP7 DB 3AH DB 'lc' DW PUT DB 0F8H DB 'ld' DWRP17 DB 75H DB 'nl' DW GRP17 DB 7DH DB 'ge' DW GRP17 DB 7DH DB 'nb' DW GRP17 DB 73H DB 'ae' DW GRP17 D RCR AL LHALF: AND AL,0FH OR AL,30H CMP AL,'9'+1 JC RET ADD AL,7 RET INCBUF: INC BX CMP BX,HEXBUF+BUFSIZ 'mul' DW GRP10 DB 28H DB 'div' DW GRP10 DB 38H DB 'ret' DW PUT DB 0CFH DB 'nto' DW PUT DB 0CEH J2: DB DB 1 DB 'own' DW PUT DB 0FDH E2: DB 1 DB 'i' DW PUT DB 0FBH E3: DB 3 DB 'qu' DW GRP5 DB 2 DB 'sc' DDH DB 'ds' DW GRP6 DB 0C5H DB 'es' DW GRP6 DB 0C4H L4: DB 5 DB 'oop' DW GRP17 DB 0E2H DB 'odb' DW PUT PUT DB 0FCH DB 'li' DW PUT DB 0FAH DB 'mc' DW PUT DB 0F5H DB 'bw' DW PUT DB 98H DB 'wd' DW PUT DB 99HB 73H DB 'nc' DW GRP17 DB 73H DB 'ng' DW GRP17 DB 7EH DB 'le' DW GRP17 DB 7EH DB 'na' DW GRP17 DB 76H JZ RET CMP BX,LSTBUF+BUFSIZ JZ RET CMP BX,HEXBUF+BUFSIZ+BUFSIZ JNZ RET MOV BX,HEXBUF ;Wrap back to first buffer RET10 DB 'p' DW GRP17 DB 0EBH DB 'z' DW GRP17 DB 74H DB 'e' DW GRP17 DB 74H DB 'l' DW GRP17 DB 7CH DB 'b' DB 0ACH DB 'odw' DW PUT DB 0ADH DB 'ahf' DW PUT DB 9FH DB 'ock' DW PUT DB 0F0H L5: DB 2 DB 'oope' DW GBH DB 'ahf' DW PUT DB 9EH T4: DB 1 DB 'est' DW GRP20 DB 84H U2: DB 1 DB 'p' DW PUT DB 0FCH W4: DB 1 PUT DB 0F2H DB 'epne' DW PUT DB 0F2H S3: DB 11 DB 'ub' DW GRP7 DB 2AH DB 'bb' DW GRP7 DB 1AH DB 'bc' R5 DW NONE DW NONE ;S DW S3 DW S4 DW NONE DW NONE DW NONE ;T DW NONE DW T4 DW NONE DW NONE DW U2 ;U DW DB 0E6H DB 'utw' DW GRP4 DB 0E7H P3: DB 2 DB 'op' DW GRP22 DB 8FH DB 'ut' DW GRP5 DB 3 P4: DB 2 DB ';H DW H3 DW H4 DW NONE DW NONE DW I2 ;I DW I3 DW I4 DW NONE DW NONE DW J2 ;J DW J3 DW J4 DW NONE DW RP17 DB 0E1H DB 'oopz' DW GRP17 DB 0E1H L6: DB 2 DB 'oopne' DW GRP17 DB 0E0H DB 'oopnz' DW GRP17 DB 0E0H DB 'ait' DW PUT DB 9BH X3: DB 1 DB 'or' DW GRP13 DB 32H X4: DB 2 DB 'chg' DW GRP3 DB 86H DB 'lat' DW DW GRP7 DB 1AH DB 'tc' DW PUT DB 0F9H DB 'td' DW PUT DB 0FDH DB 'ti' DW PUT DB 0FBH DB 'hl' DW GRP12 NONE DW NONE DW NONE DW NONE DW NONE ;V DW NONE DW NONE DW NONE DW NONE DW NONE ;W DW NONE DW W4 DW NONush' DW GRP2 DB 0FFH DB 'opf' DW PUT DB 9DH P5: DB 1 DB 'ushf' DW PUT DB 9CH R3: DB 6 DB 'et' DW GRP16NONE DW NONE ;K DW NONE DW NONE DW NONE DW NONE DW NONE ;L DW L3 DW L4 DW L5 DW L6 DW NONE ;M DW M3 DW M3: DB 2 DB 'ov' DW GRP1 DB 88H DB 'ul' DW GRP10 DB 20H M4: DB 2 DB 'ovb' DW PUT DB 0A4H DB 'ovw' DWPUT DB 0D7H OPTAB: DW NONE DW A3 DW NONE DW A5 DW NONE DW NONE ;B DW NONE DW NONE DW NONE DW NONE DDB 20H DB 'hr' DW GRP12 DB 28H DB 'al' DW GRP12 DB 20H DB 'ar' DW GRP12 DB 38H DB 'eg' DW GRP21 DB 26H E DW NONE DW NONE ;X DW X3 DW X4 DW NONE DW NONE DW NONE ;Y DW NONE DW NONE DW NONE DW NONE DW NONE ;Z DB 0C3H DB 'ep' DW PUT DB 0F3H DB 'ol' DW GRP12 DB 0 DB 'or' DW GRP12 DB 8 DB 'cl' DW GRP12 DB 10H M4 DW NONE DW NONE DW NONE ;N DW N3 DW NONE DW NONE DW NONE DW O2 ;O DW O3 DW O4 DW NONE DW NONE DW N PUT DB 0A5H N3: DB 3 DB 'ot' DW GRP9 DB 10H DB 'eg' DW GRP9 DB 18H DB 'op' DW PUT DB 90H O2: DB 1 DW NONE ;C DW C3 DW C4 DW NONE DW NONE DW D2 ;D DW D3 DW D4 DW NONE DW NONE DW E2 ;E DW E3 DW NONE DW ES4: DB 5 DB 'cab' DW PUT DB 0AEH DB 'caw' DW PUT DB 0AFH DB 'tob' DW PUT DB 0AAH DB 'tow' DW PUT DB 0A DW NONE DW NONE DW NONE DW NONE HEADER: DB 13,10,'Seattle Computer Products 8086 Assembler Version 2.00' DB 13,10,'$DB 'cr' DW GRP12 DB 18H R4: DB 2 DB 'epz' DW PUT DB 0F3H DB 'epe' DW PUT DB 0F3H R5: DB 2 DB 'epnz' DWONE ;P DW P3 DW P4 DW P5 DW NONE DW NONE ;Q DW NONE DW NONE DW NONE DW NONE DW NONE ;R DW R3 DW R4 DW B 'r' DW GRP13 DB 0AH O3: DB 2 DB 'ut' DW GRP4 DB 0E6H DB 'rg' DW GRP5 DB 0 O4: DB 2 DB 'utb' DW GRP4 5 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 ' ERRMES: DM '***** ERROR no. ' NOSPAC: DB 13,10,'No directory space',13,10,24H ENDMES: DM 'H',13,10 NOMEM: DB 13,10,'Insuff STACK: EQU $ START: EQU $ U 0 TARBELLDOUBLE: EQU 0 LOAD: EQU 400H ;Address to load program SEG: EQU 40H ;LOAD/10H SECTOR: EQU 51 ;No. of 128-byte seS 2 DLABEL: DS 2 CON: DS 2 UNDEF: DS 2 LENID: DS 1 ID: DS 80 CHR: DS 1 SYM: DS 1 BASE: DS 2 HEAP: DS 2 SYMFLG: DS 1 Cize of ;program at any address. The program is assumed to ;occupy consecutive sectors starting at track 0, sector ;2, and wiicient memory',13,10,'$' NOFILE: DB 13,10,'File not found',13,10,'$' WRTERR: DB 13,10,'Disk write error',13,10,'$' BADDSK: DBctors to load BOOTER: EQU 200H ;"B" command puts booter here ;**************************************************************ODE: DS 2 DATSIZ: DS 1 RELOC: DS 1 BCOUNT: DS 1 COUNT: DS 1 ERR: DS 1 HEXPNT: DS 2 HEXLEN: DS 2 HEXADD: DS 2 LASTAD: DSll begin exection at its load address (which ;must be a 16-byte boundary) with the Instruction ;Pointer set to zero. ; Vari 13,10,'Bad disk specifier',13,10,'$' ERCNTM: DM 13,10,13,10,'Error Count =' SYMMES: DM 13,10,'Symbol Table',13,10,13,10 EXTE CROMEMCO: EQU CROMEMCOLARGE+CROMEMCOSMALL TARBELL: EQU TARBELLSINGLE+TARBELLDOUBLE WD1771: EQU CROMEMCO+TARBELLSINGLE W 2 HEXCNT: DS 1 CHKSUM: DS 1 SKPFLG: DS 1 LINFLG: DS 1 PREV: DS 1 IFFLG: DS 1 CHKLAB: DS 1 LSTPNT: DS 2 ERRCNT: DS 2 Lations are available for the Cromemco 4FDC with ; large disks, the 4FDC with small disks, the Tarbell ; single-density controlND: DB 'ASM',0,0,0,0 IFEND: DB 5,'endif' RETSTR: DM 'ret' HEXFCB: DB 0,' HEX',0,0,0,0 DS 16 DB 0 LSTFCB: DB 0,' ;This is a disk boot routine for the 1771/1791 type disk ;controllers. It would normally reside on track 0, ;sector 1, to be D1791: EQU TARBELLDOUBLE SMALL: EQU CROMEMCOSMALL LARGE: EQU CROMEMCOLARGE+TARBELL IF SMALL MAXSECT:EQU 18 ENDIF STRET: DS 2 RETPT: DS 2 HEXBUF: DS BUFSIZ+BUFSIZ LSTBUF: DS BUFSIZ BC: DS 2 DE: DS 2 HL: DS 2 IX: DS 2 IY: DS 2 DS 50 ler, and the Tarbell double- ; density controller. Select one. CROMEMCOSMALL: EQU 0 CROMEMCOLARGE: EQU 1 TARBELLSINGLE: EQ PRN',0,0,0,0 DS 16 DB 0 PC: DS 2 OLDPC: DS 2 LABPT: DS 2 FLAG: DS 1 LONG: DS 1 ADDR: DS 2 ALABEL: DS 2 DATA: Dloaded by the "B" command of the ;monitor at address 200H. By changing the equates ;below, it may be configured to load any sIF LARGE MAXSECT:EQU 26 ENDIF IF TARBELL DISK: EQU 78H ENDIF IF CROMEMCO DISK: EQU 30H ENDIF IF WD1771 REATB DISK JP GETSTAT BOOT: MOV AX,SEG MOV SS,AX MOV ES,AX MOV DS,AX JMP 0,SEG ION: -- To coordinate the game moves. ; ; CALLED BY: -- None ; ; CALLS: -- INITBD ; CPTRMV ; M: OUTB DISK IF CROMEMCO MOV AL,WAITBYTE OUT DISK+4 ;Turn on hardware wait ENDIF READ: INB DISK+4 IF TARBECHAR EQU 1 PRINTBUF EQU 9 INBUF EQU 10 SYSTEM EQU 5 ;*********************************************************** ; EQUATEDCOM:EQU 88H ENDIF IF WD1791 READCOM:EQU 80H ENDIF IF CROMEMCOLARGE WAITBYTE:EQU 0B1H ENDIF IF CROMEMCOSMALL;*********************************************************** ; ; SARGON ; ; Sargon is a computer chess playing program desi PLYRMV ; ; ARGUMENTS: None ;*********************************************************** DRIVER: MOV SP,STLL ROL AL JNC DONE ENDIF IF CROMEMCO ROR AL JC DONE ENDIF INB DISK+3 STOB LOOP READ GETSTAT: INB DISKS ;*********************************************************** ; PAWN: EQU 1 KNIGHT: EQU 2 BISHOP: EQU 3 ROOK: EQU 4 QUEE WAITBYTE:EQU 0A1H ENDIF ORG BOOTER PUT 100H XOR AX,AX MOV DS,AX MOV ES,AX MOV SS,AX UP MOV DI,LOAD MOVgned ; and coded by Dan and Kathe Spracklen. Copyright 1978. All ; rights reserved. No part of this publication may be ; reACK ; Set stack pointer MOV DX,CLRMSG ; Request color choice MOV CL,PRINTBUF CALL SYSTEM MOV CL,INCHAR ; Accept response+4 IF TARBELL ROL AL JC GETSTAT ENDIF IF CROMEMCO ROR AL JNC GETSTAT ENDIF DONE: IN DISK AND AL,9CH N: EQU 5 KING: EQU 6 WHITE: EQU 0 BLACK: EQU 80H BPAWN: EQU BLACK+PAWN ORG 100H PUT 100H ;************************* DX,SECTOR MOV BL,2 SECT: MOV AL,BL OUTB DISK+2 MOV CX,128 IF TARBELL INB DISK ;Get head load status ENDIF produced without the prior written permission. ;*********************************************************** ;*************** CALL SYSTEM CMP AL,57H ; Did player request white ? JZ DR05 ; Yes - branch CMP AL,42H ; Did player request black ? 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 OU********************************** ; MAIN PROGRAM DRIVER ;*********************************************************** ; FUNCT IF CROMEMCO INB DISK+4 ;Get head load status ENDIF TEST AL,20H MOV AL,READCOM JNZ OUTCOM MOV AL,READCOM+4 OUTCO******************************************** ; SYSTEM EQUATES ;*********************************************************** IN JNZ DRIVER ; No - error XOR AL,AL JP DR10 ; Jump DR05: MOV AL,BLACK ; Set computers color to black DR10: MOV [KOLOR],ALction table for any ; given piece. ;*********************************************************** DPOINT: EQU $-TBA******************************** ; DIRECT -- Direction Table. Used to determine the dir- ; ection of movement od Array. Used to hold the current position ; of the board during play. The board itself ; looks like:rd MOV AL,[KOLOR] ; Get color OR AL,AL ; Computer move ? JZ DR25 ; Yes - jump DR20: CALL PLYRMV ; Do player move DR25********************************************************* PVALUE: EQU $-TBASE-1 DB 1,3,3,5,9,10 ;************************* DR15: MOV DX,PLYDEP ; Request depth of search MOV CL,PRINTBUF CALL SYSTEM MOV CL,INCHAR CALL SYSTEM SUB AL,31H ; SuSE DB 20,16,8,0,4,0,0 ;*********************************************************** ; DCOUNT -- Direction Table Counter. f each piece. ;*********************************************************** DIRECT: EQU $-TBASE DB +09,+11,-11,-09 DB +10,- ; FFFFFFFFFFFFFFFFFFFF ; FFFFFFFFFFFFFFFFFFFF ; FF0402030506030204FF ; FF01: CALL CPTRMV ; Do computer move MOV BX,MOVENO INC B,[BX] ; Increment move number JP DR20 ; Back to player move ;************************************* ; PIECES -- The initial arrangement of the first rank of ; pieces on the boarbtract Ascii constant JB DR15 ; Under minimum - prompt again CMP AL,6 ; Over maximum of 6 ? JNB DR15 ; Yes - prompt agaUsed to determine ; the number of directions of movement for any ; given piece. ;********************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 ; ******************************************************** ; TABLES SECTION ;***************************************************d. Use to set up the board ; for the start of the game. ;*********************************************************in INC AL ; Increment by one MOV [PLYMAX],AL ; Set desired depth MOV DX,CRLF ; Output CRLF MOV CL,PRINTBUF CALL SYST*************************************** DCOUNT: EQU $-TBASE DB 4,4,8,4,4,8,8 ;************************************************************************ ; DPOINT -- Direction Table Pointer. Used to determine ; where to begin in the dire FF0000000000000000FF ; FF8181818181818181FF ; FF8482838586838284FF ; FFFFFFFF******** ORG 200H ; Start at 200H START: ORG START+80H PUT START+80H TBASE: EQU START+100H ;**************************** PIECES: EQU $-TBASE DB 4,2,3,5,6,3,2,4 ;*********************************************************** ; BOARD -- BoarEM XOR AL,AL MOV [COLOR],AL ; Set color to white INC AL MOV [MOVENO],AL ; Set move number to 1 CALL INITBD ; Init boa*************** ; PVALUE -- Point Value. Gives the point value of each ; piece, or the worth of each piece. ;**FFFFFFFFFFFF ; FFFFFFFFFFFFFFFFFFFF ; The values of FF form the border of the ; board, anQU ATKLST BACT: EQU ATKLST+7 ;*********************************************************** ; PLIST -- Pinned Piece Array. half for black. ; It is used to hold the attackers of any given ; square in the order of their value. *************************************** SCORE: DW 0,0,0,0,0,0 ;*********************************************************** awn ; 2 -- Knight ; 3 -- Bishop ; 4 -- Rook ; king and the second holding the position of ; the black king. ; ; POSQ -- Position of Queens. Like d are used to indicate when a piece ; moves off the board. The individual bits of ; the other bytes in This is a two part array. ; PLISTA contains the pinned piece position. ; PLISTD contains the directio; ; 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 ; 5 -- Queen ; 6 -- King ; 7 -- Not used ; 0 -- Empty Square ;**POSK,but for queens. ;*********************************************************** POSK: DB 24,95 POSQ: DB 14,94 DB -1 ;* the board array are as ; follows: ; Bit 7 -- Color of the piece ; 1 -- Black ; n from the pinned ; piece to the attacker. ;*********************************************************** PLIST: EQ 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 ; ********************************************************* BOARD: EQU $-TBASE BOARDA: DS 120 ;**************************************************************************************** ; SCORE -- Score Array. Used during Alpha-Beta pruning to ; 0 -- White ; Bit 6 -- Not used ; Bit 5 -- Not used ; Bit 4 --Castle fU $-TBASE-1 PLISTD: EQU PLIST+10 PLISTA: DW 0,0,0,0,0,0,0,0,0,0 ;**********************************************************ay 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***************************** ; ATKLIST -- Attack List. A two part array, the first ; half for white and the second hold the scores at each ply. It includes two ; "dummy" entries for ply -1 and ply 0. ;********************lag for Kings only ; Bit 3 -- Piece has moved flag ; Bits 2-0 Piece type ; 1 -- P* ; POSK -- Position of Kings. A two byte area, the first ; byte of which hold the position of the white ; ,0,0,0,0,0,0 DW 0,0,0,0,0,0,0,0,0,0 ;*********************************************************** ; STACK -- Contains thPTRI: DW PLYIX MLPTRJ: DW 0 SCRIX: DW 0 BESTM: DW 0 MLLST: DW 0 MLNXT: DW MLIST ;***************************************t by the ; Alpha-Beta pruning process. ; ; MLLST -- Pointer to the previous move placed in the move ; through an exchange by the player not on the ; move. ; ; PTSW1 -- The maximum number of points whic- Number of Pins. Count and pointer into the ; pinned piece list. ; ; MLPTRI -- Pointer into the ply table whi pruning. ; ; NPLY -- Current ply number during Alpha-Beta ; pruning. ; ; CKFLG -- A non-zero value ie stack for the program. ;*********************************************************** ORG START+2FFH STACK: ;******************************** ; VARIABLES SECTION ; ; KOLOR -- Indicates computer's color. White is 0, and ; Black is 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 higch tells ; which pair of pointers are in current use. ; ; MLPTRJ -- Pointer into the move list to the move thatndicates the king is in check. ; ; MATEF -- A zero value indicates no legal moves. ; ; VALM -- The score of the curre*********************************************** ; TABLE INDICES SECTION ; ; M1-M4 -- Working indices used to index into ;80H. ; ; COLOR -- Indicates color of the side with the move. ; ; P1-P3 -- Working area to hold the contents of the boa 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 mov is ; currently being processed. ; ; SCRIX -- Score Index. Pointer to the score table for ; the pnt move being examined. ; ; BRDC -- A measure of mobility equal to the total number ; of squares white can mo the board array. ; ; T1-T3 -- Working indices used to index into Direction ; Count, Direction Valrd ; array for a given square. ; ; PMATE -- The move number at which a checkmate is ; discovered 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 ; ly being examined. ; ; BESTM -- Pointer into the move list for the move that ; is currently considered the besve to minus the number ; black can move to. ; ; PTSL -- The maximum number of points which could be lost ; ue, and Piece Value tables. ; ; INDX1 -- General working indices. Used for various ; INDX2 purposes. ; ; NPINS -during look ahead. ; ; MOVENO -- Current move number. ; ; PLYMAX -- Maximum depth of search using Alpha-Beta ; the white pieces minus the total value of the ; black pieces. ; ; BC0 -- The value of board contFLG -- A field in the move entry which contains flag ; information. The meaning of each bit is as ; ble location ; in the move list. ; ; MLPTR -- The Move List is a linked list of individual ; move MLEND: EQU MLIST+2040 MLPTR: EQU 0 MLFRP: EQU 2 MLTOP: EQU 3 MLFLG: EQU 4 MLVAL: EQU 5 ;*******************************G: 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 move. ; Bit 3 -- This flag is set is there is a piece ; captured, and that piece has movrol(BRDC) at ply 0. ; ; MV0 -- The value of material(MTRL) at ply 0. ; ; PTSCK -- A non-zero value indicates that th follows: ; Bit 7 -- The color of any captured piece ; 0 -- White ; s each of which is 6 bytes in length. The ; move list pointer(MLPTR) is the link field ; within a move**************************** ; PROGRAM CODE SECTION ;*********************************************************** ; BOARD SETU0 BMOVES: DB 35,55,10H DB 34,54,10H DB 85,65,10H DB 84,64,10H ;*******************************************************ed at ; least once. ; Bits 2-0 Describe the captured piece. A ; e piece has ; just moved itself into a losing exchange of ; material. ; ; BMOVES -- Our very tiny 1 -- Black ; Bit 6 -- Double move flag (set for castling and ; en passant pawn capture. ; ; 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 th**** ; MOVE LIST SECTION ; ; MLIST -- A 2048 byte storage area for generated moves. ; This area must be largezero value indicates no capture. ; ; MLVAL -- The field in the move entry which contains the ; score assigned book of openings. Determines ; the first move for the computer. ; ;**********************************************s) ; Bit 5 -- Pawn Promotion flag; set when pawn ; promotes. ; Bit 4 -- Wh ; 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 ; ; CALL enough to hold all ; the moves for a single leg of the move tree. ; ; MLEND -- The address of the last availato the move. ; ;*********************************************************** ORG START+300H PUT START+300H MLIST: DS 2048 ************* 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 CKFLen set, this flag indicates that ; this is the first move for the ; piece on theS: None ; ; ARGUMENTS: None ;*********************************************************** INITBD: MOV CX,60 ; Pre-fillto be added for the new position. ;*********************************************************** PATH: ADD [M2],CL ; Add directon is empty ; 1 -- Encountered a piece of the ; opposite color ; wn ? JNZ MP1 ; No-Skip DEC AL ; Decrement for black Pawns MP1: AND AL,7 ; Get piece type MOV [T1],AL ; Save piece typ MOV B,[SI+2],24 MOV B,[SI+3],94 RET ;*********************************************************** ; PATH ROUTINE ;********************* ; PIECE MOVER ROUTINE ;*********************************************************** ; FUNCTION: To generat 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 squarion constant to previous position MOV SI,[M2] ; Load board index MOV AL,[SI+BOARD] ; Get contents of board CMP AL,-1 ; I 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 p******************************************************* ; FUNCTION: To generate a single possible move for a given ; e all the possible legal moves for a ; given piece. ; ; CALLED BY: GENMOV ; ; CALLS: PATH ; es MOV [SI+21],AL ; White pieces LAHF OR AL,080H SAHF ; Change to black MOV [SI+91],AL ; Black pieces MOV B,[SI+31n border area ? JZ PA2 ; Yes - jump MOV [P2],AL ; Save piece MOV AH,AL ; Save piece in register AND AL,7 ; Clear fla 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 piece along its current path of motion including: ; Fetching the contents of the board at the new ; ADMOVE ; CASTLE ; ENPSNT ; ; ARGUMENTS: The piece to be moved. ;**********************************],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 gs MOV [T2],AL ; Save piece type JZ RET ; Return if empty XOR AH,[P1] ; Compare with moving piece SHL AH ; Set flag 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 position, and setting a flag describing the ; contents: ; 0 -- New positi************************* MPIECE: XOR AL,[BX] ; Piece to move AND AL,87H ; Clear flag bit CMP AL,BPAWN ; Is it a black Pa 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 MOV AL,2 SBB AL,0 RET ; Return PA2: MOV AL,3 ; Set off board flag RET ;******************************************eady for new direction ? JNC MP15 ; Yes - Jump AND AL,AL ; Test for empty square PUSHF MOV AL,[T1] ; Get piece moved OUTINE ;*********************************************************** ; FUNCTION: -- To test for en passant Pawn capture and ump JMP MP15 ; Jump MP30: POPF JNZ MP15 ; No - Jump MP31: CALL ADMOVE ; Add to move list JMP MP15 ; Jump MP35: POPF ; Find difference JNS EP10 ; Positive ? Yes - Jump NEG AL ; Else take absolute value EP10: CMP AL,10 ; Is difference 1or direction CMP AL,3 ; On diagonal moves ? JC MP35 ; Yes - Jump JZ MP30 ; -or-jump if on 2 square move POPF JNZ MPank ? JNC RET ; No - return MOV SI,[MLPTRJ] ; Get pointer to previous move TEST B,[SI+MLFLG],010H ; First move for that p CMP AL,PAWN+1 ; Is it a Pawn ? JC MP20 ; Yes - Jump CALL ADMOVE ; Add move to list POPF JNZ MP15 ; No - Jump MOV ; to add it to the move list if it is ; legal. ; ; CALLED BY: -- MPIECE ; ; CALLS: 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] 15 ; No - jump MOV AL,[M2] ; Get "to" position CMP AL,91 ; Promote white Pawn ? JNC MP25 ; Yes - Jump CMP AL,29 ; Piece ? JZ RET ; No - return MOV AL,[SI+MLTOP] ; Get "to" position MOV [M4],AL ; Store as index to board MOV SI,[M4] ;AL,[T1] ; Piece type CMP AL,KING ; King ? JZ MP15 ; Yes - Jump CMP AL,BISHOP ; Bishop, Rook, or Queen ? JNC MP10 ; Y-- ADMOVE ; ADJPTR ; ; ARGUMENTS: -- None ;*********************************************************** EL,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 romote black Pawn ? JNC MP26 ; No - Jump MP25: OR B,[P2],020H ; Set promote flag MP26: CALL ADMOVE ; Add to move list IN Load board index MOV AL,[SI+BOARD] ; Get piece moved MOV [P3],AL ; Save it AND AL,7 ; Get piece type CMP AL,PAWN ; Ies - Jump MP15: INC DI ; Increment direction index DEC CH JNZ MP5 ; Decr. count-jump if non-zerc MOV AL,[T1] ; Piece tNPSNT: MOV AL,[M1] ; Set position of Pawn TEST B,[P1],080H ; Check color, is it white ? JZ EP5 ; Yes - skip ADD AL,10 ;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] ; ReC DI ; Adjust to two square move DEC CH TEST B,[P1],008H ; Check Pawn moved flag, has it moved before ? JZ MP10 ; No - Js it a Pawn ? JNZ RET ; No - return MOV AL,[M4] ; Get "to" position MOV BX,M2 ; Get present "to" position SUB AL,[BX]ype CMP AL,KING ; King ? JNZ RET JMP CASTLE ; Yes - Try Castling ; ***** PAWN LOGIC ***** MP20: MOV AL,CH ; Counter f Add 10 for black EP5: CMP AL,61 ; On en passant capture rank ? JC RET ; No - return CMP AL,69 ; On en passant capture rstore "from" position MOV [M1],AL ;*********************************************************** ; ADJUST MOVE LIST POINTER ; Clear color bit CMP AL,ROOK ; Has Rook ever moved ? JNZ CA20 ; Yes - Jump MOV AL,CL ; Restore Rook position JP CAE ; ADJPTR ; ; ARGUMENTS: -- None ;*********************************************************** CASTLE: [P2],AL ; Zero move flags CALL ADMOVE ; Put Rook move in list CALL ADJPTR ; Re-adjust move list pointer MOV AL,[M3] ; SUB BX,6 ; Back up list pointer MOV [MLLST],BX ; Save list pointer MOV [BX],0 ; Zero out link RET ; Return ;***** MOV BX,M1 ; King position CMP AL,[BX] ; Reached King ? JNZ CA10 ; No - jump SUB AL,CH ; Determine King's position FOR DOUBLE MOVE ;*********************************************************** ; FUNCTION: -- To adjust move list pointer to 15 ; Jump CA10: MOV SI,[M3] ; Load board index MOV AL,[SI+BOARD] ; Get contents of board AND AL,AL ; Empty ? JNZ CA20 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****************************************************** ; CASTLE ROUTINE ;***************************************************** SUB AL,CH MOV [M2],AL ; Save it MOV BX,P2 ; Address of flags MOV B,[BX],40H ; Set double move flag CALL ADMOVE ; Putlink around ; second move in double move. ; ; CALLED BY: -- ENPSNT ; CASTLE ; ; No - Jump MOV AL,[M3] ; Current position CMP AL,22 ; White Queen Knight square ? JZ CA15 ; Yes - Jump CMP AL,92 ; 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****** ; FUNCTION: -- To determine whether castling is legal ; (Queen side, King side, or both) and add it king move in list MOV BX,M1 ; Addr of King "from" position MOV AL,[BX] ; Get King's "from" position MOV [BX],CL ; Stor (This mini-routine is not really called, ; but is jumped to to save time.) ; ; CALLS: -- None ; Black Queen Knight square ? JZ CA15 ; Yes - Jump CALL ATTACK ; Look for attack on square AND AL,AL ; Any attackers ? 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 ; ; to the move list if it is. ; ; CALLED BY: -- MPIECE ; ; CALLS: -- ATTACK ; ADMOVe Rook "from" position SUB AL,CH ; Get Rook "to" position MOV [M2],AL ; Store Rook "to" position XOR AL,AL ; Zero MOV; ARGUMENTS: -- None ;*********************************************************** ADJPTR: MOV BX,[MLLST] ; Get list pointer JNZ CA20 ; Yes - Jump MOV AL,[M3] ; Current position CA15: ADD AL,CH ; Next position MOV [M3],AL ; Save as board index ; CALLED BY: -- MPIECE ; ENPSNT ; CASTLE ; ; CALLS: -- None ; ; ARGUMENT: -- N 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 generate the move set for all of the ; pieces of a given color. ; ; CALL******************************************* INCHK: MOV AL,[COLOR] ; Get color INCHK1: MOV BX,POSK ; Addr of white King positiX,AX ; Store zero in link address CLD STOW MOV AL,[M1] ; Store "from" move position STOB MOV AL,[M2] ; Store "to" mon INC AL ; Incr to next board position CMP AL,99 ; End of board array ? JNZ GM5 ; No - Jump RET ; Return ;*****one ;*********************************************************** ADMOVE: MOV DX,[MLNXT] ; Addr of next loc in move list MOV chain init. MOV AL,21 ; First position on board GM5: MOV [M1],AL ; Save as index MOV SI,[M1] ; Load board index MOV AED 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 positioove position STOB MOV AL,[P2] ; Store move flags/capt. piece STOB XOR AL,AL ; Store initial move value STOB MOV [M****************************************************** ; CHECK ROUTINE ;******************************************************BX,MLEND ; Address of list end SUB BX,DX ; Calculate difference JC AM10 ; Jump if out of space MOV BX,[MLLST] ; Addr of L,[SI+BOARD] ; Fetch board contents AND AL,AL ; Is it empty ? JZ GM10 ; Yes - Jump CMP AL,-1 ; Is it a border square ? ***************************** 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 ANDLNXT],DI ; Save address for next move MOV DI,DX RET ; Return AM10: MOV [BX],0 ; Abort entry on table ovflow RET ;******* ; FUNCTION: -- To determine whether or not the ; King is in check. ; ; CALLED BY: -- GENMOV ; prev. list area MOV [MLLST],DX ; Save next as previous MOV [BX],DX ; Store link address TEST B,[P1],008H ; Has moved piec JZ GM10 ; Yes - Jump MOV [P1],AL ; Save piece MOV BX,COLOR ; Address of color of piece XOR AL,[BX] ; Test color of piX,[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 ********************************************************* ; GENERATE MOVE ROUTINE ;******************************************* FNDMOV ; EVAL ; ; CALLS: -- ATTACK ; ; ARGUMENTS: -- Color of King ;****************e moved before ? JNZ AM5 ; Yes - jump OR B,[P2],010H ; Set first move flag AM5: XCHG DX,DI ; Address of move area XOR Aece TEST AL,080H ; Match ? JNZ GM10 CALL MPIECE ; Yes - call Move Piece GM10: MOV AL,[M1] ; Fetch current board positi ;*********************************************************** ; FUNCTION: -- To find all attackers on a given square ; for a Knight CALL ATKADJ ; Scan adjacent squares MOV AH,20H ; Bit 5 set MOV AL,[BP+11] ; Get piece at +11 AND AL,87H ; PINFND ; CASTLE ; INCHK ; ; CALLS: -- ATKADJ ; AT attacker on adjacent ; squares. ; ; CALLED BY: -- ATTACK ; ; CALLS: -- ATKCHK ; ; ARGUMENTS: -- example a queen lined up behind a bishop ; of her same color along a diagonal.) The ; ? JNZ AT20 ; No - jump OR [BP-9],AH ; Turn on bit 5 AT20: MOV SI,DIRECT+TBASE ; Load direction table MOV AH,BISHOP ; Che by scanning outward from the square ; until a piece is found that attacks ; that s; 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 KOUT ; ; ARGUMENTS: -- None ;*********************************************************** ATTACK: PUSH CX ; Save Register The piece under attack. The attacker. ;*********************************************************** ATKADJ: MOV CX,8 ; 8 dir bishop is then said to be transparent to the ; queen, since both participate in the ; attack.ck for a Bishop CALL ATKOUT ; Scan outwards MOV AH,ROOK ; Check for a Rook CALL ATKOUT ; Scan outwards XOR AL,AL ; Nquare, or a piece is found that ; doesn't attack that square, or the edge ; of the board is repiece 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 CX 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 directi ; ; In the case where this routine is called ; by CASTLE or INCHK, the routine is ; o attackers POP CX ; Restore CX reg RET ; Return ;*********************************************************** ; ATTACached. ; ; In determining which pieces attack ; a square, this routine also takes into ; AT10: MOV AL,[BP-11] ; Get piece at -11 AND AL,87H ; Clear flag bit CMP AL,PAWN ; White Pawn ? JNZ AT15 ; No - jump T+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 piec terminated as soon as an attacker of the ; opposite color is encountered. ; ; CALLED BY: -- POINTSK ADJACENT SCAN ROUTINE ;*********************************************************** ; FUNCTION: -- To scan for a specified account the ability of certain pieces to ; attack through another attacking piece. (For ; 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 e AND AL,7 ; Get piece type CMP AL,AH ; Same as what we want ? JNZ AA10 ; No - jump CALL ATKCHK ; Check and save atttack JP AO10 ; Keeping going that direction ;*********************************************************** ; ATTACK CHECK A JZ AO22 ; Yes - jump CMP AL,QUEEN ; Queen ? JZ AO20 ; Yes - jump CMP AL,PAWN+20H ; Pawn with bit 5 ? JZ AO21 ; Yes -POP 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 ? JZcker. ;*********************************************************** ATKOUT: MOV CL,4 ; 4 directions to scan AO5: MOV DX,0C0H HK, control is returned to ; the aforementioned routines as soon as an ; attacker of the opposacker AA10: LOOP AA5 ; Go check for next direction RET ; Return ;******************************************************ND SAVE ROUTINE ;*********************************************************** ; FUNCTION: -- To check if a piece can attack 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 AN ; Bitmask for color flags XCHG AX,BX ; Save AX LODB ; Get direction byte CBW ; Convert to word XCHG AX,BX ; Save ite color is encountered. ; ; CALLED BY: -- ATTACK ; ; CALLS: -- None ; ; ARGUMENTS: -- The attacking piece. The***** ; ATTACK OUTWARD SCAN ROUTINE ;*********************************************************** ; FUNCTION: -- To scan fothe target ; square and save the attacking piece value ; in the attack list. ; ; FH ; 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 bitdirection and restore AX MOV DI,BP ; Load pointer to piece AO10: ADD DI,BX ; Add direction constant MOV AL,[DI] ; Get at piece under attack. ;*********************************************************** ATKCHK: MOV AL,[DI] ; Get piece CMP B,[T1r a specified attacker outwards ; from the piece under attack, until found ; or edge of the bo The pin piece list is checked for the ; attacking piece, and if found there, the ; piece 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: MOtacking piece AND AL,27H ; Get piece type and bit 5 JZ AO10 ; No piece, keep going CMP AL,AH ; Same as what we want ? ],7 ; Call from POINTS ? JZ ACK10 ; Yes - jump XOR AL,[BP] ; Attacker and target same color ? JNS RET ; Yes - return ard is reached. ; ; CALLED BY: -- ATTACK ; ; CALLS: -- ATKCHK ; ; ARGUMENTS: -- The piece under attack. The attais not included in the attack list. ; ; In the case where ATTACK is called by ; CASTLE or INCV AL,1 ; Set attacker found flag POP CX ; Restore CX reg RET ; Return from ATTACK ACK10: PUSH CX ; Save regs PUSH DI 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 ; Combaddress ACK30: OR DH,DH ; Queen found this scan ? JZ ACK31 ; No - jump MOV AL,QUEEN ; Use Queen slot in attack list ACK3oard MOV [P1],AL ; Save MOV CH,8 ; Init scan direction count XOR AL,AL MOV [INDX2],AL ; Init direction index MOV DI,pposite direction ? CMP AH,BL ; Same as attacking direction ? JZ ACK15 ; Yes - jump ACK20: POP AX ; Restore regs. POP ATTACK ; ; ARGUMENTS: -- None ;*********************************************************** PINFND: XOR AL,AL ; Zero pi MOV CL,[NPINS] ; Number of pinned pieces JCXZ ACK26 ; No pins - jump PUSH AX ; Save AX MOV AX,DI ; Load piece pointeine with point value ACK40: MOV [DI],AL ; Put back into attack list POP DI ; Restore regs POP CX RET ; Return ;***1: 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 savedDI POP CX RET ; Return to ATTACK ACK25: POP AX ; Restore AX ACK26: MOV CL,AL ; Put piece in CL AND CL,7 ; Get piecen count MOV [NPINS],AL MOV DX,POSK ; Addr of King/Queen pos list PF1: MOV BP,DX MOV AL,[BP] ; Get position of royal pier in AX SUB AX,BOARDA ; Minus BOARDA for position MOV DI,PLISTA ; Pin list address ACK15: OR AL,AL ; Set flags for REP R******************************************************** ; PIN FIND ROUTINE ;*************************************************ttack 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 PF5 type MOV DI,PVALUE+TBASE ; PVALUE list address ADD DI,CX ; Point to piece value MOV CL,[DI] ; Get point value of piece ce AND AL,AL ; Is it on board ? JNZ PF1A ; Yes- continue JMP PF26 PF1A: CMP AL,-1 ; At end of list ? JZ RET ; Yes rEPZ SCAB ; Search list for position JNZ ACK25 ; Continue if not found OR AH,AH ; Is this the first find ? JNZ ACK20 ********** ; FUNCTION: -- To produce a list of all pieces pinned ; against the King or Queen, for both whit 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 pinned MOV DI,ATKLST ; Init address of attack list TEST AL,80H ; Is it white ? JZ ACK30 ; Yes - jump ADD DI,7 ; Attack list eturn MOV [M3],AL ; Save position as board index MOV SI,[M3] ; Load index to board MOV AL,[SI+BOARD] ; Get contents of b ; No - jump MOV AH,[DI+9] ; Get direction CMP AH,BL ; Same as attacking direction ? JZ ACK15 ; Yes - jump NEG AH ; Oe ; and black. ; ; CALLED BY: -- FNDMOV ; EVAL ; ; CALLS: -- PATH ; piece position JZ PF15 ; Yes - jump AND AL,AL ; Possible pin ? JZ JPF25 ; No - jump MOV AL,[T2] ; Piece type encounIncrement direction index DEC CH JZ PF26 ; Done ? Yes - Continue JMP PF2 PF26: INC DX ; Incr King/Queen pos index JMP XCHG DX,BX ; Reverse for black PF19A: MOV AL,[BX] ; Number of defenders XCHG DX,BX ; Reverse for attackers SUB AL,[BX] V DH,[SI+PVALUE] ; Get attacked piece value SAL DH ; Double it MOV CH,DH ; Save CALL NEXTAD ; Retrieve first attacker JMP PF5 ; Jump PF19: MOV AL,[P1] ; Load King or Queen AND AL,7 ; Clear flags CMP AL,QUEEN ; Queen ? JNZ PF20 ; No - j[DE] XCHG CX,[BC] ; Swap regs. MOV AL,[P1] ; Piece attacked MOV BX,WACT ; Addr of white attkrs/dfndrs MOV DX,BACT ; tered CMP AL,QUEEN ; Queen ? JZ PF19 ; Yes - jump MOV BL,AL ; Save piece type MOV AL,CH ; Direction counter CMP AL, PF1 ; Jump ;*********************************************************** ; EXCHANGE ROUTINE ;***************************** ; 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 ; Juump PUSH CX ; Save regs. PUSH DX PUSH DI XOR AX,AX ; Zero out attack list MOV CX,7 MOV BX,ATKLST XCHG DI,BX CLAddr of black attkrs/dfndrs TEST AL,080H ; Is piece white ? JZ XC5 ; Yes - jump XCHG DX,BX ; Swap list pointers XC5: M5 ; Non-diagonal direction ? JC PF10 ; Yes - jump MOV AL,BL ; Piece type CMP AL,BISHOP ; Bishop ? JNZ PF25 ; No - ju****************************** ; FUNCTION: -- To determine the exchange value of a ; piece on a given squar 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 atD REP STOW XCHG DI,BX MOV AL,7 ; Set attack flag MOV [T1],AL CALL ATTACK ; Find attackers/defenders MOV BX,WACT OV CH,[BX] ; Init list counts XCHG DX,BX MOV CL,[BX] XCHG DX,BX XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Restore rmp JMP PF20 ; Jump JPF25: JMP PF25 PF10: MOV AL,BL ; Piece type CMP AL,ROOK ; Rook ? JNZ PF25 ; No - jump JMP PF20e by examining all ; attackers and defenders of that piece. ; ; CALLED BY: -- POINTS ; ; CALLS: -- LISTD],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 a ; White queen attackers MOV DX,BACT ; Black queen attackers TEST B,[P1],080H ; Is queen white ? JZ PF19A ; Yes - skip egs. MOV CL,0 ; Init attacker/defender flag MOV DL,0 ; Init points lost count MOV SI,[T3] ; Load piece value index MO ; Jump PF15: AND AL,AL ; Possible pin ? JNZ PF25 ; No - jump MOV AL,[M2] ; Save possible pin position MOV [M4],AL NEXTAD ; ; ARGUMENTS: -- None. ;*********************************************************** XCHNG: XCHG BX,[HL] XCHG DX,ttacker value CALL NEXTAD ; Retrieve next defender value JNZ XC15 ; Jump if none XC18: LAHF XC19: TEST CL,001H ; Attack*************************** ;FUNCTION: -- To perform a static board evaluation and ; derive a score for a gi ; Decrement list count NX5: INC BX ; Increment list pointer CMP AL,[BX] ; Check next item in list JZ NX5 ; Jump if emp6A ; Yes - Jump JMP PT6X ; Jump PT6AA: TEST B,[BX],010H ; Castled yet ? JZ PT6A ; No - jump MOV AL,+6 ; Bonus for cas that piece from the list. ; ; CALLED BY: -- XCHNG ; ; CALLS: -- None ; ; ARGUMENTS: -- Attack list ax MOV SI,[M3] ; Load board index MOV AL,[SI+BOARD] ; Get piece from board CMP AL,-1 ; Off board edge ? JNZ PT5A JMP er or defender ? JZ XC20 ; Jump if defender NEG CH ; Negate value for attacker XC20: ADD DL,CH ; Total points lost SAHven board position ; ; CALLED BY: -- FNDMOV ; EVAL ; ; CALLS: -- ATTACK ; XCHNG ;ty 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 ; Jumddresses. ; Side flag ; Attack list counts ;*************************************************PT25 ; Yes - jump PT5A: MOV BX,P1 ; Save piece, if any MOV [BX],AL AND AL,7 ; Save piece type, if any MOV [T3],AL CMF JZ RET ; Return if none MOV CH,BL ; Prev attckr becomes defender JMP XC10 ; Jump ;******************************** LIMIT ; ; ARGUMENTS: -- None ;*********************************************************** POINTS: XOR AL,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 m********** NEXTAD: INC CL ; Increment side flag XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Swap registers XCHG CH,CL ;P AL,KNIGHT ; Less than a Knight (Pawn) ? JC PT6X ; Yes - Jump CMP AL,ROOK ; Rook, Queen or King ? JC PT6B ; No - jump *************************** ; NEXT ATTACKER/DEFENDER ROUTINE ;*********************************************************** ; FAL ; Zero out variables MOV [MTRL],AL MOV [BRDC],AL MOV [PTSL],AL MOV [PTSW1],AL MOV [PTSW2],AL MOV [PTSCK],AL MOn ;*********************************************************** ; 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 Swap list counts XCHG DX,BX ; Swap list pointers XOR AL,AL CMP AL,CH ; At end of list ? JZ NX6 ; Yes - jump DEC CH CMP AL,KING ; Is it a King ? JZ PT6AA ; Yes - jump MOV AL,[MOVENO] ; Get move number CMP AL,7 ; Less than 7 ? JC PTUNCTION: -- To retrieve the next attacker or defender ; piece value from the attack list, and delete ; 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 indePT6D ; Jump if white MOV AL,+2 ; Two point penalty for black PT6D: MOV BX,BRDC ; Get address of board control ADD [BX],AMP AL,[BX] ; Compare to current value JC PT23 ; Jump if greater than MOV [BX],AL ; Store as new 2nd max lost PT23: TEST Store new value as max lost MOV SI,[MLPTRJ] ; Load pointer to this move MOV AL,[M3] ; Get position of lost piece CMP AL,[EST B,[COLOR],080H ; Is color of side just moved white ? JZ PT28 ; Yes - jump NEG AL ; Negate for black PT28: MOV BX,MTRL25 ; Yes - jump CALL XCHNG ; Evaluate exchange, if any XOR AL,AL ; Check for a loss CMP AL,DL ; Points lost ? JZ PT2],AL ; Store as max points won XOR AL,AL ; Zero out 2nd max points won MOV [PTSW2],AL PT25A: MOV AL,[PTSL] ; Get max pointL ; Add on penalty/bonus points PT6X: XOR AX,AX ; Zero out attack list MOV CX,7 MOV BX,ATKLST XCHG DI,BX CLD REP B,[P1],080H ; Test piece color MOV AL,DH ; Value of piece JZ PT24 ; Jump if white NEG AL ; Negate for black PT24: MOV 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 3 ; No - Jump DEC DH ; Deduct half a Pawn value MOV AL,[P1] ; Get piece under attack XOR AL,[COLOR] ; Compare color of 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]STOW XCHG DI,BX CALL ATTACK ; Build attack list for square MOV BX,BACT ; Get black attacker count addr MOV AL,[WACT] ;BX,MTRL ; Get addrs of material total ADD AL,[BX] ; Add new value MOV [BX],AL ; Store PT25: MOV AL,[M3] ; Get current bOV 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 ; side just moved with piece TEST AL,080H ; Do colors match ? MOV AL,DL ; Points lost JNZ PT20 ; Jump if no match MOV B ; 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 Get white attacker count SUB AL,[BX] ; Compute count difference MOV BX,BRDC ; Address of board control ADD AL,[BX] ; Aoard position INC AL ; Increment CMP AL,99 ; At end of board ? JZ PT25AA JMP PT5 ; No - jump PT25AA: MOV AL,[PTSCK] BX] ; 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 difX,PTSL ; Previous max points lost CMP AL,[BX] ; Compare to current value JC PT23 ; Jump if greater than MOV [BX],DL ; zero ? JZ PT27 ; Yes - jump DEC AL ; Decrement it SHR AL ; Divide it by 2 PT27: SUB AL,CH ; Subtract points lost Tccum board control score MOV [BX],AL ; Save MOV AL,[P1] ; Get piece on current square AND AL,AL ; Is it empty ? JZ PT; Moving piece lost flag AND AL,AL ; Was it lost ? JZ PT25A ; No - jump MOV AL,[PTSW2] ; 2nd max points won MOV [PTSW1ference MOV CH,AL ; Save MOV AL,[PTSCK] ; Moving piece lost flag AND AL,AL ; Is it zero ? JZ PT29 ; Yes - jump MOV ********************* ; MOVE ROUTINE ;*********************************************************** ; FUNCTION: -- To executgister ; Output - Limited value in the AL register. ;*********************************************************flag MOV [DI+BOARD],DL ; Insert piece at new position MOV B,[SI+BOARD],0 ; Empty previous position TEST DH,040H ; Double MLVAL],AL ; Save score in move list RET ; Return ;*********************************************************** ; LIMIT RO ; "To" position MOV [M2],AL ; Save INC BX ; Increment pointer MOV DH,[BX] ; Get captured piece/flags MOV SI,[M1] ; CH,0 ; Zero board control points PT29: MOV AL,6 ; Load board control limit CALL LIMIT ; Limit to plus or minus value MOVe a move from the move list on the ; board array. ; ; CALLED BY: -- CPTRMV ; PLYRMV ; ** 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 RETUTINE ;*********************************************************** ; FUNCTION: -- To limit the magnitude of a given value Load "from" pos board index MOV DL,[SI+BOARD] ; Get piece moved TEST DH,020H ; Test Pawn promotion flag JNZ MV15 ; Jump DH,AL ; Save limited value MOV AL,DL ; Get material points ADD AL,AL ; Multiply by 4 ADD AL,AL ADD AL,DH ; Add boar EVAL ; FNDMOV ; VALMOV ; ; CALLS: -- None ; ; ARGUMENTS: -- None ;** 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 B; to another given value. ; ; CALLED BY: -- POINTS ; ; CALLS: -- None ; ; ARGUMENTS: -- Input -if set MOV AL,DL ; Piece moved AND AL,7 ; Clear flag bits CMP AL,QUEEN ; Is it a queen ? JZ MV20 ; Yes - jump CMP Ad control TEST B,[COLOR],080H ; Is color of side just moved white ? JNZ PT30 ; No - jump NEG AL ; Negate for white PT30********************************************************* MOVE: MOV BX,[MLPTRJ] ; Load move list pointer INC BX ; 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,004 Value, to be limited in the CH ; register. ; - Value to limit to in the AL reL,KING ; Is it a king ? JZ MV30 ; Yes - jump MV5: MOV DI,[M2] ; Load "to" pos board index OR DL,008H ; Set piece moved : ADD AL,80H ; Rescale score (neutral = 80H) MOV [VALM],AL ; Save score MOV SI,[MLPTRJ] ; Load move list pointer MOV [SI+past link bytes INC BX MV1: MOV AL,[BX] ; "From" position MOV [M1],AL ; Save INC BX ; Increment pointer MOV AL,[BX] H ; Change Pawn to a Queen JMP MV5 ; Jump MV20: MOV BX,POSQ ; Addr of saved Queen position MV21: TEST DL,080H ; Is QueenM20 ; Yes - jump CMP AL,KING ; Was it a King ? JZ UM30 ; Yes - jump UM5: TEST DH,010H ; Is this 1st move for piece ? ; Increment past link bytes INC BX UM1: MOV AL,[BX] ; Get "from" position MOV [M1],AL ; Save INC BX ; Increment poin UM30: MOV BX,POSK ; Address of saved King pos TEST DH,040H ; Was it a castle ? JZ UM21 ; No - jump AND DL,0EFH ; CleaE ROUTINE ;*********************************************************** ; FUNCTION: -- To reverse the process of the move roUM10 ; Yes - jump INC BX ; Increment to black Queen pos UM10: MOV AL,[M2] ; Queen's previous position MOV [BX],AL ; Sav white ? JZ MV22 ; Yes - jump INC BX ; Increment to black Queen pos MV22: MOV AL,[M2] ; Get new Queen position MOV [BXJNZ UM16 ; Yes - jump UM6: MOV DI,[M1] ; Load "from" pos board index MOV [DI+BOARD],DL ; Return to previous board pos MOVter 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 UM1utine, ; thereby restoring the board array to its ; previous position. ; ; CALLED BY: -- Ve RET ; Return UM15: AND DL,0FBH ; Restore Queen to Pawn JMP UM5 ; Jump UM16: AND DL,0F7H ; Clear piece moved flag ],AL ; Save JMP MV5 ; Jump MV30: MOV BX,POSK ; Get saved King position TEST DH,020H ; Castling ? JZ MV21 ; No - jump AL,DH ; Get captured piece, if any AND AL,8FH ; Clear flags MOV [SI+BOARD],AL ; Return to board TEST DH,040H ; Was it 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 ;**************ALMOV ; EVAL ; FNDMOV ; ASCEND ; ; CALLS: -- None ; ; ARGUMENTS: -JMP UM6 ; Jump UM20: MOV BX,POSQ ; Addr of saved Queen position UM21: TEST DL,080H ; Is Queen white ? JZ UM22 ; Yes - ju OR DL,010H ; Set King castled flag JMP MV21 ; Jump MV40: MOV BX,[MLPTRJ] ; Get move list pointer ADD BX,8 ; Incrementa double move ? JNZ UM40 ; Yes - jump MOV AL,DH ; Get captured piece, if any AND AL,7 ; Clear flag bits CMP AL,QUEEN ? 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 ; increasing- None ;*********************************************************** UNMOVE: MOV BX,[MLPTRJ] ; Load move list pointer INC BXmp INC BX ; Increment to black Queen pos UM22: MOV AL,[M1] ; Get previous position MOV [BX],AL ; Save JMP UM5 ; Jump to next move JMP MV1 ; Jump (2nd part of dbl move) ;*********************************************************** ; UN-MOV; Was it a Queen ? JNZ RET ; No - return MOV BX,POSQ ; Address of saved Queen pos TEST DH,080H ; Is Queen white ? JZ move value scores. ; ; CALLED BY: -- FNDMOV ; ; CALLS: -- EVAL ; ; ARGUMENTS: -- None ;************************************ EVAL: CALL MOVE ; Make move on the board array CALL INCHK ; Determine if move is legal AND AL,AL ; Legal m**************************************** ; FUNCTION: -- To evaluate a given move in the move list. ; It fir],AL MOV BX,0 ; Initialize best move to zero MOV [BESTM],BX MOV BX,MLIST ; Initialize ply list pointers MOV [MLNXT],BX [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 S the techniques of alpha-beta pruning. ; ; CALLED BY: -- CPTRMV ; ; CALLS: -- PINFND ; POINTS ************************************ SORTM: MOV CX,[MLPTRI] ; Move list begin pointer MOV DX,0 ; Initialize working pointersove ? JZ EV5 ; Yes - jump XOR AL,AL ; Score of zero MOV [VALM],AL ; For illegal move JMP UNMOVE ; Jump EV5: CALL PINst 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 I,DX ; Transfer move pointer MOV AL,[VALM] ; Get new move value CMP AL,[SI+MLVAL] ; Less than list value ? JNC SR30 ; No ; GENMOV ; SORTM ; ASCEND ; UNMOVE ; ; ARGUMENTS: -- Non 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 FND ; Compile pinned list CALL POINTS ; Assign points to move JMP UNMOVE ; Restore board array ;**********************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 o - jump SR25: MOV [BX],CH ; Link new move into list DEC BX MOV [BX],CL JMP SR5 ; Jump SR30: XCHG DX,BX ; Swap pointere ;*********************************************************** FNDMOV: MOV AL,[MOVENO] ; Current move number CMP AL,1 ; FirDEC BX MOV [BX],DL XOR AL,AL ; End of list ? CMP AL,CH JZ RET ; Yes - return SR10: MOV [MLPTRJ],CX ; Save list pointe************************************* ; FIND MOVE ROUTINE ;*********************************************************** ; FUNC ; 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 plys JMP SR15 ; Jump ;*********************************************************** ; EVALUATION ROUTINE ;*******************st move ? JNZ L0003 CALL BOOK ; Yes - execute book opening L0003: XOR AL,AL ; Initialize ply number to zero MOV [NPLYr CALL EVAL ; Evaluate move MOV BX,[MLPTRI] ; Begining of move list MOV CX,[MLPTRJ] ; Restore list pointer SR15: MOV DL,TION: -- To determine the computer's best move by ; performing a depth first tree search using ; 0 material CALL PINFND ; Compile pin list CALL POINTS ; Evaluate board at ply 0 MOV AL,[BRDC] ; Get board control pointLPTRJ] ; Load move pointer MOV AL,[SI+MLVAL] ; Get move score AND AL,AL ; Is it zero (illegal move) ? JZ FM15 ; Yes - juK ; Check for legal move AND AL,AL ; Is move legal JZ FM16 ; Yes - jump CALL UNMOVE ; Restore board position JMP FM1X ; Restore pointer DEC BX JMP FM37 ; Jump JFM15: JMP FM15 FM35: CALL PINFND ; Compile pin list CALL POINTS ; Evalua FM15: MOV BX,[MLPTRJ] ; Load last move pointer MOV DL,[BX] ; Get next move pointer INC BX MOV DH,[BX] MOV AL,DH AND KFLG] ; Get check flag AND AL,AL ; Was King in check ? MOV AL,80H ; Pre-set stalemate score JZ FM36 ; No - jump (stalems MOV [BC0],AL ; Save MOV AL,[MTRL] ; Get material count MOV [MV0],AL ; Save FM5: MOV BX,NPLY ; Address of ply counter mp CALL MOVE ; Execute move on board array FM19: XOR B,[COLOR],80H ; Toggle color, is new color white ? JS FM20 ; No - ju5 ; 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 MAL,AL ; End of move list ? JNZ FM15A JMP FM25 ; Yes - jump FM15A: MOV [MLPTRJ],DX ; Save current move pointer MOV BX,[Mate) MOV AL,[MOVENO] ; Get move number MOV [PMATE],AL ; Save MOV AL,0FFH ; Pre-set checkmate score JMP FM36 ; Jump FM INC B,[BX] ; Increment ply count XOR AL,AL ; Initialize mate flag MOV [MATEF],AL CALL GENMOV ; Generate list of moves mp INC B,[MOVENO] ; Increment move number FM20: MOV BX,[SCRIX] ; Load score table pointer MOV AL,[BX] ; Get score two plysJMP 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 LPTRI] ; Save in ply pointer list MOV [BX],DL INC BX MOV [BX],DH MOV AL,[NPLY] ; Current ply counter MOV BX,PLYMAX ; M30: MOV AL,[NPLY] ; Get ply counter CMP AL,1 ; At top of tree ? JZ RET ; Yes - return CALL ASCEND ; Ascend one ply in t MOV AL,[NPLY] ; Current ply counter MOV BX,PLYMAX ; Address of maximum ply number CMP AL,[BX] ; At max ply ? JNC L0004 above INC BX ; Increment to current ply MOV [SCRIX],BX ; Save it INC BX MOV [BX],AL ; Save score as initial value Jf 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 Jaximum ply number ? CMP AL,[BX] ; Compare JC FM18 ; Jump if not max CALL MOVE ; Execute move on board array CALL INCHree MOV BX,[SCRIX] ; Load score table pointer INC BX ; Increment to current ply INC BX MOV AL,[BX] ; Get score DEC B CALL SORTM ; No - call sort L0004: MOV BX,[MLPTRI] ; Load ply index pointer MOV [MLPTRJ],BX ; Save as last move pointer MP FM5 ; Jump FM25: MOV AL,[MATEF] ; Get mate flag AND AL,AL ; Checkmate or stalemate ? JNZ FM30 ; No - jump MOV AL,[CC JFM15 ; Jump if less than JZ JFM15 ; Jump if equal MOV [BX],AL ; Save as new score 1 ply above MOV AL,[NPLY] ; Get cuvious ply ;*********************************************************** ; ONE MOVE BOOK OPENING ; **************************w color white ? JNS AC5 ; Yes - jump DEC B,[MOVENO] ; Decrement move number AC5: DEC [SCRIX] ; Decrement score table inde ; 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 ; Retuturn FM40: CALL ASCEND ; Ascend one ply in tree JMP FM15 ; Jump ;*******************************************************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 RErrent ply counter CMP AL,1 ; At top of tree ? JNZ JFM15 ; No - jump MOV BX,[MLPTRJ] ; Load current move pointer MOV [B******************************** ; FUNCTION: -- To provide an opening book of a single ; move. ; ; CALLEDx 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 ;**************************** ; ASCEND TREE ROUTINE ;*********************************************************** ; FUNCTION: -- To adjust all necessT ; Return BM5: ADD B,[BX],6 ; Increment to black moves MOV SI,[MLPTRJ] ; Pointer to opponents 1st move MOV AL,[SI+MLFRP]ESTM],BX ; Save as best move pointer MOV AL,[SCORE+1] ; Get best move score CMP AL,0FFH ; Was it a checkmate ? JNZ JFM15 BY: -- FNDMOV ; ; CALLS: -- None ; ; ARGUMENTS: -- None ;*******************************************************DEC 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 dary parameters to ; ascend one ply in the tree. ; ; CALLED BY: -- FNDMOV ; ; CALLS: -- UNMOVE ; ; AR ; Get "from" position CMP AL,22 ; Is it a Queen Knight move ? JZ BM9 ; Yes - Jump CMP AL,27 ; Is it a King Knight move ; No - jump MOV BX,PLYMAX ; Get maximum ply number SUB B,[BX],2 ; Subtract 2 MOV AL,[KOLOR] ; Get computer's color TEST**** BOOK: POP AX MOV B,[SCORE+1],0 ; Zero out score table MOV [BESTM],BMOVES-2 ; Init best move ptr to book MOV BX,BESTMX] 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: -- FNDGUMENTS: -- None ;*********************************************************** ASCEND: XOR B,[COLOR],80H ; Toggle color, is ne ? JZ BM9 ; Yes - jump CMP AL,34 ; Is it a Queen Pawn ? JZ BM9 ; Yes - jump JC RET ; If Queen side Pawn opening - AL,080H ; Is it white ? JZ RET ; Yes - return MOV BX,PMATE ; Checkmate move number DEC B,[BX] ; Decrement RET ; Re ; Initialize address of pointer MOV AL,[KOLOR] ; Get computer's color AND AL,AL ; Is it white ? JNZ BM5 ; No - jump MMOV ; FCDMAT ; MOVE ; BITASN ; INCHK ; ; ARGUMENTS: -- N not the current move is checkmate. If it is, ; a losing player is offered another game, ; ; Output "check" MOV CL,PRINTBUF CALL SYSTEM CP24: MOV AL,[SCORE+1] ; Check again for mates CMP AL,0FFH ; Player mated MOV CL,INCHAR ; Input any char to play again CALL SYSTEM JMP DRIVER ; Jump (Rest of game init) ;********************* ; Convert to Ascii MOV [MVEMSG+3],BX ; Put in move message MOV DH,[SI+MLFRP] ; "From" position of the move CALL BITASN SUB AL,CH ; Number of moves till mate AND AL,AL ; Checkmate ? JNZ RET ; No - return RCR AH TEST CL,001H ; Check flaone ;*********************************************************** CPTRMV: CALL FNDMOV ; Select best move MOV BX,[BESTM] ; Mo while a loss for the computer signals the ; King to tip over in resignation. ; ; CALLED BY: -- C? JNZ RET ; No - return MOV CL,0 ; Set player mate flag CALL FCDMAT ; Full checkmate ? RET ; Return ;************************************************* ; BOARD INDEX TO ASCII SQUARE NAME ;***************************************************; Convert to Ascii MOV [MVEMSG],BX ; Put in move message MOV DX,MVEMSG ; Output move MOV CL,PRINTBUF CALL SYSTEM CP1C: g for who is mated RCL AH JZ FM04 ; Jump if player MOV DX,CKMSG ; Print "CHECK" MOV CL,PRINTBUF CALL SYSTEM MOV DX,ve list pointer variable MOV [MLPTRJ],BX ; Pointer to move data MOV AL,[SCORE+1] ; To check for mates CMP AL,1 ; Mate agaPTRMV ; ; CALLS: -- None ; ; ARGUMENTS: -- The only value passed in a register is the ; flag which ************************************************ ; FORCED MATE HANDLING ;************************************************************* ; FUNCTION: -- To translate a hexadecimal index in the ; board array into an ascii description ; MOV AL,[COLOR] ; Should computer call check ? MOV CH,AL XOR AL,80H ; Toggle color MOV [COLOR],AL CALL INCHK ; Check foUWIN ; Output "YOU WIN" MOV CL,PRINTBUF CALL SYSTEM JP FM08 ; Jump FM04: MOV DX,CKMSG ; Print "CHECK" MOV CL,PRINTBUFinst computer ? JNZ CP0C ; No - jump MOV CL,1 ; Computer mate flag CALL FCDMAT ; Full checkmate ? CP0C: CALL MOVE ; Ptells FCDMAT whether the computer ; or the player is mated. ;******************************************************* ; 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 ; ; ARGUMr check AND AL,AL ; Is enemy in check ? MOV AL,CH ; Restore color MOV [COLOR],AL JZ CP24 ; No - return MOV DX,CKMSG CALL SYSTEM MOV DX,IWIN ; Output "I WIN" MOV CL,PRINTBUF CALL SYSTEM FM08: POP BX ; Remove return addresses POP BXroduce move on board array MOV SI,[MLPTRJ] ; Get pointer to move MOV DH,[SI+MLTOP] ; "To" position of the move CALL BITASN********** FCDMAT: MOV AL,[MOVENO] ; Current move number MOV CH,AL ; Save MOV AL,[PMATE] ; Move number where mate occurs ENTS: -- Board index input in register DH and the ; Ascii square name is output in register BX. ;***********p if invalid MOV [MVEMSG+1],AL ; Move list "to" position CALL VALMOV ; Determines if a legal move OR AL,AL ; Legal ? Jpty ? JZ PLYRMV ; Jump if empty MOV CH,AL ; Save length LAHF INC BX ; Point to actual buffer SAHF MOV AL,[BX] ; V 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 validate the players move ; Also allows player to resign the game by ; entering R. ; ; CALL PLYRMV ; ; CALLS: -- None ; ; ARGUMENTS: -- Accepts the square name in pointer BX ; and outputs th************************************************ BITASN: SUB AL,AL ; Get ready for division MOV DL,10 CALL DIVIDE ; DividZ RET ; Yes - return PL08: MOV DX,INVAL ; Output "INVALID MOVE--TRY AGAIN" MOV CL,PRINTBUF CALL SYSTEM JP PLYRMV ; JumpGet 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 ED BY: -- DRIVER ; ; CALLS: -- ASNTBI ; VALMOV ; ; ARGUMENTS: -- None ;*************************e board index in register AL. ; CF = 0 if ok. CF = 1 if invalid. ;********************************************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 ;*********************************************************** ; ASCII SQUARE NAME TO BOARD INDEX ;*************************h 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 ;********************************************************* PLYRMV: MOV DX,BUFFER ; Ask for input MOV CL,INBUF CALL SYSTEM MOV DX,CRLF ; Output C*************** ATBINX: INC BX ; Increment pointer to skip a char ASNTBI: MOV AL,[BX] ; Ascii file letter (a - h) INC BX ,30H ; Convert rank to Ascii (1-8) MOV BH,AL ; Save RET ; Return ;************************************************************************************* ; FUNCTION: -- To convert an algebraic square name in ; Ascii to a hexad ; 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 ; ;RLF MOV CL,PRINTBUF CALL SYSTEM MOV BX,BUFFER+1 ; Point to input length MOV AL,[BX] ; Get input length OR AL,AL ; Em 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******** ; PLAYERS MOVE ANALYSIS ;*********************************************************** ; FUNCTION: -- To accept andecimal board index. ; This routine also checks the input for ; validity. ; ; CALLED BY: -- CALLS: -- GENMOV ; MOVE ; INCHK ; UNMOVE ; ; ARGUMENTS: -- ReturnsL 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 ( Was it a legal move ? AND AL,AL JNZ VA9 ; No - jump VA8: POP BX ; Restore saved register RET ; Return VA9: CALL UNMtual move. Ply depth is the number of half-turns the computer looks ahead. For example, with a ply depth of 3, the computer moves VA5: MOV AL,[MVEMSG] ; "From" position CMP AL,[SI+MLFRP] ; Is it in list ? JNZ VA6 ; No - jump MOV AL,[MVEMSG+1] ;This chess game uses algebraic chess notation. The files are lettered "a" to "h" and the ranks are numbered 1 to 8. The lower l flag in register AL, 0 for valid ; and 1 for invalid move. ;*************************************************W/B): $" PLYDEP: DB 13,10,"Ply depth (1-6): $" MVEMSG: DB " ",13,10,"$" CKMSG: DB "CHECK",13,10,"$" UWIN: DB "You win",1OVE ; 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 your "To" position CMP AL,[SI+MLTOP] ; Is it in list ? JZ VA7 ; Yes - jump VA6: MOV DL,[SI+MLPTR] ; Pointer to next list move eft-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 pawn********** VALMOV: MOV BX,[MLPTRJ] ; Save last move pointer PUSH BX ; Save register MOV AL,[KOLOR] ; Computers color XOR3,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 BX ; 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.  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 up two squares you would enter E2-E4. You must enter your file letters in upper case, while the computer will always use lower AL,80H ; Toggle color MOV [COLOR],AL ; Store MOV BX,PLYIX-2 ; Load move list index MOV [MLPTRI],BX MOV BX,MLIST+1024 ;IY: DS 2 BC: DS 2 DE: DS 2 HL: DS 2 SION ;*********************************************************** DIVIDE: PUSH CX MOV CH,8 DD04: SAL DH RCL AL SUB AL,D SI JP VA5 ; Jump VA7: MOV [MLPTRJ],SI ; Save opponents move pointer CALL MOVE ; Make move on board array CALL INCHK ; case. To castle, enter only the king's move. The computer castles the same way. To capture En Passant, enter your pawn's ac Next available list pointer MOV [MLNXT],BX CALL GENMOV ; Generate opponents moves MOV SI,MLIST+1024 ; Index to start of 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 E,COMTAB FINDCOM: MOV DI,IDLEN MOV CL,[SI] JCXZ EXTERNAL REPE CMPB LAHF ADD SI,CX ;Bump to next position without SI,LINBUF+2 MOV DI,ID CALL FILEDRV ;Get COM drive MOV [SPECDRV],AL MOV CX,8 CALL COPYNAM ;Copy file name MOV AL,9LIM SUB AL,20H ;Lower-case changed to upper-case DELIM: CMP AL," " JZ RET CMP AL,"=" JZ RET CMP AL,"," JZ RET RLF MOV CL,PRINTBUF CALL SYSTEM MOV DX,COMMAND MOV AX,2522H ;Set vector 34 (terminate) INT 33 MOV AX,2523H ;Set vectSTEM 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],0QU 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 PRINTBaffecting flags SAHF LODW ;Get address of command JNZ FINDCOM CALL AX ;Call command JMP COMMAND SETDRV1: JMP SETDR 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 or 35 (CTRL-C) INT 33 GETCOM: MOV CL,GETDRV CALL SYSTEM ADD AL,"A" MOV CL,OUTCH MOV DL,AL CALL SYSTEM ;Print dri 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 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 wV DRVCHK: DEC DL ;Adjust for correct drive number DEC AL ;Check if anything else is on line JZ SETDRV1 EXTERNAL: MOV 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 ISDELIve letter MOV DL,":" MOV CL,OUTCH CALL SYSTEM ;Print : MOV DX,LINBUF MOV CL,INBUF CALL SYSTEM MOV DL,10 MOV CL,AX,100H PUSH BX PUSH AX MOV CL,SETDMA MOV DX,80H CALL SYSTEM RET L BADCOM: MOV DX,BADNAM MOV CL,PRINTBUF CALLith A: SETDRV: MOV CL,SELDRV CALL SYSTEM COMMAND: MOV SP,STACK CLD MOV AX,CS MOV SS,AX MOV ES,AX MOV DS,AX M AL,[SPECDRV] MOV [IDLEN],AL PUSH DS MOV DX,TPA ADD DX,0FH ;Round to next paragraph SHR DX SHR DX SHR DX SHR DX 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 RETOUTCH CALL SYSTEM ;New line MOV CH,0 MOV SI,FILIFO ;8 spaces MOV DI,ID CALL FILLBUF MOV DI,FCB CALL FILLBUF MOV SYSTEM JMP COMMAND NEXTCHR: ;Convert lower case input to upper case LODB CMP AL,"a"-1 JB DELIM CMP AL,"z" JA DEOV 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,C ;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 SUB DI,3 CMP AL,"." JNZ NOMATCH MOV CX,3 COPYNAM: CALL NEXTCHR JZ NOMATCH CMP AL,13 JZ NOMATCH CMP AL,"." V 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 witOPEN 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: LOD NOTFND: DB "Source file not found$" NOSPCE: DB "Insufficient disk space$" FCBFIL: DB 11,"?" DB 0 SPECDRV: DS 1 NUMRE SYSTEM ;Print space MOV SI,LINBUF+2+9 MOV CX,3 CALL OUTCNT ;Print 3 chars (ext) MOV DX,CRLF MOV CL,PRINTBUF CALL 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,JZ RET STOB LOOP COPYNAM NOMATCH: XOR AL,AL DEC SI RET FILLBUF: LODB MOV CL,AL JCXZ RET LODB REP STOB 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 SIB 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 1SYSTEM ;Print new line MOV CL,SRCHNXT JP EACHFILE OUTCNT: LODB PUSH CX PUSH SI MOV DL,AL MOV CL,OUTCH CALL SYS[NUMREC] MOV AH,RDBLK INT 33 JCXZ CPYDONE MOV DX,DSTFCB MOV AH,WRBLK INT 33 OR AL,AL JZ CPYBLK MOV DX,NOSPCE JP FILLBUF DIR: CMP B,[FCB+1]," " JNZ HASNAME MOV SI,FCBFIL MOV DI,FCB+1 CALL FILLBUF ;Fill 11 bytes with "?" H,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,"CRTEM POP SI POP CX LOOP OUTCNT RET RENAME: MOV CL,RENAM MOV DX,FCB JMP 5 ERASE: MOV CL,DELETE MOV DX,FCB MOV AH,PRINTBUF INT 33 CPYDONE: MOV DX,DSTFCB MOV AH,CLOSE INT 33 RET NOSRC: MOV DX,NOTFND MOV AH,PRINTBUF INASNAME: MOV DX,LINBUF+2+1 MOV CL,SETDMA CALL SYSTEM MOV CL,SRCHFRST MOV DX,FCB EACHFILE: CALL SYSTEM INC AL ;FF 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:  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,T 33 RET DS 40 STACK: BADNAM: DB "Bad command or file name" CRLF: DB 13,10,"$" ERAMES: DB "Erase all files (Y/N)? $"= file not found JZ RET MOV SI,LINBUF+2+1 MOV CX,8 CALL OUTCNT ;Print 8 chars (name) MOV CL,OUTCH MOV DL," " CALLVB 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 IN JMP AUXOUT JMP READ JMP WRITE JMP RETL ;Flush buffers INIT: MOV AX,CS MOV DS,AX MOV SS,AX MOV SP,STACK M: EQU DOUB1SIDE+DOUB2SIDE WD1771: EQU CROMEMCO+SNGL1SIDE IF WD1791 READCOM:EQU 80H WRITECOM:EQU 0A0H ENDIF IF WD177 LOOP RDLP OR AL,AL RETL: RET L WRITE: CALL SEEK WRTLP: PUSH CX CALL WRITESECT POP CX JC ERROR INC DH ADD co controllers. ; Select disk controller here TARBELL:EQU 0 CROMEMCO:EQU 1 ; For either disk controller, a custom drive BADCOM: DB 13,10,"Bad or missing Command Interpreter",13,10,"$" FCB: DB 1,"COMMAND COM" DS 24 STATUS: IN STAT AND 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 DX1 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 ; table may be defined CUSTOM: EQU 0 ; If Tarbell disk controller, select one-sided or two-sided drives ; and single or doublAL,DAV RET L AUXIN: INP: IN STAT AND AL,DAV JZ INP IN DATA AND AL,7FH RET L AUXOUT: OUTP: PUSH AX OUTLP,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 COMERU 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: ;e density controller DOUB1SIDE:EQU 0 DOUB2SIDE:EQU 0 SNGL1SIDE:EQU 0 ; If Cromemco disk controller, select drive configura: IN STAT AND AL,TBMT JZ OUTLP POP AX OUT DATA RET L PRINT: PUSH AX PRINLP: IN PSTAT AND AL,TBMT JZ PRINR 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 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 ation SMALLCRO:EQU 0 ;3 small drives COMBCRO:EQU 1 ;2 large drives and 1 small one LARGECRO:EQU 0 ;4 large drives WD1791LP POP AX OUT PDATA RET L READ: CALL SEEK RDLP: PUSH CX CALL READSECT POP CX JC ERROR INC DH ADD SI,128 ; I/O System for 86-DOS. ; Assumes a CPU Support card at F0 hex for character I/O, ; with disk drivers for Tarbell or Cromem21H PUSH BX MOV AX,100H PUSH AX RET L COMERR: MOV DX,BADCOM MOV AH,9 ;Print string INT 21H EI STALL: JP STALLddress in DS ; DI = pointer to drive's track counter in CS ; CX unchanged. MOV SI,BX ; Save transfer address CBW MOV 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 IF CROMEMCO TEST AH,10H ;Check for small disk JNZ CHKSTP CMP DH,18 ;Only 18 sectors/track on small ones JA STEP CHKSTEC BL JNZ TRYHOM RET MOVHEAD: IF CROMEMCO TEST AH,10H ;Check 8" (PerSci) bit JNZ FASTSK ENDIF DCOM: OUT DISent 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,[ET MOV BL,10 WRTAGN: OR AL,WRITECOM OUT DISK PUSH SI WRLOOP: IN DISK+4 TEST AL,DONEBIT IF TARBELL JZ WRDONEBX,AX ; Prepare to index on drive number SEG CS MOV AL,[BX+DRVTAB] OUT DISK+4 ; Select drive IF CROMEMCO OR AL,80H15ms head load delay if selecting a different drive SEG CS CMP AH,[CURDRV] SEG CS MOV [CURDRV],AH JZ RET OR AL,4 RP: 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 JNZDI] ;Xchange current track with desired track OUT DISK+1 ;Inform controller chip of current track CMP AL,DL JZ ONTRK M ENDIF IF CROMEMCO JNZ WRDONE ENDIF LODB OUT DISK+3 LOOP WRLOOP WRDONE: POP SI CALL GETSTAT AND AL,09CH ;Set auto-wait bit ENDIF MOV AH,AL ;Save for later XCHG AX,DX MOV DL,26 ;26 sectors per track IF CROMEMCO TEET READSECT: CALL SETUP JC RET MOV BL,10 RDAGN: OR AL,READCOM OUT DISK PUSH SI RLOOP: IN DISK+4 TEST AL,DONh 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 cOV BH,3 ;Seek retry count CMP AL,-1 ;Head position known? JNZ NOHOME ;If not, home head TRYSK: CALL HOME NOHOME: MO JZ RET MOV AL,0 DEC BL JNZ WRTAGN STC RET HOME: IF CROMEMCO TEST AH,10H ;Check 8" (PerSci) bit JNZ RESTORST DH,10H ;Check if small disk JNZ BIGONE MOV DL,18 ;18 sectors on small disk track BIGONE: ENDIF DIV AL,DL ;CompuEBIT IF TARBELL JZ RDONE ENDIF IF CROMEMCO JNZ RDONE ENDIF IN DISK+3 MOV [SI],AL INC SI LOOP RLOOP RDIF 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,DONEBV AL,DL OUT DISK+3 MOV AL,1CH CALL MOVHEAD AND AL,98H JZ ONTRK DEC BH JNZ TRYSK STC ONTRK: RET SETUP: E ENDIF MOV BL,3 TRYHOM: MOV AL,0CH CALL DCOM AND AL,98H JZ RET MOV AL,58H ;Step in with update CALL DCOM Dte track and sector XCHG AX,DX INC DH ;First sector is 1, not zero SEG CS MOV BL,[BX+TRKPT] ;Get this drive's displacemONE: POP SI CALL GETSTAT AND AL,9CH JZ RET MOV AL,0 DEC BL JNZ RDAGN STC RET WRITESECT: CALL SETUP JC RIT JZ CHKRES IN DISK JP RESTORE ;Reload head RESDONE: MOV AL,7FH OUT 4 CALL GETSTAT MOV AL,0 OUT DISK+1 ;TellLFAT FAT2: DS LFAT FAT3: DS LFAT ENDIF IF COMBCRO ; Table for two large drives and one small one DRVTAB: DB 31H,32H,24mco drive select byte is derived as follows: ; Bit 7 = 0 ; Bit 6 = X (unassigned) ; Bit 5 = 1 (motor on) ; Bit 4 = 0 for 5",DW 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: DKPT: 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 LFA 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 SKH 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 D 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 LARGB 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,3T ENDIF WAIT MOV AL,7FH OUT 4 MOV AL,0 RET ENDIF DS 20H STACK: LFAT: EQU 300H SFAT: EQU 200H CURDRV: DS 1 LDRIVW FAT2 ORG 0 FAT0: DS LFAT FAT1: DS LFAT FAT2: DS SFAT ENDIF IF SMALLCRO ; Table for 3 small drives DRVTAB: DB 21ECRO ; 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 TRKTAB: DB -1,-1,-1,-1 ENDIF IF TARBELL INITTAB:DB 4 ;Number of drives DW LDRIVE DW FAT0 DW LDRIVE DW FAT1 DWE: DB 1 ;Records/sector DB 4 ;Records/cluster DW 52 ;Reserved records DB 6 ;FAT size (records) DB 2 ;Number of FATs 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 ives 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 LDRIVE DW FAT2 DW LDRIVE DW FAT3 ORG 0 FAT0: DS LFAT FAT1: DS LFAT FAT2: DS LFAT FAT3: DS LFAT ENDIF ; CromeDB 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 ORG 0 FAT0: DS SFAT FAT1: DS SFAT FAT2: DS SFAT ENDIF IF CUSTOM ; Table for 2 large drives DRVTAB: DB 31H,32H TRV AX,2523H INT 33 MOV SI,BAK MOV DI,FCB+9 MOV CX,3 ;File must not have .BAK extension REPE CMPB JZ NOTBAK ;OpeOV BX,CX SHL BX CALL [BX+TABLE] JMP COMMAND SKIP: LODB SKIP1: CMP AL," " JZ SKIP RET COMERR: MOV DX,BADCO B,[EDITBUF],255 MOV [POINTER],START MOV [CURRENT],1 COMMAND: MOV SP,STACK MOV AL,PROMPT CALL OUT MOV DX,COMBUF 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: JTOBIG JMP ERROR NOTEOF: MOV DX,NOEOF JMP ERROR SETUP: MOV DX,START MOV AH,SETDMA INT 33 MOV CX,[6] SUB CX,80H er of the next two tables. They are ; linked and chnges should be be to both. TABLE DW NOCOM ;No command--edit line 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 INM MOV AH,PRINTBUF INT 33 JP COMMAND GETNUM: CALL SKIP CMP AL,"." JZ CURLIN CMP AL,"#" JZ MAXLIN MOV DX,0 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 ; 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 ENDED DW INSERT DW LIST DW DELETE DW COMERR DW COMERR FINDLIN: ; Inputs ; BX = Line number to be located in bT 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 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 X 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 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 uffer (0 means last line) ; Outputs: ; DX = Actual line found ; DI = Pointer to start of line DX ; Zero set if BX = DX ; AL33 MOV AL,"$" MOV DI,FCB2+9 STOB STOB STOB MOV AH,DELFIL INT 33 ;Create .$$$ file to make sure directory has rooDX,AX LODB JP NUMLP CURLIN: MOV DX,[CURRENT] LODB RET MAXLIN: MOV DX,-1 LODB RET COMTAB DB "SFDLIE",13 JNZ 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 SCAB JNZ NOTEOF REPE SCAB INC DI SAVEND: CLD INC DI MOV B,[DI],1AH MOV [ENDTXT],DI MOV B,[COMBUF],128 MOV,CX destroyed. No other registers affected. MOV DX,[CURRENT] MOV DI,[POINTER] CMP BX,DX JZ RET JA FINDIT MOV DX,1 m MOV AH,MAKE INT 33 OR AL,AL JZ SETUP MOV DX,NODIR JMP ERROR NOTBAK: MOV DX,NOBAK JMP ERROR TOOBIG: MOV DX, NUMCOM EQU $-COMTAB ;-----------------------------------------------------------------------; ; Carefull changing the ordP BX RET CONV10: ;Inputs: ; BX = Binary number to be displayed ; Function: ; Ouputs binary number. Five digits with LODB STOB INC DL CMP AL,13 LOOPNZ LOADLP MOV [EDITBUF+1],DL MOV [OLDLEN],DL MOV SI,[POINTER] CALL DISPONE CAX CALL SHOWNUM POP CX OUTLN: LODB CALL OUT CMP AL,10 LOOPNZ OUTLN JCXZ RET DEC DI JZ RET CMP BX,BP LAHF I 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 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 DISPLActed. 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 leading ; zero suppression. Zero prints 5 blanks. XOR AX,AX MOV DL,AL MOV CX,16 CONV: SHL BX ADC AL,AL DAA XCLL SHOWNUM MOV AH,INBUF ;Get input buffer MOV DX,EDITBUF INT 33 MOV AL,10 CALL OUT MOV CL,[EDITBUF+1] MOV CH,0 J 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:Y MOV DI,21 JP DISPLAY DISPONE: MOV DI,1 DISPLAY: ; Inputs: ; BX = Line number ; SI = Pointer to text buffer 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,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 DIGCXZ RET MOV DL,[OLDLEN] MOV DH,0 MOV SI,2+EDITBUF MOV DI,[POINTER] REPLACE: ; Inputs: ; CX = Length of new text RAM1] 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 = Terminati ; DI = No. of lines ; Function: ; Ouputs specified no. of line to terminal, each ; with leading line number. ; Outputs: ; CX STD DOMOV: INC CX REP MOVB CLD POP CX POP DI POP SI COPYIN: REP MOVB RET DELETE: MOV BX,[PARAMITS 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 ZERDIG; DX = Length of original text ; SI = Pointer to new text ; DI = Pointer to old text in buffer ; Function: ; New text replac 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 BX = Last line output. ; All registers destroyed. MOV CX,[ENDTXT] SUB CX,SI JZ RET MOV BP,[CURRENT] DISPLN: PUSH C1] OR BX,BX JNZ DELFIN1 MOV BX,[CURRENT] DELFIN1: CALL FINDLIN JNZ RET MOV [CURRENT],BX MOV [POINTER],DI PUSH D MOV BL,0 ZERDIG: ADD AL,"0" SUB AL,BL JMP OUT LIST: MOV BX,[PARAM1] OR BX,BX JNZ CHKP2 MOV BX,[CURRENT] es old text in buffer and buffer ; size is adjusted. CX or DX may be zero. ; CX, SI, DI all destroyed. No other registers affeXOR CX,CX GETIT: LODB CMP AL,1AH JZ RET CMP AL,0DH JZ RET STOB INC CX JP GETIT MEMERR: MOV DX,MEMFUL MET BAK: DB "BAK" NOBAK: DB "Cannot edit .BAK file--rename file$" NODIR: DB "No room in directory for file$" TOBIG: DB "F 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 .BAnput buffer as empty READHEX: CALL GETCH CMP AL,":" ;Search for : to start line JNZ READHEX CALL GETBYT ;Get byte cou 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: ; HEX2BIN ; Converts Intel hex format files to straight binary FCB: EQU 5CH READ: EQU 20 SETDMA: EQU 26 OPEN: EQU 15 CLOOV AH,PRINTBUF INT 33 JMP COMMAND INSERT: MOV BX,[PARAM1] OR BX,BX JNZ INS MOV BX,[CURRENT] INC BX INS: CAile too big to fit into memory$" NOEOF: DB "No end-of-file mark found in file$" DSKFUL: DB "Disk full--file write not completeK 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 MOV [POINTER],DI MOV [CURRENT],BX MOV SI,BP INC SI MOV CX,[LAST] SUB CX,BP REP MOVB DEC DI MOV [ENDTXT],DI SE: EQU 16 CREATE: EQU 22 DELETE: EQU 19 BLKWRT: EQU 40 BUFFER: EQU 80H BUFSIZ: EQU 128 ORG 100H PUT 100H HEX2BIN:LL FINDLIN MOV CX,[ENDTXT] ;Get End-of-text marker MOV SI,CX SUB CX,DI ;Calculate number of bytes to copy INC CX MOd$" MEMFUL: DB 13,10,"Memory full",13,10,"$" BADCOM: DB "Entry error",13,10,"$" NEWFIL: DB "New file",13,10,"$" FCB2: DS 36 2 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,[RET ENDED: ;Write text out to .$$$ file MOV DI,[ENDTXT] MOV CX,128 MOV AL,1AH REP STOB MOV CX,[ENDTXT] CALL NU MOV DI,FCB+9 CMP B,[DI]," " JNZ HAVEXT MOV SI,HEX MOVB MOVW HAVEXT: ;Get load offset (default is -100H) MOV AH,V DI,[LAST] DOWN REP MOVB XCHG SI,DI UP INC DI MOV BP,SI MOV BX,DX INLP: CALL SHOWNUM MOV DX,EDITBUF MOV 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 COM0H 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 lMRECS INC CX MOV [FCB2+RR],0 MOV DX,FCB2 MOV AH,WRBLK INT 33 OR AL,AL JNZ WRTERR ;Close .$$$ file MOV AH,CLOSE OPEN 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 iAH,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 BUF: DS 2+128 EDITBUF: DS 2+255 DS 40 ALIGN STACK: START: argest address so far JBE READHEX MOV BP,DI ;Save new largest JP READHEX NOFIL: MOV DX,NOFILE QUIT: MOV AH,9 IN: DB "Disk directory full$" START: opy file name MOV AL,[DSTFCB] OR AL,AL JNZ DSTDRV MOV CL,GETDRV CALL SYSTEM ;Use default drive INC AX DSTDRV: V 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,SE 0,0,0,0 INVSRC: MOV DX,BADSRC JMP EXIT NONAME: MOV DX,BADFN JMP EXIT RDCPM: MOV SP,100H CMP B,[FCB+1]," " T 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 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 3 JZ NONAME XOR AL,AL XCHG AL,[FCB] OR AL,AL JNZ HASDRV MOV CL,GETDRV CALL SYSTEM INC AX HASDRV: DEC AX MOV MOV SI,BUFFER NOREAD: LODB CMP AL,1AH JZ DONE RET GETBYT: CALL HEXDIG MOV BL,AL CALL HEXDIG SHL BL SHL B MOV CL,SETDMA MOV DX,SECBUF CALL SYSTEM BEGDIR: XOR AX,AX MOV BX,[BP+NUMENT] READDIR: MOV DI,DIRBUF PUSH AX 3 MOV AH,CLOSE INT 33 EXIT: INT 32 NOROOM: MOV DX,DIRFUL JMP QUIT HEX: DB "HEX" COM: DB "COM" ERRMES: DB "Err [DRIVE],AL CMP AL,15 JA INVSRC ;Invalid drive number CBW MOV BX,AX SHL BX MOV BP,[BX+CPMTAB] OR BP,BP JZ INVSRL 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 FCB 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 PUSH BX CALL READSEC POP BX POP AX MOV SI,DIRBUF ENUMDIR: MOV DI,FCB MOV CX,13 REPE CMPB JZ RDENTRY ADD or in HEX file--conversion aborted$" NOFILE: DB "File not found$" ADDR: DB "Address out of range--conversion aborted$" DIRFULC MOV SI,FCB2 MOV DI,DSTFCB MOVB CMP B,[FCB2+1]," " JNZ HASDST MOV SI,FCB+1 HASDST: MOV CX,11 REP MOVB ;CJC 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 MORINTBUF 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 DWSI,CX ADD SI,19 ;Point to next entry DEC BX JS DONE CMP SI,DIRBUF+128 JB ENUMDIR INC AX JP READDIR BADPARM: e 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 Eor number READABS: MOV CX,1 MOV BX,DI MOV AL,[DRIVE] PUSH BP INT 37 POP AX POP BP JNC RDDONE MOV DX,DSKERR FCB EQU 5CH ORG 100H PUT 100H JMP START SECS: DW 52 ;Patch for different configs START: MOV AL,[FCB] OR AL,AC POP SI POP CX LOOP RDNXTAL INC B,[FCB+12] ;Increment extent counter JMP BEGDIR ;Scan from beginning of directory 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,0MOV DX,SAMDSK JMP EXIT RDENTRY: ADD SI,3 ;Point to AL array MOV CX,16 ;16 AL bytes per entry RDNXTAL: LODB MOVXTMSK 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 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 DONE: MOV CL,CLOSE MOV DX,DSTFCB CALL SYSTEM JMP 0 ;Read allocation block READSEC: XOR DX,DX MOV BX,[BP+SPT] ,0 DW 0,0,0,0 DW 0,0,0,0 DW 0,0,0,0  AH,0 TEST B,[BP+DSISIZ+1],0FFH JZ SMALDSK MOV AH,[SI] ;Big disk, use words instead INC SI DEC CX SMALDSK: OR AXhe 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 DDIV 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 t,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 DIDB 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 SYSOKrack JNZ BIGTRK ;Use words instead of bytes for xlat table MOV AX,CX MOV BX,[BP+XLTTBL] XLAT ADD DX,AX ;Logical sect,SECBUF CALL READSEC MOV CL,SEQWRT MOV DX,DSTFCB CALL SYSTEM POP CX POP AX INC CH CMP CH,[BP+BLKMSK] JBE RDALOory allocation bitmap 1 DW 16 ;Directory check vector size DW 2 ;Tracks to skip DW MOD6 ;Modulo-6 sector translate table : DB "System transfered$" ERREAD: DB "Disk read error$" ERWRIT: DB "Disk write error$" DRVBAD: DB "Bad drive specification" MOV B,[BX],0 CALL FINDOP ENLIN: MOV SP,STACK MOV AL,[CHAR] CMP AL,';' JNZ NOCOM MOV AL,9 CALL PUTCH MOV AL,'V AL,'M' MOV [PUTFCB+11],AL MOV DX,FCB MOV CL,OPEN CALL SYSTEM INC AL MOV DX,NOFILE JZ ABORTJ MOV DX,PUTFCB MOPUSH DX PUSH CX MOV BX,[GETPT] ; Get buffer pointer. CMP BX,GETBUF+80H ; Past end-of-buffer? JNZ GETIT ; Jump if not. ile EOL: EQU 0DH FCB: EQU 5CH SYSTEM: EQU 5 OPEN: EQU 15 CLOSE: EQU 16 SETDMA: EQU 26 CREATE: EQU 22 DELETE: EQU 19 REAH 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 B END: ;' NOCOM: CALL PUTCH PUTLIN: CMP AL,EOF JZ END CALL GETCH CALL PUTCH CMP AL,10 JNZ PUTLIN JP TRANLN END: MOV 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 CD: 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 MOX,[PUTPT] MOV [BX],AL LAHF INC BX SAHF MOV [PUTPT],BX CMP BX,PUTBUF+80H JNZ POPRET MOV DX,PUTBUF MOV [PUTPT],DV CH,127 MOV AL,1AH FILL: CALL PUTCH DEC CH JNZ FILL MOV DX,PUTFCB MOV CL,CLOSE CALL SYSTEM MOV DX,ENDMES ABORTFCB 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 ; tV 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 MX MOV CL,SETDMA CALL SYSTEM MOV DX,PUTFCB MOV CL,WRITE CALL SYSTEM OR AL,AL MOV DX,WRTERR JNZ ABORT POPRET: PT: MOV CL,PRNBUF CALL SYSTEM JMP 0 DELIM: CALL GETCH DELCHK: CMP AL,EOL JZ DOLIN CMP AL,EOF JZ DOLIN CMP 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. OV 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 MOOP AX XCHG AH,AL SAHF NOTAF: POP CX POP DX POP BX RET ; ; Get character from source file. ; GETCH: PUSH BX ; Z80 to 8086 Translator version 2.0 ; Runs on the 8086 under 86-DOS ; by Tim Paterson ; ORG 100H EOF: EQU 1AH ;End of f';' JZ DOLIN CMP AL,' ' JZ RET CMP AL,':' JZ RET CMP AL,',' JZ RET CMP AL,9 RET HEX: AND AL,0FH ADD AL,90 LAHF INC BX ; Point to next character. SAHF MOV [GETPT],BX ; Save new pointer. TESEND: MOV [CHAR],AL JP NOTAF ; P 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 CRET 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: 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,C AL LAHF XCHG AX,BP SAHF MOV B,[BX],'[' JP NEXCH NOTLEF: CMP AL,')' JNZ NOTRIT LAHF XCHG AX,BP SAHF DEC NC BX MOV B,[BX],']' INC BX JP ENDRW RET FINDOP: MOV BX,OPCODE MOV CX,5 XOR AL,AL UP MOV DI,BX REPNZ SCABop registers and return. LOAD: CALL DELIM JZ LOADOP EATLAB: CALL PUTCH CALL DELIM JNZ EATLAB ENLAB: MOV AL,':' 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,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 AL LAHF XCHG AX,BP SAHF MOV B,[BX],']' JP NEXCH NOTRIT: MOV [BX],AL CMP AL,'''' JZ EATQUO CALL IDCHK JNC GE 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 MOCALL PUTCH LOADOP: MOV BX,OPCODE EATEM: CALL DELIM JZ EATEM LOADLP: CALL IDCHK JNC $+5 JMP OPERR MOV [BX],AL 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 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 OUTSTTID NEXCH: INC BX CALL GETCH IDRET: CALL DELCHK JNZ OPCHAR CMP AL,' ' JZ OPCHAR RET EATQUO: INC BX CALL GETV 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 RCLINC BX CALL DELIM JNZ LOADLP MOV B,[BX],0 CMP AL,':' JNZ RET MOV BX,OPCODE CALL TRANS JP ENLAB GETOP: XOR AL, JZ IXIY MOV BX,IYDI CMP AL,RDI JNZ NORW IXIY: LAHF XCHG AX,BP SAHF JZ NOTENC LAHF XCHG AX,BP SAHF CALL OW 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 CH MOV [BX],AL CMP AL,';' JZ L0000 CALL DELCHK L0000: CMP AL,'''' JNZ EATQUO JP NEXCH IDCHK: CMP AL,'0' JC 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 MOVAL LAHF XCHG AX,BP SAHF GETLP: CALL DELIM JZ GETLP OPCHAR: CMP AL,'(' JNZ NOTLEF LAHF XCHG AX,BP SAHF INUTSTR 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 CALL LCHECK JNZ $+5 JMP STAX ;If immediate move, check for byte memory reference MOV AL,[OP1] CMP AL,'[' ;Memory refe XCHG DX,BX JMP TRANS LDAX: MOV BX,LDAX1 LSAX: CALL OUTSTR MOV SI,DX LODB CALL TRNTOK JP OUTSTR STAX: MOV BRLFTB CALL OUTSTR MOV BX,OP1 CALL GETOUT JP IODONE GETPORT: MOV AL,[BX] CMP AL,'[' JNZ NOBRAK LAHF INC BX SALL OUTSTR CALL TWOOPS MOV BX,DAD2 JP OUTSTR INCDEC: MOV AL,[OP1] CMP AL,RCX+1 ;16-bit? JNC ONEOPJ MOV BX,LAHF MP AL,RDX RET ONEOP: CALL OUTSTR TRNOP1: MOV AL,9 TRAN1: MOV BX,OP1 JP PTRANS IN: MOV AL,[OP1] CMP AL,RAL C BX ADD AL,AL JNC OUTSTR RET NEWOP: MOV AL,13 CALL PUTCH MOV AL,10 CALL PUTCH MOV AL,9 RET LDDR: CALL OUTrence? JNZ TWOOPS MOV AL,[OP1+1] ;Referencing IX as a word? CMP AL,RIX JZ TWOOPS CMP AL,RIY JZ TWOOPS MOV AL,[OP2]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 LAHFAHF 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,'[' XCHG DX,BX MOV BX,OP2 JZ GETPORT MOV BX,SAVEAX CALL OUTSTR CALL OUTSTR MOV BX,OP2 CALL GETPORT MOV BX,MOV0 CSTR MOV BX,BLMOVE JP OUTSTR CPDR: CALL OUTSTR MOV BX,CMPREP JP OUTSTR ADD: MOV AL,[OP1] CMP AL,RBX JZ DAD ARI CMP AL,20H ;Could be immediate? MOV AL,9 JC L0001 CALL BFLAG ;Add "B," L0001: CALL TRAN1 JP TRNOP2 TWOOPS: C 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,[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 CALLALL ONEOP MOV AL,',' CALL PUTCH MOV AL,RAL CALL TRNTOK IODONE: MOV BX,RESTAX JMP OUTSTR OUT: MOV AL,[OP2] XCHGTH: CALL OUTSTR MOV AL,[OP2] OR AL,AL JZ $+5 JMP TWOOPS MOV AL,9 CALL PUTCH MOV AL,RAL CALL TRNTOK MOV AL,',ALL TRNOP1 TRNOP2: MOV AL,',' TRAN2: MOV BX,OP2 PTRANS: CALL PUTCH TRANS: MOV AL,[BX] LAHF INC BX SAHF OR ALBX] POP CX POP BX OR AL,AL JZ RET JMP PUTCH PUSH: MOV DX,PUSHAF JP AFCHK POP: MOV DX,POPAF AFCHK: MOV AL,[ONTOK 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, DX,BX MOV BX,OP1 CMP AL,RAL JZ GETOUT MOV BX,SAVEAX CALL OUTSTR MOV BX,MOVAL CALL OUTSTR CALL TRNOP2 MOV BX,C' JMP TRAN1 ACCUM: CALL OUTSTR MOV AL,9 CALL PUTCH MOV AL,RAL JMP TRNTOK ONEOPJ: JMP ONEOP DAD: MOV BX,DAD1 C,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 CP1] CMP AL,RAX JNZ ONEOPJ XCHG DX,BX OUTSTR: MOV AL,[BX] OR AL,AL JNZ L0002 CALL NEWOP L0002: CALL PUTCH INCH CMP AL,ODDPAR MOV BX,WARNPA JZ OUTSTRJ CMP AL,EVEPAR JZ OUTSTRJ RET FIXCON: MOV AL,[OP1] CMP AL,RGCL JNZ R 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,LL BFLAG L0004: CALL TRAN2 MOV AL,',' CALL PUTCH CALL GETBIT MOV BX,BITERR JNC L0005 CALL OUTSTR L0005: POP BPS: 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,OPX] 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 R,OPCODE DM 'W' DW PSEUDO,OPCODE DM 'B' DW PSEUDO,OPCODE DM 'M' DW PSEUDO,OPCODE DM 'S' DW ONEOP,OPCODE DB 0 ET 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 OPS,MOPS,NOPS,OOPS DW POPS,QOPS,ROPS,SOPS,TOPS DW UOPS,VOPS,WOPS,XOPS,YOPS DW ZOPS AOPS: DM 'DD' DW ADD,OPCODE DM '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 P MOV AL,[OP1+1] CMP AL,STP JZ XTHL MOV BX,XCHG CALL OUTSTR JMP TWOOPS XTHL: MOV BX,XTHL1 CALL OUTSTR CALL TRNOPEOPS: DM 'X' DW EX,EXAF DM 'I' DW OUTSTR,OPCODE DM 'XX' DW OUTSTR,EXX DM 'QU' DW ONEOP,OPCODE DM 'NDIF' DW O[OP2+2],BX JP DIRECT ONEOPJ1: JMP ONEOP DOCALL: MOV AL,[OP2] OR AL,AL JZ ONEOPJ1 CALL FIXCON DEC AL XOR AL,1 DC' DW ARITH,OPCODE DM 'ND' DW ARITH,OPCODE DB 0 BOPS: DM 'IT' DW BITSET,TESBIT DB 0 COPS: DM 'ALL' DW DOCAL 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 'RA2 MOV BX,XTHL2 OUTSTRJ1: JMP OUTSTR PSEUDO: CALL ONEOP MOV AL,[OP2] OR AL,AL JZ RET JMP TRNOP2 RET BITSET: UTSTR,OPCODE DB 0 FOPS: DB 0 GOPS: DB 0 HOPS: DM 'ALT' DW OUTSTR,HLT DB 0 IOPS: DM 'NC' DW INCDEC,OPCODE D 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 L000L,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 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' MOV CL,0 JP SETRES RES: MOV CL,-1 SETRES: CALL OUTSTR PUSH BX MOV AL,[OP2] CMP AL,'[' MOV AL,9 JNZ L0004 CALM '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 LO3 CALL PTRANS L0003: MOV BX,CRLF CALL OUTSTR CALL TRANS CALL OUTSTR MOV BX,LABEL+4 NEXLAB: INC [BX] MOV AL,[BUTSTR,CMC DB 0 DOPS: DM 'EC' DW INCDEC,OPCODE DM 'JNZ' DW ONEOP,DJNZ DM 'AA' DW OUTSTR,OPCODE DM 'I' DW OUTST DW ONEOP,ROL DM 'RC' DW ONEOP,ROR DM 'ES' DW RES,RESBIT DM 'ETI' DW OUTSTR,IRET DM 'ETN' DW OUTSTR,IRET DM 'S9,'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: DMag 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'DS 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: EQ'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,'MHCLCHALIXIY' RWTAB: DB 'ABCDEHLBDHSACNZNPMPPII' LENRW: EQU $-RWTAB DB 0,0,0,0,0,0,0,'CELPF',0,'C',0,'Z',0,0,'OEYX' HEADERT' 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 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 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,NOOVB',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,'BX: DB 13,10,'Z80 to 8086 Translator version 2.0',13,10,'$' NOROOM: DB 13,10,'Insufficient directory space to create file',13,10EOP,SAR DM 'RL' DW ONEOP,SHR DM 'CF' DW OUTSTR,STC DM 'ET' DW BITSET,SETBIT DB 0 TOPS: DB 0 UOPS: DB 0 VOPSCHG: 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,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,,'$' NOFILE: DB 13,10,'File not found',13,10,'$' ENDMES: DB 13,10,'Translation complete',13,10,'$' WRTERR: DB 13,10,'Out of d: 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' SSAR' 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 'CH',13,10 DB '; *** WARNING: DJNZ does not affect flags - DEC does.',0 DM 'JNZ' WARNPA: DM 13,10,'; *** WARNING: Parity flisk space',13,10,'$' OPCDER: DM 13,10,'*** Opcode Error ' CRLF: DM 13,10 LABEL: DB 'L0000',0 DM ':',9 PUTPT: DS 2 GETPT: TAX1: 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,: DM 'CMP' SBB: DM 'SBB' CALL: DM 'CALL' TOKTAB: DB 'SIDI' DB 'PEPOS',0,'NSNZZ',0,'NCC',0 DB 'AXSPBXDXCX' DB 'BLBHDLD