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