home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
JSAGE
/
ZSUS
/
PROGPACK
/
ANY4.LBR
/
ANY4.ZZ0
/
ANY4.Z80
Wrap
Text File
|
2000-06-30
|
4KB
|
158 lines
; ANY4.Z80, from ANYWHERE.ASM by Bridger Mitchell
; (ref. The Computer Journal, issue #33, pp.11,14-15)
; July 18, 1988 mods by Bruce Morgen to avoid lots of
; "LD (HL),nn" opcodes - at first it turned out to be
; a byte longer and a little slower! Anyway, it's a
; brain-teaser to do it that way and I wound up with
; a combination of the two approaches that seems
; reasonably efficient and compact. The register
; recovery feature is also sketched out - all primary
; registers except BC and IY can be passed to the
; program by PUSHing at ANYWHERE+3 and POPping at
; RDONE+3. After the initial relocate-&-move run,
; of course, any register can be passed.
; July 15, 1988 mods by Bruce Morgen to to "pull" the
; relocated code down over the Where-Am-I and relocator
; routines as suggested by Bridger in the TCJ piece.
; July 14, 1988 mods by Bruce Morgen to allow easier
; creation of relocatable programs using MLOAD instead
; of a debugger/save sequence. Sample procedure:
; ZAS ANY4 H or Z80ASM ANY4/H
; Assemble to a HEXfile
; (M80/L80 can't handle this correctly,
; use the M80 equate and the RELHEX
; utility if you must use M80.)
; MLOAD PROGNAME=PROGNAME.PRL,ANY4
; MLOAD v2.1 or later required
prl equ 1 ; Could also use SPR files, but
; the DSEG handling could be
; tricky - PRL preferred.
m80 equ 1 ; Make this a 1 if using the
; M80/RELHEX method
if m80
.z80
aseg
endif
org 100h ; Code is position-independent,
; but MLOAD needs this anyway
anywhere:
db 01h ; "LD BC" opcode
ds 2 ; PRL format code length here
; (proper HEXfile won't overlay)
; Bridger's Where-Am-I routine
; We could save registers other than BC & IY here for later recovery
; e.g.:
; push hl
; push de
ld hl,0000 ; Zero out HL
push hl ; Use it to clear IX & IY first
pop ix
push hl
pop iy
add ix,sp ; Store incoming SP in IX
ld a,(hl) ; Get byte at 0000h
di ; Disable interrupt system
ld (hl),0c9h ; Poke a RET at 0000h
rst 0 ; "CALL" it
me: ld (hl),a ; Replace the original byte
dec sp ; Adjust SP
dec sp
ei ; Interrupts OK again
pop hl ; Get ANYWHERE+ME from stack
ld de,anywhere-me ; Signed difference in DE
add hl,de ; HL pts to ANYWHERE
; Bridger's neat word-wide PRL/SPR relocator begins here,
; slightly modified to save the byte count and bitmap start
reloc:
push bc ; Byte count to stack - b/m
push hl ; ANYWHERE to stack
exx
pop de ; Set DE' to relocation base of code
pop bc ; Set BC' to byte count - b/m
if prl
dec d ; -100H for PRL version
endif
exx
inc h ; Adjust HL to code start - b/m
di
ld sp,hl
dec sp
add hl,bc
ld e,00000001b ; Init. rotation counter byte
ex de,hl ; Bitmap start to DE
add iy,de ; Get bitmap start in IY - b/m
ex de,hl ; Bitmap start back to HL
rloop: ld a,b ; Anything left to process?
or c
jr z,rdone ; Branch ahead if done
dec bc ; Decrement 16-bit byte counter
rrc e ; Rotate right, bit 7 = carry
jr nc,rsame ; If bit reset, same bitmap byte
ld d,(hl) ; Otherwise get byte from bitmap
inc hl ; Point to the next one
rsame: rlc d ; Rotate left, bit 0 = carry
jr nc,noof ; No carry means no relocation
exx ; Go to alt. regs.
pop hl ; Get value in HL'
add hl,de ; Add in relocation base
push hl ; Put back relocated value
exx ; Back to primary regs.
noof: inc sp ; Increment pointer to code
jr rloop ; Loop around
rdone: ld sp,ix ; Recover incoming SP
ei
; Now overlay the bitmap area with our move & run routine - b/m
; We could recover saved registers other than BC & IY here
; e.g.:
; pop de
; pop hl
exx ; Go to alt. registers
push iy ; Get bitmap start into HL'
pop hl
if prl
inc d ; Adjust runtime origin if PRL
endif
ld (hl),0edh ; Move LDIR to (HL')
inc hl
ld (hl),0b0h
inc hl
ld (hl),0d9h ; EXX opcode next
inc hl
ld (hl),0c3h ; JP opcode next
inc hl
ld (hl),e ; Then ANYWHERE, as JP's operand
inc hl
ld (hl),d
ld h,d ; Copy LDIR dest. in DE' to HL'
ld l,e
inc h ; "Compute" LDIR source
jp (iy) ; Branch to MOVER & the program
; This code gets moved to (and executed in) the bitmap area
;
;mover: ldir ; Move source to dest.
; exx ; To primary regs.
; jp "real"_anywhere ; Branch to the program
end