From decwrl!elroy.jpl.nasa.gov!usc!cs.utexas.edu!rutgers!mit-eddie!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr Sat Mar 3 17:35:59 PST 1990 Article 837 of comp.sources.games: Path: decwrl!elroy.jpl.nasa.gov!usc!cs.utexas.edu!rutgers!mit-eddie!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr From: billr@saab.CNA.TEK.COM (Bill Randle) Newsgroups: comp.sources.games Subject: v09i027: NetHack3 - display oriented dungeons & dragons (Ver. 3.0), Patch7aa Message-ID: <5241@tekred.CNA.TEK.COM> Date: 24 Feb 90 01:09:25 GMT Sender: news@tekred.CNA.TEK.COM Lines: 2437 Approved: billr@saab.CNA.TEK.COM Submitted-by: Izchak Miller Posting-number: Volume 9, Issue 27 Archive-name: NetHack3/Patch7aa Patch-To: NetHack3: Volume 7, Issue 56-93 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'others/ovlmgr.asm' <<'END_OF_FILE' X; SCCS Id: @(#)ovlmgr.asm 3.0.624 90/02/18 X; Copyright (c) Pierre Martineau and Stephen Spackman, 1989, 1990. X; This product may be freely redistributed. See NetHack license for details. X X PAGE 60,132 X TITLE 'Overlay manager for use with Microsoft overlay linker' X SUBTTL 'Brought to you by Pierre Martineau and Stephen Spackman' X X; acknowledgements: - No thanks to Microsoft X; - alltrsidsctysti!!! X; - izchak and friends for impetus X; - us for brilliance X; - coffee for speed X; - others as necessary X X; assumptions: - all registers are preserved including flags X; - the stack is preserved X; - re-entrancy is not rEQUired X XDOSALLOC EQU 48h ; memory allocation XDOSFREE EQU 49h ; free allocated memory XDOSREALLOC EQU 4ah ; modify memory block XDOSREAD EQU 3fh ; read bytes from handle XDOSSEEK EQU 42h ; logical handle seek XDOSOPEN EQU 3dh ; open handle XDOSCLOSE EQU 3eh ; close handle XDOSGETVEC EQU 35h ; get interrupt vector XDOSSETVEC EQU 25h ; set interrupt vector XDOSEXEC EQU 4bh ; exec child process XDOS EQU 21h ; Dos interrupt # XPRINT EQU 09h ; print string XTERMINATE EQU 4ch ; terminate process XCR EQU 0dh XLF EQU 0ah XBELL EQU 07h XFAERIE EQU 0h ; Used for dummy segment allocation XPARSIZ EQU 10h ; this is the size of a paragraph - this better not change! X X; The following EXTRNs are supplied by the linker X XEXTRN $$OVLBASE:BYTE ; segment of OVERLAY_AREA XEXTRN $$MPGSNOVL:BYTE ; ^ to module table XEXTRN $$MPGSNBASE:WORD ; ^ to module segment fixups XEXTRN $$INTNO:BYTE ; interrupt number to be used XEXTRN $$COVL:WORD ; number of physical overlays XEXTRN $$CGSN:WORD ; number of modules XEXTRN $$MAIN:FAR ; ^ to function main() X XPUBLIC $$OVLINIT ; Our entry point X ; called by the c startup code X Xovlflgrec RECORD running:1=0,locked:1=0,loaded:1=0 ; overlay flags X X; This is a dirty hack. What we need is a virtual segment that will be built X; by the (our) loader in multiple copies, one per overlay. Unfortunately, this X; doesn't seem to be a sensible idea in the minds of the folks at Microsoft. X; Declaring this segment AT will ensure that it never appears in the exefile, X; and ASSUME is dumb enough to be fooled. X; X; The reason we want to do this is also not-to-be-tried-at-home: it turns out X; that we can code a faster interrupt handler if we map overlay numbers to X; segment values. Normally I would consider this unacceptable programming X; practise because it is 86-mode specific, but the *need* for this entire X; programme is 86-mode specific, anyway. X Xpspseg SEGMENT PARA AT FAERIE ; dummy segment for psp X ORG 2ch ; ^ to segment of environmemt in psp Xpspenv LABEL WORD Xpspseg ENDS X Xovltbl SEGMENT PARA AT FAERIE ; Dummy segment definition for overlay table X X; NOTE: This segment definition MUST be exactly 16 bytes long X Xovlflg ovlflgrec <0,0,0> ; overlay flags Xovltblpad1 DB ? ; go ahead, delete me! Xovlmemblk DW ? ; ^ to allocated memory block Xovllrudat DD ? ; misc lru data (pseudo time stamp) Xovlseg DW ? ; ovl segment physical add. Xovlfiloff DW ? ; ovl file offset in pages (512 bytes) Xovlsiz DW ? ; ovl size in paragraphs Xovltblpad DB PARSIZ - ($ - ovlflg) MOD PARSIZ DUP (?) ; pad to 16 bytes X XIF1 XIF ($ - ovlflg) GT PARSIZ X .ERR X %OUT This segment MUST be no more than 16 bytes, REALLY!!! XENDIF XENDIF X XOVLSEGSIZ EQU PARSIZ ; this had better be true!!! (16 bytes) X Xovltbl ENDS X XEXEHDR STRUC ; structure of an EXE header Xexesign DW 5a4dh ; signature Xexelstpgesiz DW ? ; last page size (512 byte pages) Xexesiz DW ? ; total pages (including partial last page) Xrelocitems DW ? ; number of relocation entries Xhdrparas DW ? ; number of paragraphs in the header Xminalloc DW ? ; minimum paragraph allocation Xmaxalloc DW ? ; maximum patagraph allocation Xexess DW ? ; initial stack segment Xexesp DW ? ; initial stack pointer Xexechksum DW ? ; checksum Xexeip DW ? ; initial instruction pointer Xexecs DW ? ; initial code segment Xreloctbloff DW ? ; offset from beginning of header to relocation table Xexeovlnum DW ? ; overlay number XEXEHDR ENDS X XMASK_used EQU 1 ; memory block flag X XMEMCTLBLK STRUC ; memory block structure Xmemblkflg DB ? ; flags Xmemblkpad1 DB ? ; go ahead, delete me! Xmemblknxt DW ? ; ^ to next block Xmemblkprv DW ? ; ^ to previous block Xmemblkovl DW ? ; ^ to overlay occupying this block Xmemblksiz DW ? ; size in paragraphs Xmemblkpad DB PARSIZ - memblkpad MOD PARSIZ DUP (?) ; pad to 16 bytes XMEMCTLBLK ENDS X XMEMCTLBLKSIZ EQU TYPE MEMCTLBLK / PARSIZ ; should equal 1 paragraph X X;------------------------------------------------------------------------------- X Xcode SEGMENT PUBLIC X X; NOTE: the following order is optimum for alignement purposes accross the X; entire INTEL 80x86 family of processors. X Xovltim DD ? ; pseudo-lru time variable Xfarcall DD ? ; internal trampoline. Xoldvec DD -1 ; saved interrupt vector Xoldint21 DD -1 ; saved int 21 vector Xovlexefilhdl DW -1 ; always-open file handle of our .EXE Xovltblbse DW -1 ; segment of first overlay descriptor Xovlcnt DW ? ; # overlays Xmodcnt DW ? ; # of modules Xovlrootcode DW ? ; logical segment of OVERLAY_AREA Xovldata DW ? ; logical segment of OVERLAY_END Xmemblk1st DW ? ; first memory block Xpspadd DW ? ; our psp address + 10h (for relocations) Xbxreg DW ? ; temp save area Xesreg DW ? ; temp save area Xmoduletbl DD 256 DUP (?) ; module lookup table (256 modules) Xcurovl DW OFFSET stkframe ; ^ into stack frame Xstkframe DW 64*3 DUP (?) ; internal stack (64 ovls deep) Xhdr EXEHDR <> ; EXE header work area Xintnum DB ? ; overlay interrupt number X Xnoroom DB CR,LF,'Not enough memory to run this program. Time to go to the store.',CR,LF,BELL,'$' Xnocore DB CR,LF,'Your dog eats all your remaining memory! You die.',CR,LF,BELL,'$' Xnofile DB CR,LF,'The Nymph stole your .EXE file! You die.',CR,LF,BELL,'$' Xexitmsg DB CR,LF,'$' X X;------------------------------------------------------------------------------- X X$$OVLINIT PROC FAR ; Init entry point X X ASSUME CS:code,DS:pspseg,ES:NOTHING X X push ax X push bx X push cx X push dx X push si X push di X push bp X push ds X push es ; save the world X mov ax,ds ; get our psp X add ax,10h X mov pspadd,ax ; save it X mov ds,pspenv ; get environment segment X mov si,-1 Xenvloop: ; search for end of environment X inc si X cmp WORD PTR [si],0 X jnz envloop X add si,4 ; point to EXE filename X mov al,0 ; access code X mov ah,DOSOPEN X mov dx,si X int DOS ; open EXE X jnc dontdie X mov al,5 X mov dx,OFFSET nofile X jmp putserr ; cry to the world! Xdontdie: X mov ovlexefilhdl,ax ; save handle X mov ax,SEG $$OVLBASE ; OVERLAY_AREA segment X mov ovlrootcode,ax X X; Now allocate memory X mov bx,0900h ; allocate memory for malloc() X mov ah,DOSALLOC X int DOS X jnc getmore X jmp buyram Xgetmore: X mov es,ax ; find largest free memory X mov ah,DOSALLOC X mov bx,0ffffh ; Everything X int DOS X mov ah,DOSALLOC ; allocate our own memory X int DOS X jnc gotitall X jmp buyram Xgotitall: X mov ovltblbse,ax ; overlay descriptor table begins at start of memory block X mov ax,SEG $$COVL ; segment of DGROUP X mov ds,ax X mov cx,$$CGSN ; number of modules X mov modcnt,cx ; save for later use X mov cx,$$COVL ; number of physical overlays X mov ovlcnt,cx ; save for later use X sub bx,cx ; enough mem for ovl tbl? X jnc memloop X jmp buyram Xmemloop: X push bx X mov ah,DOSFREE ; free first block for malloc() X int DOS X jnc cockadoodledoo X jmp buyram Xcockadoodledoo: X X ASSUME ES:ovltbl X X xor bp,bp X xor di,di X xor si,si Xfilsegtbllpp: ; initialise ovl table X call gethdr ; get an EXE header X mov ax,ovltblbse X add ax,hdr.exeovlnum X mov es,ax ; ^ to ovl table entry X xor ax,ax X mov WORD PTR ovllrudat,ax ; initialise ovl lru X mov WORD PTR ovllrudat+2,ax X mov ovlseg,ax ; initialise ovl segment X mov ovlflg,al ; initialise ovl flags X mov ax,hdr.exesiz X shl ax,1 X shl ax,1 X shl ax,1 X shl ax,1 X shl ax,1 ; * 32 X mov dx,hdr.exelstpgesiz X or dx,dx X jz emptypage X shr dx,1 X shr dx,1 X shr dx,1 X shr dx,1 ; / 16 X inc dx X sub ax,20h X add ax,dx Xemptypage: X mov ovlsiz,ax ; overlay size in paragraphs X sub ax,hdr.hdrparas ; actual size of code and relocation table X cmp hdr.exeovlnum,0 ; skip if ovl 0 (root code) X jz notlargest X cmp ax,di ; find largest ovl X jc notlargest X mov di,ax X mov si,ovlsiz Xnotlargest: X mov ovlfiloff,bp ; initialise ovl file offset X add bp,hdr.exesiz ; ^ to next overlay X mov dx,bp X mov cl,dh X mov dh,dl X xor ch,ch X xor dl,dl X shl dx,1 X rcl cx,1 ; cx:dx = bp * 512 X mov al,0 X mov ah,DOSSEEK ; seek to next ovl X int DOS X mov ax,ovlcnt X dec ax X cmp ax,hdr.exeovlnum ; all overlays done? X jz makmemblk X jmp filsegtbllpp ; Nope, go for more. Xmakmemblk: X push si ; contains largest ovl size in paragraphs X X ASSUME ES:nothing ; prepare first two memory blocks X ; OVERLAY_AREA and allocated memory block X mov ax,ovlrootcode ; OVERLAY_AREA segment X mov es,ax X mov si,ovltblbse X add si,ovlcnt ; end of ovl table X mov es:memblkflg,0 ; clear mem flags X mov es:memblknxt,si ; point to next X mov es:memblkprv,0 ; set previous to nothing X mov es:memblksiz,di ; di contains OVERLAY_AREA size in paragraphs X add di,ax X mov ovldata,di ; end of OVERLAY_END X mov es,si ; end of ovl tbl (first memory block in allocated memory) X mov es:memblkflg,0 ; clear mem flags X mov es:memblknxt,0 ; set next to nothing X mov es:memblkprv,ax ; point to previous X pop si X pop bx X mov es:memblksiz,bx ; allocated memory block size less ovl table X mov memblk1st,ax ; save pointer to first mem block X mov WORD PTR ovltim,0 ; initialise global lru time stamp X mov WORD PTR ovltim+2,0 X mov ax,OFFSET stkframe X mov curovl,ax ; initialise stack frame pointer X mov di,ax X mov WORD PTR cs:[di],-1 ; initialise stack frame X add di,6 X mov ax,ovltblbse X mov cs:[di],ax X mov curovl,di X mov es,ax X mov es:ovlflg,MASK running OR MASK locked OR MASK loaded ; set flags on ovl 0 X inc si ; largest ovl size + 1 paragraph X cmp bx,si ; enough memory to alloc largest? X jnc chgintvec Xbuyram: X mov al,5 X mov dx,OFFSET noroom ; free up some TSRs or something X jmp putserr Xchgintvec: X mov ax,SEG $$INTNO X mov ds,ax X mov ah,DOSGETVEC X mov al,$$INTNO ; get int number to use X mov intnum,al X int DOS ; get original vector X mov WORD PTR oldvec,bx ; save original vector X mov WORD PTR oldvec+2,es X X mov ah,DOSGETVEC X mov al,21h X int DOS ; get original vector X mov WORD PTR oldint21,bx ; save original vector X mov WORD PTR oldint21+2,es X X mov ah,DOSSETVEC X mov al,intnum X mov bx,cs X mov ds,bx X mov dx,OFFSET ovlmgr ; point to ovlmgr X int DOS ; set vector X X mov ah,DOSSETVEC X mov al,21h X mov bx,cs X mov ds,bx X mov dx,OFFSET int21 ; point to int21 X int DOS ; set vector X X mov cx,modcnt ; module count X mov ax,SEG $$MPGSNBASE X mov es,ax X mov ax,cs X mov ds,ax X X ASSUME DS:code X X mov bx,OFFSET $$MPGSNBASE ; ^ to linker provided overlay segment fixups X mov si,OFFSET $$MPGSNOVL ; ^ to linker provided module table X mov di,OFFSET moduletbl ; ^ to our module table Xmodloop: X mov al,es:[si] ; real physical ovl number X xor ah,ah X add ax,ovltblbse ; ovlctlseg address X mov [di],ax ; save in module table X mov ax,es:[bx] ; get seg fixup X sub ax,ovlrootcode ; adjust for relative reference X mov [di+2],ax ; save in module table X add di,4 X add bx,2 X inc si X loop modloop X X pop es X pop ds X pop bp X pop di X pop si X pop dx X pop cx X pop bx X pop ax ; restore the world X jmp $$MAIN ; And away we go! X X$$OVLINIT ENDP X X;------------------------------------------------------------------------------- X Xovlmgr PROC FAR ; This the it! X X ASSUME CS:code,DS:NOTHING,ES:NOTHING X X mov bxreg,bx ; preserve bx X mov esreg,es ; and es X pop bx ; retrieve caller ip X pop es ; " " cs X push ax X push si X mov ax,es:[bx+1] ; offset in ovl to call X mov WORD PTR farcall,ax ; into trampoline X xor ah,ah X mov al,es:[bx] ; module # to call X add bx,3 ; fix return address X mov si,curovl ; get stack frame pointer X mov cs:[si+2],es ; save return seg X mov cs:[si+4],bx ; and return offset X X mov bx,ax X shl bx,1 X shl bx,1 ; * 4 (2 words/entry in module tbl) X add bx,OFFSET moduletbl X mov es,cs:[bx] ; ovl tbl entry X mov ax,cs:[bx+2] ; segment fixup X mov cs:[si+6],es ; ovl entry into stack frame X add curovl,6 ; update stack X X ASSUME ES:ovltbl X X mov si,WORD PTR ovltim ; lru time stamp X inc si ; time passes! X mov WORD PTR ovltim,si ; update global clock X mov WORD PTR ovllrudat,si ; as well as ovl clock X mov si,WORD PTR ovltim+2 ; high order word X jz ininc ; dword increment Xcryupcdon: mov WORD PTR ovllrudat+2,si X test ovlflg,mask loaded ; ovl loaded? X jz inload ; load it then. Xovlloadedupc: X add ax,ovlseg ; add fixup and segment address X mov WORD PTR farcall+2,ax ; into trampoline X mov bx,bxreg ; retore all registers X mov es,esreg X pop si X pop ax X popf ; don't forget these! X call DWORD PTR farcall ; and GO X pushf ; preserve registers again! X mov esreg,es X mov bxreg,bx X mov bx,curovl ; stack frame pointer X mov es,cs:[bx-6] ; retrieve ovl tbl entry X push cs:[bx-4] ; set return address X push cs:[bx-2] X push cx X mov cx,WORD PTR ovltim ; do the lru thing again X inc cx X mov WORD PTR ovltim,cx X mov WORD PTR ovllrudat,cx X mov cx,WORD PTR ovltim+2 X jz outinc Xcrydncdon: mov WORD PTR ovllrudat+2,cx X test ovlflg,mask loaded ; ovl loaded? X jz outload ; better get it before someone notices Xjmpback: X sub curovl,6 ; adjust stack X mov bx,bxreg ; get registers back X mov es,esreg X pop cx X iret ; and GO back X Xininc: X inc si X mov WORD PTR ovltim+2,si ; update global clock X jmp cryupcdon X Xinload: X call loadoverlay ; self explanatory X jmp ovlloadedupc X Xoutinc: X inc cx X mov WORD PTR ovltim+2,cx X jmp crydncdon X Xoutload: X call loadoverlay X jmp jmpback X Xovlmgr ENDP X X;------------------------------------------------------------------------------- X Xloadoverlay PROC NEAR ; load overlay pointed to by es X X ASSUME CS:code,DS:NOTHING,ES:ovltbl X X push ax X push bx X push cx X push dx X push si X push di X push bp X push ds X push es ; just in case X call setrunning ; set the running flags X test ovlflg,MASK running ; was it already running? X jnz fxdadr ; Yup, it's a toughie X mov ax,ovlsiz ; How much? X call getpages ; never fail mem alloc, you bet. X jmp gleaner Xfxdadr: X call releasepages ; free memory where this ovl should be loaded Xgleaner: X mov ovlmemblk,ax ; memory block to use X add ax,MEMCTLBLKSIZ ; skip mem ctl blk X mov ds,ax X mov dx,ovlfiloff ; where in the file is it? X mov cl,dh X mov dh,dl X xor ch,ch X xor dl,dl X shl dx,1 X rcl cx,1 ; cx:dx = dx * 512 X mov ah,DOSSEEK ; lseek to position X mov al,0 X mov bx,ovlexefilhdl ; never closing handle X int DOS X jc burnhead ; oops! X xor dx,dx X mov cx,ovlsiz ; number of paragraphs to load X shl cx,1 X shl cx,1 X shl cx,1 X shl cx,1 ; * 16 = number of bytes X mov ah,DOSREAD ; prevent random DOS behaviour X int DOS X jc burnhead ; double oops! X call ovlrlc ; perform relocation normally done by DOS EXE loader X pop es ; retrieve ovl tbl entry X or ovlflg,MASK loaded ; because it is now X pop ds X pop bp X pop di X pop si X pop dx X pop cx X pop bx X pop ax X ret X Xburnhead: X mov al,5 X mov dx,OFFSET nofile X jmp putserr X Xloadoverlay ENDP X X;------------------------------------------------------------------------------- X Xovlrlc PROC NEAR ; ds:0 -> the overlay to relocate X X ASSUME CS:code,DS:NOTHING,ES:ovltbl X X mov cx,ds:relocitems ; roto-count X mov ax,ds X add ax,ds:hdrparas ; skip header X mov ovlseg,ax ; actual code starts here X mov di,ax X sub di,ovlrootcode ; segment fixup value X mov si,ds:reloctbloff ; ^ relocation tbl in header X jcxz relocdone ; not such a good idea, after all Xdorelocs: ; labels don't GET comments X lodsw ; offset into load module X mov bx,ax X lodsw ; segment in load module (zero reference) X add ax,pspadd ; now it is psp relative X add ax,di ; and now it is relative to the actual load address X mov es,ax X mov ax,es:[bx] ; pickup item to relocate X add ax,pspadd ; make it psp relative X cmp ax,ovlrootcode ; is it below the OVERLAY_AREA? X jc reloccomputed ; yup. it's relocated X cmp ax,ovldata ; is it above OVERLAY_AREA X jnc reloccomputed ; yup. it's relocated X add ax,di ; it's in OVERLAY_AREA, this one's ours. Xreloccomputed: X mov es:[bx],ax ; RAM it home!?! X loop dorelocs ; what goes around, comes around. Xrelocdone: ret X Xovlrlc ENDP X X;------------------------------------------------------------------------------- X Xgetvictim PROC NEAR ; select a victim to discard (and free up some memory) X X ASSUME CS:code,DS:ovltbl,ES:NOTHING X X push bx X push cx X push dx X push si X push di X push bp X push ds X mov ds,ovltblbse ; ^ ovl tbl X xor ax,ax ; will contain the low word of lru X mov dx,ax ; will contain the high word of lru X mov bp,ax ; will contain ovl tbl entry X mov bx,ax ; ovl tbl ptr X mov cx,ovlcnt Xfoon1: test ovlflg[bx],MASK loaded X jz skip1 X test ovlflg[bx],MASK locked X jnz skip1 X mov si,WORD PTR ovltim X mov di,WORD PTR ovltim+2 X sub si,WORD PTR ovllrudat[bx] X sbb di,WORD PTR ovllrudat[bx+2] X cmp dx,di X jc better1 X jnz skip1 X cmp ax,si X jnc skip1 Xbetter1: mov ax,si X mov dx,di X mov bp,bx Xskip1: add bx,OVLSEGSIZ X loop foon1 X or bp,bp ; were we more successful this time? X jnz gotvictim ; now we got one. Xnomoremem: X mov al,5 ; were really %$# now! X mov dx,OFFSET nocore X jmp putserr Xgotvictim: X shr bp,1 ; convert offset to segment X shr bp,1 X shr bp,1 X shr bp,1 X mov ax,ds X add ax,bp X pop ds X pop bp X pop di X pop si X pop dx X pop cx X pop bx X ret Xgetvictim ENDP X X;------------------------------------------------------------------------------- X Xsetrunning PROC NEAR ; set running flag on overlays still running X X ASSUME CS:code,DS:NOTHING,ES:ovltbl X X push es X mov es,ovltblbse X mov cx,ovlcnt X xor bx,bx Xjim: and ovlflg[bx],NOT MASK running ; start by clearing them all X add bx,OVLSEGSIZ X loop jim X X ; Now chain down the stack links, setting running flags X X mov bx,curovl X sub bx,6 X jmp jam Xjamloop: X mov ds,cs:[bx] X X ASSUME DS:ovltbl X X or ovlflg,MASK running X sub bx,6 Xjam: X cmp WORD PTR cs:[bx],-1 ; end of stack ? X jnz jamloop X pop es X ret X Xsetrunning ENDP X X;------------------------------------------------------------------------------- X Xint21 PROC FAR X X; free almost all overlay memory if app. tries to call the DOS exec function. X X cmp ah,DOSEXEC X jz freeall X cmp ah,TERMINATE X jz saybyebye Xnotours: X jmp cs:oldint21 Xsaybyebye: X pop ax ; clean up stack X pop ax X pop ax X mov al,0 ; return code 0 X mov dx,OFFSET exitmsg X jmp putserr Xfreeall: X or al,al ; is it load and exec? X jnz notours X push ax X push bx X push cx X push dx X push si X push di X push bp X push es X push ds ; preserve calling env. X X ASSUME CS:code,DS:NOTHING,ES:ovltbl X X mov ax,cs:memblk1st ; start de-allocating from first blk X jmp short lastblk Xunloadlp: X mov ds,ax X cmp ax,cs:ovltblbse ; in alloced area ? X jc nextmemblk X test ds:memblkflg,MASK_used ; mem blk used ? X jz nextmemblk X mov es,ds:memblkovl X and ovlflg,NOT MASK loaded ; flag overlay as unloaded Xnextmemblk: X mov ax,ds:memblknxt Xlastblk: X or ax,ax ; keep going till no more X jnz unloadlp X X mov ax,cs:ovltblbse X add ax,cs:ovlcnt X mov es,ax ; ^ to first mem blk in alloced mem X mov es:memblksiz,2 ; adjust size X mov es:memblknxt,0 ; no other blocks after this one X mov es:memblkflg,0 ; not used X X mov dx,WORD PTR cs:oldint21 X mov ds,WORD PTR cs:oldint21+2 X mov ah,DOSSETVEC ; put back DOS vector to avoid calling ourselves again! X mov al,21h X int DOS X X mov dx,WORD PTR cs:oldvec X mov ds,WORD PTR cs:oldvec+2 X mov ah,DOSSETVEC X mov al,intnum X int DOS X X mov es,cs:ovltblbse X mov bx,cs:ovlcnt X add bx,2 ; re-adjust alloced size X mov ah,DOSREALLOC X int DOS X mov bp,sp X push [bp+22] ; ensure returned flags are based on user's! X popf X pop ds X pop es X pop bp X pop di X pop si X pop dx X pop cx X pop bx X pop ax X X int DOS ; allow DOS to continue! X X push ax X push bx X push cx X push dx X push si X push di X push bp X push es X push ds ; preserve calling env. X mov bp,sp X pushf X pop [bp+22] ; fix return flags X X; re-allocate our memory after a DOS exec function X X call reallocmem X X mov ah,DOSGETVEC X mov al,21h X int DOS ; get original vector X mov WORD PTR cs:oldint21,bx ; save original vector X mov WORD PTR cs:oldint21+2,es X X mov ah,DOSSETVEC X mov al,21h X mov bx,cs X mov ds,bx X mov dx,OFFSET int21 ; point to int21 X int DOS ; set vector X X mov ah,DOSGETVEC X mov al,intnum X int DOS ; get original vector X mov WORD PTR cs:oldvec,bx ; save original vector X mov WORD PTR cs:oldvec+2,es X X mov ah,DOSSETVEC X mov al,intnum X mov bx,cs X mov ds,bx X mov dx,OFFSET ovlmgr ; point to ovlmgr X int DOS ; set vector X X pop ds X pop es X pop bp X pop di X pop si X pop dx X pop cx X pop bx X pop ax X iret X Xint21 ENDP X X;------------------------------------------------------------------------------- X Xreallocmem PROC NEAR X X; re-allocate our memory after a DOS exec function X X push es X mov ah,DOSREALLOC X mov es,cs:ovltblbse ; mem blk handle X mov bx,0ffffh ; find out how much there is X int DOS X mov ah,DOSREALLOC ; re-allocate our own memory X mov es,cs:ovltblbse X push bx ; contains largest available blk X int DOS X mov ax,cs:ovltblbse X add ax,cs:ovlcnt X mov es,ax ; ^ to first mem blk in alloced mem X pop ax X sub ax,cs:ovlcnt ; remove ovl tbl size X mov es:memblksiz,ax ; fix mem blk size X X pop es X ret X Xreallocmem ENDP X X;------------------------------------------------------------------------------- X Xreleasepages PROC NEAR ; Arg in es, result in ax X X; release any memory (and overlays) where this overlay should reside X X ASSUME ES:ovltbl X X mov bx,es:ovlmemblk ; start of memory to release Xdoitagain: X mov ax,memblk1st ; first memory blk X jmp dvart Xdvartloop: X mov ds,ax ; memory blk to check X cmp bx,ax ; does it start below the memory to release? X jnc dvartsmaller ; yup X mov dx,bx X add dx,es:ovlsiz X add dx,MEMCTLBLKSIZ ; end of memory to release X cmp ax,dx ; does it start above? X jnc dvartsilly ; yup X call killmem ; it's in the way. Zap it. X jmp chkmemblk Xdvartsmaller: X add ax,ds:memblksiz ; end of this memory blk X cmp bx,ax ; does it end below the memory to release? X jnc dvartsilly ; yup X call killmem ; Oh well, zap it too. Xchkmemblk: ; was that enough? X mov ax,ds ; recently freed memory blk X cmp bx,ax ; does it start in the memory to be released? X jc dvartsilly ; yup, wasn't enough X mov dx,bx X add dx,es:ovlsiz X add dx,MEMCTLBLKSIZ ; end of memory to be released X add ax,ds:memblksiz ; end of freed memory X cmp ax,dx ; does it end in the memory to be released? X jc dvartsilly ; yup, release more Xdvartgotblk: X mov ax,ds ; this is it! X mov cx,bx X sub cx,ax ; # of paragraphs between start of memory to release and mem blk X jz nosplit X call splitblkhigh ; split the block Xnosplit: X mov cx,es:ovlsiz X add cx,MEMCTLBLKSIZ ; paragraphs needed to load ovl X jmp splitblklow ; split remaining block Xdvartsilly: X mov ax,ds:memblknxt Xdvart: X or ax,ax ; enf of mem list? X jz dvartnocore X jmp dvartloop ; play it again Sam. Xdvartnocore: X mov al,5 ; super OOPS! X mov dx,OFFSET nocore X jmp putserr X Xreleasepages ENDP X X;------------------------------------------------------------------------------- X Xgetpages PROC NEAR ; get enough memory to load ovl X X mov cx,ax X add cx,MEMCTLBLKSIZ ; total paragraphs needed X call largestmem ; find largest free blk X cmp dx,cx ; large enough? X jnc gotdork ; yup. Xdorkkill: X call getvictim ; select a victim to release X call killovl ; kill the selected victim X cmp ds:memblksiz,cx ; was it enough? X jc dorkkill ; nope, select another one Xgotdork: X jmp splitblklow ; split the free blk X Xgetpages ENDP X X;------------------------------------------------------------------------------- X Xsplitblklow PROC NEAR X X; split a block of memory returning the lower one to be used. X X push es X or ds:memblkflg,MASK_used ; set low block used X mov ax,ds X add ax,cx X mov es,ax ; ^ to upper blk to be created X mov ax,ds:memblksiz X sub ax,cx X cmp ax,1 ; must be at least 1 para remaining to split X jc noodorksplit ; don't split X mov ds:memblksiz,cx ; fix blk sizes X mov es:memblksiz,ax X mov ax,ds:memblknxt ; fix pointers X mov es:memblknxt,ax X mov ds:memblknxt,es X mov es:memblkprv,ds X mov es:memblkflg,0 ; set upper to not used X push ds X mov ax,es:memblknxt X or ax,ax X jz domergelow X mov ds,ax ; fix blk after upper to point to upper X mov ds:memblkprv,es Xdomergelow: X mov ax,es X mov ds,ax X call mergemem ; merge remaining free memory X pop ds Xnoodorksplit: X pop es X mov ds:memblkovl,es ; fix ptr to ovl X mov ax,ds ; return lower blk segment X ret X Xsplitblklow ENDP X X;------------------------------------------------------------------------------- X Xsplitblkhigh PROC NEAR X X; split a block of memory returning the upper one to be used. X X push es X mov ax,ds X add ax,cx X mov es,ax ; ^ to upper blk to be created X mov ax,ds:memblksiz X sub ax,cx ; # of para remaining in upper blk X mov ds:memblksiz,cx ; fix blk sizes X mov es:memblksiz,ax X mov ax,ds:memblknxt ; fix blk pointers X mov es:memblknxt,ax X mov ds:memblknxt,es X mov es:memblkprv,ds X mov ds:memblkflg,0 ; set lower to not used X or es:memblkflg,MASK_used ; set upper to used X mov ax,es:memblknxt X or ax,ax X jz domergehigh X push ds ; fix blk after upper to point to upper X mov ds,ax X mov ds:memblkprv,es X pop ds Xdomergehigh: X call mergemem ; merge remaining free memory Xnodorksplit: X mov ax,es X mov ds,ax X pop es X mov ds:memblkovl,es ; fix ovl ptr X mov ax,ds ; return upper blk segment X ret X Xsplitblkhigh ENDP X X;------------------------------------------------------------------------------- X Xlargestmem PROC NEAR ; returns seg in ax, size in dx; clobbers bx,ds,es X ; retruns first block that's large enough if possible X X mov ax,memblk1st ; first mem blk X xor dx,dx ; largest size found X jmp gook Xgookloop: mov ds,ax X test ds:memblkflg,MASK_used ; is this blk used? X jnz gookme ; yup X cmp ds:memblksiz,cx ; is it large enough? X jc gookme ; nope X mov dx,ds:memblksiz ; got one! X ret Xgookme: X mov ax,ds:memblknxt Xgook: or ax,ax ; end of list? X jnz gookloop ; around and around X ret X Xlargestmem ENDP X X;------------------------------------------------------------------------------- X Xkillmem PROC NEAR X X test ds:memblkflg,MASK_used ; is it used? X jz memnotused ; don't kill ovl X push es X mov es,ds:memblkovl X and es:ovlflg,NOT MASK loaded ; zap ovl associated with this blk X pop es Xmemnotused: X jmp mergemem ; merge free memory X Xkillmem ENDP X X;------------------------------------------------------------------------------- X Xkillovl PROC NEAR ; preserves bx X X mov ds,ax X X ASSUME DS:ovltbl X X and ovlflg,NOT MASK loaded ; ovl no longer loaded X mov ax,ovlmemblk ; get mem blk X mov ds,ax X jmp mergemem ; merge free memory X Xkillovl ENDP X X;------------------------------------------------------------------------------- X Xmergemem PROC NEAR X X; merge physically adjacent free memory blocks. Preserves es. ds -> a free block. X X push es X and ds:memblkflg,NOT MASK_used ; set current free X mov ax,ds:memblkprv ; get previous blk X or ax,ax ; was there a previous blk? X jz gibber ; nope X mov es,ax X test es:memblkflg,MASK_used ; is the previous blk used? X jnz gibber ; yup X add ax,es:memblksiz ; end of previous blk X mov dx,ds X cmp dx,ax ; physically adjacent? X jnz gibber ; nope X mov ax,ds:memblksiz X add es:memblksiz,ax ; adjust size of new larger blk X mov ax,ds:memblknxt ; fix pointers X mov es:memblknxt,ax X or ax,ax X jz almostgibber X mov ds,ax ; fix pointer of next blk X mov ds:memblkprv,es Xalmostgibber: X mov ax,es X mov ds,ax ; new blk segment Xgibber: X mov ax,ds:memblknxt ; get next blk X or ax,ax ; was there a next blk? X jz killdone ; nope X mov es,ax X test es:memblkflg,MASK_used ; is the nxt blk used? X jnz killdone ; yup X mov ax,ds X add ax,ds:memblksiz ; end of this blk X mov dx,es X cmp ax,dx ; physically adjacent? X jnz killdone ; nope X mov ax,es:memblksiz X add ds:memblksiz,ax ; adjust size of new larger blk X mov ax,es:memblknxt ; fix pointers X mov ds:memblknxt,ax X or ax,ax X jz killdone X mov es,ax ; fix pointer of blk after nxt X mov es:memblkprv,ds Xkilldone: X and ds:memblkflg,NOT MASK_used ; make sure it's free X pop es X ret X Xmergemem ENDP X X;------------------------------------------------------------------------------- X Xgethdr PROC NEAR ; read EXE header from handle X X push cx X mov ax,cs X mov ds,ax X mov dx,OFFSET hdr ; a place to put it X mov bx,ovlexefilhdl ; the file handle X mov cx,TYPE EXEHDR ; header size in bytes X mov ah,DOSREAD X int DOS ; read from file X jc exegone ; oops X cmp ax,cx ; got correct number of bytes? X jnz exegone ; nope X pop cx X ret ; Wow, it worked! Xexegone: X mov al,5 ; You lose! X mov dx,OFFSET nofile X jmp putserr X Xgethdr ENDP X X;------------------------------------------------------------------------------- X Xputserr PROC NEAR X X; display error msg, close file, restore int vectors, free mem and return to DOS. X X push ax ; keep return code for later X mov ax,cs X mov ds,ax X mov ah,PRINT X int DOS ; display error msg X mov dx,WORD PTR oldvec ; get old vector X cmp dx,-1 ; was it ever replaced? X jz free21 ; nope X push ds X mov ds,WORD PTR oldvec+2 X mov ah,DOSSETVEC ; put it back then. X mov al,intnum X int DOS X pop ds Xfree21: X mov dx,WORD PTR oldint21 X cmp dx,-1 X jz freemem X push ds X mov ds,WORD PTR oldint21+2 X mov ah,DOSSETVEC ; put it back then. X mov al,21h X int DOS X pop ds Xfreemem: X mov ax,ovltblbse ; get memory blk segment X cmp ax,-1 ; was one ever allocated? X jz closefile ; nope X mov es,ax X mov ah,DOSFREE ; must free it. X int DOS Xclosefile: X mov bx,ovlexefilhdl ; get file handle X cmp bx,-1 ; was the file ever opened? X jz byebye ; nope X mov ah,DOSCLOSE ; close it X int DOS Xbyebye: X pop ax ; return code in al X mov ah,TERMINATE X int DOS ; terminate this process X Xputserr ENDP X Xcode ENDS X X END END_OF_FILE if test 30539 -ne `wc -c <'others/ovlmgr.asm'`; then echo shar: \"'others/ovlmgr.asm'\" unpacked with wrong size! fi # end of 'others/ovlmgr.asm' if test -f 'src/lev_lex.c' -a "${1}" != "-c" ; then echo shar: Renaming existing file \"'src/lev_lex.c'\" to \"'src/lev_lex.c.orig'\" mv -f 'src/lev_lex.c' 'src/lev_lex.c.orig' fi echo shar: Extracting \"'src/lev_lex.c'\" \(21018 characters\) sed "s/^X//" >'src/lev_lex.c' <<'END_OF_FILE' X# include "stdio.h" X# define U(x) x X# define NLSTATE yyprevious=YYNEWLINE X# define BEGIN yybgin = yysvec + 1 + X# define INITIAL 0 X# define YYLERR yysvec X# define YYSTATE (yyestate-yysvec-1) X# define YYOPTIM 1 X# define YYLMAX 200 X# define output(c) putc(c,yyout) X# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar) X# define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;} X# define yymore() (yymorfg=1) X# define ECHO fprintf(yyout, "%s",yytext) X# define REJECT { nstr = yyreject(); goto yyfussy;} Xint yyleng; extern char yytext[]; Xint yymorfg; Xextern char *yysptr, yysbuf[]; Xint yytchar; XFILE *yyin ={stdin}, *yyout ={stdout}; Xextern int yylineno; Xstruct yysvf { X struct yywork *yystoff; X struct yysvf *yyother; X int *yystops;}; Xstruct yysvf *yyestate; Xextern struct yysvf yysvec[], *yybgin; X/* SCCS Id: @(#)lev_lex.c 3.0 90/01/04 X/* Copyright (c) 1989 by Jean-Christophe Collet */ X/* NetHack may be freely redistributed. See license for details. */ X X#define LEV_LEX_C X X/* block some unused #defines to avoid overloading some cpp's */ X#define MONDATA_H /* comment this line for pre-compiled headers */ X#define MONFLAG_H /* comment this line for pre-compiled headers */ X X#include "hack.h" X#include "lev_comp.h" X#include "sp_lev.h" X X/* Most of these don't exist in flex, yywrap is macro and X * yyunput is properly declared in flex.skel. X */ X#ifndef FLEX_SCANNER Xint FDECL (yyback, (int *, int)); Xint NDECL (yylook); Xint NDECL (yyinput); Xint NDECL (yywrap); Xint NDECL (yylex); Xint FDECL (yyunput, (int)); Xint FDECL (yyoutput, (int)); X#endif X X#ifdef MSDOS X#undef exit X#endif X X/* this doesn't always get put in lev_comp.h X * (esp. when using older versions of bison) X */ X Xextern YYSTYPE yylval; X X#ifdef MACOS X#undef putchar X#undef putc X#undef printf X#undef Printf X#define Printf printf X# ifdef LSC X#define putc(c,stream) (fputc(c,stream)) X#define putchar(c) (fputc(c,stdout)) X# endif X#endif Xint line_number = 1; X X/* This is *** UGLY *** but I can't think a better way to do it X * I really need a huge buffer to scan maps... X */ X X#undef YYLMAX X#define YYLMAX 2048 X X# define MAPC 2 X# define YYNEWLINE 10 Xyylex(){ Xint nstr; extern int yyprevious; Xwhile((nstr = yylook()) >= 0) Xyyfussy: switch(nstr){ Xcase 0: Xif(yywrap()) return(0); break; Xcase 1: X{ line_number++; yymore(); } Xbreak; Xcase 2: X{ BEGIN 0; X line_number++; X yytext[yyleng-7] = 0; /* Discard \nENDMAP */ X yylval.map = (char *) alloc(strlen(yytext)+1); X strcpy(yylval.map, yytext); X return MAP_ID; X } Xbreak; Xcase 3: X { line_number++; } Xbreak; Xcase 4: X return MAZE_ID; Xbreak; Xcase 5: X return LEVEL_ID; Xbreak; Xcase 6: Xreturn GEOMETRY_ID; Xbreak; Xcase 7: X { BEGIN MAPC; line_number++; } Xbreak; Xcase 8: X return OBJECT_ID; Xbreak; Xcase 9: X return MONSTER_ID; Xbreak; Xcase 10: X return TRAP_ID; Xbreak; Xcase 11: X return DOOR_ID; Xbreak; Xcase 12: Xreturn DRAWBRIDGE_ID; Xbreak; Xcase 13: Xreturn MAZEWALK_ID; Xbreak; Xcase 14: X return REGION_ID; Xbreak; Xcase 15: Xreturn RANDOM_OBJECTS_ID; Xbreak; Xcase 16: Xreturn RANDOM_MONSTERS_ID; Xbreak; Xcase 17: Xreturn RANDOM_PLACES_ID; Xbreak; Xcase 18: X return ALTAR_ID; Xbreak; Xcase 19: X return LADDER_ID; Xbreak; Xcase 20: Xreturn NON_DIGGABLE_ID; Xbreak; Xcase 21: X return ROOM_ID; Xbreak; Xcase 22: X { yylval.i=D_ISOPEN; return DOOR_STATE; } Xbreak; Xcase 23: X { yylval.i=D_CLOSED; return DOOR_STATE; } Xbreak; Xcase 24: X { yylval.i=D_LOCKED; return DOOR_STATE; } Xbreak; Xcase 25: X { yylval.i=D_NODOOR; return DOOR_STATE; } Xbreak; Xcase 26: X { yylval.i=D_BROKEN; return DOOR_STATE; } Xbreak; Xcase 27: X { yylval.i=W_NORTH; return DIRECTION; } Xbreak; Xcase 28: X { yylval.i=W_EAST; return DIRECTION; } Xbreak; Xcase 29: X { yylval.i=W_SOUTH; return DIRECTION; } Xbreak; Xcase 30: X { yylval.i=W_WEST; return DIRECTION; } Xbreak; Xcase 31: X { yylval.i = -1; return RANDOM_TYPE; } Xbreak; Xcase 32: X return O_REGISTER; Xbreak; Xcase 33: X return M_REGISTER; Xbreak; Xcase 34: X return P_REGISTER; Xbreak; Xcase 35: X return A_REGISTER; Xbreak; Xcase 36: X { yylval.i=1; return LEFT_OR_RIGHT; } Xbreak; Xcase 37: X { yylval.i=3; return LEFT_OR_RIGHT; } Xbreak; Xcase 38: X { yylval.i=2; return CENTER; } Xbreak; Xcase 39: X { yylval.i=1; return TOP_OR_BOT; } Xbreak; Xcase 40: X { yylval.i=3; return TOP_OR_BOT; } Xbreak; Xcase 41: X { yylval.i=1; return LIGHT_STATE; } Xbreak; Xcase 42: X { yylval.i=0; return LIGHT_STATE; } Xbreak; Xcase 43: X { yylval.i=A_LAW; return ALIGNMENT; } Xbreak; Xcase 44: X { yylval.i=A_NEUTRAL; return ALIGNMENT; } Xbreak; Xcase 45: X { yylval.i=A_CHAOS; return ALIGNMENT; } Xbreak; Xcase 46: X { yylval.i=1; return ALTAR_TYPE; } Xbreak; Xcase 47: X { yylval.i=0; return ALTAR_TYPE; } Xbreak; Xcase 48: X { yylval.i=1; return UP_OR_DOWN; } Xbreak; Xcase 49: X { yylval.i=0; return UP_OR_DOWN; } Xbreak; Xcase 50: X { yylval.i=atoi(yytext); return INTEGER; } Xbreak; Xcase 51: X{ yytext[yyleng-1] = 0; /* Discard the trailing \" */ X yylval.map = (char *) alloc(strlen(yytext+1)+1); X strcpy(yylval.map, yytext+1); /* Discard the first \" */ X return STRING; } Xbreak; Xcase 52: X { line_number++; } Xbreak; Xcase 53: X ; Xbreak; Xcase 54: X { yylval.i = yytext[1]; return CHAR; } Xbreak; Xcase 55: X { return yytext[0]; } Xbreak; Xcase -1: Xbreak; Xdefault: Xfprintf(yyout,"bad switch yylook %d",nstr); X} return(0); } X/* end of yylex */ X#ifdef AMIGA Xlong *alloc(n) X unsigned n; X{ X return ((long *)malloc (n)); X} X#endif Xint yyvstop[] ={ X0, X X55, X0, X X53, X55, X0, X X52, X0, X X55, X0, X X55, X0, X X50, X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X55, X0, X X1, X52, X0, X X53, X55, X0, X X55, X0, X X55, X0, X X55, X0, X X53, X0, X X51, X0, X X50, X0, X X48, X0, X X3, X0, X X1, X0, X X53, X0, X X1, X3, X0, X X54, X0, X X43, X0, X X41, X0, X X39, X0, X X11, X0, X X4, X0, X X21, X0, X X10, X0, X X49, X0, X X28, X0, X X36, X0, X X22, X0, X X30, X0, X X7, X0, X X18, X0, X X5, X0, X X35, X0, X X47, X0, X X45, X0, X X27, X0, X X34, X0, X X37, X0, X X29, X0, X X42, X0, X X19, X0, X X8, X0, X X14, X0, X X40, X0, X X26, X0, X X38, X0, X X23, X0, X X24, X0, X X25, X0, X X32, X0, X X31, X0, X X46, X0, X X9, X0, X X33, X0, X X44, X0, X X2, X0, X X6, X0, X X13, X0, X X12, X0, X X20, X0, X X17, X0, X X15, X0, X X16, X0, X0}; X# define YYTYPE int Xstruct yywork { YYTYPE verify, advance; } yycrank[] ={ X0,0, 0,0, 1,5, 0,0, X0,0, 0,0, 0,0, 0,0, X8,43, 0,0, 1,6, 1,7, X9,45, 0,0, 6,42, 0,0, X8,43, 8,43, 0,0, 0,0, X9,45, 9,0, 41,94, 0,0, X0,0, 0,0, 0,0, 0,0, X0,0, 0,0, 0,0, 0,0, X0,0, 1,6, 0,0, 1,8, X1,5, 6,42, 0,0, 8,43, X1,9, 8,44, 8,43, 9,45, X41,95, 9,45, 9,45, 41,95, X45,96, 1,10, 0,0, 0,0, X0,0, 0,0, 0,0, 8,43, X0,0, 0,0, 0,0, 9,45, X0,0, 0,0, 0,0, 0,0, X0,0, 0,0, 1,11, 14,51, X15,53, 1,12, 13,50, 14,52, X1,13, 17,56, 36,89, 49,99, X51,101, 1,14, 1,15, 1,16, X1,17, 11,47, 15,54, 1,18, X12,48, 1,19, 16,55, 12,49, X2,5, 18,57, 19,60, 40,93, X47,97, 18,58, 48,98, 50,100, X2,6, 2,7, 1,20, 1,21, X1,22, 1,23, 1,24, 18,59, X24,68, 34,86, 52,102, 53,103, X54,104, 1,25, 1,26, 1,27, X1,28, 1,29, 20,61, 1,30, X1,31, 1,32, 1,33, 2,6, X1,34, 2,8, 2,35, 23,67, X21,62, 26,73, 2,9, 21,63, X29,78, 32,83, 2,5, 55,105, X2,5, 2,5, 28,76, 2,10, X10,46, 10,46, 10,46, 10,46, X10,46, 10,46, 10,46, 10,46, X10,46, 10,46, 22,64, 27,74, X28,77, 22,65, 56,106, 30,79, X2,11, 22,66, 31,81, 2,12, X57,107, 27,75, 2,13, 30,80, X58,108, 31,82, 2,5, 2,14, X2,36, 2,16, 2,17, 59,109, X25,69, 2,18, 2,5, 2,19, X25,70, 33,84, 60,110, 33,85, X25,71, 62,113, 61,111, 2,5, X63,114, 64,115, 25,72, 65,116, X2,20, 2,21, 2,22, 2,23, X2,24, 61,112, 66,117, 3,37, X67,118, 68,119, 69,120, 2,25, X2,26, 2,27, 2,28, 2,29, X35,87, 2,30, 2,31, 2,32, X2,33, 70,121, 2,34, 71,122, X35,87, 35,88, 2,5, 2,5, X2,5, 3,38, 72,123, 73,124, X3,39, 74,125, 75,126, 76,128, X3,9, 77,129, 78,130, 79,131, X80,132, 81,133, 82,134, 83,135, X84,136, 86,137, 89,138, 35,87, X75,127, 35,87, 35,87, 93,139, X97,140, 98,141, 99,142, 95,94, X89,103, 100,143, 101,144, 102,145, X103,146, 104,147, 3,11, 35,87, X105,148, 3,12, 3,40, 106,149, X3,13, 107,150, 108,151, 109,152, X110,153, 3,14, 3,15, 3,16, X3,17, 95,95, 111,154, 3,18, X95,95, 3,19, 112,155, 113,156, X114,157, 115,158, 116,159, 117,160, X118,161, 119,162, 121,163, 123,164, X124,165, 4,37, 3,20, 3,21, X3,22, 3,23, 3,24, 125,166, X126,167, 127,168, 128,169, 129,170, X130,171, 3,25, 3,26, 3,27, X3,28, 3,29, 131,172, 3,30, X3,31, 3,32, 3,33, 4,38, X3,34, 132,173, 4,41, 133,174, X134,175, 136,176, 4,9, 137,177, X138,178, 139,179, 4,39, 140,180, X4,39, 4,39, 142,181, 143,182, X144,183, 145,184, 146,185, 147,186, X148,187, 149,188, 150,189, 151,190, X154,191, 155,192, 156,193, 157,194, X158,195, 159,196, 160,197, 164,198, X4,11, 165,199, 166,200, 4,12, X4,40, 167,201, 4,13, 168,202, X169,203, 171,204, 4,39, 4,14, X4,36, 4,16, 4,17, 172,205, X173,206, 4,18, 4,39, 4,19, X174,207, 175,208, 176,209, 179,210, X181,211, 182,212, 183,213, 4,39, X185,214, 186,215, 38,42, 38,90, X4,20, 4,21, 4,22, 4,23, X4,24, 187,216, 188,217, 189,218, X190,219, 193,220, 194,221, 4,25, X4,26, 4,27, 4,28, 4,29, X195,222, 4,30, 4,31, 4,32, X4,33, 38,91, 4,34, 39,90, X38,92, 197,223, 4,39, 4,39, X4,39, 198,224, 199,225, 200,226, X38,92, 201,227, 38,92, 38,92, X203,228, 205,229, 207,230, 210,231, X211,232, 212,233, 214,234, 215,235, X216,236, 39,92, 218,237, 225,238, X39,92, 226,239, 231,240, 232,241, X233,242, 234,243, 236,244, 241,248, X39,92, 244,249, 39,92, 39,92, X237,245, 245,250, 237,246, 237,247, X38,92, 246,251, 247,252, 248,253, X249,254, 250,255, 251,256, 252,257, X38,92, 254,258, 255,259, 256,260, X257,261, 258,262, 259,263, 260,264, X261,265, 38,92, 263,266, 264,267, X265,268, 266,269, 267,270, 269,271, X39,92, 0,0, 0,0, 0,0, X0,0, 0,0, 0,0, 0,0, X39,92, 0,0, 0,0, 0,0, X0,0, 0,0, 0,0, 0,0, X0,0, 39,92, 0,0, 0,0, X0,0, 0,0, 0,0, 0,0, X38,92, 38,92, 38,92, 0,0, X0,0, 0,0, 0,0, 0,0, X0,0, 0,0, 0,0, 0,0, X0,0, 0,0, 0,0, 0,0, X0,0, 0,0, 0,0, 0,0, X0,0, 0,0, 0,0, 0,0, X39,92, 39,92, 39,92, 0,0, X0,0}; Xstruct yysvf yysvec[] ={ X0, 0, 0, Xyycrank+-1, 0, 0, Xyycrank+-87, 0, 0, Xyycrank+-181, yysvec+1, 0, Xyycrank+-267, yysvec+2, 0, Xyycrank+0, 0, yyvstop+1, Xyycrank+5, 0, yyvstop+3, Xyycrank+0, 0, yyvstop+6, Xyycrank+-7, 0, yyvstop+8, Xyycrank+-11, 0, yyvstop+10, Xyycrank+88, 0, yyvstop+12, Xyycrank+5, 0, yyvstop+15, Xyycrank+5, 0, yyvstop+17, Xyycrank+1, 0, yyvstop+19, Xyycrank+2, 0, yyvstop+21, Xyycrank+3, 0, yyvstop+23, Xyycrank+7, 0, yyvstop+25, Xyycrank+7, 0, yyvstop+27, Xyycrank+24, 0, yyvstop+29, Xyycrank+8, 0, yyvstop+31, Xyycrank+6, 0, yyvstop+33, Xyycrank+13, 0, yyvstop+35, Xyycrank+45, 0, yyvstop+37, Xyycrank+12, 0, yyvstop+39, Xyycrank+7, 0, yyvstop+41, Xyycrank+71, 0, yyvstop+43, Xyycrank+14, 0, yyvstop+45, Xyycrank+46, 0, yyvstop+47, Xyycrank+36, 0, yyvstop+49, Xyycrank+20, 0, yyvstop+51, Xyycrank+54, 0, yyvstop+53, Xyycrank+50, 0, yyvstop+55, Xyycrank+18, 0, yyvstop+57, Xyycrank+63, 0, yyvstop+59, Xyycrank+4, 0, yyvstop+61, Xyycrank+-199, 0, yyvstop+63, Xyycrank+9, yysvec+15, yyvstop+65, Xyycrank+0, 0, yyvstop+67, Xyycrank+353, 0, yyvstop+70, Xyycrank+377, 0, yyvstop+73, Xyycrank+13, 0, yyvstop+75, Xyycrank+-12, yysvec+35, yyvstop+77, Xyycrank+0, yysvec+6, yyvstop+79, Xyycrank+0, yysvec+8, 0, Xyycrank+0, 0, yyvstop+81, Xyycrank+9, 0, 0, Xyycrank+0, yysvec+10, yyvstop+83, Xyycrank+8, 0, 0, Xyycrank+15, 0, 0, Xyycrank+10, 0, 0, Xyycrank+16, 0, 0, Xyycrank+8, 0, 0, Xyycrank+20, 0, 0, Xyycrank+17, 0, 0, Xyycrank+30, 0, 0, Xyycrank+53, 0, 0, Xyycrank+76, 0, 0, Xyycrank+78, 0, 0, Xyycrank+89, 0, 0, Xyycrank+88, 0, 0, Xyycrank+109, 0, 0, Xyycrank+73, 0, 0, Xyycrank+61, 0, 0, Xyycrank+69, 0, 0, Xyycrank+71, 0, 0, Xyycrank+86, 0, 0, Xyycrank+79, 0, 0, Xyycrank+73, 0, 0, Xyycrank+78, 0, 0, Xyycrank+75, 0, 0, Xyycrank+103, 0, 0, Xyycrank+91, 0, 0, Xyycrank+115, 0, 0, Xyycrank+105, 0, 0, Xyycrank+100, 0, 0, Xyycrank+118, 0, 0, Xyycrank+113, 0, 0, Xyycrank+120, 0, 0, Xyycrank+125, 0, 0, Xyycrank+113, 0, 0, Xyycrank+121, 0, 0, Xyycrank+111, 0, 0, Xyycrank+109, 0, 0, Xyycrank+115, 0, 0, Xyycrank+120, 0, 0, Xyycrank+0, 0, yyvstop+85, Xyycrank+114, 0, 0, Xyycrank+0, yysvec+35, 0, Xyycrank+0, 0, yyvstop+87, Xyycrank+150, 0, 0, Xyycrank+0, 0, yyvstop+89, Xyycrank+0, yysvec+38, yyvstop+91, Xyycrank+0, yysvec+39, 0, Xyycrank+167, 0, 0, Xyycrank+0, 0, yyvstop+93, Xyycrank+-229, yysvec+35, 0, Xyycrank+0, 0, yyvstop+96, Xyycrank+171, 0, 0, Xyycrank+155, 0, 0, Xyycrank+151, 0, 0, Xyycrank+164, 0, 0, Xyycrank+174, 0, 0, Xyycrank+174, 0, 0, Xyycrank+175, 0, 0, Xyycrank+162, 0, 0, Xyycrank+153, 0, 0, Xyycrank+182, 0, 0, Xyycrank+185, 0, 0, Xyycrank+181, 0, 0, Xyycrank+178, 0, 0, Xyycrank+176, 0, 0, Xyycrank+159, 0, 0, Xyycrank+169, 0, 0, Xyycrank+151, 0, 0, Xyycrank+161, 0, 0, Xyycrank+153, 0, 0, Xyycrank+159, 0, 0, Xyycrank+156, 0, 0, Xyycrank+162, 0, 0, Xyycrank+157, 0, 0, Xyycrank+0, 0, yyvstop+98, Xyycrank+158, 0, 0, Xyycrank+0, 0, yyvstop+100, Xyycrank+168, 0, 0, Xyycrank+161, 0, 0, Xyycrank+167, 0, 0, Xyycrank+173, 0, 0, Xyycrank+169, 0, 0, Xyycrank+185, 0, 0, Xyycrank+177, 0, 0, Xyycrank+189, 0, 0, Xyycrank+194, 0, 0, Xyycrank+197, 0, 0, Xyycrank+198, 0, 0, Xyycrank+188, 0, 0, Xyycrank+0, 0, yyvstop+102, Xyycrank+200, 0, 0, Xyycrank+191, 0, 0, Xyycrank+298, 0, 0, Xyycrank+232, 0, 0, Xyycrank+229, 0, 0, Xyycrank+0, 0, yyvstop+104, Xyycrank+248, 0, 0, Xyycrank+246, 0, 0, Xyycrank+247, 0, 0, Xyycrank+241, 0, 0, Xyycrank+231, 0, yyvstop+106, Xyycrank+235, 0, 0, Xyycrank+252, 0, 0, Xyycrank+254, 0, 0, Xyycrank+243, 0, 0, Xyycrank+244, 0, 0, Xyycrank+0, 0, yyvstop+108, Xyycrank+0, 0, yyvstop+110, Xyycrank+214, 0, 0, Xyycrank+211, 0, 0, Xyycrank+215, 0, 0, Xyycrank+226, 0, 0, Xyycrank+227, 0, 0, Xyycrank+214, 0, 0, Xyycrank+229, 0, 0, Xyycrank+0, 0, yyvstop+112, Xyycrank+0, 0, yyvstop+114, Xyycrank+0, 0, yyvstop+116, Xyycrank+230, 0, 0, Xyycrank+217, 0, 0, Xyycrank+220, 0, 0, Xyycrank+226, 0, 0, Xyycrank+235, 0, 0, Xyycrank+241, 0, 0, Xyycrank+0, 0, yyvstop+118, Xyycrank+240, 0, 0, Xyycrank+236, 0, 0, Xyycrank+232, 0, 0, Xyycrank+242, 0, 0, Xyycrank+249, 0, 0, Xyycrank+238, 0, 0, Xyycrank+0, 0, yyvstop+120, Xyycrank+0, 0, yyvstop+122, Xyycrank+290, 0, 0, Xyycrank+0, 0, yyvstop+124, Xyycrank+274, 0, 0, Xyycrank+273, 0, 0, Xyycrank+276, 0, 0, Xyycrank+0, 0, yyvstop+126, Xyycrank+295, 0, 0, Xyycrank+292, 0, 0, Xyycrank+296, 0, 0, Xyycrank+286, 0, 0, Xyycrank+294, 0, 0, Xyycrank+294, 0, 0, Xyycrank+0, 0, yyvstop+128, Xyycrank+0, 0, yyvstop+130, Xyycrank+264, 0, 0, Xyycrank+264, 0, 0, Xyycrank+266, 0, 0, Xyycrank+0, 0, yyvstop+132, Xyycrank+289, 0, 0, Xyycrank+293, 0, 0, Xyycrank+293, 0, 0, Xyycrank+298, 0, 0, Xyycrank+283, 0, 0, Xyycrank+0, 0, yyvstop+134, Xyycrank+284, 0, 0, Xyycrank+0, 0, yyvstop+136, Xyycrank+292, 0, 0, Xyycrank+0, 0, yyvstop+138, Xyycrank+301, 0, 0, Xyycrank+0, 0, yyvstop+140, Xyycrank+0, 0, yyvstop+142, Xyycrank+323, 0, 0, Xyycrank+331, 0, 0, Xyycrank+323, 0, 0, Xyycrank+0, 0, yyvstop+144, Xyycrank+330, 0, 0, Xyycrank+325, 0, 0, Xyycrank+337, 0, 0, Xyycrank+0, 0, yyvstop+146, Xyycrank+315, 0, 0, Xyycrank+0, 0, yyvstop+148, Xyycrank+0, 0, yyvstop+150, Xyycrank+0, 0, yyvstop+152, Xyycrank+0, 0, yyvstop+154, Xyycrank+0, 0, yyvstop+156, Xyycrank+0, 0, yyvstop+158, Xyycrank+297, 0, 0, Xyycrank+305, 0, 0, Xyycrank+0, 0, yyvstop+160, Xyycrank+0, 0, yyvstop+162, Xyycrank+0, 0, yyvstop+164, Xyycrank+0, 0, yyvstop+166, Xyycrank+404, 0, 0, Xyycrank+347, 0, 0, Xyycrank+327, 0, 0, Xyycrank+342, 0, 0, Xyycrank+0, 0, yyvstop+168, Xyycrank+347, 0, 0, Xyycrank+347, 0, 0, Xyycrank+0, 0, yyvstop+170, Xyycrank+0, 0, yyvstop+172, Xyycrank+0, 0, yyvstop+174, Xyycrank+348, 0, 0, Xyycrank+0, 0, yyvstop+176, Xyycrank+0, 0, yyvstop+178, Xyycrank+356, 0, 0, Xyycrank+346, 0, 0, Xyycrank+363, 0, 0, Xyycrank+354, 0, 0, Xyycrank+362, 0, 0, Xyycrank+366, 0, 0, Xyycrank+355, 0, 0, Xyycrank+360, 0, 0, Xyycrank+370, 0, 0, Xyycrank+0, 0, yyvstop+180, Xyycrank+361, 0, 0, Xyycrank+355, 0, 0, Xyycrank+370, 0, 0, Xyycrank+373, 0, 0, Xyycrank+372, 0, 0, Xyycrank+358, 0, 0, Xyycrank+376, 0, 0, Xyycrank+375, 0, 0, Xyycrank+0, 0, yyvstop+182, Xyycrank+377, 0, 0, Xyycrank+363, 0, 0, Xyycrank+365, 0, 0, Xyycrank+367, 0, 0, Xyycrank+367, 0, 0, Xyycrank+0, 0, yyvstop+184, Xyycrank+368, 0, 0, Xyycrank+0, 0, yyvstop+186, Xyycrank+0, 0, yyvstop+188, X0, 0, 0}; Xstruct yywork *yytop = yycrank+502; Xstruct yysvf *yybgin = yysvec+1; Xchar yymatch[] ={ X00 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , X01 ,011 ,012 ,01 ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , X040 ,01 ,'"' ,'#' ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,'#' ,01 ,'#' ,'#' ,01 , X'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' , X'0' ,'0' ,01 ,01 ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,'#' ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,'#' ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,01 ,'#' ,01 ,01 ,01 , X01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,01 ,01 ,01 ,01 ,01 , X01 ,01 ,01 ,'#' ,'#' ,'#' ,01 ,01 , X0}; Xchar yyextra[] ={ X0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0, X0,0,0,0,0,0,0,0, X0}; X/* ncform 4.1 83/08/11 */ X Xint yylineno =1; X# define YYU(x) x X# define NLSTATE yyprevious=YYNEWLINE Xchar yytext[YYLMAX]; Xstruct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp; Xchar yysbuf[YYLMAX]; Xchar *yysptr = yysbuf; Xint *yyfnd; Xextern struct yysvf *yyestate; Xint yyprevious = YYNEWLINE; Xyylook(){ X register struct yysvf *yystate, **lsp; X register struct yywork *yyt; X struct yysvf *yyz; X int yych; X struct yywork *yyr; X# ifdef LEXDEBUG X int debug; X# endif X char *yylastch; X /* start off machines */ X# ifdef LEXDEBUG X debug = 0; X# endif X if (!yymorfg) X yylastch = yytext; X else { X yymorfg=0; X yylastch = yytext+yyleng; X } X for(;;){ X lsp = yylstate; X yyestate = yystate = yybgin; X if (yyprevious==YYNEWLINE) yystate++; X for (;;){ X# ifdef LEXDEBUG X if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1); X# endif X yyt = yystate->yystoff; X if(yyt == yycrank){ /* may not be any transitions */ X yyz = yystate->yyother; X if(yyz == 0)break; X if(yyz->yystoff == yycrank)break; X } X *yylastch++ = yych = input(); X tryagain: X# ifdef LEXDEBUG X if(debug){ X fprintf(yyout,"char "); X allprint(yych); X putchar('\n'); X } X# endif X yyr = yyt; X if ( (int)yyt > (int)yycrank){ X yyt = yyr + yych; X if (yyt <= yytop && yyt->verify+yysvec == yystate){ X if(yyt->advance+yysvec == YYLERR) /* error transitions */ X {unput(*--yylastch);break;} X *lsp++ = yystate = yyt->advance+yysvec; X goto contin; X } X } X# ifdef YYOPTIM X else if((int)yyt < (int)yycrank) { /* r < yycrank */ X yyt = yyr = yycrank+(yycrank-yyt); X# ifdef LEXDEBUG X if(debug)fprintf(yyout,"compressed state\n"); X# endif X yyt = yyt + yych; X if(yyt <= yytop && yyt->verify+yysvec == yystate){ X if(yyt->advance+yysvec == YYLERR) /* error transitions */ X {unput(*--yylastch);break;} X *lsp++ = yystate = yyt->advance+yysvec; X goto contin; X } X yyt = yyr + YYU(yymatch[yych]); X# ifdef LEXDEBUG X if(debug){ X fprintf(yyout,"try fall back character "); X allprint(YYU(yymatch[yych])); X putchar('\n'); X } X# endif X if(yyt <= yytop && yyt->verify+yysvec == yystate){ X if(yyt->advance+yysvec == YYLERR) /* error transition */ X {unput(*--yylastch);break;} X *lsp++ = yystate = yyt->advance+yysvec; X goto contin; X } X } X if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){ X# ifdef LEXDEBUG X if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1); X# endif X goto tryagain; X } X# endif X else X {unput(*--yylastch);break;} X contin: X# ifdef LEXDEBUG X if(debug){ X fprintf(yyout,"state %d char ",yystate-yysvec-1); X allprint(yych); X putchar('\n'); X } X# endif X ; X } X# ifdef LEXDEBUG X if(debug){ X fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1); X allprint(yych); X putchar('\n'); X } X# endif X while (lsp-- > yylstate){ X *yylastch-- = 0; X if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){ X yyolsp = lsp; X if(yyextra[*yyfnd]){ /* must backup */ X while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){ X lsp--; X unput(*yylastch--); X } X } X yyprevious = YYU(*yylastch); X yylsp = lsp; X yyleng = yylastch-yytext+1; X yytext[yyleng] = 0; X# ifdef LEXDEBUG X if(debug){ X fprintf(yyout,"\nmatch "); X sprint(yytext); X fprintf(yyout," action %d\n",*yyfnd); X } X# endif X return(*yyfnd++); X } X unput(*yylastch); X } X if (yytext[0] == 0 /* && feof(yyin) */) X { X yysptr=yysbuf; X return(0); X } X yyprevious = yytext[0] = input(); X if (yyprevious>0) X output(yyprevious); X yylastch=yytext; X# ifdef LEXDEBUG X if(debug)putchar('\n'); X# endif X } X } Xyyback(p, m) X int *p; X{ Xif (p==0) return(0); Xwhile (*p) X { X if (*p++ == m) X return(1); X } Xreturn(0); X} X /* the following are only used in the lex library */ Xyyinput(){ X return(input()); X } Xyyoutput(c) X int c; { X output(c); X } Xyyunput(c) X int c; { X unput(c); X } END_OF_FILE if test 21018 -ne `wc -c <'src/lev_lex.c'`; then echo shar: \"'src/lev_lex.c'\" unpacked with wrong size! fi # end of 'src/lev_lex.c' echo shar: End of archive 27 \(of 30\). cp /dev/null ark27isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 30 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0