86DOS A86 86DOS A86 !86DOS A86"ASM A86#$%&'()*+,-./012 for SEARCH FIRST and SEARCH NEXT FIRCLUS:DS 2 ;First cluster of file LSTCLUS:DS 2 ;Last cluster accessed FILSIZ: DS 2 ;Si ; INTBASE+14H: BIOS DISK READ ; INTBASE+18H: BIOS DISK WRITE ; INTBASE+40H: Long jump to CALL entry point MAXCALL:EQU 3ASM A863456789:;<=>?@ABASM A86bCDEFGHIJKLMNOBOOT A86PQRCHESS A86STUVWXYZ[\]^_`abze of file in records CLUSPOS:DS 2 ;Position of last cluster accessed DIRTYFIL:DS 1 ;File has been written to if <>0 SIZCHG6 MAXCOM: EQU 40 ESCCH: EQU 1BH INTBASE:EQU 80H INTTAB: EQU 20H ENTRYPOINTSEG: EQU 0CH ENTRYPOINT: EQU INTBASE+40H CONTC:CHESS A86cdefghijklmnopqrCHESS A86stuvwxyz{|}~CHESS A86CHESS A86C: DS 1 ;Directory needs update if <>0 ORG 32 NR: DS 1 ;Next record RR: DS 3 ;Random record ; Description of 16-byte EQU INTTAB+3 EXIT: EQU INTBASE+8 LONGJUMP:EQU 0EAH LONGCALL:EQU 9AH MAXDIF: EQU 0FFFH SAVEXIT:EQU 10 ; Field definitionCHESS DOCCOMMAND A865DOSIO A86DEDLIN A86G; QDOS High-performance operating system for the 8086 version 0.11 ; by Tim Paterson ; Interrupt Entry Points: ; INTBdirectory entry (same as returned by SEARCH FIRST ; and SEARCH NEXT, functions 17 and 18). ; ; Location bytes Description ; for FCBs ORG 0 DS 12 ;Drive code and name EXTENT: DS 4 ENTPOS: DS 2 ;Position of entry in directory DRVBP: DS 2 ;BPHEX2BIN A86RDCPM A86SYS A86TRANS A86~ASE: ABORT ; INTBASE+4: COMMAND ; INTBASE+8: BASE EXIT ADDRESS ; INTBASE+C: CONTROL-C ABORT ; INTBASE+10H: FATAL ERROR ABORT ; 0 11 File name and extension ( 0E5H if empty) ; 11 2 First allocation unit ( < 4080 ) ; 13 3 File size, in byte MOV DI,AX SHL DI MOV AH,DPBSIZ MUL AX,AH MOV BX,DRVTAB ADD DI,BX ADD AX,DI MOV BP,AX SEG CS MOV [FATBASE],A DB "WB" ;Skip to char DB "UH" ;Copy line DB "HH" ;Kill line (no change in template) DB "RM" ;Reedit line (new template) IT STOW ;Set abort address--displacement MOV AX,CS MOV B,[ENTRYPOINT],LONGJUMP MOV [ENTRYPOINT+1],ENTRY MOV [ENTRYPOf first cluster MAXCLUS:DS 2 ;Number of clusters on drive + 1 DIRTYFAT:DS 1 ;-1=FAT has been changed FAT: DS 2 ;Start of F DX LODW INC AX STOW ;MAXCLUS XOR AL,AL STOB POP SI ;Restore pointer to init. table LODW ;Allocation table dis (LSB first, 24 bits max.) ; Field definition for Drive Parameter Block ORG 0 DRVNUM: DS 1 ;Drive number SECSIZ: DSX PERDEV: SEG CS MOV [BX],DI INC BX INC BX MOV AL,CH STOB ;DRVNUM LODW ;Pointer to DPT PUSH SI MOV SI,AX DB "DD" ;Backspace DB "P@" ;Enter insert mode DB "QL" ;Exit insert mode DB ESCCH,ESCCH ;Escape character DB ESCCH,ESCCINT+3],CS STOW STOW STOW MOV [INTBASE+4],COMMAND MOV DI,INTBASE+14H MOV AX,BIOSREAD STOW MOV AX,BIOSSEG STOW AT DPBSIZ: EQU $ ; BIOS entry point defintions BIOSSEG: EQU 40H ORG 0 DS 3 BIOSSTAT: DS 3 BIOSIN: DS 3 BIOSsplacement SEG CS ADD AX,[FATBASE] STOW ;FAT MOV DL,0 SHR DX ;FAT size in bytes ADD AX,DX CMP AX,BP ;Bigger th 1 ;Size of physical sector in records CLUSMSK:DS 1 ;Records/cluster - 1 CLUSSHFT:DS 1 ;Log2 of records/cluster FIRFAT: DS MOVB ;SECSIZ LODB DEC AL STOB ;CLUSMSK CBW FIGSHFT: INC AH SAR AL JNZ FIGSHFT MOV AL,AH STOB ;CLUSSHFH ;End of table ESCTABLEN:EQU $-ESCTAB HEADER: DB 13,10,"86-DOS version 0.11" DB 13,10 DB "Copyright 1980 Seattle Comp STOW ;Add 2 to DI STOW MOV [INTBASE+18H],BIOSWRITE MOV DX,CS MOV DS,DX ADD DX,BP MOV [DMAADD],80H MOV [DMAADD+2],OUT: DS 3 BIOSPRINT: DS 3 BIOSAUXIN: DS 3 BIOSAUXOUT: DS 3 BIOSREAD: DS 3 BIOSWRITE: DS 3 BIOSFLUSH: DS 3 ; Start of an already allocated JBE SMFAT MOV BP,AX SMFAT: INC CH ;Next I/O device number DEC CL JNZ PERDEV ADD BP,15 ;True 2 ;Starting record of FATs FATSIZ: DS 1 ;Number of records occupied by FAT FATCNT: DS 1 ;Number of FATs for this drive FIT LODW STOW ;FIRFAT (= number of reserved records) MOV DX,AX LODB STOB ;FATSIZ MOV AH,AL PUSH AX LODB STOButer Products, Inc.",13,10,"$" DOSINIT: DI UP MOV AX,CS MOV ES,AX LODB CBW MOV CX,AX SEG CS MOV [NUMDRV],ALDX MOV AX,[DRVTAB] MOV [CURDRVPT],AX MOV CX,DX MOV BX,0FH MEMSCAN: INC CX JZ HAVMEM MOV DS,CX MOV AL,[BX] NOTcode ORG 0 PUT 100H JMP DOSINIT ESCTAB: DB "SC" ;Copy one char DB "VN" ;Skip one char DB "TA" ;Copy to char 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 MOV AX,QURDIR: DS 2 ;Starting record of directory DIRSIZ: DS 1 ;Number of records occupied by directory FIRREC: DS 2 ;First record o ;FATCNT MUL AX,AH ADD AX,DX STOW ;FIRDIR MOV DX,AX LODB STOB ;DIRSIZ CBW ADD AX,DX STOW ;FIRREC POP AL MOV [BX],AL CMP AL,[BX] NOT AL MOV [BX],AL JZ MEMSCAN HAVMEM: SEG CS MOV [ENDMEM],CX XOR CX,CX MOV DS,CX ONLY DW SETATTRIB ;30 DW GETDSKPT DW USERCODE DW RNDRD DW RNDWRT DW FILESIZE ;35 DW SETRNDREC ; Extended FunctionPOP DX POP SI POP DI POP BP POP DS POP ES POP SS SEG CS MOV SP,[SPSAVE] IRET DISPATCH: ; Standard FunctionHR DI MOV DI,[BX] JNC ALIGNED SHL DX SHL DX SHL DX SHL DX AND DI,0FH JP PACKIN ALIGNED: AND DI,0F000H PACKINnt SEG CS PUSH [TEMP] ;Stack now ordered as if INT had been used CMP CL,MAXCALL ;This entry point doesn't get as many cal too big. CMP BX,[BP+MAXCLUS] JA HURTFAT LEA DI,[SI+BX] SHR BX MOV DI,[DI+BX] JNC HAVCLUS SHR DI SHR DI SHR MOV [EXIT],100H MOV [EXIT+2],DX MOV [INTBASE+0CH],100H MOV [INTBASE+0EH],DX CALL SETMEM MOV SI,HEADER CALL OUTMES s DW SETVECT DW NEWBASE DW BLKRD DW BLKWRT ;40 VERSION: GETIO: SETIO: WRTPROT: GETRDONLY: SETATTRIB: USERCODE:s DW ABORT ;0 DW CONIN DW CONOUT DW READER DW PUNCH DW LIST ;5 DW RAWIO DW GETIO DW SETIO DW PRTBUF DW B: OR DI,DX MOV [BX],DI RET GETFILE: ; Inputs: ; DS,DX point to FCB ; Function: ; Find file name in disk directoryls JA BADCALL MOV AH,CL SAVREGS: SEG CS MOV [SPSAVE],SP SEG CS MOV [SSSAVE],SS INC SP INC SP SEG CS POP [TEDI SHR DI STC HAVCLUS: RCL BX AND DI,0FFFH RET HURTFAT: MOV SI,BADMES CALL OUTMES JMP ERROR PACK: ; In RET L QUIT: MOV AH,0 JP SAVREGS COMMAND: ;Interrupt call entry point CMP AH,MAXCOM JBE SAVREGS BADCALL: MOV A MOV AL,0 RET READER: CALL BIOSAUXIN,BIOSSEG RET PUNCH: MOV AL,DL CALL BIOSAUXOUT,BIOSSEG RET UNPACK:UFIN ;10 DW CONSTAT DW VERSION DW DSKRESET DW SELDSK DW OPEN ;15 DW CLOSE DW SRCHFRST DW SRCHNXT DW DELETE . First byte is ; drive number (0=current disk). "?" matches any ; character. ; Outputs: ; Carry set if file not found ; ELMP] MOV SP,CS MOV SS,SP MOV SP,STACK PUSH ES PUSH DS PUSH BP PUSH DI PUSH SI PUSH DX PUSH CX PUSH BX PUSputs: ; DS = CS ; BX = Cluster number ; DX = Data ; SI = Pointer to drive FAT ; Outputs: ; The data is stored in the FAT aL,0 IRET: IRET ENTRY: ;System call entry point and dispatcher POP AX ;IP from the long call at 5 POP AX ;Segment from ; Inputs: ; DS = CS ; BX = Cluster number ; BP = Base of drive parameters ; SI = Pointer to drive FAT ; Outputs: ; DI DW SEQRD ;20 DW SEQWRT DW CREATE DW RENAME DW INUSE DW CURDRV ;25 DW SETDMA DW GETFATPT DW WRTPROT DW GETRDSE ; BP = Base of drive parameters ; DS = CS ; ES = CS ; AL = Directory record number ; BX = Pointer into directory buffer H AX MOV BL,AH MOV BH,0 SHL BX UP SEG CS CALL [BX+DISPATCH] SEG CS MOV [AXSAVE],AL POP AX POP BX POP CX t the given cluster. ; BX,DX,DI all destroyed ; No other registers affected MOV DI,BX SHR BX ADD BX,SI ADD BX,DI Sthe long call at 5 SEG CS POP [TEMP] ;IP from the CALL 5 PUSHF ;Start re-ordering the stack DI PUSH AX ;Save segme= Contents of FAT for given cluster ; Zero set means DI=0 (free cluster) ; No other registers affected. Fatal error if cluster ; SI = Pointer to First Cluster field in directory entry ; [DIRBUF] has directory record with match ; [NAME1] has file name ame in upper case ; All registers except DX destroyed ; Carry set if bad file name or drive MOV AX,CS MOV ES,AX MOV DIALL FINDNAME JC ERRET SAVDREC: MOV AH,AL RENFIL: MOV DI,BX MOV SI,NAME2 MOV CX,11 NEWNAM: LODB CMP AL,"?" JZ er STOW ; last cluster accessed LODB SHL AL LODW RCL AX STOW ; size of file in records XOR AX,AX STOW ; po DELETE: ; System call 19 CALL GETFILE JC ERRET PUSH AX PUSH BX CALL FATREAD POP BX DELFILE: MOV B,[BX],0E5H rectory ; entry in DIRBUF, and the top of the stack has the ; address and segment of the FCB to be opened. This ; entry point; All other registers destroyed. CALL MOVNAME JC RET ;Bad file name? FINDNAME: MOV AX,CS MOV DS,AX MOV AL,0 RDIRR,NAME1 MOV SI,DX LODB SEG ES CMP [NUMDRV],AL JC RET CBW XCHG AX,BP SHL BP MOV BP,[BP+CURDRVPT] LODNAME: ; ThNOCHG MOV [DI],AL NOCHG: INC DI LOOP NEWNAM CALL NEXTENT JZ RENFIL MOV AL,AH PUSH AX CALL DIRWRITE POP AX Csition of last cluster STOW ; file not dirty FATREAD: TEST B,[BP+DIRTYFAT],-1 JNZ RET CALL FIGFAT NEXTFAT: PUSH PUSH BX MOV BX,[BX+11] MOV SI,[BP+FAT] OR BX,BX JZ DELNXT CMP BX,[BP+MAXCLUS] JA DELNXT CALL RELEASE DELNXT: PO is used by CREATE. POP ES POP DI JC ERRET MOV AH,[BP+DRVNUM] INC AH SEG ES MOV [DI],AH SEG ES MOV [DI+EXTENT]EC: PUSH AX CALL DIRREAD POP AX MOV BX,DIRBUF-16 CONTSRCH: CALL NEXTENT JZ RET NDIRREC: INC AL ;Next directory is entry point copies a file name from DS,SI ; to ES,DI converting to upper case. MOV CX,11 MOVCHK: LODB AND AL,7FH CMALL NDIRREC JNC SAVDREC ;New record read, save current number XOR AL,AL RET ERRET: MOV AL,-1 RET MOVNAME: DX PUSH CX PUSH BX PUSH AX CALL DREAD OR AL,AL POP AX POP BX POP CX POP DX JNZ BADFAT SUB AL,[BP+FATCNT] P BX CALL NEXTENT JZ DELFILE POP AX PUSH AX CALL DIRWRITE POP AX CALL NDIRREC PUSH AX JNC DELFILE POP AX C,0 ;Set extent field to 0 ADD DI,16 ;Point to entry pos. field MOV CX,BX SUB CX,DIRBUF MOV AH,CL STOW ;directory lorecord CMP AL,[BP+DIRSIZ] JB RDIRREC STC RET NEXTENT: ADD BX,16 CMP BX,DIRBUF+127 JA RET CMP B,[BX],0E5H JZP AL,60H JLE CASEOK AND AL,5FH CASEOK: CMP AL,20H JC RET STOB LOOP MOVCHK RET OPEN: ;System call 15 PUSH DX ; Inputs: ; DS, DX point to FCB ; Outputs: ; ES = CS ; If file name OK: ; BP has base of driver parameters ; [NAME1] has n JZ RET NEG AL ;{Insert error code here. AL=number of bad fats. ;Since one good FAT was read, should include option ;to rewALL FATWRT XOR AL,AL RET RENAME: ;System call 23 CALL MOVNAME JC ERRET ADD SI,5 MOV DI,NAME2 CALL LODNAME Ccation MOV AX,BP STOW ;pointer to driver parameters LEA SI,[BX+11] LODW ;Get starting cluster STOW ; first clust NEXTENT MOV SI,BX MOV DI,NAME1 MOV CX,11 WILDCRD: REPE CMPB JZ RET CMP B,[DI-1],"?" JZ WILDCRD JP NEXTENT PUSH DS CALL GETFILE DOOPEN: ; Enter here to perform OPEN on file already found ; in directory. DS=ES=CS, BX points to dirite all FATs.} JP FATWRT BADFAT: ADD DX,CX DEC AL JNZ NEXTFAT POP BP ;{Insert error code here. All FATs on drive call 22 CALL MOVNAME JC ERRET3 MOV DI,NAME1 MOV CX,11 MOV AL,"?" REPNE SCAB JZ ERRET3 PUSH DX PUSH DS MOV ADD DX,CX DEC AL JNZ EACHFAT OKRET: MOV AL,0 RET BADCLOSE: MOV B,[BP+DIRTYFAT],0 MOV AL,-1 RET FIGFAT:sters destroyed. MOV AL,[BP+DRVNUM] PUSH BP PUSH BX PUSH CX PUSH DX CALL BIOSREAD,BIOSSEG POP DX POP DI POP MOV [BX+14],DX MOV DL,0 RCR DL MOV [BX+13],DL CALL DIRWRITE CHKFATWRT: ; Do FATWRT only if FAT is dirty TEST umber ; BP = Base of drive parameters ; Function: ; Read the directory block into DIRBUF. ; Outputs: ; BP unchanged ; All are bad.} MOV SI,BADFATMES CALL HARDERR JP FATREAD CLOSE: ;System call 16 MOV DI,DX TEST B,[DI+DIRTYFIL],-1 JZ NOAX,CS MOV DS,AX XOR AX,AX RDIRREC2: PUSH AX CALL DIRREAD POP AX MOV DI,DIRBUF-16 MOV CX,8 FNDFRE: ADD DI,16 ; Loads registers with values needed to read or ; write a FAT. MOV AL,[BP+FATCNT] MOV BX,[BP+FAT] MOV CL,[BP+FATSIZ] ;NBX POP BP JC HARDREAD XOR AL,AL RET HARDREAD: MOV SI,RDERRMES CALL HARDERR JP DREAD DIRWRITE: ; Inputs: B,[BP+DIRTYFAT],-1 JZ OKRET FATWRT: ; Inputs: ; DS = CS ; BP = Base of drive parameter table ; Function: ; Write theother registers destroyed. CALL DIRCOMP DREAD: ; Inputs: ; BX,DS = Transfer address ; CX = Number of records ; DX =FLSH PUSH DI MOV BP,[DI+DRVBP] MOV AL,[BP+DRVNUM] CALL BIOSFLUSH,BIOSSEG POP DI NOFLSH: TEST B,[DI+SIZCHG],-1 JZ CMP B,[DI],0E5H LOOPNE FNDFRE JZ FREESPOT INC AL CMP AL,[BP+DIRSIZ] JC RDIRREC2 POP DS POP DX ERRET3: MOV AL,-1o. of records occupied by FAT MOV CH,0 MOV DX,[BP+FIRFAT] ;Record number of start of FATs RET DIRCOMP: ; Prepare reg; DS = CS ; AL = Directory block number ; BP = Base of drive parameters ; Function: ; Write the directory block into DIRBUF. FAT back to disk and reset FAT ; dirty bit. ; Outputs: ; AL = 0 ; BP unchanged ; All other registers destroyed MOV B,[ Absolute record number ; BP = Base of drive parameters ; Function: ; Calls BIOS to perform disk read. If BIOS reports ; errOKRET MOV DX,DI PUSH DX PUSH DS CALL GETFILE POP ES POP DI JC BADCLOSE MOV CX,BX SUB CX,DIRBUF MOV AH,CL S RET FREESPOT: MOV BX,DI MOV SI,NAME1 MOV CX,5 MOVB REP MOVW XCHG AL,AH MOV CL,5 REP STOB XCHG AL,AH isters for directory read or write CBW ADD AX,[BP+FIRDIR] MOV DX,AX MOV BX,DIRBUF MOV CX,1 RET CREATE: ;System ; Outputs: ; BP unchanged ; All other registers destroyed. CALL DIRCOMP DWRITE: ; Inputs: ; BX,DS = Transfer adBP+DIRTYFAT],0 CALL FIGFAT EACHFAT: PUSH DX PUSH CX PUSH BX PUSH AX CALL DWRITE POP AX POP BX POP CX POP DXors, will call HARDERR for further action. ; Outputs: ; AL = 0 if no error, otherwise non-zero ; BP preserved. All other regiEG ES CMP AX,[DI+ENTPOS] JNZ BADCLOSE SEG ES MOV CX,[DI+FIRCLUS] MOV [BX+11],CX SEG ES MOV DX,[DI+FILSIZ] SHR DXPUSH AX PUSH BX CALL DIRWRITE POP BX POP AX JMP DOOPEN DIRREAD: ; Inputs: ; DS = CS ; AL = Directory block ndress ; CX = Number of records ; DX = Absolute record number ; BP = Base of drive parameters ; Function: ; Calls BIOS to pe JP FINBLK BLKWRT: ;System call 40 MOV DI,DX MOV AX,[DI+RR] CALL STORE FINBLK: MOV [CXSAVE],CX JCXZ FINRND INCV SP,[SPSAVE] MOV DS,[DSSAVE] SEG CS JMP L,[EXITHOLD] SEQRD: ;System call 20 CALL GETREC MOV CX,1 CALL LOAD J divide by 128 ROL BX XCHG BL,BH JNZ CHKMAX MOV BH,2 ;All 512 records OK CHKMAX: CMP CX,BX JBE SAVCNT MOV CX,BX UTMES GETINSTR: CALL IN OR AL,20H CMP AL,"a" JZ ERROR CMP AL,"r" JZ RET CMP AL,"i" JZ IGNORE CMP AL,"c" JNZ DX ; [NEXTADD] = Displacement of disk transfer within segment ; [DSKERR] = 0 (no errors yet) ; [TRANS] = 0 (No transfers yetrform disk write. If BIOS reports ; errors, will call HARDERR for further action. ; Outputs: ; AL = 0 if no error, otherwise 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 XCHGCXZ SETNREX INC AX JP SETNREX SEQWRT: ;System call 21 CALL GETREC MOV CX,1 CALL STORE JCXZ SETNREX INC AX JP MOV B,[DSKERR],2 ;Flag that trimming took place SAVCNT: MOV [RECCNT],CX RET SEGEND: MOV B,[DSKERR],2 MOV CX,0 POP B GETINSTR POP AX MOV AL,1 RET IGNORE: POP AX MOV AL,0 RET ABORT: SEG CS MOV DS,[CSLOC] XOR AX,AX MOV ES,) ; If SETUP detects no records will be transfered, it returns 1 level up ; with CX = 0. MOV BP,[DI+DRVBP] MOV BX,DS non-zero ; BP preserved. All other registers destroyed. MOV AL,[BP+DRVNUM] MOV AH,0 CMP DX,[BP+FIRREC] RCR AH PUSH CL,CH SEG ES MOV [DI+EXTENT],CX MOV AL,[DSKERR] RET SETUP: ; Inputs: ; DS:DI point to FCB ; AX = Record positioSETNREX RNDRD: ;System call 33 MOV CX,1 MOV DI,DX MOV AX,[DI+RR] CALL LOAD JP FINRND RNDWRT: ;System call 34 MX RET FNDCLUS: ; Inputs: ; DS = CS ; CX = No. of clusters to skip ; BP = Base of drive parameters ; SI = FAT pointAX MOV SI,SAVEXIT MOV DI,EXIT MOVW MOVW MOVW MOVW ERROR: MOV SP,BPSAVE MOV AX,CS MOV DS,AX MOV ES,AX CALLMOV ES,BX MOV BX,CS MOV DS,BX MOV [RECPOS],AX MOV [FCB],DX MOV BX,[DMAADD] MOV [NEXTADD],BX MOV B,[DSKERR],0 MOVBP PUSH BX PUSH CX PUSH DX CALL BIOSWRITE,BIOSSEG POP DX POP DI POP BX POP BP JC HARDWRITE XOR AL,AL RET n in file of disk transfer ; CX = Record count ; Outputs: ; DS = CS ; ES:DI point to FCB ; CX = No. of records to transfer OV 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 LOADer ; ES:DI point to FCB ; Outputs: ; BX = Last cluster skipped to ; CX = No. of clusters remaining (0 unless EOF) ; DX = Po WRTFATS XOR AX,AX MOV DS,AX MOV SI,EXIT MOV DI,EXITHOLD MOVW MOVW POP BP POP ES POP ES POP DS POP SS MO [TRANS],0 MOV SI,[BP+FAT] ADD BX,7FH ;See if there is any space left JC SEGEND AND BL,80H NEG BX ;These instructionsHARDWRITE: MOV SI,WRTERRMES CALL HARDERR JP DWRITE HARDERR: SUB DI,CX ADD DX,DI CALL SHFTDI7 ADD BX,DI CALL O ; BP = Base of drive parameters ; SI = FAT pointer ; [RECCNT] = Record count ; [RECPOS] = Record position in file ; [FCB] =sition of last cluster ; DI destroyed. No other registers affected. SEG ES MOV BX,[DI+LSTCLUS] SEG ES MOV DX,[DI+CLUSCLUSSHFT] SHR AX,CL MOV CX,AX CALL FNDCLUS OR CX,CX JNZ LVDSK MOV DX,0FFFH MOV B,[BP+DIRTYFAT],-1 MOV DI,[FCB] I+LSTCLUS],AX MOV AX,[RECPOS] MOV BX,[TRANS] ADD AX,BX SEG ES CMP AX,[DI+FILSIZ] JBE SAMSIZ SEG ES MOV [DI+FILSIuts: ; DS = CS ; BX = Physical cluster ; CX = No. of records ; DL = record within cluster ; BP = Base of drives parameters SEG ES MOV BX,[DI+FILSIZ] SUB BX,AX JBE WRTERRJ CMP BX,CX JNB ENUF MOV B,[DSKERR],1 MOV [RECCNT],BX ENUF: MOVst cluster minus current cluster JCXZ HAVSTART ;See if no more data PUSH CX ;No. of clusters of first MOV CX,AX CALL ALPOS] OR BX,BX JZ NOCLUS SUB CX,DX JNB FINDIT ADD CX,DX XOR DX,DX SEG ES MOV BX,[DI+FIRCLUS] FINDIT: JCXZ RET MOV AX,[RECPOS] SEG ES MOV [DI+FILSIZ],AX SEG ES MOV B,[DI+SIZCHG],-1 XOR CX,CX RET STORE: ; Inputs: ; DS:DIZ],AX SEG ES MOV B,[DI+SIZCHG],-1 SAMSIZ: DEC AX MOV DX,AX MOV CL,[BP+CLUSSHFT] SHR DX,CL SEG ES MOV [DI+CLUSPO ; [NEXTADD] = transfer address ; Outputs: ; AX = No. of records remaining ; BX = Transfer address ; CX = No. or records to CL,[BP+CLUSSHFT] SHR AX,CL MOV CX,AX CALL FNDCLUS OR CX,CX JNZ WRTERR MOV DL,[RECPOS] AND DL,[BP+CLUSMSK] MOV CLOCATE POP CX JC WRTERR DEC CX JZ NOSKIP CALL SKPCLP PUSH BX WRCLUS: POP BX NOSKIP: MOV DL,[RECPOS] AND DL,[ SKPCLP: CALL UNPACK CMP DI,0FFFH JZ RET XCHG BX,DI INC DX LOOP SKPCLP RET NOCLUS: INC CX DEC DX RET L point to FCB ; AX = Position in file of disk transfer ; CX = Record count ; Outputs: ; AX = Position of last record writtenS],DX MOV CX,BX RET WRTERRJ:JP WRTERR HAVSTART: MOV CX,AX PUSH BX CALL FNDCLUS JCXZ WRCLUS CALL ALLOCATE Pbe transferred ; DX = Physical record address ; DI = Next cluster ; [CLUSNUM] = Last cluster accessed ; [NEXTADD] updated ;X,[RECCNT] RDLP: CALL OPTIMIZE PUSH DI PUSH AX PUSH DS MOV DS,[DMAADD+2] CALL DREAD POP DS POP CX POP BX JCBP+CLUSMSK] MOV CX,[RECCNT] WRTLP: CALL OPTIMIZE PUSH DI PUSH AX PUSH DS MOV DS,[DMAADD+2] CALL DWRITE POP DS OAD: ; Inputs: ; DS:DI point to FCB ; AX = Position in file to read ; CX = No. of records to read ; Outputs: ; AX = Posi ; CX = No. of records written ; ES:DI point to FCB ; LSTCLUS, CLUSPOS fields in FCB set CALL SETUP JCXZ WRTEOF MOV BOP BX JNC NOSKIP WRTERR: MOV B,[DSKERR],1 LVDSK: MOV AX,[RECPOS] XOR CX,CX MOV DI,[FCB] RET WRTEOF: MOV CL,[BP+ BP unchanged. Note that segment of transfer not set. PUSH DX PUSH BX MOV AL,[BP+CLUSMSK] INC AL ;Number of records pXZ SETFCB MOV DL,0 CMP BX,0FFFH JNZ RDLP MOV B,[DSKERR],1 SETFCB: MOV AX,[CLUSNUM] MOV DI,[FCB] SEG ES MOV [D POP CX POP BX MOV DL,0 OR CX,CX JNZ WRTLP CALL SETFCB SEG ES MOV B,[DI+DIRTYFIL],-1 RET OPTIMIZE: ; Inption of last record read ; CX = No. of records read ; ES:DI point to FCB ; LSTCLUS, CLUSPOS fields in FCB set CALL SETUP X,CX ADD BX,AX DEC BX MOV CL,[BP+CLUSSHFT] SHR AX,CL SHR BX,CL MOV CX,AX MOV AX,BX CALL FNDCLUS SUB AX,DX ;Laer cluster MOV AH,AL SUB AL,DL ;AL = Number of records left in first cluster MOV DX,CX MOV SI,[BP+FAT] MOV CX,0 OPTCng dirty bit ; FIRCLUS field of FCB set if file was null ; SI,BP unchanged. All other registers destroyed. PUSH BX MOV A DI,DX MOV AL,[DI+NR] MOV BX,[DI+EXTENT] SHL AL SHR BX RCR AL MOV AH,BL RET ALLOCATE: ; Inputs: ; DS = CSputs: ; BX = Cluster in a file ; SI = Base of drive FAT ; DS = CS ; Outputs: ; BX = Last cluster in the file ; DI destroyeBH ROR BX MOV SI,[NEXTADD] ADD BX,SI ;Adjust by size of transfer MOV [NEXTADD],BX ADD [TRANS],CX POP DX POP BX I+FIRCLUS],BX OR [SI],0FFFH RET RELEASE: ; Inputs: ; DS = CS ; BX = Cluster in file ; SI = FAT pointer ; BP = BaLUS: ;AL has number of records available in current cluster ;AH has number of records available in next cluster ;BX has curreX,BX ALLOC: MOV DX,BX FINDFRE: INC BX CMP BX,[BP+MAXCLUS] JL TRYOUT CMP AX,1 JG TRYIN POP BX MOV DX,0FFFH CA ; ES = Segment of FCB ; BX = Last cluster of file (0 if null file) ; CX = No. of clusters to allocate ; DX = Position of cld. No other registers affected. CALL UNPACK CMP DI,0FFFH JZ RET MOV BX,DI JP GETEOF SRCHFRST: ;System call 17 PUSH CX MOV CL,[BP+CLUSSHFT] DEC DX DEC DX SHL DX,CL OR DL,BL ADD DX,[BP+FIRREC] POP CX MOV BX,SI RET BLKDON:se of drive parameters ; Function: ; Frees cluster chain starting with [BX] ; AX,BX,DX,DI all destroyed. Other registers unchnt physical cluster ;CX has number of sequential records found so far ;DX has number of records left to transfer ;SI has FAT LL RELBLKS OR [SI],0FFFH STC RET TRYOUT: CALL UNPACK JZ HAVFRE TRYIN: DEC AX JLE FINDFRE XCHG AX,BX CALL Uuster BX ; BP = Base of drive parameters ; SI = FAT pointer ; [FCB] = Displacement of FCB within segment ; Outputs: ; IF in CALL GETFILE SAVPLCE: ; Search-for-next enters here to save place and report ; findings. JC KILLSRCH MOV [SRCHDON],AL MOV CX,DX ;Make the total equal to the request JP FINCLUS GETREC: ; Inputs: ; DS:DX point to FCB ; Outputs: ; Aanged. XOR DX,DX RELBLKS: ; Enter here with DX=0FFFH to put an end-of-file mark ; in the first cluster and free the rest pointer CALL UNPACK ADD CL,AL ADC CH,0 CMP CX,DX JAE BLKDON MOV AL,AH INC BX CMP DI,BX JZ OPTCLUS DEC BX FINPACK JZ HAVFRE XCHG AX,BX JP FINDFRE HAVFRE: XCHG BX,DX MOV AX,DX CALL PACK MOV BX,AX LOOP ALLOC MOV DX,0FFFsufficient space ; THEN ; Carry set ; ELSE ; Carry clear ; BX = First cluster allocated ; FAT is fully updated includiMOV [PDIR],BX MOV [SRCHBP],BP ;Information in directory entry must be copied into the first ; 16 bytes starting at the disk X = Record number determined by EXTENT and NR fields ; DS:DI point to FCB ; BX destroyed. No other registers affected. MOVin the chain. CALL UNPACK JZ RET MOV AX,DI CALL PACK CMP AX,0FFFH MOV BX,AX JNZ RELEASE RET GETEOF: ; InNCLUS: MOV [CLUSNUM],BX ;Last cluster accessed SUB DX,CX ;Number of records still needed MOV AX,DX MOV BX,CX XCHG BL,H CALL PACK MOV B,[BP+DIRTYFAT],-1 POP BX CALL UNPACK XCHG BX,DI OR DI,DI JNZ RET MOV DI,[FCB] SEG ES MOV [Dtransfer address. MOV SI,BX LES DI,[DMAADD] MOV CX,8 REP MOVW MOV AL,0 RET KILLSRCH: MOV AL,-1 MOV [SRCHDONSE: LODW MOV BP,AX TEST B,[BP+DIRTYFAT],-1 JZ SETBIT STC SETBIT: RCL BX LOOP CHKUSE MOV AL,BL RET SETRND] MOV [CURDRVPT],AX WRTFATS: ; DS=CS. Writes back all dirty FATs. All registers destroyed. MOV CL,[NUMDRV] MOV CH,0 MO AND CL,0FEH MOV BP,CX JMP [BP+ESCFUNC] ENDLIN: STOB CALL OUT POP DI MOV [DI-1],DH INC DH COPYNEW: MOV BP,ESADD+2],DS RET GETFATPT: ;System call 27 MOV AX,CS MOV DS,AX MOV [DSSAVE],CS MOV BP,[CURDRVPT] CALL FATREAD MOV IN: SEG CS MOV AL,[CARPOS] SEG CS MOV [STARTPOS],AL PUSH SI MOV DI,INBUF MOV AH,CH MOV BH,CH MOV DH,CH GETCH:],AL RET SRCHNXT: ;System call 18 MOV AX,CS MOV ES,AX MOV DS,AX MOV AL,[SRCHDON] CMP AL,-1 JZ RET MOV BX,[PREC: ;System call 36 CALL GETREC MOV [DI+33],AX MOV AL,0 JZ BIGRR INC AL BIGRR: MOV [DI+35],AL RET SELDSK: ;V SI,CURDRVPT+2 WRTFAT: LODW PUSH CX PUSH SI MOV BP,AX CALL CHKFATWRT POP SI POP CX LOOP WRTFAT MOV AL,-1 C MOV BX,DS MOV ES,BX MOV DS,BP MOV SI,INBUF MOV CL,DH REP MOVB RET CRLF: MOV AL,13 CALL OUT MOV AL,10 JBX,[BP+FAT] MOV AL,[BP+CLUSMSK] INC AL MOV DX,[BP+MAXCLUS] DEC DX MOV B,[BP+DIRTYFAT],-1 MOV [BXSAVE],BX MOV [DXSA CALL IN CMP AL,7FH JZ BACKSP CMP AL,8 JZ BACKSP CMP AL,13 JZ ENDLIN CMP AL,10 JZ PHYCRLF CMP AL,"X"-"@" JDIR] MOV BP,[SRCHBP] CALL CONTSRCH JP SAVPLCE FILESIZE: ;System call 35 PUSH DI PUSH DX CALL GETFILE POP DI System call 14 MOV DH,0 MOV BX,DX PUSH CS POP DS CMP BL,[NUMDRV] JGE RET SHL BX MOV AX,[BX+CURDRVPT+2] MOV [CUALL BIOSFLUSH,BIOSSEG RET CURDRV: ;System call 25 SEG CS MOV BP,[CURDRVPT] MOV AL,[BP+DRVNUM] RET INUSE: ;SyMP OUT PHYCRLF: CALL CRLF JP GETCH KILNEW: MOV AL,"\" CALL OUT POP SI PUTNEW: CALL CRLF JMP NEWLIN BACKSVE],DX RET GETDSKPT: ;System call 31 SEG CS MOV [DSSAVE],CS SEG CS MOV BX,[CURDRVPT] SEG CS MOV [BXSAVE],BX Z KILNEW CMP AL,ESCCH JZ ESC SAVCH: CMP DH,DL JAE GETCH STOB INC DH CALL OUT OR AH,AH JNZ GETCH CMP BH,BL POP ES MOV AL,-1 JC RET ADD DI,33 ;Write size in RR field LEA SI,[BX+13] LODB SHL AL LODW RCL AX ;Round to neRDRVPT],AX RET BUFIN: ;System call 10 MOV AX,CS MOV ES,AX MOV SI,DX MOV CH,0 LODW OR AL,AL JZ RET MOV BL,stem call 24 MOV AX,CS MOV DS,AX MOV CL,[NUMDRV] MOV CH,0 MOV SI,CX SHL SI ADD SI,CURDRVPT MOV BX,0 DOWN CHKUP: OR DH,DH JZ OLDBAK CALL BACKUP SEG ES MOV AL,[DI] CMP AL," " JAE OLDBAK CMP AL,9 JZ BAKTAB CALL BACKMES RET DSKRESET: ;System call 13 SEG CS MOV [DMAADD+2],DS MOV AX,CS MOV DS,AX MOV [DMAADD],80H MOV AX,[CURDRVPT+2 JAE GETCH INC SI INC BH JP GETCH ESC: CALL IN MOV CL,ESCTABLEN PUSH DI MOV DI,ESCTAB REPNE SCAB POP DI arest record STOW MOV AL,0 RCL AL STOB RET SETDMA: ;System call 26 SEG CS MOV [DMAADD],DX SEG CS MOV [DMAAH MOV BH,CH CMP AL,BL JBE NOEDIT CMP B,[BX+SI],0DH JZ EDITON NOEDIT: MOV BL,CH EDITON: MOV DL,AL DEC DX NEWLOLDBAK: OR AH,AH JNZ GETCH1 OR BH,BH JZ GETCH1 DEC BH DEC SI GETCH1: JMP GETCH BAKTAB: PUSH DI DEC DI DOWNL,20H JB CTRLOUT CMP AL,7FH JZ OUTCH SEG CS INC B,[CARPOS] OUTCH: CALL BIOSOUT,BIOSSEG SEG CS TEST B,[PFLAG],-1ES JNZ NOTFND NOT CL ADD CL,BL SUB CL,BH RET NOTFND: POP BP JMP GETCH REEDIT: MOV AL,"@" CALL OUT POP DIK JZ IN RET RAWIO: ;System call 6 MOV AL,DL CMP AL,-1 JNZ RAWOUT CALL BIOSSTAT,BIOSSEG JZ RET CALL BIOSIN,BIOP COPYEACH COPYSTR: CALL FINDOLD JP COPYEACH COPYONE: MOV CL,1 COPYEACH: CMP DH,DL JZ GETCH2 CMP BH,BL JZ GOV AL,"^" CALL OUT POP AX OR AL,40H JP OUT ZERPOS: SEG CS MOV B,[CARPOS],0 JP OUTCH BACKPOS: SEG CS DEC B, MOV CL,DH MOV AL," " PUSH BX MOV BL,7 JCXZ FIGTAB FNDPOS: SCAB JNA CHKCNT SEG ES CMP B,[DI+1],9 JZ HAVTAB JZ STATCHK CALL BIOSPRINT,BIOSSEG STATCHK: CALL BIOSSTAT,BIOSSEG JZ RET INCHK: CALL BIOSIN,BIOSSEG CMP AL,'S'-'@' PUSH DI PUSH ES PUSH DS CALL COPYNEW POP DS POP ES POP SI MOV BL,DH JMP PUTNEW ENTERINS: MOV AH,-1 JMPSSEG RET RAWOUT: CALL BIOSOUT,BIOSSEG RET LIST: ;System call 5 MOV AL,DL CALL BIOSPRINT,BIOSSEG RET PRTBUF: ;ETCH2 LODB STOB CALL OUT INC BH INC DH LOOP COPYEACH GETCH2: JMP GETCH SKIPONE: CMP BH,BL JZ GETCH2 INC [CARPOS] JP OUTCH TAB: MOV AL,0 SEG CS XCHG AL,[CARPOS] OR AL,0F8H NEG AL PUSH CX MOV CL,AL MOV CH,0 TABLP DEC BL CHKCNT: LOOP FNDPOS FIGTAB: SEG CS SUB BL,[STARTPOS] HAVTAB: SUB BL,DH ADD CL,BL AND CL,7 UP POP BX JNZ NOSTOP CALL BIOSIN,BIOSSEG NOSTOP: CMP AL,'P'-'@' JZ PRINTON CMP AL,'N'-'@' JZ PRINTOFF CMP AL,'C'-'@' JNZ GETCH EXITINS: MOV AH,0 JMP GETCH ESCFUNC: DW GETCH DW TWOESC DW EXITINS DW ENTERINS DW BACKSP DW REEDIT System call 9 MOV SI,DX OUTSTR: LODB CMP AL,"$" JZ RET CALL OUT JP OUTSTR OUTMES: ;String output for internal meBH INC SI JMP GETCH SKIPSTR: CALL FINDOLD ADD SI,CX ADD BH,CL JMP GETCH FINDOLD: CALL IN MOV CL,BL SUB C: MOV AL," " CALL OUTCH LOOP TABLP POP CX RET CONSTAT: ;System call 11 CALL BIOSSTAT,BIOSSEG JZ RET OR AL,- POP DI JZ OLDBAK TABBAK: CALL BACKMES LOOP TABBAK JP OLDBAK BACKUP: DEC DH DEC DI BACKMES: MOV AL,8 CALL OU RET INT CONTC ;Execute user Ctrl-C handler RET PRINTON: SEG CS MOV B,[PFLAG],1 RET PRINTOFF: SEG CS MOV B,[P DW KILNEW DW COPYLIN DW SKIPSTR DW COPYSTR DW SKIPONE DW COPYONE CONOUT: ;System call 2 MOV AL,DL OUT: CMP Assages SEG CS LODB CMP AL,"$" JZ RET CALL OUT JP OUTMES SETVECT: ; Interrupt call 37 XOR BX,BX MOV ES,BX L,BH JZ NOTFND DEC CX JZ NOTFND PUSH ES PUSH DS POP ES PUSH DI MOV DI,SI INC DI REPNE SCAB POP DI POP 1 RET CONIN: ;System call 1 CALL INCHK PUSH AX CALL OUT POP AX RET IN: ;Internal input routine CALL INCHT MOV AL," " CALL OUTCH MOV AL,8 JMP OUTCH TWOESC: MOV AL,ESCCH JMP SAVCH COPYLIN: MOV CL,BL SUB CL,BH JFLAG],0 RET CTRLOUT: CMP AL,10 JZ OUTCH CMP AL,13 JZ ZERPOS CMP AL,8 JZ BACKPOS CMP AL,9 JZ TAB PUSH AX MMOV BL,AL SHL BX SHL BX SEG ES MOV [BX],DX SEG ES MOV [BX+2],DS RET NEWBASE: ; Interrupt call 38 MOV ES,DX user FCB RECPOS: DS 2 NEXTADD:DS 2 RECCNT: DS 2 CLUSNUM:DS 2 TRANS: DS 2 DS 50 ;Stack space AXSAVE: DS 2 BXSAVE: DS 213,10,"$" BADFATMES:DB 13,10,"All FATs on disk are bad",13,10,"$" RDERRMES:DB 13,10,"Disk read error",13,10,"$" WRTERRMES:DB ction codes PRINTMES: EQU 9 OPEN: EQU 15 CLOSE: EQU 16 DELETE: EQU 19 READ: EQU 20 SETDMA: EQU 26 MAKE: EQU 22 SEQWRT: E CX,CX MOV DS,CX MOV ES,DX MOV SI,EXIT MOV DI,SAVEXIT MOVW MOVW MOVW MOVW SEG CS MOV CX,[ENDMEM] SEG ES SEG CS MOV DS,[CSLOC] XOR SI,SI MOV DI,SI MOV CX,80H REP MOVW SETMEM: ; Inputs: ; DX = Segment ; Function: CXSAVE: DS 2 DXSAVE: DS 2 SISAVE: DS 2 DISAVE: DS 2 BPSAVE: DS 2 DSSAVE: DS 2 ESSAVE: DS 2 STACK: SSSAVE: DS 2 SPSAVE13,10,"Disk write error",13,10,"$" CARPOS: DB 0 STARTPOS:DB 0 PFLAG: DB 0 SRCHDON:DB -1 PDIR: DS 2 SRCHBP: DS 2 EXITHOLQU 21 ;The following equates define some token values returned by GETSYM UNDEFID:EQU 0 ;Undefined identifier (including no nMOV [2],CX SUB CX,DX CMP CX,MAXDIF JBE HAVDIF MOV CX,MAXDIF HAVDIF: MOV BX,ENTRYPOINTSEG SUB BX,CX SHL CX SHL C ; Completely prepares a program base at the ; specified segment. ; Outputs: ; DS = DX ; ES = DX ; [0] has INT 20H ; [2]: DS 2 CURDRVPT:DS 2 DRVTAB: ;Address of start of DPBs D:DS 4 ENDMEM: DS 2 FATBASE:DS 2 INBUF: DS 255 DIRBUF: DS 128 NUMDRV: DS 1 ;Number of drives NAME1: DS 11 ;File name buffeearby RET) CONST: EQU 1 ;Constant (including $) REG: EQU 2 ;8-bit register XREG: EQU 3 ;16-bit register (except segment regisX SHL CX SHL CX MOV DS,DX MOV [6],CX MOV [8],BX MOV [0],20CDH ;"INT INTTAB" MOV B,[5],LONGCALL RET SHFTDI7:; Seattle Computer Products 8086 Assembler version 2.00 ; by Tim Paterson ; Runs on the 8086 under 86-DOS SYMWID: EQU 10 = First unavailable segment ([ENDMEM]) ; [5] to [9] form a long call to the entry point ; [10] to [13] have exit address (fror NAME2: DS 11 DMAADD: DS 4 ;User's disk transfer address (disp/seg) TEMP: CSLOC: DS 2 DSKERR: DS 1 FCB: DS 2 ;Address of ters) SREG: EQU 4 ;Segment register ORG 100H PUT 100H JMP BEGIN CPYRHT: DB 'Copyright 1979 by Seattle Computer Pro SHL DI SHL DI SHL DI SHL DI SHL DI SHL DI SHL DI RET ;***** DATA AREA ***** BADMES: DB 13,10,"Bad FAT", FCB: EQU 5CH BUFSIZ: EQU 128 EOL: EQU 13 ;ASCII carriage return OBJECT: EQU 100H ;DEFAULT "PUT" ADDRESS ;System call funm INT 22H) ; [14] to [17] have ctrl-C exit address (from INT 23H) ; AX,DX,BP unchanged. All other registers destroyed. XORducts, 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  ; CALLED BY: -- None ; ; CALLS: -- INITBD ; CPTRMV ; PLYRMV ; ; ARGUMENTS: NM: OUTB DISK IF CROMEMCO MOV AL,WAITBYTE OUT DISK+4 ;Turn on hardware wait ENDIF READ: INB DISK+4 IF TARBEYSTEM: EQU 5 ;*********************************************************** ; EQUATES ;****************************************DCOM:EQU 88H ENDIF IF WD1791 READCOM:EQU 80H ENDIF IF CROMEMCOLARGE WAITBYTE:EQU 0B1H ENDIF IF CROMEMCOSMALL;*********************************************************** ; ; SARGON ; ; Sargon is a computer chess playone ;********************************************************** DRIVER: MOV SP,STACK ; Set stack pointer MOV DX,CLRMSG ; ReqLL ROL AL JNC DONE ENDIF IF CROMEMCO ROR AL JC DONE ENDIF INB DISK+3 STOB LOOP READ GETSTAT: INB DISK******************* ; PAWN: EQU 1 KNIGHT: EQU 2 BISHOP: EQU 3 ROOK: EQU 4 QUEEN: EQU 5 KING: EQU 6 WHITE: EQU 0 BLACK: WAITBYTE:EQU 0A1H ENDIF ORG BOOTER PUT 100H XOR AX,AX MOV DS,AX MOV ES,AX MOV SS,AX UP MOV DI,LOAD MOVing program designed ; and coded by Dan and Kathe Spracklen. Copyright 1978. All ; rights reserved. No part of this publicatuest color choice MOV CL,PRINTBUF CALL SYSTEM MOV CL,INCHAR ; Accept response CALL SYSTEM CMP AL,57H ; Did player req+4 IF TARBELL ROL AL JC GETSTAT ENDIF IF CROMEMCO ROR AL JNC GETSTAT ENDIF DONE: IN DISK AND AL,9CH EQU 80H BPAWN: EQU BLACK+PAWN ORG 100H PUT 100H ;*********************************************************** ; MAIN P DX,SECTOR MOV BL,2 SECT: MOV AL,BL OUTB DISK+2 MOV CX,128 IF TARBELL INB DISK ;Get head load status ENDIF ion may be ; reproduced without the prior written permission. ; ;*********************************************************** uest white ? JZ DR05 ; Yes - branch CMP AL,42H ; Did player request black ? JNZ DRIVER ; No - error XOR AL,AL JP DR 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 OUROGRAM DRIVER ;*********************************************************** ; FUNCTION: -- To coordinate the game moves. ; 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 ;*********************************************************** INCHAR: EQU 1 PRINTBUF:EQU 9 INBUF: EQU 10 S10 ; Jump DR05: MOV AL,BLACK ; Set computers color to black DR10: MOV [KOLOR],AL DR15: MOV DX,PLYDEP ; Request depth of sear given piece. ;*********************************************************** DPOINT: EQU $-TBASE DB 20,16,8,0,4,0,0 ;*******ECT -- Direction Table. Used to determine the dir- ; ection of movement of each piece. ;************************ current position ; of the board during play. The board itself ; looks like: ; FFFFFFFFF Computer move ? JZ DR25 ; Yes - jump DR20: CALL PLYRMV ; Do player move DR25: CALL CPTRMV ; Do computer move MOV BX,MO**************************** PVALUE: EQU $-TBASE-1 DB 1,3,3,5,9,10 ;********************************************************ch MOV CL,PRINTBUF CALL SYSTEM MOV CL,INCHAR CALL SYSTEM SUB AL,31H ; Subtract Ascii constant JB DR15 ; Under mini**************************************************** ; DCOUNT -- Direction Table Counter. Used to determine ; t*********************************** DIRECT: EQU $-TBASE DB +09,+11,-11,-09 DB +10,-10,+01,-01 DB -21,-12,+08,+19 DB +21FFFFFFFFFFF ; FFFFFFFFFFFFFFFFFFFF ; FF0402030506030204FF ; FF0101010101010101FF ; VENO INC B,[BX] ; Increment move number JP DR20 ; Back to player move ;*********************************************** ; PIECES -- The initial arrangement of the first rank of ; pieces on the board. Use to set up the board ; mum - prompt again CMP AL,6 ; Over maximum of 6 ? JNB DR15 ; Yes - prompt again INC AL ; Increment by one MOV [PLYMAXhe number of directions of movement for any ; given piece. ;******************************************************,+12,-08,-19 DB +10,+10,+11,+09 DB -10,-10,-11,-09 ;*********************************************************** ; DP FF0000000000000000FF ; FF0000000000000000FF ; FF0000000000000060FF ; FF00000000000*************** ; TABLES SECTION ;*********************************************************** ORG 200H ; Start at 200H STA for the start of the game. ;*********************************************************** PIECES: EQU $-TBASE DB 4],AL ; Set desired depth MOV DX,CRLF ; Output CRLF MOV CL,PRINTBUF CALL SYSTEM XOR AL,AL MOV [COLOR],AL ; Set color t***** DCOUNT: EQU $-TBASE DB 4,4,8,4,4,8,8 ;*********************************************************** ; PVALUE -- OINT -- Direction Table Pointer. Used to determine ; where to begin in the direction table for any ; 00000FF ; FF8181818181818181FF ; FF8482838586838284FF ; FFFFFFFFFFFFFFFFFFFF ; RT: ORG START+80H PUT START+80H TBASE: EQU START+100H ;*********************************************************** ; DIR,2,3,5,6,3,2,4 ;*********************************************************** ; BOARD -- Board Array. Used to hold theo white INC AL MOV [MOVENO],AL ; Set move number to 1 CALL INITBD ; Init board MOV AL,[KOLOR] ; Get color OR AL,AL ; Point Value. Gives the point value of each ; piece, or the worth of each piece. ;******************************* FFFFFFFFFFFFFFFFFFFF ; The values of FF form the border of the ; board, and are used to indicate wh** ATKLST: DW 0,0,0,0,0,0,0 WACT: EQU ATKLST BACT: EQU ATKLST+7 ;***************************************************** half for white and the second half for black. ; It is used to hold the attackers of any given ; sqmy" entries for ply -1 and ply 0. ;************************************************************ SCORE: DW 0,0,0,0,0,0 ; 1 -- Pawn ; 2 -- Knight ; 3 -- Bishop ; 4 -- Rook e of which hold the position of the white ; king and the second holding the position of ; the black kien a piece ; moves off the board. The individual bits of ; the other bytes in the board array are as ****** ; PLIST -- Pinned Piece Array. This is a two part array. ; PLISTA contains the pinned piece position. uare in the order of their value. ; ; WACT -- White Attack Count. This is the first ; byte of the array and te************************************************************ ; PLYIX -- Ply Table. Contains pairs of pointers, a pair ; ; 5 -- Queen ; 6 -- King ; 7 -- Not used ; ng. ; ; POSQ -- Position of Queens. Like POSK,but for queens. ;********************************************************* ; follows: ; Bit 7 -- Color of the piece ; 1 -- Black ; ; PLISTD contains the direction from the pinned ; piece to the attacker. ;****************************lls how many pieces are ; in the white portion of the attack list. ; ; BACT -- Black Attack Count. This is the for each ply. The first pointer points to the ; top of the list of possible moves at that ply. ; 0 -- Empty Square ;************************************************************ BOARD: EQU $-TBASE BOARDA: DS 120 *** POSK: DB 24,95 POSQ: DB 14,94 DB -1 ;************************************************************ ; SCORE -- 0 -- White ; Bit 6 -- Not used ; Bit 5 -- Pawn attack flag for ATTACK ; Bit 4 -- ******************************* PLIST: EQU $-TBASE-1 PLISTD: EQU PLIST+10 PLISTA: DW 0,0,0,0,0,0,0,0,0,0 ;************ eighth byte of ; the array and does the same for black. ;********************************************************* The second pointer points to which move in the ; list is the one currently being considered. ;************** ;************************************************************ ; ATKLIST -- Attack List. A two part array, the first ; Score Array. Used during Alpha-Beta pruning to ; hold the scores at each ply. It includes two ; "dumCastle flag for Kings only ; Bit 3 -- Piece has moved flag ; Bits 2-0 Piece type ; *********************************************** ; POSK -- Position of Kings. A two byte area, the first ; byt********************************************** PLYIX: DW 0,0,0,0,0,0,0,0,0,0 DW 0,0,0,0,0,0,0,0,0,0 ;*****************T2: DW TBASE T3: DW TBASE INDX1: DW TBASE INDX2: DW TBASE NPINS: DW TBASE MLPTRI: DW PLYIX MLPTRJ: DW 0 SCRIX: DW 0 BEST the move list for the move that ; is currently considered the best by the ; Alpha-Beta pruning procesck can move to. ; ; PTSL -- The maximum number of points which could be lost ; through an exchange by the plal working indices. Used for various ; INDX2 purposes. ; ; NPINS -- Number of Pins. Count and pointer into the ; ent move number. ; ; PLYMAX -- Maximum depth of search using Alpha-Beta ; pruning. ; ; NPLY -- Current pl******************************************* ; STACK -- Contains the stack for the program. ;*******************************M: DW 0 MLLST: DW 0 MLNXT: DW MLIST ;************************************************************ ; VARIABLES SECTION s. ; ; MLLST -- Pointer to the previous move placed in the move ; list. Used during generation of the move liyer not on the ; move. ; ; PTSW1 -- The maximum number of points which could be won ; through an pinned piece list. ; ; MLPTRI -- Pointer into the ply table which tells ; which pair of pointers arey number during Alpha-Beta ; pruning. ; ; CKFLG -- A non-zero value indicates the king is in check. ; ; MATE***************************** ORG START+2FFH STACK: ;************************************************************ ; T ; ; KOLOR -- Indicates computer's color. White is 0, and ; Black is 80H. ; ; COLOR -- Indicates color ofst. ; ; MLNXT -- Pointer to the next available space in the move ; list. ; ;********************************exchange by the player not on the ; move. ; ; PTSW2 -- The second highest number of points which could ; in current use. ; ; MLPTRJ -- Pointer into the move list to the move that is ; currently being processed. ; F -- A zero value indicates no legal moves. ; ; VALM -- The score of the current move being examined. ; ; BRDC -- ABLE INDICES SECTION ; ; M1-M4 -- Working indices used to index into ; the board array. ; ; T1-T3 -- Work the side with the move. ; ; P1-P3 -- Working area to hold the contents of the board ; array for a given squar**************************** ORG START+0 PUT START+0 M1: DW TBASE M2: DW TBASE M3: DW TBASE M4: DW TBASE T1: DW TBASE be won through a different exchange by the player ; not on the move. ; ; MTRL -- A measure of the dif; SCRIX -- Score Index. Pointer to the score table for ; the ply being examined. ; ; BESTM -- Pointer into A measure of mobility equal to the total number ; of squares white can move to minus the number ; blaing indices used to index into Direction ; Count, Direction Value, and Piece Value tables. ; ; INDX1 -- Generae. ; ; PMATE -- The move number at which a checkmate is ; discovered during look ahead. ; ; MOVENO -- Currference in material ; currently on the board. It is the total value of ; the white pieces minus the tmove entry which gives the ; board position to which the piece is moving. ; ; MLFLG -- A field in the move ent the moves for a single leg of the move tree. ; ; MLEND -- The address of the last available location ; in the************************************************** ORG START+300H PUT START+300H MLIST: DS 2048 MLEND: EQU MLIST+2040 MLP P1: DB 0 P2: DB 0 P3: DB 0 PMATE: DB 0 MOVENO: DB 0 PLYMAX: DB 2 NPLY: DB 0 CKFLG: DB 0 MATEF: DB 0 VALM: DB 0 BRDC:that ; this is the first move for the ; piece on the move. ; Bit 3 otal value of the ; black pieces. ; ; BC0 -- The value of board control(BRDC) at ply 0. ; ; MV0 -- Thry which contains flag ; information. The meaning of each bit is as ; follows: ; Bit 7 move list. ; ; MLPTR -- The Move List is a linked list of individual ; moves each of which is 6 bytes in lengTR: EQU 0 MLFRP: EQU 2 MLTOP: EQU 3 MLFLG: EQU 4 MLVAL: EQU 5 ;****************************************************** DB 0 PTSL: DB 0 PTSW1: DB 0 PTSW2: DB 0 MTRL: DB 0 BC0: DB 0 MV0: DB 0 PTSCK: DB 0 BMOVES: DB 35,55,10H DB 34,54,10H -- This flag is set is there is a piece ; captured, and that piece has moved at ; e value of material(MTRL) at ply 0. ; ; PTSCK -- A non-zero value indicates that the piece has ; just moved it-- The color of any captured piece ; 0 -- White ; 1 -- Black ; th. The ; move list pointer(MLPTR) is the link field ; within a move. ; ; MLFRP -- The field in ****** ; PROGRAM CODE SECTION ;************************************************************ ; BOARD SETUP ROUTINE ;********* DB 85,65,10H DB 84,64,10H ;************************************************************ ; MOVE LIST SECTION ; ; ML least once. ; Bits 2-0 Describe the captured piece. A ; zero value indicates no captself into a losing exchange of ; material. ; ; BMOVES -- Our very tiny book of openings. Determines ; Bit 6 -- Double move flag (set for castling and ; en passant pawn captures) ; Bit 5 -- the move entry which gives the ; board position from which the piece is moving. ; ; MLTOP -- The field in the *************************************************** ; FUNCTION: To initialize the board array, setting the ; pieIST -- A 2048 byte storage area for generated moves. ; This area must be large enough to hold all ; ure. ; ; MLVAL -- The field in the move entry which contains the ; score assigned to the move. ; ;********** the first move for the computer. ; ;************************************************************ KOLOR: DB 0 COLOR: DB 0 Pawn Promotion flag; set when pawn ; promotes. ; Bit 4 -- When set, this flag indicates ces in their initial positions for the ; start of the game. ; ; CALLED BY: DRIVER ; ; CALLS: None ; ; A PINFND ; ; CALLS: None ; ; ARGUMENTS: Direction from the direction array giving the ; constant to be add position, and setting a flag describing the ; contents: ; 0 -- New postion is emp**************************** MPIECE: XOR AL,[BX] ; Piece to move AND AL,87H ; Clear flag bit CMP AL,BPAWN ; Is it a black0 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 B,[SI+2], AL,0 RET ; Return PA2: MOV AL,3 ; Set off board flag RET ; Return ;*******************************************RGUMENTS: None ; ;************************************************************* INITBD: MOV CX,60 ; Pre-fill board with -1'ed for the new position. ;************************************************************ PATH: ADD [M2],CL ; Add direction consty ; 1 -- Encountered a piece of the ; opposite color ; Pawn ? JNZ MP1 ; No-Skip DEC AL ; Decrement for black Pawns MP1: AND AL,7 ; Get piece type MOV [T1],AL ; Save piece 24 MOV B,[SI+3],94 RET ;************************************************************ ; PATH ROUTINE ;******************************* ; PIECE MOVER ROUTINE ;************************************************************ ; FUNCTION: To generas MOV DI,BOARDA MOV AX,-1 REP STOW MOV CH,8 MOV SI,BOARDA IB2: MOV AL,[SI-8] ; Fill non-border squares MOV [SI+21tant to prev pos MOV SI,[M2] ; Load board index MOV AL,[SI+BOARD] ; Get contents of board CMP AL,-1 ; In boarder area ? 2 -- Encountered a piece of the ; same color ; 3 --type MOV DI,[T1] ; Load index to DCOUNT/DPOINT MOV CH,[DI+DCOUNT] ; Get direction count MOV AL,[DI+DPOINT] ; Get directio********************************************** ; FUNCTION: To generate a single possible move for a given ; piecte all the possible legal moves for a ; given piece. ; ; CALLED BY: GENMOV ; ; CALLS: PATH ; ],AL ; White pieces LAHF OR AL,080H SAHF ; Change to black MOV [SI+91],AL ; Black pieces MOV B,[SI+31],PAWN ; White JZ PA2 ; Yes - jump MOV [P2],AL ; Save piece MOV AH,AL ; Save piece in register AND AL,7 ; Clear flags MOV [T2],AL New position is off the ; board ; ; CALLED BY: MPIECE ; ATTACK ; n pointer MOV [INDX2],AL ; Save as index to direct MOV DI,[INDX2] ; Load index MP5: MOV CL,[DI+DIRECT] ; Get move directione 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. ;*********************************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 MOV B,[SI+71], ; Save piece type JZ RET ; Return if empty XOR AH,[P1] ; Compare with moving piece SHL AH ; Set flag MOV AL,2 SBB MOV AL,[M1] ; From position MOV [M2],AL ; Initialize to position MP10: CALL PATH ; Calculate next position CMP AL,2 ENPSNT ; Try en passant capture JMP MP15 ; Jump ;*********************************************************** ; EN PA INC DI ; Adjust to two square move DEC CH TEST B,[P1],008H ; Check Pawn moved flag, has it moved before ? JZ MP10 ; No PAWN ; Is it a Pawn ? JNZ RET ; No - return MOV AL,[M4] ; Get "to" position MOV BX,M2 ; Get present "to" position SUe type CMP AL,KING ; King ? JNZ RET JMP CASTLE ; Yes - Try Castling ; ***** PAWN LOGIC ***** MP20: MOV AL,CH ; CounteD AL,10 ; Add 10 for black EP5: CMP AL,61 ; On en passant capture rank ? JC RET ; No - return CMP AL,69 ; On en passant; Ready for new direction ? JNC MP15 ; Yes - Jump AND AL,AL ; Test for empty square PUSHF MOV AL,[T1] ; Get piece movSSANT ROUTINE ;*********************************************************** ; FUNCTION: -- To test for en passant Pawn captu- Jump JMP MP15 ; Jump MP30: POPF JNZ MP15 ; No - Jump MP31: CALL ADMOVE ; Add to move list JMP MP15 ; Jump MP35: PB AL,[BX] ; Find difference JNS EP10 ; Positive ? Yes - Jump NEG AL ; Else take absolute value EP10: CMP AL,10 ; Is difr for direction CMP AL,3 ; On diagonal moves ? JC MP35 ; Yes - Jump JZ MP30 ; -or-jump if on 2 square move POPF JNZ capture rank ? JNC RET ; No - return MOV SI,[MLPTRJ] ; Get pointer to previous move TEST B,[SI+MLFLG],010H ; First move ed CMP AL,PAWN+1 ; Is it a Pawn ? JC MP20 ; Yes - Jump CALL ADMOVE ; Add move to list POPF JNZ MP15 ; No - Jump Mre and ; to add it to the move list if it is ; legal. ; ; CALLED BY: -- MPIECE ; ; CALLSOPF JZ MP36 ; Yes - Jump MOV AL,[M2] ; Get "to" position CMP AL,91 ; Promote white Pawn ? JNC MP37 ; Yes - Jump CMference 10 ? JNZ RET ; No - return OR B,[P2],040H ; Set double move flag CALL ADMOVE ; Add Pawn move to move list MOV MP15 ; No - jump MOV AL,[M2] ; Get "to" position CMP AL,91 ; Promote white Pawn ? JNC MP25 ; Yes - Jump CMP AL,29 for that piece ? JZ RET ; No - return MOV AL,[SI+MLTOP] ; Get "to" postion MOV [M4],AL ; Store as index to board MOV SOV AL,[T1] ; Piece type CMP AL,KING ; King ? JZ MP15 ; Yes - Jump CMP AL,BISHOP ; Bishop, Rook, or Queen ? JNC MP10 : -- ADMOVE ; ADJPTR ; ; ARGUMENTS: -- None ;*****************************************************P AL,29 ; Black Pawn promotion ? JNC MP31 ; No- Jump MP37: OR B,[P2],020H ; Set promote flag JP MP31 ; Jump MP36: CALL AL,[M1] ; Save initial Pawn position MOV [M3],AL MOV AL,[M4] ; Set "from" and "to" positions ; for dummy move MOV [; Promote black Pawn ? JNC MP26 ; No - Jump MP25: OR B,[P2],020H ; Set promote flag MP26: CALL ADMOVE ; Add to move list I,[M4] ; Load board index MOV AL,[SI+BOARD] ; Get piece moved MOV [P3],AL ; Save it AND AL,7 ; Get piece type CMP AL,; Yes - Jump MP15: INC DI ; Increment direction index DEC CH JNZ MP5 ; Decr. count-jump if non-zerc MOV AL,[T1] ; Piec******* ENPSNT: MOV AL,[M1] ; Set position of Pawn TEST B,[P1],080H ; Check color, is it white ? JZ EP5 ; Yes - skip ADM1],AL MOV [M2],AL MOV AL,[P3] ; Save captured Pawn MOV [P2],AL CALL ADMOVE ; Add Pawn capture to move list MOV AL,[k position MOV AL,CL MOV [M3],AL ; Store as board index MOV SI,[M3] ; Load board index MOV AL,[SI+BOARD] ; Get content, or both) and add it ; to the move list if it is. ; ; CALLED BY: -- MPIECE ; ; CALLS: -- ATTACK ;n MOV [BX],CL ; Store Rook "from" position SUB AL,CH ; Get Rook "to" position MOV [M2],AL ; Store Rook "to" position -- None ; ; ARGUMENTS: -- None ;************************************************************* ADJPTR: MOV BX,[MLLST] ; AL ; Any attackers ? JNZ CA20 ; Yes - Jump MOV AL,[M3] ; Current position CA15: ADD AL,CH ; Next position MOV [M3],ALM3] ; Restore "from" position MOV [M1],AL ;************************************************************ ; ADJUST MOVEs of board AND AL,7FH ; Clear color bit CMP AL,ROOK ; Has Rook ever moved ? JNZ CA20 ; Yes - Jump MOV AL,CL ; Restor ADMOVE ; ADJPTR ; ; ARGUMENTS: -- None ;*************************************************XOR AL,AL ; Zero MOV [P2],AL ; Zero move flags CALL ADMOVE ; Put Rook move in list CALL ADJPTR ; Re-adjust move list pGet list pointer SUB BX,6 ; Back up list pointer MOV [MLLST],BX ; Save list pointer MOV [BX],0 ; Zero out link RET ; ; Save as board index MOV BX,M1 ; King position CMP AL,[BX] ; Reached King ? JNZ CA10 ; No - jump SUB AL,CH ; Dete LIST POINTER FOR DOUBLE MOVE ;************************************************************ ; FUNCTION: -- To adjust move le Rook position JP CA15 ; Jump CA10: MOV SI,[M3] ; Load board index MOV AL,[SI+BOARD] ; Get contents of board AND AL,AL*********** CASTLE: TEST B,[P1],008H ; Has king moved ? JNZ RET ; Yes - return MOV AL,[CKFLG] ; Fetch Check Flag AND ointer MOV AL,[M3] ; Restore King position MOV [M1],AL ; Store CA20: MOV AL,CH ; Scan Index CMP AL,1 ; Done ? JZ RE Return ;************************************************************ ;CASTLE ROUTINE ;********************************rmine King's position SUB AL,CH MOV [M2],AL ; Save it MOV BX,P2 ; Address of flags MOV B,[BX],40H ; Set double move flist pointer to link around ; second move in double move. ; ; CALLED BY: -- ENPSNT ; CASTLE ; Empty ? JNZ CA20 ; No - Jump MOV AL,[M3] ; Current position CMP AL,22 ; White Queen Knight square ? JZ CA15 ; YeAL,AL ; Is the King in check ? JNZ RET ; Yes - Return MOV CX,0FF03H ; Initialize King-side values CA5: ADD CL,[M1] ; RooT ; Yes - return MOV CX,01FCH ; Set Queen-side initial values JMP CA5 ; Jump ;***************************************************************** ; FUNCTION: -- To determine whether castling is legal ; (Queen side, King sideag CALL ADMOVE ; Put king move in list MOV BX,M1 ; Addr of King "from" position MOV AL,[BX] ; Get King's "from" positio ; (This mini-routine is not really called, ; but is jumped to to save time.) ; ; CALLS: s - Jump CMP AL,92 ; Black Queen Knight square ? JZ CA15 ; Yes - Jump CALL ATTACK ; Look for attack on square AND AL,*********************** ; ADMOVE ROUTINE ;************************************************************ ; FUNCTION: -- To aKFLG],AL ; Save attack count as flag MOV DX,[MLNXT] ; Addr of next avail list space MOV BX,[MLPTRI] ; Ply list pointer indexry on table ovflow RET ;************************************************************ ; GENERATE MOVE ROUTINE ;******ing is in check. ; ; CALLED BY: -- GENMOV ; FNDMOV ; EVAL ; ; CALLS: -- ATTACK ; ST B,[P1],008H ; Has moved piece moved before ? JNZ AM5 ; Yes - jump OR B,[P2],010H ; Set first move flag AM5: XCHG DX,DI or of piece XOR AL,[BX] ; Test color of piece TEST AL,080H ; Match ? JNZ GM10 CALL MPIECE ; Yes - call Move Piece GMdd a move to the move list ; ; CALLED BY: -- MPIECE ; ENPSNT ; CASTLE ; ; CALLS: -- INC BX ; Increment to next ply INC BX MOV [BX],DX ; Save move list pointer INC BX INC BX MOV [MLPTRI],BX ; Save n****************************************************** ; FUNCTION: -- To generate the move set for all of the ; ; ARGUMENTS: -- Color of King ;************************************************************ INCHK: MOV AL,[COLOR] ; Get col ; Address of move area XOR AX,AX ; Store zero in link address CLD STOW MOV AL,[M1] ; Store "from" move position STO10: MOV AL,[M1] ; Fetch current board position INC AL ; Incr to next board position CMP AL,99 ; End of board array ? JN None ; ; ARGUMENT: -- None ;************************************************************* ADMOVE: MOV DX,[MLNXT] ; Addr ew index MOV [MLLST],BX ; Last pointer for chain init. MOV AL,21 ; First position on board GM5: MOV [M1],AL ; Save as ind pieces of a given color. ; ; CALLED BY: -- FNDMOV ; ; CALLS: -- MIECE ; INCHK ; ; ARGUMENTS:or INCHK1: MOV BX,POSK ; Addr of white King position AND AL,AL ; White ? JZ IC5 ; Yes - Skip INC BX ; Addr of black KB MOV AL,[M2] ; Store "to" move position STOB MOV AL,[P2] ; Store move flags/capt. piece STOB XOR AL,AL ; Store iniZ GM5 ; No - Jump RET ; Return ;************************************************************ ; CHECK ROUTINE ;****of next loc in move list MOV BX,MLEND ; Address of list end SUB BX,DX ; Calculate difference JC AM10 ; Jump if out of spex MOV SI,[M1] ; Load board index MOV AL,[SI+BOARD] ; Fetch board contents AND AL,AL ; Is it empty ? JZ GM10 ; Yes - -- None ;************************************************************ GENMOV: CALL INCHK ; Test for King in check MOV [Cing position IC5: MOV AL,[BX] ; Fetch King position MOV [M3],AL ; Save MOV SI,[M3] ; Load board index MOV AL,[SI+BOARDtial move value STOB MOV [MLNXT],DI ; Save address for next move MOV DI,DX RET ; Return AM10: MOV [BX],0 ; Abort ent******************************************************** ; FUNCTION: -- To determine whether or not the ; Kace MOV BX,[MLLST] ; Addr of prev. list area MOV [MLLST],DX ; Save next as previous MOV [BX],DX ; Store link address TEJump CMP AL,-1 ; Is it a boarder square ? JZ GM10 ; Yes - Jump MOV [P1],AL ; Save piece MOV BX,COLOR ; Address of col] ; Fetch board contents MOV [P1],AL ; Save AND AL,7 ; Get piece type MOV [T1],AL ; Save ;**********************ard pointer to it MOV DH,0 ; Init. scan count/flags MOV SI,DIRECT+TBASE ; Load direction table MOV AH,KING ; Check for aled ; by CASTLE or INCHK, the routine is ; terminated as soon as an attacker of the ; Restore CX reg RET ; Return ;************************************************************ ; ATTACK ADJACENT SCAN ROU; a square, this routine also takes into ; account the ability of certain pieces to ; 11 AND AL,87H ; Clear flag bit CMP AL,PAWN ; White Pawn ? JNZ AT15 ; No - jump OR [BP-11],AH ; Set Pawn attack flag ************************************** ; ATTACK ROUTINE ;************************************************************ ; FUNCT King CALL ATKADJ ; Scan adjacent squares MOV AH,KNIGHT ; Check for a Knight CALL ATKADJ ; Scan adjacent squares MOV A opposite color is encountered. ; ; CALLED BY: -- POINTS ; PINFND ; CASTLE ; TINE ;************************************************************ ; FUNCTION: -- To scan for a specified attacker on adjac attack through another attacking piece. (For ; example a queen lined up behind a bishop ; AT15: MOV AL,[BP-9] ; Get piece at -9 AND AL,87H ; Clear flag bit CMP AL,PAWN ; White Pawn ? JNZ AT20 ; No - jump OR ION: -- To find all attackers on a given square ; by scanning outward from the square ; untH,20H ; Pawn attack flag MOV AL,[BP+11] ; Get piece at +11 AND AL,87H ; Clear flag bit CMP AL,BPAWN ; Black Pawn ? JNZ INCHK ; ; CALLS: -- ATKADJ ; ATKOUT ; ; ARGUMENTS: -- None ;**************************ent ; squares. ; ; CALLED BY: -- ATTACK ; ; CALLS: -- ATKCHK ; ; ARGUMENTS: -- The piece under of her same color along a diagonal.) The ; bishop is then said to be transparent to the ; [BP-9],AH ; Set Pawn attack flag AT20: MOV SI,DIRECT+TBASE ; Load direction table MOV AH,BISHOP ; Check for a Bishop CALL Ail a piece is found that attacks ; that square, or a piece is found that ; doesn't attack that AT5 ; No - jump OR [BP+11],AH ; Set Pawn attack flag AT5: MOV AL,[BP+9] ; Get piece at +9 AND AL,87H ; Clear flag bit ********************************** ATTACK: PUSH CX ; Save Register CX MOV BP,[M3] ; Get piece index ADD BP,BOARD ; Add boattack. The attacker. ;************************************************************ ATKADJ: MOV CX,8 ; 8 directions to scan queen, since both participate in the ; attack. ; ; In the case where this routine is calTKOUT ; Scan outwards MOV AH,ROOK ; Check for a Rook CALL ATKOUT ; Scan outwards XOR AL,AL ; No attackers POP CX ; square, or the edge ; of the board is reached. ; ; In determining which pieces attack CMP AL,BPAWN ; Black Pawn ? JNZ AT10 ; No - jump OR [BP+9],AH ; Set Pawn attack flag AT10: MOV AL,[BP-11] ; Get piece at -AA5: XCHG AX,BX ; Save AX LODB ; Get direction byte CBW ; Convert to word XCHG AX,BX ; Save direction and restore AXND B,[DI],0DFH ; Remove Pawn attack flag AO22: MOV AL,[DI] ; Get piece ADD AL,80H ; CY if black, NC if white RCR AL ; Biand restore AX MOV DI,BP ; Load pointer to piece AO10: ADD DI,BX ; Add direction constant MOV AL,[DI] ; Get attacking pi ; ; ARGUMENTS: -- The attacking piece. The piece under attack. ;***********************************************************ed attacker outwards ; from the piece under attack, until found ; or edge of the board is react. ; ; The pin piece list is checked for the ; attacking piece, and if found there, the ; MOV DI,BP ; Load pointer to piece ADD DI,BX ; Add direction constant MOV AL,[DI] ; Get attacking piece AND AL,7 ; Gt 7 set if black, bit 6 if white AND DL,AL ; Keep only bits 6 and 7 JZ AO15 ; Nothing, next direction CALL ATKCHK ; Cheece AND AL,27H ; Get piece type and Pawn attack flag JZ AO10 ; No piece, keep going CMP AL,AH ; Same as what we want ? * ATKCHK: MOV AL,[DI] ; Get piece CMP B,[T1],7 ; Call from POINTS ? JZ ACK10 ; Yes - jump XOR AL,[BP] ; Attacker and thed. ; ; CALLED BY: -- ATTACK ; ; CALLS: -- ATKCHK ; ; ARGUMENTS: -- The piece under attack. The attacker. ;*** piece is not included in the attack list. ; ; In the case where ATTACK is called by ; et piece type CMP AL,AH ; Same as what we want ? JNZ AA10 ; No - jump CALL ATKCHK ; Check and save attacker AA10: LOOPck and save attack JP AO10 ; Keeping going that direction ;*********************************************************** JZ AO22 ; Yes - jump CMP AL,QUEEN ; Queen ? JZ AO20 ; Yes - jump CMP AL,PAWN+20H ; Pawn with Pawn attack flag ? JZ Aarget same color ? JNS RET ; Yes - return POP AX POP AX ; Set SP level to ATTACK MOV AX,0DFFFH ; FF (border) in AL and********************************************************* ATKOUT: MOV CL,4 ; 4 directions to scan AO5: MOV DX,0C0H ; Bitmask CASTLE or INCHK, control is returned to ; the aforementioned routines as soon as an ; a AA5 ; Go check for next direction RET ; Return ;************************************************************ ; ATT* ; ATTACK CHECK AND SAVE ROUTINE ;************************************************************ ; FUNCTION: -- To check ifO21 ; Yes - jump AO15: LOOP AO5 ; Go check for next direction RET ; Return AO20: INC DH ; Set Queen found flag AO21: A DF in AH CMP [BP+9],AL ; Is +9 border ? JZ ACK5 ; Yes, jump AND [BP+9],AH ; Remove Pawn attack flag ACK5: CMP [BP+11],A for color flags XCHG AX,BX ; Save AX LODB ; Get direction byte CBW ; Convert to word XCHG AX,BX ; Save direction ttacker of the opposite color is encountered. ; ; CALLED BY: -- ATKADJ ; ATKOUT ; ; CALLS: -- None ACK OUTWARD SCAN ROUTINE ;************************************************************ ; FUNCTION: -- To scan for a specifi a piece can attack the target ; square and save the attacking piece value ; in the attack lisL ; Is +11 border ? JZ ACK6 ; Yes - jump AND [BP+11],AH ; Remove Pawn attack flag ACK6: CMP [BP-9],AL ; Is -9 border ? JHG AL,CL ; Save point value in AL ADD DI,CX ; Attack list slot address MOV CH,[DI] ; Get data already there TEST CH,0FHOV CL,AL ; Put piece in CL AND CL,7 ; Get piece type MOV DI,PVALUE+TBASE ; PVALUE list address ADD DI,CX ; Point to pie PF1: MOV BP,DX MOV AL,[BP] ; Get position of royal piece AND AL,AL ; Is it on board ? JNZ PF1A ; Yes - continue JMP t address ACK15: OR AL,AL ; Set flags for REP REPZ SCAB ; Search list for position JNZ ACK25 ; Continue if not found TINE ;************************************************************ ; FUNCTION: -- To produce a list of all pieces pinned ;Z ACK7 ; Yes - jump AND [BP-9],AH ; Remove Pawn attack flag ACK7: CMP [BP-11],AL ; Is -11 border ? JZ ACK8 ; Yes - jump ; Is first slot empty ? JZ ACK40 ; Yes - jump TEST CH,0F0H ; Is second slot empty ? JZ ACK35 ; Yes - jump INC DI ;ce value MOV CL,[DI] ; Get point value of piece MOV DI,ATKLST ; Init address of attack list TEST AL,80H ; Is it white ? PF26 PF1A: CMP AL,-1 ; At end of list ? JZ RET ; Yes return MOV [M3],AL ; Save position as board index MOV SI,[M3] ; OR AH,AH ; Is this the first find ? JNZ ACK20 ; No - jump MOV AH,[DI+9] ; Get direction CMP AH,BL ; Same as attacking against the King or Queen, for both white ; and black. ; ; CALLED BY: -- FNDMOV ; AND [BP-11],AH ; Remove Pawn attack flag ACK8: MOV AL,1 ; Set attacker found flag POP CX ; Restore CX reg RET ; Return Increment to King slot MOV CH,[DI] ; Get byte XCHG AL,CH ; Byte to AL, point value to CH ACK35: SHL AL ; Lower bits to JZ ACK30 ; Yes - jump ADD DI,7 ; Attack list address ACK30: OR DH,DH ; Queen found this scan ? JZ ACK31 ; No - jump Load index to board MOV AL,[SI+BOARD] ; Get contents of board MOV [P1],AL ; Save MOV CH,8 ; Init scan direction count direction ? JZ ACK15 ; Yes - jump NEG AH ; Opposite direction ? CMP AH,BL ; Same as attacking direction ? JZ ACK15 EVAL ; ; CALLS: -- PATH ; ATTACK ; ; ARGUMENTS: -- None ;******************************** from ATTACK ACK10: PUSH CX ; Save regs PUSH DI MOV CL,[NPINS] ; Number of pinned pieces JCXZ ACK26 ; No pins - jump upper SHL AL SHL AL SHL AL OR AL,CH ; Combine with point value ACK40: MOV [DI],AL ; Put back into attack list POP D MOV AL,QUEEN ; Use Queen slot in attack list ACK31: AND AL,7 ; Attacking piece type INC B,[DI] ; Increment list count XCXOR AL,AL MOV [INDX2],AL ; Init direction index MOV DI,[INDX2] PF2: MOV AL,[M3] ; Get King/Queen position MOV [M2],AL ;; Yes - jump ACK20: POP AX ; Restore regs. POP DI POP CX RET ; Return to ATTACK ACK25: POP AX ; Restore AX ACK26: M**************************** PINFND: XOR AL,AL ; Zero pin count MOV [NPINS],AL MOV DX,POSK ; Addr of King/Queen pos list PUSH AX ; Save AX MOV AX,DI ; Load piece pointer in AX SUB AX,BOARDA ; Minus BOARDA for position MOV DI,PLISTA ; Pin lisI ; Restore regs POP CX RET ; Return ;************************************************************ ; PIN FIND ROU Save XOR AL,AL MOV [M4],AL ; Clear pinned piece saved pos MOV CL,[DI+DIRECT] ; Get direction of scan PF5: CALL PATH ; estore regs. POP DX POP CX JNS PF25 ; Jump if pin not valid PF20: MOV BX,NPINS ; Address of pinned piece count INC B,[; Zero out attack list MOV CX,7 MOV BX,ATKLST XCHG DI,BX CLD REP STOW XCHG DI,BX MOV AL,7 ; Set attack flag Mwhite ? JZ XC5 ; Yes - jump XCHG DX,BX ; Swap list pointers XC5: MOV CH,[BX] ; Init list counts XCHG DX,BX MOV CL,[BL,BL ; Piece type CMP AL,BISHOP ; Bishop ? JNZ PF25 ; No - jump JMP PF20 ; Jump JPF25: JMP PF25 PF10: MOV AL,BL ; Pitermine the exchange value of a ; piece on a given square by examining all ; attackers and defCompute next position AND AL,AL ; Is it empty ? JZ PF5 ; Yes - jump CMP AL,3 ; Off board ? JZ JPF25 ; Yes - jump CBX] ; Increment MOV SI,[NPINS] ; Load pin list index MOV [SI+PLISTD],CL ; Save direction of pin MOV AL,[M4] ; Position oOV [T1],AL CALL ATTACK ; Find attackers/defenders MOV BX,WACT ; White queen attackers MOV DX,BACT ; Black queen attackeX] XCHG DX,BX XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Restore regs. MOV CL,0 ; Init attacker/defender flag MOV DLece type CMP AL,ROOK ; Rook ? JNZ PF25 ; No - jump JMP PF20 ; Jump PF15: AND AL,AL ; Possible pin ? JNZ PF25 ; No enders of that piece. ; ; CALLED BY: -- POINTS ; ; CALLS: -- NEXTAD ; ; ARGUMENTS: -- None. ;******************MP AL,2 ; Piece of same color found ? MOV AL,[M4] ; Load pinned piece position JZ PF15 ; Yes - jump AND AL,AL ; Possibf pinned piece MOV [SI+PLIST],AL ; Save in list PF25: INC DI ; Increment direction index DEC CH JZ PF26 ; Done ? Yes - rs TEST B,[P1],080H ; Is queen white ? JZ PF19A ; Yes - skip XCHG DX,BX ; Reverse for black PF19A: MOV AL,[BX] ; Numbe,0 ; Init points lost count MOV SI,[T3] ; Load piece value index MOV DH,[SI+PVALUE] ; Get attacked piece value SAL DH ;- jump MOV AL,[M2] ; Save possible pin position MOV [M4],AL JMP PF5 ; Jump PF19: MOV AL,[P1] ; Load King or Queen AN***************************************** XCHNG: XCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Swap regs. MOV AL,[P1] ; Piecle pin ? JZ JPF25 ; No - jump MOV AL,[T2] ; Piece type encountered CMP AL,QUEEN ; Queen ? JZ PF19 ; Yes - jump MOV Continue JMP PF2 PF26: INC DX ; Incr King/Queen pos index JMP PF1 ; Jump ;****************************************r of defenders XCHG DX,BX ; Reverse for attackers SUB AL,[BX] ; Defenders minus attackers DEC AL ; Less 1 POP DI ; R Double it MOV CH,DH ; Save CALL NEXTAD ; Retrieve first attacker JNZ XC10 JMP RET ; Return if none XC10: MOV BL,AL D AL,7 ; Clear flags CMP AL,QUEEN ; Queen ? JNZ PF20 ; No - jump PUSH CX ; Save regs. PUSH DX PUSH DI XOR AX,AX e attacked MOV BX,WACT ; Addr of white attkrs/dfndrs MOV DX,BACT ; Addr of black attkrs/dfndrs TEST AL,080H ; Is piece BL,AL ; Save piece type MOV AL,CH ; Direction counter CMP AL,5 ; Non-diagonal direction ? JC PF10 ; Yes - jump MOV A******************** ; EXCHANGE ROUTINE ;************************************************************ ; FUNCTION: -- To de ; Save attacker value CALL NEXTAD ; Get next defender JZ XC18 ; Jump if none LAHF CMP CH,BL ; Attacked less than att SHR AH SHR AH SHR AH SHR AH MOV [BX],AH AND AL,0FH DEC BX ; Decrement list pointer ADD AL,AL ; Double it NX6: Attack list counts ;********************************************************* NEXTAD: INC CL ; Increment side flag Xpiece, if any MOV [BX],AL AND AL,7 ; Save piece type, if any MOV [T3],AL CMP AL,KNIGHT ; Less than a Knight (Pawn) ? becomes defender JMP XC10 ; Jump ;************************************************************ ; NEXT ATTACKER/DEFENDEne ;************************************************************** POINTS: XOR AL,AL ; Zero out variables MOV [MTRL],AL Macker ? JNC XC19 ; No - jump XC15: CMP AL,BL ; Defender less than attacker ? JC RET ; Yes - return CALL NEXTAD ; RetrXCHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Restore regs. RET ; Return ;*******************************************CHG BX,[HL] XCHG DX,[DE] XCHG CX,[BC] ; Swap registers XCHG CH,CL ; Swap list counts XCHG DX,BX ; Swap list pointers JC PT6X ; Yes - Jump CMP AL,ROOK ; Rook, Queen or King ? JC PT6B ; No - jump CMP AL,KING ; Is it a King ? JZ PT6AA R ROUTINE ;************************************************************ ; FUNCTION: -- To retrieve the next attacker or defOV [BRDC],AL MOV [PTSL],AL MOV [PTSW1],AL MOV [PTSW2],AL MOV [PTSCK],AL MOV BX,T1 ; Set attacker flag MOV B,[BX],7 ieve next attacker value JZ RET ; Return if none MOV BL,AL ; Save attacker value CALL NEXTAD ; Retrieve next defender v***************** ; POINT EVALUATION ROUTINE ;************************************************************ ;FUNCTION: -- T XOR AL,AL CMP AL,CH ; At end of list ? JZ NX6 ; Yes - jump DEC CH ; Decrement list count NX5: INC BX ; Increment li; Yes - jump MOV AL,[MOVENO] ; Get move number CMP AL,7 ; Less than 7 ? JC PT6A ; Yes - Jump JMP PT6X ; Jump PT6AA: ender ; piece value from the attack list, and delete ; that piece from the list. ; ; CALLED MOV AL,21 ; Init to first square on board PT5: MOV [M3],AL ; Save as board index MOV SI,[M3] ; Load board index MOV ALalue JNZ XC15 ; Jump if none XC18: LAHF XC19: TEST CL,001H ; Attacker or defender ? JZ XC20 ; Jump if defender NEG CHo perform a static board evaluation and ; derive a score for a given board position ; ; CALLED BY: -- FNDMOVst pointer CMP AL,[BX] ; Check next item in list JZ NX5 ; Jump if empty MOV AL,[BX] ; Get value from list MOV AH,AL TEST B,[BX],010H ; Castled yet ? JZ PT6A ; No - jump MOV AL,+6 ; Bonus for castling TEST B,[BX],080H ; Check piece colorBY: -- XCHNG ; ; CALLS: -- None ; ; ARGUMENTS: -- Attack list addresses. ; Side flag ; ,[SI+BOARD] ; Get piece from board CMP AL,-1 ; Off board edge ? JNZ PT5A JMP PT25 ; Yes - jump PT5A: MOV BX,P1 ; Save ; Negate value for attacker XC20: ADD DL,CH ; Total points lost SAHF JZ RET ; Return if none MOV CH,BL ; Prev attckr ; EVAL ; ; CALLS: -- ATTACK ; XCHNG ; LIMIT ; ; ARGUMENTS: -- No JZ PT6D ; Jump if white MOV AL,-6 ; Bonus for black castling JP PT6D ; Jump PT6A: TEST B,[BX],008H ; Has piece moved 3 ; No - jump MOV [PTSCK],AL ; Save position as a flag JP PT23 ; Jump PT20: MOV BX,PTSW1 ; Previous maximum points won n value MOV AL,[P1] ; Get piece under attack XOR AL,[COLOR] ; Compare color of side just moved with piece TEST AL,080H ; ; Yes - jump DEC AL ; Decrement it PT26: MOV CH,AL ; Save it MOV AL,[PTSW1] ; Max points won AND AL,AL ; Is it zero ack list for square MOV BX,BACT ; Get black attacker count addr MOV AL,[WACT] ; Get white attacker count SUB AL,[BX] ; C AL,[BX] ; Add new value MOV [BX],AL ; Store PT25: MOV AL,[M3] ; Get current board position INC AL ; Increment CMP ALyet ? JZ PT6X ; No - jump JP PT6C ; Jump PT6B: TEST B,[BX],008H ; Has piece moved yet ? JNZ PT6X ; Yes - jump PT6C: MCMP AL,[BX] ; Compare to current value JC PT21 ; Jump if greater than MOV AL,[BX] ; Load previous max value MOV [BX],DL Do colors match ? MOV AL,DL ; Points lost JNZ PT20 ; Jump if no match MOV BX,PTSL ; Previous max points lost CMP AL,? JZ PT27 ; Yes - jump MOV AL,[PTSW2] ; 2nd max points won AND AL,AL ; Is it zero ? JZ PT27 ; Yes - jump DEC AL ; ompute count difference MOV BX,BRDC ; Address of board control ADD AL,[BX] ; Accum board control score MOV [BX],AL ; Sa,99 ; At end of board ? JZ PT25AA JMP PT5 ; No - jump PT25AA: MOV AL,[PTSCK] ; Moving piece lost flag AND AL,AL ; Was OV AL,-2 ; Two point penalty for white TEST B,[BX],080H ; Check piece color JZ PT6D ; Jump if white MOV AL,+2 ; Two poi ; Store new value as max won PT21: MOV BX,PTSW2 ; Previous 2nd max points won CMP AL,[BX] ; Compare to current value JC [BX] ; Compare to current value JC PT23 ; Jump if greater than MOV [BX],DL ; Store new value as max lost MOV SI,[MLPTRJDecrement it SHR AL ; Divide it by 2 PT27: SUB AL,CH ; Subtract points lost TEST B,[COLOR],080H ; Is color of side just mve MOV AL,[P1] ; Get piece on current square AND AL,AL ; Is it empty ? JZ PT25 ; Yes - jump CALL XCHNG ; Evaluate exit lost ? JZ PT25A ; No - jump MOV AL,[PTSW2] ; 2nd max points won MOV [PTSW1],AL ; Store as max points won XOR AL,AL nt penalty for black PT6D: MOV BX,BRDC ; Get address of board control ADD [BX],AL ; Add on penalty/bonus points PT6X: XOR PT23 ; Jump if greater than MOV [BX],AL ; Store as new 2nd max lost PT23: TEST B,[P1],080H ; Test piece color MOV AL,DH ] ; Load pointer to this move MOV AL,[M3] ; Get position of lost piece CMP AL,[SI+MLTOP] ; Is it the one moving ? JNZ PT2oved white ? JZ PT28 ; Yes - jump NEG AL ; Negate for black PT28: MOV BX,MTRL ; Net material on board ADD AL,[BX] ; Achange, if any XOR AL,AL ; Check for a loss CMP AL,DL ; Points lost ? JZ PT23 ; No - Jump DEC DH ; Deduct half a Paw; Zero out 2nd max points won MOV [PTSW2],AL PT25A: MOV AL,[PTSL] ; Get max points lost AND AL,AL ; Is it zero ? JZ PT26AX,AX ; Zero out attack list MOV CX,7 MOV BX,ATKLST XCHG DI,BX CLD REP STOW XCHG DI,BX CALL ATTACK ; Build att; Value of piece JZ PT24 ; Jump if white NEG AL ; Negate for black PT24: MOV BX,MTRL ; Get addrs of material total ADDdd exchange adjustments MOV BX,MV0 ; Material at ply 0 SUB AL,[BX] ; Subtract from current MOV CH,AL ; Save MOV AL,30tive ? JZ LIM10 ; No - jump NEG AL ; Make positive CMP AL,CH ; Compare to limit JNC RET ; Return if outside limit ************************** ; FUNCTION: -- To limit the magnitude of a given value ; to another given value.L,[SI+BOARD] ; Get piece moved TEST DH,020H ; Test Pawn promotion flag JNZ MV15 ; Jump if set MOV AL,DL ; Piece moved Get material points ADD AL,AL ; Multiply by 4 ADD AL,AL ADD AL,DH ; Add board control TEST B,[COLOR],080H ; Is color o FNDMOV ; VALMOV ; ; CALLS: -- None ; ; ARGUMENTS: -- None ;************************************** ; Load material limit CALL LIMIT ; Limit to plus or minus value MOV DL,AL ; Save limited value MOV AL,[BRDC] ; Get boaMOV AL,CH ; Output value as is RET ; Return LIM10: CMP AL,CH ; Compare to limit JC RET ; Return if outside limit MOV ; ; CALLED BY: -- POINTS ; ; CALLS: -- None ; ; ARGUMENTS: -- Input - Value to be limited in the CH ; AND AL,7 ; Clear flag bits CMP AL,QUEEN ; Is it a queen ? JZ MV20 ; Yes - jump CMP AL,KING ; Is it a king ? JZ MV30 f side just moved white ? JNZ PT30 ; No - jump NEG AL ; Negate for white PT30: ADD AL,80H ; Rescale score (neutral = 80H********************** MOVE: MOV BX,[MLPTRJ] ; Load move list pointer INC BX ; Increment past link bytes INC BX MV1: MOV rd control points MOV BX,BC0 ; Board control at ply zero SUB AL,[BX] ; Get difference MOV CH,AL ; Save MOV AL,[PTSCK] AL,CH ; Output value as is RET ; Return ;*********************************************************** ; MOVE ROUTIN register. ; - Value to limit to in the AL register. ; Output - Limite ; Yes - jump MV5: MOV DI,[M2] ; Load "to" pos board index OR DL,008H ; Set piece moved flag MOV [DI+BOARD],DL ; Insert p) MOV [VALM],AL ; Save score MOV SI,[MLPTRJ] ; Load move list pointer MOV [SI+MLVAL],AL ; Save score in move list RET AL,[BX] ; "From" position MOV [M1],AL ; Save INC BX ; Increment pointer MOV AL,[BX] ; "To" position MOV [M2],AL ; S ; Moving piece lost flag AND AL,AL ; Is it zero ? JZ PT29 ; Yes - jump MOV CH,0 ; Zero board control points PT29: MOVE ;*********************************************************** ; FUNCTION: -- To execute a move from the move list on the d value in the AL register. ;************************************************************ LIMIT: TEST CH,080H ; Is value negaiece at new position MOV B,[SI+BOARD],0 ; Empty previous position TEST DH,040H ; Double move ? JNZ MV40 ; Yes - jump M; Return ;*********************************************************** ; LIMIT ROUTINE ;********************************ave INC BX ; Increment pointer MOV DH,[BX] ; Get captured piece/flags MOV SI,[M1] ; Load "from" pos board index MOV D AL,6 ; Load board control limit CALL LIMIT ; Limit to plus or minus value MOV DH,AL ; Save limited value MOV AL,DL ; ; board array. ; ; CALLED BY: -- CPTRMV ; PLYRMV ; EVAL ; OV AL,DH ; Get captured piece, if any AND AL,7 CMP AL,QUEEN ; Was it a queen ? JNZ RET ; No - return MOV BX,POSQ ; Adposition MOV [M2],AL ; Save INC BX ; Increment pointer MOV DH,[BX] ; Get captured piece/flags MOV SI,[M2] ; Load "toy restoring the board array to its ; previous position. ; ; CALLED BY: -- VALMOV ; EVAL ;DL,0FBH ; Restore Queen to Pawn JMP UM5 ; Jump UM16: AND DL,0F7H ; Clear piece moved flag JMP UM6 ; Jump UM20: MOV BX,0: MOV BX,POSK ; Get saved King position TEST DH,020H ; Castling ? JZ MV21 ; No - jump OR DL,010H ; Set King castled fif any AND AL,8FH ; Clear flags MOV [SI+BOARD],AL ; Return to board TEST DH,040H ; Was it a double move ? JNZ UM40 ; dr of saved Queen position TEST DH,080H ; Is Queen white ? JZ MV10 ; Yes - jump INC BX ; Increment to black Queen pos " pos board index MOV DL,[SI+BOARD] ; Get piece moved TEST DH,020H ; Was it a Pawn promotion ? JNZ UM15 ; Yes - jump M FNDMOV ; ASCEND ; ; CALLS: -- None ; ; ARGUMENTS: -- None ;**********************POSQ ; Addr of saved Queen position UM21: TEST DL,080H ; Is Queen white ? JZ UM22 ; Yes - jump INC BX ; Increment to bllag JMP MV21 ; Jump MV40: MOV BX,[MLPTRJ] ; Get move list pointer ADD BX,8 ; Increment to next move JMP MV1 ; Jump (2Yes - jump MOV AL,DH ; Get captured piece, if any AND AL,7 ; Clear flag bits CMP AL,QUEEN ; Was it a Queen ? JNZ RET MV10: XOR AL,AL ; Set saved position to zero MOV [BX],AL RET ; Return MV15: OR DL,004H ; Change Pawn to a Queen JMP MOV AL,DL ; Get piece moved AND AL,7 ; Clear flag bits CMP AL,QUEEN ; Was it a Queen ? JZ UM20 ; Yes - jump CMP AL,KIN*************************************** UNMOVE: MOV BX,[MLPTRJ] ; Load move list pointer INC BX ; Increment past link bytes ack Queen pos UM22: MOV AL,[M1] ; Get previous position MOV [BX],AL ; Save JMP UM5 ; Jump UM30: MOV BX,POSK ; Address nd part of dbl move) ;********************************************************** ; UN-MOVE ROUTINE ;*******************; No - return MOV BX,POSQ ; Address of saved Queen pos TEST DH,080H ; Is Queen white ? JZ UM10 ; Yes - jump INC BX ;V5 ; Jump MV20: MOV BX,POSQ ; Addr of saved Queen position MV21: TEST DL,080H ; Is Queen white ? JZ MV22 ; Yes - jump G ; Was it a King ? JZ UM30 ; Yes - jump UM5: TEST DH,010H ; Is this 1st move for piece ? JNZ UM16 ; Yes - jump UM6: M INC BX UM1: MOV AL,[BX] ; Get "from" position MOV [M1],AL ; Save INC BX ; Increment pointer MOV AL,[BX] ; Get "to" of saved King pos TEST DH,040H ; Was it a castle ? JZ UM21 ; No - jump AND DL,0EFH ; Clear castled flag JMP UM21 ; J*************************************** ; FUNCTION: -- To reverse the process of the move routine, ; thereb Increment to black Queen pos UM10: MOV AL,[M2] ; Queen's previous position MOV [BX],AL ; Save RET ; Return UM15: AND INC BX ; Increment to black Queen pos MV22: MOV AL,[M2] ; Get new Queen position MOV [BX],AL ; Save JMP MV5 ; Jump MV3OV DI,[M1] ; Load "from" pos board index MOV [DI+BOARD],DL ; Return to previous board pos MOV AL,DH ; Get captured piece, ump UM40: MOV BX,[MLPTRJ] ; Load move list pointer ADD BX,8 ; Increment to next move JMP UM1 ; Jump (2nd part of dbl move board, then if ; the move is legal, it evaluates it, and then ; restores the boaard position.ter MOV AL,[VALM] ; Get new move value CMP AL,[SI+MLVAL] ; Less than list value ? JNC SR30 ; No - jump SR25: MOV [BX],CHMOV ; SORTM ; ASCEND ; UNMOV ; ; ARGUMENTS: -- None ;*******************CL MOV CL,[BX] ; Link to next move INC BX MOV CH,[BX] MOV [BX],DH ; Store to link in list DEC BX MOV [BX],DL XORlist CALL POINTS ; Assign points to move JMP UNMOVE ; Restore board array ;****************************************) ;********************************************************** ; SORT ROUTINE ;***************************************** ; ; CALLED BY: -- SORT ; ; CALLS: -- MOVE ; INCHK ; PINFND ; POI ; Link new move into list DEC BX MOV [BX],CL JMP SR5 ; Jump SR30: XCHG DX,BX ; Swap pointers JMP SR15 ; Jump ***************************************** FNDMOV: MOV AL,[MOVENO] ; Currnet move number CMP AL,1 ; First move ? JNZ L0003 AL,AL ; End of list ? CMP AL,CH JZ RET ; Yes - return SR10: MOV [MLPTRJ],CX ; Save list pointer CALL EVAL ; Evaluate ***************** ; FIND MOVE ROUTINE ;********************************************************* ; FUNCTION: -- To determi***************** ; FUNCTION: -- To sort the move list in order of ; increasing move value scores. ; ; CANTS ; UNMOV ; ; ARGUMENTS: -- None ;************************************************************* EVAL: C ;********************************************************** ; EVALUATION ROUTINE ;****************************************** CALL BOOK ; Yes - execute book opening L0003: XOR AL,AL ; Initialize ply number to zero MOV [NPLY],AL MOV BX,0 ; Inimove MOV BX,[MLPTRI] ; Begining of move list MOV CX,[MLPTRJ] ; Restore list pointer SR15: MOV DL,[BX] ; Next move for compne the computer's best move by ; performing a depth first tree search using ; the techniques oLLED BY: -- FNDMOV ; ; CALLS: -- EVAL ; ; ARGUMENTS: -- None ;***************************************************ALL MOVE ; Make move on the board array CALL INCHK ; Determine if move is legal AND AL,AL ; Legal move ? JZ EV5 ; Yes **************** ; FUNCTION: -- To evaluate a given move in the move list. ; It first makes the move on thetialize best move to zero MOV [BESTM],BX MOV BX,MLIST ; Initialize ply list pointers MOV [MLNXT],BX MOV BX,PLYIX-2 MOVare INC BX MOV DH,[BX] XOR AL,AL ; At end of list ? CMP AL,DH JZ SR25 ; Yes - jump MOV SI,DX ; Transfer move poinf alpha-beta pruning. ; ; CALLED BY: -- CPTRMV ; ; CALLS: -- PINFND ; POINTS ; GEN********** SORTM: MOV CX,[MLPTRI] ; Move list begin pointer MOV DX,0 ; Initialize working pointers SR5: MOV BH,CH MOV BL,- jump XOR AL,AL ; Score of zero MOV [VALM],AL ; For illegal move JMP UNMOVE ; Jump EV5: CALL PINFND ; Compile pinned [MLPTRI],BX MOV AL,[KOLOR] ; Initialize color MOV [COLOR],AL MOV BX,SCORE ; Initialize score index MOV [SCRIX],BX MOV AL,[NPLY] ; Get ply counter MOV BX,PLYMAX ; Max ply number CMP AL,[BX] ; Beyond max ply ? JZ FM17 JMP FM35 ; Yes - juist ? JNZ FM15A JMP FM25 ; Yes - jump FM15A: MOV [MLPTRJ],DX ; Save current move pointer MOV BX,[MLPTRI] ; Save in ply pO] ; Get move number MOV [PMATE],AL ; Save MOV AL,0FFH ; Pre-set checkmate score JMP FM36 ; Jump FM30: MOV AL,[NPLY] ; nt ply count XOR AL,AL ; Initialize mate flag MOV [MATEF],AL CALL GENMOV ; Generate list of moves MOV AL,[NPLY] ; Curr; Increment move number FM20: MOV BX,[SCRIX] ; Load score table pointer MOV AL,[BX] ; Get score two plys above INC BX ; I AL,[PLYMAX] ; Get max ply number ADD AL,2 ; Add 2 MOV CH,AL ; Save as counter XOR AL,AL ; Zero out score table FM1: Mmp FM17: MOV AL,[COLOR] ; Get current color XOR AL,80H ; Get opposite color CALL INCHK1 ; Determine if King is in check ointer list MOV [BX],DL INC BX MOV [BX],DH MOV AL,[NPLY] ; Current ply counter MOV BX,PLYMAX ; Maximum ply number ? Get ply counter CMP AL,1 ; At top of tree ? JZ RET ; Yes - return CALL ASCEND ; Ascend one ply in tree MOV BX,[SCRIX]ent ply counter MOV BX,PLYMAX ; Address of maximum ply number CMP AL,[BX] ; At max ply ? JNC L0004 CALL SORTM ; No - cncrement to current ply MOV [SCRIX],BX ; Save it INC BX MOV [BX],AL ; Save score as initial value JMP FM5 ; Jump FM25OV [BX],AL INC BX DEC CH JNZ FM1 MOV [BC0],AL ; Zero ply 0 board control MOV [MV0],AL ; Zero ply 0 material CALL PIN AND AL,AL ; In check ? JZ FM35 ; No - jump JMP FM19 ; Jump (One more ply for check) FM18: MOV SI,[MLPTRJ] ; Load move pCMP AL,[BX] ; Compare JC FM18 ; Jump if not max CALL MOVE ; Execute move on board array CALL INCHK ; Check for legal m ; Load score table pointer INC BX ; Increment to current ply INC BX MOV AL,[BX] ; Get score DEC BX ; Restore pointerall sort L0004: MOV BX,[MLPTRI] ; Load ply index pointer MOV [MLPTRJ],BX ; Save as last move pointer FM15: MOV BX,[MLPTRJ]: MOV AL,[MATEF] ; Get mate flag AND AL,AL ; Checkmate or stalemate ? JNZ FM30 ; No - jump MOV AL,[CKFLG] ; Get check flFND ; Complie pin list CALL POINTS ; Evaluate board at ply 0 MOV AL,[BRDC] ; Get board control points MOV [BC0],AL ; Savointer MOV AL,[SI+MLVAL] ; Get move score AND AL,AL ; Is it zero (illegal move) ? JZ FM15 ; Yes - jump CALL MOVE ; Exove AND AL,AL ; Is move legal ? JZ FM16 ; Yes - jump CALL UNMOVE ; Restore board position JMP FM15 ; Jump FM16: MOV DEC BX JMP FM37 ; Jump JFM15: JMP FM15 FM35: CALL PINFND ; Compile pin list CALL POINTS ; Evaluate move CALL UNMOV ; Load last move pointer MOV DL,[BX] ; Get next move pointer INC BX MOV DH,[BX] MOV AL,DH AND AL,AL ; End of move lag AND AL,AL ; Was King in check ? MOV AL,80H ; Pre-set stalemate score JZ FM36 ; No - jump (stalemate) MOV AL,[MOVENe MOV AL,[MTRL] ; Get material count MOV [MV0],AL ; Save FM5: MOV BX,NPLY ; Address of ply counter INC B,[BX] ; Incremeecute move on board array FM19: XOR B,[COLOR],80H ; Toggle color, is new color white ? JS FM20 ; No - jump INC B,[MOVENO] E ; Restore board position MOV AL,[VALM] ; Get value of move FM36: OR B,[MATEF],001H ; Set mate flag MOV BX,[SCRIX] ; LoadY] ; Decrement ply counter MOV BX,[MLPTRI] ; Load ply list pointer DEC BX ; Load pointer to move list top DEC BX MOV DEE ROUTINE ;********************************************************* ; FUNCTION: -- To adjust all necessary parameters to BM5: ADD B,[BX],6 ; Increment to black moves MOV SI,[MLPTRJ] ; Pointer to opponents 1st move MOV AL,[SI+MLFRP] ; Get "from"est move pointer MOV AL,[SCORE+1] ; Get best move score CMP AL,0FFH ; Was it a checkmate ? JNZ JFM15 ; No - jump MOV BMOV ; ; CALLS: -- None ; ; ARGUMENTS: -- None ;*********************************************************** BOOK: P score table pointer FM37: CMP AL,[BX] ; Compare to score 2 ply above JC FM40 ; Jump if less JZ FM40 ; Jump if equal NX,[BX] MOV [MLNXT],DX ; Update move list avail ptr DEC BX ; Get ptr to next move to undo DEC BX MOV DX,[BX] MOV [MLPT ; ascend one ply in the tree. ; ; CALLED BY: -- FNDMOV ; ; CALLS: -- UNMOV ; ; ARGUMENTS: -- No position CMP AL,22 ; Is it a Queen Knight move ? JZ BM9 ; Yes - Jump CMP AL,27 ; Is it a King Knight move ? JZ BM9 X,PLYMAX ; Get maximum ply number SUB B,[BX],2 ; Subtract 2 MOV AL,[KOLOR] ; Get computer's color TEST AL,080H ; Is it whOP AX MOV B,[SCORE+1],0 ; Zero out score table MOV [BESTM],BMOVES-2 ; Init best move ptr to book MOV BX,BESTM ; InitializeEG AL ; Negate score INC BX ; Incr score table pointer CMP AL,[BX] ; Compare to score 1 ply above JC JFM15 ; Jump if lRI],BX ; Save new ply list pointer MOV [MLPTRJ],DX ; Save next move pointer JMP UNMOVE ; Restore board to previous ply ne ;************************************************************ ASCEND: XOR B,[COLOR],80H ; Toggle color, is new color white ; Yes - jump CMP AL,34 ; Is it a Queen Pawn ? JZ BM9 ; Yes - jump JC RET ; If Queen side Pawn opening - ; return (ite ? JZ RET ; Yes - return MOV BX,PMATE ; Checkmate move number DEC B,[BX] ; Decrement RET ; Return FM40: CALL ASC address of pointer MOV AL,[KOLOR] ; Get computer's color AND AL,AL ; Is it white ? JNZ BM5 ; No - jump MOV AL,0 ; Loess than JZ JFM15 ; Jump if equal MOV [BX],AL ; Save as new score 1 ply above MOV AL,[NPLY] ; Get current ply counter ;********************************************************** ; ONE MOVE BOOK OPENING ;**************************************? JNS AC5 ; Yes - jump DEC B,[MOVENO] ; Decrement move number AC5: DEC [SCRIX] ; Decrement score table index DEC B,[NPLP-K4) CMP AL,35 ; Is it a King Pawn ? JZ RET ; Yes - return (P-K4) BM9: ADD B,[BX],3 ; (P-Q4) RET ; Return to CPTRMV END ; Ascend one ply in tree JMP FM15 ; Jump ;********************************************************** ; ASCEND TRad random number (0) TEST AL,001H ; Test random bit JZ RET ; Return if zero (P-K4) ADD B,[BX],3 ; P-Q4 RET ; Return CMP AL,1 ; At top of tree ? JNZ JFM15 ; No - jump MOV BX,[MLPTRJ] ; Load current move pointer MOV [BESTM],BX ; Save as b******************* ; FUNCTION: -- To provide an opening book of a single ; move. ; ; CALLED BY: -- FND ;*********************************************************** ; COMPUTER MOVE ROUTINE ;*********************************ET ; No - return MOV CL,0 ; Set player mate flag CALL FCDMAT ; Full checkmate ? RET ; Return ;**************** to Ascii MOV [MVEMSG],BX ; Put in move message MOV DX,MVEMSG ; Output move MOV CL,PRINTBUF CALL SYSTEM CP1C: MOV AL,[Cr who is mated RCL AH JZ FM04 ; Jump if player MOV DX,CKMSG ; Print "CHECK" MOV CL,PRINTBUF CALL SYSTEM MOV DX,UWINointer variable MOV [MLPTRJ],BX ; Pointer to move data MOV AL,[SCORE+1] ; To check for mates CMP AL,1 ; Mate against compV ; ; CALLS: -- None ; ; ARGUMENTS: -- The only value passed in a register is the ; flag which tell************************** ; FUNCTION: -- To control the search for the computers move ; and the display of******************************************* ; FORCED MATE HANDLING ;**********************************************************OLOR] ; Should computer call check ? MOV CH,AL XOR AL,80H ; Toggle color MOV [COLOR],AL CALL INCHK ; Check for check ; Output "YOU WIN" MOV CL,PRINTBUF CALL SYSTEM JP FM08 ; Jump FM04: MOV DX,CKMSG ; Print "CHECK" MOV CL,PRINTBUF Cuter ? JNZ CP0C ; No - jump MOV CL,1 ; Computer mate flag CALL FCDMAT ; Full checkmate ? CP0C: CALL MOVE ; Produce mos FCDMAT whether the computer ; or the player is mated. ;***************************************************** that move on the board ; and in the move list. ; ; CALLED BY: -- DRIVER ; ; CALLS: -- FNDMOV ; * ; FUNCTION: -- To examine situations where there exits ; a forced mate and determine whether or ; AND AL,AL ; Is enemy in check ? MOV AL,CH ; Restore color MOV [COLOR],AL JZ CP24 ; No - return MOV DX,CKMSG ; OutputALL SYSTEM MOV DX,IWIN ; Output "I WIN" MOV CL,PRINTBUF CALL SYSTEM FM08: POP BX ; Remove return addresses POP BX Mve on board array MOV SI,[MLPTRJ] ; Get pointer to move MOV DH,[SI+MLTOP] ; "To" position of the move CALL BITASN ; Conve****** FCDMAT: MOV AL,[MOVENO] ; Current move number MOV CH,AL ; Save MOV AL,[PMATE] ; Move number where mate occurs SUB FCDMAT ; MOVE ; BITASN ; INCHK ; ; ARGUMENTS: -- None ;*** not the current move is checkmate. If it is, ; a losing player is offered another game, ; "check" MOV CL,PRINTBUF CALL SYSTEM CP24: MOV AL,[SCORE+1] ; Check again for mates CMP AL,0FFH ; Player mated ? JNZ ROV CL,INCHAR ; Input any char to play again CALL SYSTEM JMP DRIVER ; Jump (Rest of game init) ;*********************rt to Ascii MOV [MVEMSG+3],BX ; Put in move message MOV DH,[SI+MLFRP] ; "From" position of the move CALL BITASN ; Convert AL,CH ; Number of moves till mate AND AL,AL ; Checkmate ? JNZ RET ; No - return RCR AH TEST CL,001H ; Check flag fo******************************************************** CPTRMV: CALL FNDMOV ; Select best move MOV BX,[BESTM] ; Move list p while a loss for the computer signals the ; King to tip over in resignation. ; ; CALLED BY: -- CPTRM************************************** ; BOARD INDEX TO ASCII SQUARE NAME ;***************************************************BX] ; Get first char CMP AL,"R" ; Restart game ? JNZ PL05 ; Jump if not restart JMP DRIVER PL05: MOV AL,CH ; Get inpu; CALLED BY: -- DRIVER ; ; CALLS: -- ASNTBI ; VALMOV ; ; ARGUMENTS: -- None ;*******************nd outputs the board index in register AL. ; CF = 0 if ok. CF = 1 if invalid. ;*******************************ide 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 ; Jump ;************************************************************ ; ASCII SQUARE NAME TO BOARD INDEX ;********************** ; FUNCTION: -- To translate a hexadecimal index in the ; board array into an ascii description ;t length CMP AL,5 ; Long enough ? JC PL08 ; Jump if less than 5 chars CALL ASNTBI ; Convert "from" to a board index J***************************************** PLYRMV: MOV DX,BUFFER ; Ask for input MOV CL,INBUF CALL SYSTEM MOV DX,CRLF ; O***************************** ATBINX: INC BX ; Increment pointer to skip a char ASNTBI: MOV AL,[BX] ; Ascii file letter (a -AL,30H ; Convert rank to Ascii (1-8) MOV BH,AL ; Save RET ; Return ;******************************************************************************************** ; FUNCTION: -- To convert an algebraic square name in ; Asc of the square in algebraic chess notation. ; ; CALLED BY: -- CPTRMV ; ; CALLS: -- DIVIDE ; ; ARGUC PL08 ; Jump if invalid MOV [MVEMSG],AL ; Move list "from" position CALL ATBINX ; Convert "to" to a board index JC PL08utput CRLF MOV CL,PRINTBUF CALL SYSTEM MOV BX,BUFFER+1 ; Point to input length MOV AL,[BX] ; Get input length OR AL,A h) INC BX SUB AL,41H ; File 1 - 8 JC RET ; Not file letter CMP AL,8 ; Check upper bound CMC JC RET ; Invalid ************** ; PLAYERS MOVE ANALYSIS ;*********************************************************** ; FUNCTION: -- To acceii to a hexadecimal board index. ; This routine also checks the input for ; validity. ; ; CAMENTS: -- Board index input in register DH and the ; Ascii square name is output in register BX. ;********** ; Jump if invalid MOV [MVEMSG+1],AL ; Move list "to" position CALL VALMOV ; Determines if a legal move OR AL,AL ; LegaL ; Empty ? JZ PLYRMV ; Jump if empty MOV CH,AL ; Save length LAHF INC BX ; Point to actual buffer SAHF MOV AL,[MOV CH,AL MOV AL,[BX] SUB AL,31H ; Rank 1 - 8 JC RET CMP AL,8 ; Check upper bound CMC JC RET ADD AL,AL ; Multippt and validate the players move ; Also allows player to resign the game by ; entering R. ; LLED BY: -- PLYRMV ; ; CALLS: -- None ; ; ARGUMENTS: -- Accepts the square name in pointer BX ; a************************************************** BITASN: SUB AL,AL ; Get ready for division MOV DL,10 CALL DIVIDE ; Divl ? JZ RET ; Yes - return PL08: MOV DX,INVAL ; Output "INVALID MOVE--TRY AGAIN" MOV CL,PRINTBUF CALL SYSTEM JP PLYRMV ly rank by 10 MOV CL,AL ADD AL,AL ADD AL,AL ADD AL,CL ADD AL,CH ; 10 * rank + file INC BX ; Increment pointer ADturn VA9: CALL UNMOVE ; Un-do move on board array VA10: MOV AL,1 ; Set flag for invalid move POP BX ; Restore saved regisMOV AL,[MVEMSG+1] ; "To" position CMP AL,[SI+MLTOP] ; Is it in list ? JZ VA7 ; Yes - jump VA6: MOV DL,[SI+MLPTR] ; Pointer***************************** VALMOV: MOV BX,[MLPTRJ] ; Save last move pointer PUSH BX ; Save register MOV AL,[KOLOR] ; Co CLRMSG: DB 13,10,"Choose your color (W/B): $" PLYDEP: DB 13,10,"Ply depth (1-6): $" MVEMSG: DB " ",13,10,"$" CKMSG: DB "D AL,21 RET ; Return ;*********************************************************** ; VALIDATE MOVE SUBROUTINE ;*****ter MOV [MLPTRJ],BX ; Save move pointer RET ; Return ;************************************************************ to next list move MOV DH,[SI+MLPTR+1] XOR AL,AL ; At end of list ? CMP AL,DH JZ VA10 ; Yes - jump PUSH DX ; Move tmputers color XOR AL,80H ; Toggle color MOV [COLOR],AL ; Store MOV BX,PLYIX-2 ; Load move list index MOV [MLPTRI],BX CHECK",13,10,"$" UWIN: DB "You win",13,10,"$" IWIN: DB "I win" CRLF: DB 13,10,"$" INVAL: DB "INVALID MOVE--TRY AGAIN",13,10,****************************************************** ; FUNCTION: -- To check a players move for validity. ; ; CALLED BY: ; POSITIVE INTEGER DIVISION ;************************************************************ DIVIDE: PUSH CX MOV CH,8 DD04: So SI register POP SI JP VA5 ; Jump VA7: MOV [MLPTRJ],SI ; Save opponents move pointer CALL MOVE ; Make move on board arMOV BX,MLIST+1024 ; Next available list pointer MOV [MLNXT],BX CALL GENMOV ; Generate opponents moves MOV SI,MLIST+1024 ;"$" BUFFER: DB 7 DS 6 IX: DS 2 IY: DS 2 BC: DS 2 DE: DS 2 HL: DS 2  -- PLYRMV ; ; CALLS: -- GENMOV ; MOVE ; INCHK ; UNMOVE ; ; ARGUMAL DH RCL AL SUB AL,DL JS DD05 INC DH JP DD06 DD05: ADD AL,DL DD06: DEC CH JNZ DD04 POP CX RET ;*******ray CALL INCHK ; Was it a legal move ? AND AL,AL JNZ VA9 ; No - jump VA8: POP BX ; Restore saved register RET ; Re Index to start of moves VA5: MOV AL,[MVEMSG] ; "From" position CMP AL,[SI+MLFRP] ; Is it in list ? JNZ VA6 ; No - jump ENTS: -- Returns flag in register AL, 0 for valid ; and 1 for invalid move. ;******************************************************************************* ; STANDARD MESSAGES ;******************************************************* This chess game uses algebraic chess notation. The files are lettered "a" to "h" and the ranks are numbered 1 to 8. The lower ls each time MOV DX,CRLF MOV CL,PRINTBUF CALL SYSTEM MOV DX,COMMAND MOV AX,2522H ;Set vector 34 (terminate) INT 33 EN: EQU 15 CLOSE: EQU 16 MAKE: EQU 22 DELETE: EQU 19 RDBLK: EQU 39 WRBLK: EQU 40 SETDMA: EQU 26 SELDRV: EQU 14 GETDRV: Eto next position without affecting flags SAHF LODW ;Get address of command JNZ FINDCOM CALL AX ;Call command JMP COwill consider 1. All of his possible moves 2. All of your responses to those moves. 3. All of his possible replies to youropy file name MOV AL,9 SUB AL,CL MOV [IDLEN],AL MOV DI,81H MOV CX,0 PUSH SI COMTAIL: LODB STOB ;Move command 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 pawnMOV AX,2523H ;Set vector 35 (CTRL-C) INT 33 GETCOM: MOV CL,GETDRV CALL SYSTEM ADD AL,"A" MOV CL,OUTCH MOV DL,AL CQU 25 PRINTBUF:EQU 9 OUTCH: EQU 2 INBUF: EQU 10 RR: EQU 33 SYSTEM: EQU 5 ORG 100H PUT 100H MOV SP,STACK CLD MMMAND SETDRVJ:JMP SETDRV DRVCHK: DEC DL ;Adjust for correct drive number DEC AL ;Check if anything else is on line responses. Start at ply depth 2 to get the feel for it. A move of "R" will restart the game. tail to 80H CMP AL,13 LOOPNZ COMTAIL NOT CL MOV [80H],CL POP SI MOV DI,FCB CALL PARSENAM MOV DI,FCB+10H CALL P up two squares you would enter E2-E4. You must enter your file letters in upper case, while the computer will always use lowerALL SYSTEM ;Print drive letter MOV DL,":" MOV CL,OUTCH CALL SYSTEM ;Print ":" MOV DX,LINBUF MOV CL,INBUF CALL SYSTOV DL,0 ;Start with drive A SETDRV: MOV CL,SELDRV CALL SYSTEM COMMAND: MOV SP,STACK CLD MOV AX,CS MOV SS,AX MOV JZ SETDRVJ EXTERNAL: MOV AL,[SPECDRV] MOV [IDLEN],AL PUSH DS MOV DX,TPA ADD DX,0FH ;Round to next paragraph SHR DARSENAM MOV AL,[IDLEN] MOV DL,[SPECDRV] OR DL,DL ;Check if drive was specified JNZ DRVCHK DEC AL ;Check for null com case. To castle, enter only the king's move. The computer castles the same way. To capture En Passant, enter your pawn's acEM MOV DL,10 MOV CL,OUTCH CALL SYSTEM ;New line MOV CH,0 MOV SI,FILIFO ;8 spaces MOV DI,ID CALL FILLBUF MOV DI, ES,AX MOV DS,AX MOV CX,[6] SUB CX,TPA AND CL,80H ;Round down ROL CX XCHG CH,CL MOV [NUMREC],CX ;Number of recordX SHR DX SHR DX SHR DX ;Divide 16 MOV CX,CS ADD DX,CX ;New segment MOV DS,DX MOV AH,SETBASE INT 33 MOV DX,10FCB: EQU 5CH DSKRESET:EQU 13 SETBASE:EQU 38 SRCHFRST:EQU 17 SRCHNXT:EQU 18 RENAM: EQU 23 INCHAR: EQU 1 GETFAT: EQU 27 OPmand JZ GETCOM MOV SI,COMTAB FINDCOM: MOV DI,IDLEN MOV CL,[SI] JCXZ EXTERNAL REPE CMPB LAHF ADD SI,CX ;Bump tual move. Ply depth is the number of half-turns the computer looks ahead. For example, with a ply depth of 3, the computer FCB CALL FILLBUF MOV SI,LINBUF+2 MOV DI,ID CALL FILEDRV ;Get COM drive MOV [SPECDRV],AL MOV CX,8 CALL COPYNAM ;C0H MOV CL,SETDMA CALL SYSTEM MOV BX,DS ;New segment into BX POP DS MOV DX,IDLEN MOV AH,OPEN INT 33 OR AL,AL Je) MOV CL,OUTCH MOV DL," " CALL SYSTEM ;Print space MOV SI,LINBUF+2+9 MOV CX,3 CALL OUTCNT ;Print 3 chars (ext) MP AL,13 JZ NOMATCH CMP AL,"." JZ RET STOB LOOP COPYNAM NOMATCH: XOR AL,AL DEC SI RET FILLBUF: LODB MOV STOW STOB ;Fill first 3 bytes with FF INC AX ;AX = 0 SHR CX JNC DOFILL STOB ;Odd byte DOFILL: REP STOW MOVRET CMP AL,"," JZ RET CMP AL,";" JZ RET CMP AL,9 ;Check for TAB character RET FILEDRV: CALL NEXTCHR JZ FILED INT 33 MOV SI,TPA OUTLP: LODB CMP AL,1AH ;Is EOF? JZ RET MOV CL,OUTCH MOV DL,AL CALL SYSTEM JP OUTLP RET NZ BADCOM MOV [IDLEN+RR],0 MOV CX,512 ;512 records MOV AH,RDBLK INT 33 MOV DS,BX MOV ES,BX MOV SS,BX MOV SP,40HMOV DX,CRLF MOV CL,PRINTBUF CALL SYSTEM ;Print new line MOV CL,SRCHNXT JP EACHFILE OUTCNT: LODB PUSH CX PUSH SI CL,AL JCXZ RET LODB REP STOB JP FILLBUF DIR: CMP B,[FCB+1]," " JNZ HASNAME MOV SI,FCBFIL MOV DI,FCB+1 CAL AX,CS MOV DS,AX MOV ES,AX MOV SI,FCBFIL MOV DI,FCB+1 CALL FILLBUF MOV DX,FCB MOV CL,DELETE CALL SYSTEM ;DeleteRV ;Skip delim CMP AL,13 JZ NOMATCH CMP B,[SI],":" JNZ NOMATCH SUB AL,40H ;Convert to drive number INC SI RET CLEAR: MOV DX,ERAMES MOV CL,PRINTBUF CALL SYSTEM ;Confirm erase MOV CL,INCHAR CALL SYSTEM CMP AL,"Y" JZ DOCLEA MOV AX,0 PUSH AX MOV AX,100H PUSH BX PUSH AX MOV CL,SETDMA MOV DX,80H CALL SYSTEM RET L BADCOM: MOV DX,BAD MOV DL,AL MOV CL,OUTCH CALL SYSTEM POP SI POP CX LOOP OUTCNT RET RENAME: MOV CL,RENAM MOV DX,FCB JMP 5 L FILLBUF ;Fill 11 bytes with "?" HASNAME: MOV DX,LINBUF+2+1 MOV CL,SETDMA CALL SYSTEM MOV CL,SRCHFRST MOV DX,FCB E all files MOV CL,DSKRESET JMP 5 COPY: MOV SI,FCB+10H MOV DI,DSTFCB MOVB CMP B,[SI]," " ;Has file name? JNZ HAS PARSENAM: CALL NEXTCHR JZ ISDELIM CMP AL,13 JNZ PARSENAM DEC SI ISDELIM: CALL FILEDRV STOB MOV CX,11 CALL COR CMP AL,"y" JZ DOCLEAR RET DOCLEAR: MOV DL,[FCB] OR DL,DL JZ CLRDSK DEC DL MOV CL,SELDRV CALL SYSTEM CLRDSKNAM MOV CL,PRINTBUF CALL SYSTEM JMP COMMAND NEXTCHR: ;Convert lower case input to upper case LODB CMP AL,"a"-1 J ERASE: MOV CL,DELETE MOV DX,FCB JMP 5 CREATE: MOV CL,MAKE MOV DX,FCB JMP 5 TYPE: MOV DX,TPA MOV CL,SETDMAACHFILE: CALL SYSTEM INC AL ;FF = file not found JZ RET MOV SI,LINBUF+2+1 MOV CX,8 CALL OUTCNT ;Print 8 chars (namDSTNAM MOV SI,FCB+1 HASDSTNAM: MOVB MOV CX,7 REP MOVW MOV DX,FCB MOV AH,OPEN INT 33 OR AL,AL JNZ NOSRC MOPYNAM ADD DI,CX CMP CX,3 JB RET SUB DI,3 CMP AL,"." JNZ NOMATCH MOV CX,3 COPYNAM: CALL NEXTCHR JZ NOMATCH C: MOV CL,GETFAT CALL SYSTEM MOV CX,DX INC DX SHR DX ADD CX,DX MOV AX,DS MOV ES,AX MOV DI,BX MOV AX,0FFFFH B DELIM CMP AL,"z" JA DELIM SUB AL,20H ;Lower-case changed to upper-case DELIM: CMP AL," " JZ RET CMP AL,"=" JZ CALL SYSTEM MOV DX,FCB MOV AH,OPEN INT 33 OR AL,AL JNZ RET ;Not found MOV [FCB+RR],0 MOV CX,512 MOV AH,RDBLKV DX,DSTFCB MOV AH,DELETE INT 33 MOV AH,MAKE INT 33 MOV DX,TPA MOV AH,SETDMA INT 33 MOV [FCB+RR],0 MOV [DSTFCBco controllers. ; Select disk controller here TARBELL:EQU 0 CROMEMCO:EQU 1 ; For either disk controller, a custom drive 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 DX 11,"?" DB 0 SPECDRV:DS 1 NUMREC: DS 2 IDLEN: DS 1 ID: DS 8 COM: DB "COM" DSTFCB: DS 36 LINBUF: DB 80H,1,13 D1 READCOM:EQU 88H WRITECOM:EQU 0A8H ENDIF IF TARBELL DONEBIT:EQU 80H DISK: EQU 78H ENDIF IF CROMEMCO DONEBIT:EQ+RR],0 CPYBLK: MOV DX,FCB MOV CX,[NUMREC] MOV AH,RDBLK INT 33 JCXZ CPYDONE MOV DX,DSTFCB MOV AH,WRBLK INT 33 table may be defined CUSTOM: EQU 0 ; If Tarbell disk controller, select one-sided or two-sided drives ; and single or doubl,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 COMERS 80H FILIFO: DB 8," " DB 0 DB 12," ",4,0 DB 12," ",8,0 DB 0 COMTAB: DB 4,"DIR" DW DIR DB 7,"RENAME" DW U 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 OR AL,AL JZ CPYBLK MOV DX,NOSPCE MOV AH,PRINTBUF INT 33 CPYDONE: MOV DX,DSTFCB MOV AH,CLOSE INT 33 RET NOSRC: e density controller DOUB1SIDE:EQU 0 DOUB2SIDE:EQU 0 SNGL1SIDE:EQU 0 ; If Cromemco disk controller, select drive configuraR 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 RENAME DB 6,"ERASE" DW ERASE DB 7,"CREATE" DW CREATE DB 5,"TYPE" DW TYPE DB 6,"CLEAR" DW CLEAR DB 5,"COPY" D DATA: EQU BASE+6 PSTAT: EQU BASE+0DH PDATA: EQU BASE+0CH JMP INIT JMP STATUS JMP INP JMP OUTP JMP PRINT JMP AUX MOV DX,NOTFND MOV AH,PRINTBUF INT 33 RET DS 40 STACK: BADNAM: DB "Bad command or file name" CRLF: DB 13,10,"$" tion SMALLCRO:EQU 0 ;3 small drives COMBCRO:EQU 1 ;2 large drives and 1 small one LARGECRO:EQU 0 ;4 large drives WD1791; 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 STALLW COPY DB 0 TPA: 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 ERAMES: DB "Erase all files (Y/N)? $" NOTFND: DB "Source file not found$" NOSPCE: DB "Insufficient disk space$" FCBFIL: DB: EQU DOUB1SIDE+DOUB2SIDE WD1771: EQU CROMEMCO+SNGL1SIDE IF WD1791 READCOM:EQU 80H WRITECOM:EQU 0A0H ENDIF IF WD177 BADCOM: DB 13,10,"Bad or missing Command Interpreter",13,10,"$" FCB: DB 1,"COMMAND COM" DS 24 STATUS: IN STAT AND ent into track table ADD BX,TRKTAB ;BX now points to track counter for this drive MOV DI,BX MOV AL,DL SEG CS XCHG AL,[BX,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 RSI,128 LOOP WRTLP OR AL,AL RET L ERROR: SEG CS MOV B,[DI],-1 RET L SEEK: ; Inputs: ; AL = Drive number ; P: ENDIF CMP DH,26 ;Check for overflow onto next track JBE PUTSEC STEP: INC DL MOV DH,1 MOV AL,58H ;Step in witAL,DAV RET L AUXIN: INP: IN STAT AND AL,DAV JZ INP IN DATA AND AL,7FH RET L AUXOUT: OUTP: PUSH AX OUTLPDI] ;Xchange current track with desired track OUT DISK+1 ;Inform controller chip of current track CMP AL,DL JZ ONTRK M ;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,DONBX = Disk transfer address in DS ; CX = Number of sectors to transfer ; DX = Logical record number of transfer ; Function: ;h update, no verify CALL DCOM SEG CS INC B,[DI] ;Update track counter PUTSEC: MOV AL,DH OUT DISK+2 MOV CX,80H : IN STAT AND AL,TBMT JZ OUTLP POP AX OUT DATA RET L PRINT: PUSH AX PRINLP: IN PSTAT AND AL,TBMT JZ PRINOV BH,3 ;Seek retry count CMP AL,-1 ;Head position known? JNZ NOHOME ;If not, home head TRYSK: CALL HOME NOHOME: MOST 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 RD Seeks to proper track. ; Outputs: ; AH = Drive select byte ; DL = Track number ; DH = Sector number ; SI = Disk transfer aIF TARBELL IN DISK ;Get head load bit ENDIF IF CROMEMCO IN DISK+4 ;Get head load bit XCHG AL,AH OUT DISK+4 ;TurLP POP AX OUT PDATA RET L READ: CALL SEEK RDLP: PUSH CX CALL READSECT POP CX JC ERROR INC DH ADD SI,128 V AL,DL OUT DISK+3 MOV AL,1CH CALL MOVHEAD AND AL,98H JZ ONTRK DEC BH JNZ TRYSK STC ONTRK: RET SETUP: te 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 Rddress 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 LOOP RDLP OR AL,AL RETL: RET L WRITE: CALL SEEK WRTLP: PUSH CX CALL WRITESECT POP CX JC ERROR INC DH ADD IF CROMEMCO TEST AH,10H ;Check for small disk JNZ CHKSTP CMP DH,18 ;Only 18 sectors/track on small ones JA STEP CHKSTET MOV BL,10 WRTAGN: OR AL,WRITECOM OUT DISK PUSH SI WRLOOP: IN DISK+4 TEST AL,DONEBIT IF TARBELL JZ WRDONEDW 330 IF DOUB1SIDE DRVTAB: DB 0,10H,20H,30H TRKPT: DB 0,1,2,3 TRKTAB: DB -1,-1,-1,-1 ENDIF IF DOUB2SIDE DRVTAB: D 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 DK MOV AL,50 DELAY: DEC AL JNZ DELAY ;Delay 100 microseconds GETSTAT: IN DISK+4 TEST AL,DONEBIT IF TARBELL JNZ 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 LARG ENDIF IF CROMEMCO JNZ WRDONE ENDIF LODB OUT DISK+3 LOOP WRLOOP WRDONE: POP SI CALL GETSTAT AND AL,09CHB 0,40H,10H,50H TRKPT: DB 0,0,1,1 TRKTAB: DB -1,-1 ENDIF IF SNGL1SIDE DRVTAB: DB 0F2H,0E2H,0D2H,0C0H TRKPT: DB 0,1,2,3WAIT 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 21 GETSTAT ENDIF IF CROMEMCO JZ GETSTAT ENDIF IN DISK RET IF CROMEMCO RESTORE: MOV AL,0C4H ;READ ADDRESS cECRO ; 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 dr JZ RET MOV AL,0 DEC BL JNZ WRTAGN STC RET HOME: IF CROMEMCO TEST AH,10H ;Check 8" (PerSci) bit JNZ RESTOR TRKTAB: DB -1,-1,-1,-1 ENDIF IF TARBELL INITTAB:DB 4 ;Number of drives DW LDRIVE DW FAT0 DW LDRIVE DW FAT1 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 ommand to keep head loaded OUT DISK MOV AL,77H OUT 4 CHKRES: IN 4 AND AL,40H JZ RESDONE IN DISK+4 TEST AL,DONEBives DW LDRIVE DW FAT0 DW LDRIVE DW FAT1 DW LDRIVE DW FAT2 DW LDRIVE DW FAT3 ORG 0 FAT0: DS LFAT FAT1: DS 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 D 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 TRIT 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,24EC BL JNZ TRYHOM RET MOVHEAD: IF CROMEMCO TEST AH,10H ;Check 8" (PerSci) bit JNZ FASTSK ENDIF DCOM: OUT DISmco drive select byte is derived as follows: ; Bit 7 = 0 ; Bit 6 = X (unassigned) ; Bit 5 = 1 (motor on) ; Bit 4 = 0 for 5",KPT: DB 0,1 TRKTAB: DB -1,-1 INITTAB:DB 2 DW LDRIVE DW FAT0 DW LDRIVE DW FAT1 ORG 0 FAT0: DS LFAT FAT1: DS LFAIG: MOV DX,TOBIG JMP ERROR NOTEOF: MOV DX,NOEOF JMP ERROR SETUP: MOV DX,START MOV AH,SETDMA INT 33 MOV CX,[6] NOTBAK ;Open input file MOV AH,OPEN MOV DX,FCB INT 33 MOV [HAVEOF],AL OR AL,AL JZ HAVFIL MOV DX,NEWFIL MOV AH, MOV DX,BADCOM MOV AH,PRINTBUF INT 33 JP COMMAND GETNUM: CALL SKIP CMP AL,"." JZ CURLIN CMP AL,"#" JZ MAXLIV DX,COMBUF MOV AH,INBUF INT 33 MOV AL,10 CALL OUT MOV [PARAM2],0 MOV B,[QFLG],0 MOV SI,2+COMBUF CALL GETNUM MT ENDIF  SUB CX,80H MOV [LAST],CX MOV DI,START-1 TEST B,[HAVEOF],-1 JNZ SAVEND CALL NUMRECS MOV [FCB+RR],0 MOV DX,FCB MPRINTBUF INT 33 HAVFIL: MOV SI,FCB MOV DI,FCB2 MOV CX,9 REP MOVB MOV SI,BAK MOVW MOVB MOV AH,DELFIL MOV DN MOV DX,0 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 DXFCB: EQU 5CH RENAM: EQU 23 OPEN: EQU 15 CLOSE: EQU 16 MAKE: EQU 22 DELFIL: EQU 19 RDBLK: EQU 39 WRBLK: EQU 40 SETDMA: EQOV [PARAM1],DX CALL SKIP1 CMP AL,"," JNZ CHKNXT INC SI CHKNXT: DEC SI CALL GETNUM MOV [PARAM2],DX CALL SKIP1 OV AH,RDBLK INT 33 CMP AL,2 JZ TOOBIG JCXZ SAVEND ROR CX XCHG CL,CH ADD DI,CX ;Point to last byte DOWN MOV ALX,FCB2 INT 33 MOV AL,"$" MOV DI,FCB2+9 STOB STOB STOB MOV AH,DELFIL INT 33 ;Create .$$$ file to make sure dire CBW ADD DX,AX LODB JP NUMLP CURLIN: MOV DX,[CURRENT] LODB RET MAXLIN: MOV DX,-1 LODB RET COMTAB: DU 26 PRINTBUF:EQU 9 OUTCH: EQU 2 INBUF: EQU 10 RR: EQU 33 PROMPT: EQU "*" ORG 100H PUT 100H MOV SP,STACK MOV CMP AL,"?" JNZ DISPATCH MOV [QFLG],AL CALL SKIP DISPATCH: AND AL,5FH MOV DI,COMTAB MOV CX,NUMCOM REPNE SCAB J,1AH REPNE SCAB JNZ NOTEOF REPE SCAB INC DI SAVEND: CLD INC DI MOV B,[DI],1AH MOV [ENDTXT],DI MOV B,[COMBctory has room MOV AH,MAKE INT 33 OR AL,AL JZ SETUP MOV DX,NODIR JMP ERROR NOTBAK: MOV DX,NOBAK JMP ERROR TOOBB "SFDLIE",13 NUMCOM: EQU $-COMTAB TABLE: DW NOCOM ;No command--edit line DW ENDED DW INSERT DW LIST DW DELETE DX,BREAK MOV AX,2523H INT 33 MOV SI,BAK MOV DI,FCB+9 MOV CX,3 ;File must not have .BAK extension REPE CMPB JZ NZ COMERR MOV BX,CX SHL BX CALL [BX+TABLE] JMP COMMAND SKIP: LODB SKIP1: CMP AL," " JZ SKIP RET COMERR: UF],128 MOV B,[EDITBUF],255 MOV [POINTER],START MOV [CURRENT],1 COMMAND: MOV SP,STACK MOV AL,PROMPT CALL OUT MO DW COMERR DW COMERR FINDLIN: ; Inputs ; BX = Line number to be located in buffer (0 means last line) ; Outputs: ; DXMOV DI,1 DISPLAY: ; Inputs: ; BX = Line number ; SI = Pointer to text buffer ; DI = No. of lines ; Function: ; OuputsDC DL,DL LOOP CONV MOV BL,"0"-" " XCHG AX,DX CALL LDIG MOV AL,DH CALL DIGITS MOV AL,DL DIGITS: MOV DH,AL SHR SI,2+EDITBUF MOV DI,[POINTER] REPLACE: ; Inputs: ; CX = Length of new text ; DX = Length of original text ; SI = Poinnal in 8-character ; format, suppressing leading zeros. ; AX, CX, DX destroyed. No other registers affected. PUSH BX MOVRENT] INC BX ;Default is current line plus one HAVLIN: CALL FINDLIN MOV SI,DI MOV [CURRENT],DX MOV [POINTER],SI JNZ = Actual line found ; DI = Pointer to start of line DX ; Zero set if BX = DX ; AL,CX destroyed. No other registers affected. specified no. of line to terminal, each ; with leading line number. ; Outputs: ; BX = Last line output. ; All registers desAL SHR AL SHR AL SHR AL CALL LDIG MOV AL,DH LDIG: AND AL,0FH JZ ZERDIG MOV BL,0 ZERDIG: ADD AL,"0" SUB AL,ter to new text ; DI = Pointer to old text in buffer ; Function: ; New text replaces old text in buffer and buffer ; size is AL," " CALL OUT CALL CONV10 MOV AL,":" CALL OUT MOV AL," " CALL OUT POP BX RET CONV10: ;Inputs: ; BX = RET CMP SI,[ENDTXT] JZ RET MOV DI,2+EDITBUF MOV CX,254 MOV DL,-1 LOADLP: LODB STOB INC DL CMP AL,13 LOOPNZ MOV DX,[CURRENT] MOV DI,[POINTER] CMP BX,DX JZ RET JA FINDIT MOV DX,1 MOV DI,START CMP BX,DX JZ RET FINDITtroyed. MOV CX,[ENDTXT] SUB CX,SI JZ RET MOV BP,[CURRENT] DISPLN: PUSH CX CALL SHOWNUM POP CX OUTLN: LODB BL JMP OUT LIST: MOV BX,[PARAM1] OR BX,BX JNZ CHKP2 MOV BX,[CURRENT] SUB BX,10 JA CHKP2 MOV BX,1 CHKP2: adjusted. CX or DX may be zero. ; CX, SI, DI all destroyed. No other registers affected. CMP CX,DX JZ COPYIN PUSH SI Binary number to be displayed ; Function: ; Ouputs binary number. Five digits with leading ; zero suppression. Zero prints 5 LOADLP MOV [EDITBUF+1],DL MOV [OLDLEN],DL MOV SI,[POINTER] CALL DISPONE CALL SHOWNUM MOV AH,INBUF ;Get input buffer: MOV CX,[ENDTXT] SUB CX,DI MOV AL,10 OR AL,AL ;Clear zero flag FINLIN: JCXZ RET REPNE SCAB INC DX CMP BX,DXCALL OUT CMP AL,10 LOOPNZ OUTLN JCXZ RET DEC DI JZ RET CMP BX,BP LAHF INC BX SAHF JZ OUTLF CMP BX,BP JNZCALL FINDLIN JNZ RET MOV SI,DI MOV DI,[PARAM2] INC DI SUB DI,BX JA DISPLAY MOV DI,21 JP DISPLAY DISPONE: PUSH DI PUSH CX MOV SI,DI ADD SI,DX ADD DI,CX MOV AX,[ENDTXT] SUB AX,DX ADD AX,CX CMP AX,[LAST] JAE MEMERR blanks. XOR AX,AX MOV DL,AL MOV CX,16 CONV: SHL BX ADC AL,AL DAA XCHG AL,AH ADC AL,AL DAA XCHG AL,AH A MOV DX,EDITBUF INT 33 MOV AL,10 CALL OUT MOV CL,[EDITBUF+1] MOV CH,0 JCXZ RET MOV DL,[OLDLEN] MOV DH,0 MOV JNZ FINLIN RET SHOWNUM: ; Inputs: ; BX = Line number to be displayed ; Function: ; Displays line number on termi DISPLN OUTLF: MOV AL,10 CALL OUT JP DISPLN RET: RET NOCOM: MOV BX,[PARAM1] OR BX,BX JNZ HAVLIN MOV BX,[CURXCHG AX,[ENDTXT] MOV CX,AX SUB CX,SI CMP SI,DI JA DOMOV ADD SI,CX ADD DI,CX STD DOMOV: INC CX REP MOVB SI,BP INC SI MOV CX,[LAST] SUB CX,BP REP MOVB DEC DI MOV [ENDTXT],DI RET ENDED: ;Write text out to .$$$ fileext marker MOV SI,CX SUB CX,DI ;Calculate number of bytes to copy INC CX MOV DI,[LAST] DOWN REP MOVB XCHG SI,D$" BADCOM: DB "Entry error",13,10,"$" NEWFIL: DB "New file",13,10,"$" FCB2: DS 36 PARAM1: DS 2 PARAM2: DS 2 QFLG: DS 1 HAr ; RETURN (0DH) is found. Termination char not moved. ; Outputs: ; AL = Termination character ; CX = No of characters movedKFUL ERROR: MOV AH,PRINTBUF INT 33 JMP 0 NUMRECS: SUB CX,START AND CL,80H ROL CX XCHG CL,CH RET OUT: PUCLD POP CX POP DI POP SI COPYIN: REP MOVB RET DELETE: MOV BX,[PARAM1] OR BX,BX JNZ DELFIN1 MOV BX,[CURRE MOV DI,[ENDTXT] MOV CX,128 MOV AL,1AH REP STOB MOV CX,[ENDTXT] CALL NUMRECS INC CX MOV [FCB2+RR],0 MOV DX,FI UP INC DI MOV BP,SI MOV BX,DX INLP: CALL SHOWNUM MOV DX,EDITBUF MOV AH,INBUF INT 33 MOV AL,10 CALL OUT VEOF: DS 1 OLDLEN: DS 1 CURRENT:DS 2 POINTER:DS 2 LAST: DS 2 ENDTXT: DS 2 COMBUF: DS 2+128 EDITBUF:DS 2+255 DS 40 ALI. ; SI points one past termination character ; DI points to next free location XOR CX,CX GETIT: LODB CMP AL,1AH JSH DX XCHG AX,DX MOV AH,OUTCH INT 33 XCHG AX,DX POP DX RET BREAK: IRET BAK: DB "BAK" NOBAK: DB "Cannot edNT] DELFIN1: CALL FINDLIN JNZ RET MOV [CURRENT],BX MOV [POINTER],DI PUSH DI MOV BX,[PARAM2] OR BX,BX JNZ DELFINCB2 MOV AH,WRBLK INT 33 OR AL,AL JNZ WRTERR ;Close .$$$ file MOV AH,CLOSE INT 33 MOV SI,FCB LEA DI,[SI+16] MOMOV SI,EDITBUF+2 CMP B,[SI],1AH JZ ENDINS MOV CL,[SI-1] MOV CH,0 MOV DX,SI ADD DX,CX INC DX CMP DX,BP ;Will it fGN STACK: START: Z RET CMP AL,0DH JZ RET STOB INC CX JP GETIT MEMERR: MOV DX,MEMFUL MOV AH,PRINTBUF INT 33 JMP COMMAND it .BAK file--rename file$" NODIR: DB "No room in directory for file$" TOBIG: DB "File too big to fit into memory$" NOEOF: DB2 MOV BX,DX DELFIN2: INC BX CALL FINDLIN MOV DX,DI POP DI SUB DX,DI XOR CX,CX JP REPLACE GETTEXT: ; InpV DX,SI MOV CX,9 REP MOVB MOV SI,BAK MOVW MOVB ;Rename original file .BAK MOV AH,RENAM INT 33 MOV SI,FCB MOit? JNC MEMERR REP MOVB MOVB MOV AL,10 STOB INC BX JP INLP ENDINS: MOV [POINTER],DI MOV [CURRENT],BX MOV INSERT: MOV BX,[PARAM1] OR BX,BX JNZ INS MOV BX,[CURRENT] INC BX INS: CALL FINDLIN MOV CX,[ENDTXT] ;Get End-of-t "No end-of-file mark found in file$" DSKFUL: DB "Disk full--file write not completed$" MEMFUL: DB 13,10,"Memory full",13,10,"uts: ; SI points into command line buffer ; DI points to result buffer ; Function: ; Moves [SI] to [DI] until ctrl-Z (1AH) oV DI,FCB2+16 MOV CX,6 REP MOVW ;Rename .$$$ file to original name MOV DX,FCB2 INT 33 JMP 0 WRTERR: MOV DX,DS; HEX2BIN ; Converts Intel hex format files to straight binary FCB: EQU 5CH READ: EQU 20 SETDMA: EQU 26 OPEN: EQU 15 CLOV DX,FCB MOV AH,DELETE INT 33 MOV AH,CREATE INT 33 OR AL,AL JNZ NOROOM MOV W,[FCB+33],0 MOV DX,START MOV AH,SET 33 INT 32 ADERR: MOV DX,ADDR JMP ERROR GETCH: CMP SI,BUFFER+BUFSIZ JNZ NOREAD INT 33 OR AL,AL JNZ ERROR nt MOV CL,AL MOV CH,0 JCXZ DONE CALL GETBYT ;Get high byte of load address MOV BH,AL CALL GETBYT ;Get low byte of SE: EQU 16 CREATE: EQU 22 DELETE: EQU 19 BLKWRT: EQU 40 BUFFER: EQU 80H BUFSIZ: EQU 128 ORG 100H PUT 100H HEX2BIN:TDMA INT 33 MOV CX,BP SUB CX,START-7FH AND CL,80H JCXZ EXIT ROL CX XCHG CL,CH MOV AH,BLKWRT MOV DX,FCB INT 3 MOV SI,BUFFER NOREAD: LODB CMP AL,1AH JZ DONE RET GETBYT: CALL HEXDIG MOV BL,AL CALL HEXDIG SHL BL SHL Bload address MOV BL,AL ADD BX,START-100H ;Add in offset MOV DI,BX CALL GETBYT ;Throw away type byte READLN: CMP DI,[ MOV DI,FCB+9 CMP B,[DI]," " JNZ HAVEXT MOV SI,HEX MOVB MOVW HAVEXT: ;Get load offset (default is -100H) MOV AH,3 MOV AH,CLOSE INT 33 EXIT: INT 32 NOROOM: MOV DX,DIRFUL JMP QUIT HEX: DB "HEX" COM: DB "COM" ERRMES: DB "ErrL 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: 6] JAE ADERR CMP DI,START JB ADERR CALL GETBYT ;Get data byte STOB LOOP READLN CMP DI,BP ;Check if this is the lOPEN MOV DX,FCB INT 33 OR AL,AL JNZ NOFIL MOV B,[FCB+32],0 MOV AH,READ MOV BP,START MOV SI,BUFFER+BUFSIZ ;Flag ior in HEX file--conversion aborted$" NOFILE: DB "File not found$" ADDR: DB "Address out of range--conversion aborted$" DIRFULJC 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 MOEQU 25 PRINTBUF:EQU 9 SYSTEM: EQU 5 ORG 100H PUT 100H JMP RDCPM CPMTAB: DW IBM,IBM,IBM,IBM DW 0,0,0,0 DW 0,argest address so far JBE READHEX MOV BP,DI ;Save new largest JP READHEX NOFIL: MOV DX,NOFILE QUIT: MOV AH,9 INnput buffer as empty READHEX: CALL GETCH CMP AL,":" ;Search for : to start line JNZ READHEX CALL GETBYT ;Get byte cou: DB "Disk directory full$" START: 0,0,0 DW 0,0,0,0 INVSRC: MOV DX,BADSRC JMP EXIT NONAME: MOV DX,BADFN JMP EXIT RDCPM: MOV SP,100H CMP B,[F JBE RDALOC POP SI POP CX LOOP RDNXTAL INC B,[FCB+12] ;Increment extent counter JMP BEGDIR ;Scan from beginning of diADPARM: MOV DX,SAMDSK JMP EXIT RDENTRY: ADD SI,3 ;Point to AL array MOV CX,16 ;16 AL bytes per entry RDNXTAL: MSK: EQU 3 EXTMSK: EQU 4 DSISIZ: EQU 5 NUMENT: EQU 7 ALBMP0: EQU 9 ALBMP1: EQU 10 DIRCKS: EQU 11 RESTRK: EQU 13 XLTTBL: DSTDRV: DEC AX CMP AL,[DRIVE] JZ BADPARM MOV CL,DELETE MOV DX,DSTFCB CALL SYSTEM MOV CL,MAKE MOV DX,DSTFCB CALDX,DSKERR EXIT: MOV CL,PRINTBUF CALL SYSTEM JMP 0 ;Translation table made up of WORDs BIGTRK: MOV BX,CX SHL BX CB+1]," " JZ NONAME XOR AL,AL XCHG AL,[FCB] OR AL,AL JNZ HASDRV MOV CL,GETDRV CALL SYSTEM INC AX HASDRV: DErectory DONE: MOV CL,CLOSE MOV DX,DSTFCB CALL SYSTEM JMP 0 ;Read allocation block READSEC: XOR DX,DX MOV BX,[LODB MOV AH,0 TEST B,[BP+DSISIZ+1],0FFH JZ SMALDSK MOV AH,[SI] ;Big disk, use words instead INC SI DEC CX SMALDSEQU 15 ;Below is the definition for standard single-density 8" drives IBM: DW 26 ;Sectors per track DB 3 ;Block shift L SYSTEM MOV CL,SETDMA MOV DX,SECBUF CALL SYSTEM BEGDIR: XOR AX,AX MOV BX,[BP+NUMENT] READDIR: MOV DI,DIRBUF ADD BX,[BP+XLTTBL] ADD DX,[BX] JP READABS RDDONE: RET DSKERR: DB 13,10,"HARD DISK ERROR",13,10,"$" SAMDSK: DB 13,C AX MOV [DRIVE],AL CMP AL,15 JA INVSRC ;Invalid drive number CBW MOV BX,AX SHL BX MOV BP,[BX+CPMTAB] OR BP,BP BP+SPT] DIV AX,BX ADD AX,[BP+RESTRK] MOV CX,DX MUL AX,BX ;Tracks in sectors MOV DX,AX OR BH,BH ;Check for >255 secK: OR AX,AX JZ DONE PUSH CX MOV CH,0 PUSH SI MOV CL,[BP+BLKSFT] SHL AX,CL RDALOC: PUSH AX OR AL,CH PUSH C DB 7 ;Block mask DB 0 ;Extent mask DW 242 ;Disk size - 1 DW 63 ;Directory entries - 1 DB 0C0H ;Directory allocation bi PUSH AX PUSH BX CALL READSEC POP BX POP AX MOV SI,DIRBUF ENUMDIR: MOV DI,FCB MOV CX,13 REPE CMPB JZ RDEN10,"Source and destination drives must not be the same",13,10,"$" BADSRC: DB 13,10,"Bad source drive",13,10,"$" BADFN: DB 13,1 JZ INVSRC MOV SI,FCB2 MOV DI,DSTFCB MOVB CMP B,[FCB2+1]," " JNZ HASDST MOV SI,FCB+1 HASDST: MOV CX,11 REP tors per track JNZ BIGTRK ;Use words instead of bytes for xlat table MOV AX,CX MOV BX,[BP+XLTTBL] XLAT ADD DX,AX ;LoX MOV DI,SECBUF CALL READSEC MOV CL,SEQWRT MOV DX,DSTFCB CALL SYSTEM POP CX POP AX INC CH CMP CH,[BP+BLKMSK] tmap 0 DB 0 ;Directory allocation bitmap 1 DW 16 ;Directory check vector size DW 2 ;Tracks to skip DW MOD6 ;Modulo-6 secTRY ADD SI,CX ADD SI,19 ;Point to next entry DEC BX JS DONE CMP SI,DIRBUF+128 JB ENUMDIR INC AX JP READDIR B0,"Bad file name",13,10,"$" DRIVE: DS 1 DSTFCB: DS 32 DB 0 DIRBUF: DS 128 SECBUF: DS 128 SPT: EQU 0 BLKSFT: EQU 2 BLK MOVB ;Copy file name MOV AL,[DSTFCB] OR AL,AL JNZ DSTDRV MOV CL,GETDRV CALL SYSTEM ;Use default drive INC AX gical sector number READABS: MOV CX,1 MOV BX,DI MOV AL,[DRIVE] PUSH BP INT 37 POP AX POP BP JNC RDDONE MOV tor translate table 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 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 REA END: ;' NOCOM: CALL PUTCH PUTLIN: CMP AL,EOF JZ END CALL GETCH CALL PUTCH CMP AL,10 JNZ PUTLIN JP TRANLN END: MOAL 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 POPFV CL,DELETE CALL SYSTEM MOV DX,PUTFCB MOV CL,CREATE CALL SYSTEM INC AL MOV DX,NOROOM ABORTJ: JZ ABORT MOV DX,PU CPMTAB2: DW 0,0,0,0 DW 0,0,0,0 DW 0,0,0,0 DW 0,0,0,0 D: EQU 20 WRITE: EQU 21 PRNBUF: EQU 9 MOV SP,STACK MOV DX,HEADER MOV CL,9 CALL SYSTEM MOV BX,FCB+12 XOR AL,AL MOV CH,127 MOV AL,1AH FILL: CALL PUTCH DEC CH JNZ FILL MOV DX,PUTFCB MOV CL,CLOSE CALL SYSTEM MOV DX,ENDMES ABOR 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 TFCB MOV CL,OPEN CALL SYSTEM MOV BX,PUTBUF MOV [PUTPT],BX MOV BX,GETBUF+80H MOV [GETPT],BX TRANLN: XOR AL,AL MOV 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 MT: MOV CL,PRNBUF CALL SYSTEM JMP 0 DELIM: CALL GETCH DELCHK: CMP AL,EOL JZ DOLIN CMP AL,EOF JZ DOLIN CMP AL,DX,ERREAD QUIT: MOV AH,9 INT 33 INT 32 WRERR: MOV DX,ERWRIT JP QUIT BADDRV: MOV DX,DRVBAD JP QUIT SYSOV [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: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 MO; 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,90K: 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,'FCB: EQU 5CH ORG 100H PUT 100H JMP START SECS: DW 52 ;Patch for different configs START: MOV AL,[FCB] OR 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 MOH DAA ADC AL,40H DAA PUTCH: PUSH BX PUSH DX PUSH CX LAHF XCHG AH,AL PUSH AX XCHG AH,AL AND AL,7FH MOV BC AL LAHF XCHG AX,BP SAHF MOV B,[BX],'[' JP NEXCH NOTLEF: CMP AL,')' JNZ NOTRIT LAHF XCHG AX,BP SAHF DEC op 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 DX,GETBUF ; Set `DMA address'. MOV CL,SETDMA CALL SYSTEM MOV DX,FCB ; Read the next record from source file. MOV C MOV [BX],AL MOV CH,1 LODID: INC BX CALL GETCH CALL IDCHK JC RWCHK MOV [BX],AL INC CH JP LODID RWCHK: LAHF X,[PUTPT] MOV [BX],AL LAHF INC BX SAHF MOV [PUTPT],BX CMP BX,PUTBUF+80H JNZ POPRET MOV DX,PUTBUF MOV [PUTPT],DAL LAHF XCHG AX,BP SAHF MOV B,[BX],']' JP NEXCH NOTRIT: MOV [BX],AL CMP AL,'''' JZ EATQUO CALL IDCHK JNC GECALL 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 L,READ CALL SYSTEM OR AL,AL ; Entire record read OK? MOV AL,EOF ; Force end-of-file character in case JNZ TESEND ; t 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 NORX MOV CL,SETDMA CALL SYSTEM MOV DX,PUTFCB MOV CL,WRITE CALL SYSTEM OR AL,AL MOV DX,WRTERR JNZ ABORT POPRET: PTID NEXCH: INC BX CALL GETCH IDRET: CALL DELCHK JNZ OPCHAR CMP AL,' ' JZ OPCHAR RET EATQUO: INC BX CALL GETINC 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 Ohere is nothing in the record. MOV BX,GETBUF ; Reset buffer pointer. GETIT: MOV AL,[BX] ; Get next character from buffer. W 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 OP AX XCHG AH,AL SAHF NOTAF: POP CX POP DX POP BX RET ; ; Get character from source file. ; GETCH: PUSH BX CH MOV [BX],AL CMP AL,';' JZ L0000 CALL DELCHK L0000: CMP AL,'''' JNZ EATQUO JP NEXCH IDCHK: CMP AL,'0' JC AL 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 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 CPUSH DX PUSH CX MOV BX,[GETPT] ; Get buffer pointer. CMP BX,GETBUF+80H ; Past end-of-buffer? JNZ GETIT ; Jump if not. RET CMP AL,'9'+1 CMC JNC RET CMP AL,40H JC RET AND AL,5FH CMP AL,'A' JC RET CMP AL,'Z'+1 CMC RET GETID: 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 SCABMP AL,RDX RET ONEOP: CALL OUTSTR TRNOP1: MOV AL,9 TRAN1: MOV BX,OP1 JP PTRANS IN: MOV AL,[OP1] CMP AL,RAL rence? 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 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 AHF PUSH BX MOV CX,80 MOV AL,']' UP MOV DI,BX REPNZ SCAB MOV BX,DI LAHF DEC BX SAHF MOV B,[BX],0 POP B MOV BX,DI JNZ OPERR MOV AL,4 SUB AL,CL JZ RET DEC AL JZ OPERR MOV CL,AL DEC BX DEC BX OR B,[BX],080H MO XCHG DX,BX MOV BX,OP2 JZ GETPORT MOV BX,SAVEAX CALL OUTSTR CALL OUTSTR MOV BX,OP2 CALL GETPORT MOV BX,MOV0 C 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,[ ADD BX,DX RCR SI SAHF RCL SI JP LOOKOP OPERR: MOV BX,OPCODE CALL OUTSTR CALL TWOOPS MOV BX,OPCDER CALL OUTSTX NOBRAK: MOV AL,[BX] CMP AL,RGCL JNZ FIXPOR MOV BX,IO1 CALL OUTSTR XCHG DX,BX CALL OUTSTR MOV AL,RDX CALL TRV AL,[OPCODE] SUB AL,'A' JC OPERR ADD AL,AL MOV DL,AL MOV DH,0 MOV BX,OPTAB LAHF ADD BX,DX RCR SI SAHF RCLALL ONEOP MOV AL,',' CALL PUTCH MOV AL,RAL CALL TRNTOK IODONE: MOV BX,RESTAX JMP OUTSTR OUT: MOV AL,[OP2] XCHGALL 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,[OR 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 NTOK MOV BX,IO2 JMP OUTSTR GETOUT: CALL GETPORT JNC RET MOV BX,BADIO JMP OUTSTR FIXPOR: XCHG DX,BX CALL OUTSTR SI MOV DL,[BX] INC BX MOV DH,[BX] XCHG DX,BX MOV AL,9 CALL PUTCH LOOKOP: MOV AL,[BX] OR AL,AL JZ OPERR MOV DX,BX MOV BX,OP1 CMP AL,RAL JZ GETOUT MOV BX,SAVEAX CALL OUTSTR MOV BX,MOVAL CALL OUTSTR CALL TRNOP2 MOV BX,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 IN 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 B DX,OPCODE+1 MOV CH,CL LOOKLP: MOV SI,DX LODB CMP AL,[BX] JNZ NEXOP INC DX INC BX DEC CH JNZ LOOKLP MOV DX,RLFTB CALL OUTSTR MOV BX,OP1 CALL GETOUT JP IODONE GETPORT: MOV AL,[BX] CMP AL,'[' JNZ NOBRAK LAHF INC BX SC BX ADD AL,AL JNC OUTSTR RET NEWOP: MOV AL,13 CALL PUTCH MOV AL,10 CALL PUTCH MOV AL,9 RET LDDR: CALL OUTX] CMP AL,'9'+1 JNZ RET MOV B,[BX],'0' LAHF DEC BX SAHF JP NEXLAB EX: MOV AL,[OP1] CMP AL,RAX JZ OUTSTRJ1 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 ' CALL OUTSTR XCHG DX,BX MOV BX,OPCODE-1 CALL ONEOP XCHG DX,BX OUTSTRJ: JMP OUTSTR JUMP: MOV AL,[OP1] CMP AL,'['X JMP OUTSTR BFLAG: CALL PUTCH MOV AL,'B' CALL PUTCH MOV AL,',' RET GETBIT: MOV AL,[OP1+1] OR AL,AL STC STR MOV BX,BLMOVE JP OUTSTR CPDR: CALL OUTSTR MOV BX,CMPREP JP OUTSTR ADD: MOV AL,[OP1] CMP AL,RBX JZ DAD ARI MOV AL,[OP1+1] CMP AL,STP JZ XTHL MOV BX,XCHG CALL OUTSTR JMP TWOOPS XTHL: MOV BX,XTHL1 CALL OUTSTR CALL TRNOP[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 DIRECT MOV AL,[OP1+1] MOV [OP1],AL XOR AL,AL MOV [OP1+1],AL DIRECT: MOV AL,[OP2] OR AL,AL JZ ONEOPJ CALL 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 TH: CALL OUTSTR MOV AL,[OP2] OR AL,AL JZ $+5 JMP TWOOPS MOV AL,9 CALL PUTCH MOV AL,RAL CALL TRNTOK MOV AL,',2 MOV BX,XTHL2 OUTSTRJ1: JMP OUTSTR PSEUDO: CALL ONEOP MOV AL,[OP2] OR AL,AL JZ RET JMP TRNOP2 RET BITSET: 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 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, 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' JMP TRAN1 ACCUM: CALL OUTSTR MOV AL,9 CALL PUTCH MOV AL,RAL JMP TRNTOK ONEOPJ: JMP ONEOP DAD: MOV BX,DAD1 CMOV CL,0 JP SETRES RES: MOV CL,-1 SETRES: CALL OUTSTR PUSH BX MOV AL,[OP2] CMP AL,'[' MOV AL,9 JNZ L0004 CAL3 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 OUTSTCH 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,LALL OUTSTR CALL TWOOPS MOV BX,DAD2 JP OUTSTR INCDEC: MOV AL,[OP1] CMP AL,RCX+1 ;16-bit? JNC ONEOPJ MOV BX,LAHF L BFLAG L0004: CALL TRAN2 MOV AL,',' CALL PUTCH CALL GETBIT MOV BX,BITERR JNC L0005 CALL OUTSTR L0005: POP BR,OPCODE DM 'W' DW PSEUDO,OPCODE DM 'B' DW PSEUDO,OPCODE DM 'M' DW PSEUDO,OPCODE DM 'S' DW ONEOP,OPCODE DB 0 'AX',0,'XCHG',9,'AH,AL',0,'SAHF' DOWN: DM 'DOWN' UP: DB 'UP' BLMOVE: DB 0,'MOV',9,'SI,BX',0,'MOV',9,'DI,DX' DB 0,'REP',0,'MT' 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 XCODE 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 BADIO: DM 13,10,'; *** WARNING: Flags not same as Z80.' BITERR: DM 13,10,' *** ERROR: Cannot determine bit number.' SETBIT: EOPS: DM 'X' DW EX,EXAF DM 'I' DW OUTSTR,OPCODE DM 'XX' DW OUTSTR,EXX DM 'QU' DW ONEOP,OPCODE DM 'NDIF' DW OOVB',0,'MOV',9,'DX,DI' DM 0,'MOV',9,'BX,SI' CPIR: DB 'UP' CMPREP: DB 0,'MOV',9,'DI,BX',0,'REPNZ',0,'SCAB' DM 0,'MOV',9,'BXEOP,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 'OP,OPCODE DM 'USH' DW PUSH,OPCODE DB 0 QOPS: DB 0 ROPS: DM 'ET' DW RETURN,OPCODE DM 'LA' DW ACCUM,RCL DM 'RADM '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' XUTSTR,OPCODE DB 0 FOPS: DB 0 GOPS: DB 0 HOPS: DM 'ALT' DW OUTSTR,HLT DB 0 IOPS: DM 'NC' DW INCDEC,OPCODE D,DI' DAD1: DM 'LAHF',0,'ADD' DAD2: DM 0,'RCR',9,'SI',0,'SAHF',0,'RCL',9,'SI' LAHF: DM 'LAHF' DM 0,'SAHF' DJNZ: DB 'DEC',9,: 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' CMP' 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' THL1: 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',M 'N' DW IN,INB DM 'F' DW ONEOP,OPCODE DB 0 JOPS: DM 'R' DW JUMP,JR DM 'P' DW JUMP,JMP DB 0 KOPS: DB 0 LO'CH',13,10 DB '; *** WARNING: DJNZ does not affect flags - DEC does.',0 DM 'JNZ' WARNPA: DM 13,10,'; *** WARNING: Parity flTAX1: 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 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: DMPS: DM 'D' DW LD,MOV DM 'DIR' DW OUTSTR,UP DM 'DDR' DW LDDR,DOWN DB 0 MOPS: DB 0 NOPS: DM 'EG' DW ACCUM,OPag not always same as Z80.' IO1: DB 'MOV',9,'DI,DX',0,'MOV',9,'DL,CL',0 DM 'XOR',9,'DH,DH',13,10,9 IO2: DM 0,'MOV',9,'DX,DI'HCLCHALIXIY' RWTAB: DB 'ABCDEHLBDHSACNZNPMPPII' LENRW: EQU $-RWTAB DB 0,0,0,0,0,0,0,'CELPF',0,'C',0,'Z',0,0,'OEYX' HEADERU $ ORG 1 ;This is really just for equates without EQU RSI: DS 1 RDI: DS 1 ODDPAR: DS 1 EVEPAR: DS 1 DS 5 ;MINUS,PLUS,NO: DB 13,10,'Z80 to 8086 Translator version 2.0',13,10,'$' NOROOM: DB 13,10,'Insufficient directory space to create file',13,10T ZERO,ZERO,NOT CARRY CY: DS 1 RAX: DS 1 STP: DS 1 RBX: DS 1 RDX: DS 1 RCX: DS 1 RBL: DS 1 RBH: DS 1 RDL: DS 1 RDH: DS,'$' NOFILE: DB 13,10,'File not found',13,10,'$' ENDMES: DB 13,10,'Translation complete',13,10,'$' WRTERR: DB 13,10,'Out of d 1 RGCL: DS 1 RCH: DS 1 RAL: DS 1 RIX: DS 1 RIY: DS 1 isk space',13,10,'$' OPCDER: DM 13,10,'*** Opcode Error ' CRLF: DM 13,10 LABEL: DB 'L0000',0 DM ':',9 PUTPT: DS 2 GETPT: 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