home *** CD-ROM | disk | FTP | other *** search
- Further Notes on BBL Forth
-
- The PC/Forth+ 2.00 is the one I use now. When definitions are
- compiled at addresses greater than 32K, it uses 3 byte tokens
- that takes 87 cycles through NEXT. BLL uses 2-byte tokens and
- 23 cycles through NEXT.
-
- In BBL most of my addresses are absolute SEG:OFFSET. BBL was
- written primarily to support Abundance -- not as a general
- purpose Forth, and Abundance has no need for linear addresses.
-
- However a SEG:OFFSET can nearly always be treated as if it were
- a true 32 bit number. You can add and subtract small numbers to
- them for example. If you need to compare them for equality, you
- must be sure they are canonical -- ie. offset portion is in the
- range 0..15. If you wish to subtract them, they both must have
- the same SEG portion. It turns out this comes out in the wash
- 95% of the time because CREATE canonizes HERE. If you need to
- work with data arrays larger than 64K, you have to explicitly
- convert addresses to relative, do your arithmetic and then
- convert them back. Cfa type addresses are built by Tick in such
- a way that the segment portion is always equal to CS:
-
- When you design a 32-bit Forth, you could have have 32-bit
- relative addresses, relative segment:offset or absolute
- segment:offset as the input to @ CMOVE etc. If you use anything
- other than absolute segments, @ and CMOVE must do the conversion
- every time they are used!
-
- The conversion, as long as you don't do it all that often, is
- not all that painful -- no divides or multiplies needed. Here
- is the code:
-
- CHEAD plainFL,TOREL,">REL"
- ; Converts absolute seg:offset to relative 32-bit address.
- ; ( CX=seg BX=offset --- CX=msw BX=lsw of 32-bit relative addr )
- ; CX is absolute seg, BX may be larger than 15
- ; Even handles crazy addresses like FFFF:FFFF by wrap around.
- ; The largest real address is FFFF:000F.
- ; If CX:BX is effectively < CS:0 then result will be negative.
- MOV AX,CS
- SUB CX,AX ; now have relative seg:offset in CX:BX
- MOV AX,CX ; AX:BX now has relative seg:off
- CLEAR CX ; MOV CX,DI - DI always 0
- SBB CX,DI ; CX=-1 if final result is -ve
- ; CX=0 if final result is +ve
- ; This step could be omitted if we were
- ; sure the relative is positive
- ; shift 4 high order bits of seg into CX
- SHL AX,1 ; and also shift seg AX left 4 bits
- RCL CX,1 ; must do multi-register shifts a bit at a time
- SHL AX,1 ; even on NEC chips
- RCL CX,1
- SHL AX,1
- RCL CX,1
- SHL AX,1
- RCL CX,1
- ADD BX,AX ; add shifted seg to offset
- ADC CX,DI ; add carry and 4 high order bits
- ; DI is always 0
- QNEXT
- ;=============================================
- CHEAD plainFL,RELFROM,"REL>"
- ; ( 32-bit relative address -- absolute SEG:OFF )
- ; Also handles negative relative addresses that point prior to
- ; CS:.
- ; ( CX:BX -- CX seg BX off)
- MOV DX,CX
- MOV CX,BX
- AND BX,0Fh ; ensure offset lies in [0..15]
- ; BX now has the final offset
- SHR DX,1 ; shift DX:CX right 4 bits
- RCR CX,1 ; multi-register shifts must be done
- SHR DX,1 ; a bit at a time even on NEC chips
- RCR CX,1
- SHR DX,1
- RCR CX,1
- SHR DX,1
- RCR CX,1
- MOV AX,CS
- ADD CX,AX ; rel seg:off to abs seg:off
- QNEXT
- ;====