M Equ Byte Ptr 0[BX] TITLE 'Object Vector LIST Disk file OVERFLOW SUPPORT' DGROUP GROUP DATA ; **************************************************************************** ; * * ; * DOROLLO : Put Next Byte into OBJECT LIST BUFFER * ; * Get Next Byte from OBJECT LIST BUFFER * ; * Manages ROLL OUT to a DISK FILE for the Calling routine * ; * Maximum disk file size = 65535 records = 8 megabytes * ; * * ; * Revision : Jan. 26, 1984 File "DOROLLO.A86" GSX-86 V1.3b V1-0 * ; * * ; **************************************************************************** ; * ;----------------------------------------------------------------------------+ ; OBJLST BUFFER ADDRESSING VARIABLES + ;----------------------------------------------------------------------------+ BSIZ1 EQU 2560 ;OBJLST Buffer Size (bytes) * OSIZ1 EQU 128 ;Disk File Roll Out Area Size (bytes) * ; * ;***** MODE NOTES : ********************************************************* ; * ; 1) Maximum No. of Bytes Accessable to/from OBJLST is 64K records * ; 2) Bytes in OBJLST buffer area is always resident never Rolled Out * ; to the Disk Roll Out File * ; 3) Driver Dies On a File R/W Error **** Return Error Status to Caller **** ; **** If Caller Checks Error Return **** ; 4) Buffer Size = 2560 byte (2.5 K) * ; 5) Change GETXY routine calls getbyt to get the first byte from objlst * ; 6) Close File before DELETE to deallocate disk space * ; 7) Save and Restore Es register * ; 8) Add Check abort support and file error check * ; * ;***** MODE NOTES : ********************************************************* ; * ; GETNXT : Get the next byte from OBJLST buffer and returns it in * ; GETBYT : Get the byte at location ;BYTNDX from OBJLST and returns in * ; GETXY : Get an x,y coordinate pair from OBJLST (next 4 bytes) * ; PUTPT : Put pt. coord. into OBJLST buffer (2 bytes) * ; PUTBYT : Put 1 byte into OBJLST buffer (next Byte location) * ; DOFLOW : Initialize Roll Out area and Buffer Pointers * ; DOEND : Reset Buffer Pointers and Delete Roll Out File if Created * ; getrec : compute new record no. and new byte address of requested byte * ; Check_abort : Check console stop output command * ; * ;***************************************************************************** Cseg PUBLIC GETNXT, GETBYT, PUTBYT, PUTPT, GETXY, getxy1 PUBLIC DOFLOW, DOEND, getrec EXTRN ABSHL:near, NEGHL:near, CMPDH:near, CMPS:near, SUBDH:near EXTRN MIDH:near, DIDH:near, IMOD:near Extrn msgout:near, Check_abort:near ;----------------------------------------------------------------------------+ ; BODS FUNCTIONS + ;----------------------------------------------------------------------------+ BDOS EQU 0005H ;BDOS Entry point CONOS EQU 09 ;Console String Output FCLOSE EQU 16 ;Close File FDELET EQU 19 ;Delete File WRSEQ EQU 21 ;Write Sequential FCREAT EQU 22 ;Create File RDRAN EQU 33 ;Read Random SETDMA EQU 26 ;Set DMA Address (File Record Buffer) SDMA_BASE EQU 51 ;Set DMA Address Base EJECT ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; DOFLOW - 1) Flush the record in the roll out area to disk (last + ; record in roll out file) + ; 2) Read the First Record back from roll out file into + ; roll out area, Setting up for Getbyt, Getnxt routines + ; 3) Initialize Bytes Index and Buffer Pointers + ; + ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Check was Rollout File Created ? DOFLOW: MOV AL,Byte Ptr RSTAT AND AL,AL ;RSTAT = 0, No Roll Out File JZ NOFILE ; File was Created, Flush out the Last record to roll out file Push Es MOV DX,DS MOV CL,SDMA_BASE INT 224 MOV DX,(Offset BROLL) ;Base address of roll out area MOV CL,SETDMA ;Make Current DMA area point to RollOut area INT 224 MOV DX,(Offset OUTFCB) ;Roll Out File FCB MOV CL,WRSEQ ;Write record to File INT 224 Pop Es ; Check Write status AND AL,AL JZ L@1 JMP DFULL L@1: ; Read the first record from Roll Out File into Roll Out Area DOROLL: Push Es MOV DX,DS MOV CL,SDMA_BASE INT 224 MOV DX,(Offset BROLL) ;DMA = Roll Out Area MOV CL,SETDMA INT 224 MOV Word Ptr RRRNR,0 ;Set Current Record No. in FCB to zero MOV DX,(Offset OUTFCB) MOV CL,RDRAN INT 224 Pop Es AND AL,AL JZ L@2 JMP RDERR ;Check Read Status L@2: ; Initialize Byte Index and Buffer Pointers to Beginning of OBJLST NOFILE: MOV Word Ptr BNEXT,(Offset OBJLST) ; modified the getbyt routine to use a record index - recndx, ; instead of the byte index - bytndx ; bytndx and rbase are obsolete variables : 5/27/83 mov word ptr recndx,0 ; index of next record to read MOV Word Ptr BYTNDX,0 ;Index of Next Byte in OBJLST (start at 0) ;Index of First Byte in ROLL-OUT area = bsiz1 MOV Word Ptr RBASE, BSIZ1 RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; DOEND : Clean Up Operation + ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Check Roll Out File Flag DOEND: MOV AL, Byte Ptr RSTAT OR AL, AL JZ NOFILE ;0 = No file Used ; Reset Roll Out File Used Flag, CLOSE/DELETE File MOV Byte Ptr RSTAT, 0 Push Es MOV DX, (Offset OUTFCB) ;Roll Out File FCB MOV CL, FCLOSE INT 224 ;Close it MOV DX, (Offset OUTFCB) ;Roll Out File FCB MOV CL, FDELET INT 224 ;Delete it Pop Es JMPS NOFILE ;***************************************************************************** ; * ; GETBYT : Get the Byte at BNEXT * ; * ;***************************************************************************** ; * ; Getbyt (bnext, recndx, byte) * ; * ; CALL GETBYT * ; bnext = address of the byte to be returned in * ; recndx = record no. of the byte currently requested, * ; recndx = 0, if bnext is in the memory buffer area, * ; getbyt reads this record into the roll out area,if it is * ; not the current record (rrrnr) in the roll out area. * ; RET * ; = Byte * ; bnext = address of Next Byte in OBJLST buffer * ; recndx = the record index of next byte (if not in memory buffer) * ; * ;***************************************************************************** ;***************************************************************************** ; * ; GETNXT : Get the Next Byte from Objlst List Buffer * ; * ;***************************************************************************** ; * ; Getnxt (bnext, recndx, byte) * ; * ; CALL GETNXT * ; BNEXT : Address of Next Byte * ; rexndx : record no. of next byte * ; RET * ; = The Byte returned * ; BNEXT = Points to next Location in Object List * ; recndx = record no. of next byte * ;***************************************************************************** ; Get The Next Byte from OBJLST GETNXT: GETBYT: ; is BYTE LOCATED IN OBJLST BUFFER AREA ? ; is BNEXT < BROLL (Beginning of roll out area) ? MOV BX,Word Ptr bnext ;Address of Byte to be returned MOV AL,Byte Ptr RSTAT ;Get Roll Out Flag AND AL,AL ;Any Bytes ROLLED OUT to DISK ? JZ getit ;No, Get Byte DIRECTLY from buffer ; Yes, Is Byte in OBJLST buffer ? Get it Directly if bnext < broll ; BROLL = BASE ADDRESS OF ROLL OUT AREA mov dx, (offset broll) sub dx, bx ; broll - bnext JA getit ; Byte is Not in OBJLST Buffer, it may be in Roll Out Area or ; need to be read from DISK RollOut File ; ; Check Record no. (recndx) of byte at bnext ; Is This Record Already in the Roll-Out Area ? (RRRNR) gotrec: MOV BX,Word Ptr RRRNR ; Is this Record Currently in My ROLL mov dx, word ptr recndx ; out area ? CMP bx, dx ; if not, get the record from disk JNE RDREC ;RRRNR = Record No. of Record Currently ;in the Roll Out area ; Byte is in the Roll Out Area, BNEXT is OK BFIND: mov bx, bnext GETIT: MOV AL,M ;Yes, Get Byte from Buffer INC BX ;Points to Next Byte ; is next byte still in side the memory buffer area ? ; ROLLO > BNEXT ? cmp bx, rollo jb get99 ; need next record from disk roll out file, recndx = recndx + 1 INC Word Ptr recndx ; Increment record Index mov bx, (offset broll) ; bnext = broll get99: mov word ptr bnext, bx AND AL,AL ;Clear Carry = Status OK RET RDREC: Push Es ; = Record No. to Read MOV Word Ptr RRRNR,DX ;Put it in FCB MOV DX,DS MOV CL,SDMA_BASE INT 224 MOV DX,(Offset BROLL) ;DMA = Roll Out Area MOV CL,SETDMA INT 224 MOV DX,(Offset OUTFCB) ;Roll Out File FCB MOV CL,RDRAN ;Read Record into Roll Out Area INT 224 Pop Es AND AL,AL ;Check Read Status JNZ RDERR ;OOPS, I GOOFED JMP BFIND ;ENUF FOOLING AROUND, GO GET IT RDERR: MOV DX,(Offset REMSG) MOV CL,CONOS INT 224 STC ;Set Error Return Status Mov Byte Ptr Error_flg, 0FFh ; Set File Error Flag RET ;***************************************************************************** ; * ; PUTBYT : Store the Byte in in the Object List Buffer * ; * ;***************************************************************************** ; * ; Putbyt (byte, bnext) * ; * ; CALL PUTBYT * ; = The Byte to be stored * ; RET * ; * ;***************************************************************************** PUTBYT: ; Check Error Flag Cmp Byte Ptr Error_flg, 0FFh Je EndPut MOV BX,Word Ptr BNEXT ;Get the Object List Buffer Location Pointer MOV M,AL ;Store the Byte into OBJLST INC BX MOV Word Ptr BNEXT,BX ;Store the New OBJLST location pointer ; Check OBJLST Buffer Over Flow ;ROLLO = Force Roll Out Address CMP BX,ROLLO ;Buffer Pointer > Rollo ? JE PUTJ01 OR AL,AL ;Set Return Status Endput: RET ;Return If Not ; BUFFER OVERFLOWING, Must Roll Out To Disk File PUTJ01: push di push es CALL OPENR ;Create File if not Already MOV DX,DS MOV CL,SDMA_BASE INT 224 MOV DX,(Offset BROLL) ; = Address of Roll Out Area ; Reset Addreaa Pointer of NEXT Byte To Top of ROLL-OUT area MOV Word Ptr BNEXT,DX ; = Start Address of Roll Out Area MOV CL,SETDMA ;Set DMA = RollOut Area INT 224 MOV DX,(Offset OUTFCB) MOV CL,WRSEQ ;Write Sequential Rollout area to File INT 224 AND AL,AL ;Check Return Status pop es pop di JNZ Dfull RET ; DISK FULL ERROR DFULL: MOV DX,(Offset DFMSG) ;Error Message MOV CL,CONOS INT 224 STC ;Set Error return ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; File Read/Write Error Occured, Set Error Flag + ; Set up Appropriate Error Status Flag and Return to + ; Caller for All File I/O Error Conditions in The Driver, + ; The File Error Return Condition cause the current output + ; to be aborted. + ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Mov Byte Ptr Error_flg, 0FFh ; Set File Error Flag RET ; Create/Open ROLL-OUT file OPENR: MOV AL,Byte Ptr RSTAT ;Roll-out File Status Flag AND AL,AL ;Is File Open ? JZ L@4 RET ;Yes, Return L@4: Push Es ;SETUP FCB FOR GSXTMP.$$$ File MOV AX,DS MOV ES,AX MOV DI,(offset OUTFCB) MOV SI,(offset SAVFCB) MOV CX,19 CLD REP MOVSW MOV DX,(Offset OUTFCB) ;Roll-out File FCB MOV CL,FDELET ;Delete Any Duplication File INT 224 MOV DX,(Offset OUTFCB) MOV CL,FCREAT ;Now Create It INT 224 Pop Es INC AL ;Successful ? MOV Byte Ptr RSTAT,AL ;Set File Status JZ L@5 ;***** Mov Ax, 2 Call Msgout ; I'm Here message RET L@5: JMP DFULL ;No, ERROR EJECT ;***************************************************************************** ; * ; PUTPT : Store the Coordinate of a point in the Object List Buffer * ; * ;***************************************************************************** ; * ; Putpt (Coord, bnext) * ; * ; CALL PUTPT * ; = The Coordinate to be stored * ; RET * ; BNEXT = Points to next available location in Object List Buffer * ; * ;***************************************************************************** PUTPT: MOV AL,DH ;Put the Byte to be stored in PUSH DX CALL PUTBYT ;Store the FIRST byte into OBJLST POP DX MOV AL,DL CALL PUTBYT ;Store the SECOND byte into OBJLST RET ;----------------------------------------------------------------------------+ ; GETXY : Get a x,y Coordinate pair from the Object List Buffer + ;----------------------------------------------------------------------------+ ; + ; CALL GETXY, GETXY1 + ; BNEXT = Address of next point in the OBJLST Buffer + ; bytndx = Index of next byte in the objlst buffer + ; RET + ; BNEXT = Address of next point in the OBJLST Buffer + ; BYTNDX = Index of next Point in the OBJLST buffer + ; = X coord. + ; = Y coord. + ; + ;----------------------------------------------------------------------------+ GETXY: getxy1: call getbyt ; get the Ist (high) byte from object list buffer ; using getbyt routine, so byte index bytndx instead ; of byte address bnext is used to assure that the ; correct byte is accessed from the object list buffer mov dh, al ; save the high byte in push dx call getnxt ; and the next byte pop dx mov dl, al ; 2nd (low) byte in
, = x coordinate push dx call getnxt mov ch, al ; 3rd byte in push cx ; high byte of y call getnxt pop cx mov cl, al ; 4th byte in , = y coordinate pop dx ; unstack x coordinate ret ;**************************************************************** ; * ; GETREC : Find the New Byte Address for the requested * ; byte (defined as an offset from the current * ; Byte Address, BNEXT), and Update the Record * ; index Number, RECNDX accordingly. * ; * ;**************************************************************** GETREC: ; = no. of bytes to offset from the current byte address ; for example : a polygon object data in the objlst buffer ; the byte address of x1 + offset = byte address of pxmin ; ,offset = npt x 4 bytes ;+-------------------------------------------------------------------+ ;| [<------- offset ------------>] | ;+___________________________________________________________________+ ;| NPT | x1 | y1 | ... | xnpt | ynpt | pxmin | pymin | pxmax | pymax | ;+-------------------------------------------------------------------+ mov ax, bnext ; byte address of current byte add ax, bx ; byte address of new byte mov bnext, ax ; = address of the next byte we want ; is new byte in memory ? bnext < rollo (end of buffer) ? sub ax, rollo ; = bnext - rollo, no. of bytes outside buffer jb getr99 ; bnext < rollo, new address ok mov dx, 0 jz getr01 ; bnext = rollo, need next record mov cx, 128 ; bnext > rollo, compute no. of records to read div cx ; , no. of records = no. of bytes / 128 ; , remainder = byte offset from beginning of ; roll out area (BROLL) getr01: inc word ptr recndx ; recndx = recndx + + 1 add word ptr recndx, ax ; new record no. to read mov bx, (offset broll) mov bnext, bx ; bnext = broll + remainder add bnext, dx ; byte address of the new byte getr99: ret DSEG PUBLIC OBJLST, BYTNDX, RBASE, RSTAT, NOFILE, DOROLL PUBLIC bnext, recndx Extrn Error_flg:byte, Abort_flg:byte X RS 02 Y RS 02 ;Define Roll Out File FCB OUTFCB DB 0 ;Roll Out File to Default Drive DB 'GSXTMP $$$' ;Roll out File Name DB 0,0,0,0 RS 16 ;System Reserved bytes DB 0 ;Current Record No. to R/W RRRNR DB 0,0,0,0 ;Random Record No. to R/W RSTAT DB 0 ;Roll Out File Used Flag, 0 = No File DB 0 RS 16 ;Define Roll Out File FCB SAVFCB DB 0 ;Roll Out File to Default Drive DB 'GSXTMP $$$' ;Roll out File Name DB 0,0,0,0 RS 16 ;System Reserved bytes DB 0 ;Current Record No. to R/W DB 0,0,0,0 ;Random Record No. to R/W DB 0 ;Roll Out File Used Flag, 0 = No File SFCB DB 0,0,0,0,0,0,0,0 DFMSG Db 'Not Enough Disk Space for Object List',0dh, 0ah Db 'Output Aborted', 07h, 0dh, 0ah,'$' REMSG DB 'Disk Read Error, Temporary File : GSXTMP.',07h,0dh,0ah,'$' ;----------------------------------------------------------------------------+ ; OBJLST BUFFER ADDRESSING VARIABLES + ;----------------------------------------------------------------------------+ BNEXT rw 01 ;ADDRESS of Next Byte in OBJLST BYTNDX rw 01 ;Index of Next Byte in OBJLST RBASE DW BSIZ1 ;Index of First Byte In Roll Out Area OBJLST RS BSIZ1 ;Allocate OBJLST Buffer BROLL rs OSIZ1 ;Allocate ROLL OUT area ROLLO EQU (Offset $) ;End of Ram Buffer Address recndx rw 01 ;record number of the requested byte to get ;getbyt routine performs record read when ;recndx is not the same as rrrnr, the ;record that is currently in the roll out ;area cseg END