|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 4480 (0x1180) Types: TextFile Names: »NDIM.MAC«
└─⟦01b5c9619⟧ Bits:30005906 Microsoft Multiplan v1.05 og HELP └─ ⟦this⟧ »NDIM.MAC«
; ; ; Title N-dimensional array indexing ; Name: NDIM ; ; ; Purpose: Calculate the address of an element in an ; N-dimensional array given the base address, ; N pairs of size in bytes and subscript, and the ; number of dimensions of the array. The array is ; assumed to be stored in roq major order ; (AÆ0,0,0Å,AÆ0,0,1Å,...,AÆ0,1,0Å,AÆ0,1,1Å,...). ; Also it is assumed that all dimensions begin ; at 0 as in the following Pascal declaration: ; A:ARRAYÆ0..10,0..3,0..5Å of something ; For arrays that do not begin at 0 boundaries, ; normalization must be performed before calling ; this routine. ; ; Entry: Top of stack ; Return address word ; Number dimensions word ; Dim N-1 size word ; Dim N-1 subscript word ; Dim N-2 size word ; Dim N-2 subscript word ; . . ; . . ; . . ; Dim 0 size word ; Dim 0 subscript word ; Array base address word ; NOTE: ; All sizes are in bytes ; ; Exit: HL = address ; ; Registers used: AF,BC,DE,HL ; ; Time: Approximately 1300 cycles per dimension ; plus 165 cycles overhead ; ; Size: Program 120 bytes ; Data 5 bytes ; ; ; NDIM: ;pop parameters pop hl ;Return address ld (retadr),hl ;ofset := 0 ld hl,0 ld (offset),hl ;Get number of dimensions and test for 0 pop hl ld a,l ld (numdim),a ;Get number of dimensions or a ;Test for 0 jr z,adbase ;Return with base in HL ; if there are no dimensions ;Loop each dimension ; doing offset := offset + (subscript * size) loop: pop de ;Get size pop hl ;Get subscript call nxtoff ;Offset := ofset + (subscript * size) ld hl,numdim dec (hl) ;Decrement number of dimensions jr nz,loop ;Continue through all dimensions adbase: ;Calculate starting address of element ;Offset = base + offset ld hl,(offset) pop de ;Get base address add hl,de ;Sum with offset ;Restore return address and exit ld de,(retadr) push de ret ;-------------------------------------------------- ;Subroutine NXTOFF ;Purpose: offset := offset + (subscript * size); ;Entry: offset = current offset ; DE = current size of this dimension ; HL = current subscript ;Exit: offset = offset + (subscript * size); ;Registers used: AF, BC, DE, HL ;-------------------------------------------------- NXTOFF: push hl ;Save current subscript in stack ;Check if size is power of 2 less then 256 ld a,d or a ;High byte = 0 ? jr nz,bigsz ;Jump if size is large ld a,e ;A = low byte of size ld hl,easyay ;HL = base address of easyay ld b,szeasy ;B = size of easy array ld c,0 ;C = shift counter easylp: cp (hl) jr z,iseasy ;Jump if size is a power of 2 inc hl ;Increment to next byte of easay inc c ;Increment shift counter djnz easylp ;Decrement count jr bigsz ;jump if size not easy iseasy: pop hl ;Get subscript ld a,c ;Get number of shifts or a ;Test for 0 jr z,addoff ;Jump if shift factor = 0 ;Element size * subscript reduces to left shifts ld b,a ;B = shift count shift: add hl,hl ;Multiply subscript by 2 djnz shift ;Continue until done jr addoff ;Done so add offset + subscript bigsz: ;Size is not power of 2, multiply ; element size times subscript the hard way pop bc ;Get subscript ;Multiply first subscript * row lenght using shift and add ; algorihm. Result is in HL ; BC = subscript (multiplicand) ; DE = size (multiplier) ld hl,0 ;Product = 0 ld a,15 ;count = bit elnght -1 mlp: sla e ;shift low byte of multiplier rl d ;Rotate high byte of multiplier jr nc,mlp1 ;Jump if msb of multiplier = 0 add hl,bc ;Add multiplicand to partical product mlp1: add hl,hl ;shift partical product dec a jr nz,mlp ;Continue through 15 bits ;Add in multiplicand last time if msb of multiplier is 1 or d ;Sign flag = msb of multiplier jp p,addoff add hl,bc ;Add in multiplicand if sign = 1 ;Add subscript * size to offset addoff: ex de,hl ld hl,(offset) ;Get offset add hl,de ;Add product of subscript * size ld (offset),hl ;Save offset ret easyay: ;Shift factor db 1 ;0 db 2 ;1 db 4 ;2 db 8 ;3 db 16 ;4 db 32 ;5 db 64 ;6 db 128 ;7 szeasy equ $-easyay ;DATA retadr: ds 2 ;Temporary for return address offset: ds 2 ;Temporary for partial offset numdim: ds 1 ;Number of dimensions «eof»