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
Text File  |  2000-06-30  |  4KB  |  158 lines

  1. ; ANY4.Z80, from ANYWHERE.ASM by Bridger Mitchell
  2. ; (ref. The Computer Journal, issue #33, pp.11,14-15)
  3.  
  4. ; July 18, 1988 mods by Bruce Morgen to avoid lots of
  5. ; "LD (HL),nn" opcodes - at first it turned out to be
  6. ; a byte longer and a little slower!  Anyway, it's a
  7. ; brain-teaser to do it that way and I wound up with
  8. ; a combination of the two approaches that seems
  9. ; reasonably efficient and compact.  The register
  10. ; recovery feature is also sketched out - all primary
  11. ; registers except BC and IY can be passed to the
  12. ; program by PUSHing at ANYWHERE+3 and POPping at
  13. ; RDONE+3.  After the initial relocate-&-move run,
  14. ; of course, any register can be passed.
  15.  
  16. ; July 15, 1988 mods by Bruce Morgen to to "pull" the
  17. ; relocated code down over the Where-Am-I and relocator
  18. ; routines as suggested by Bridger in the TCJ piece.
  19.  
  20. ; July 14, 1988 mods by Bruce Morgen to allow easier
  21. ; creation of relocatable programs using MLOAD instead
  22. ; of a debugger/save sequence.  Sample procedure:
  23.  
  24. ; ZAS ANY4 H or Z80ASM ANY4/H
  25. ; Assemble to a HEXfile
  26. ; (M80/L80 can't handle this correctly,
  27. ; use the M80 equate and the RELHEX
  28. ; utility if you must use M80.)
  29. ; MLOAD PROGNAME=PROGNAME.PRL,ANY4
  30. ; MLOAD v2.1 or later required
  31.  
  32. prl    equ    1        ; Could also use SPR files, but
  33.                 ; the DSEG handling could be
  34.                 ; tricky - PRL preferred.
  35.  
  36. m80    equ    1        ; Make this a 1 if using the
  37.                 ; M80/RELHEX method
  38.  
  39.      if    m80
  40.     .z80
  41.     aseg
  42.      endif
  43.  
  44.     org    100h        ; Code is position-independent,
  45.                 ; but MLOAD needs this anyway
  46.  
  47. anywhere:
  48.     db    01h        ; "LD BC" opcode
  49.     ds    2        ; PRL format code length here
  50.                 ; (proper HEXfile won't overlay)
  51. ; Bridger's Where-Am-I routine
  52. ; We could save registers other than BC & IY here for later recovery
  53. ; e.g.:
  54. ;    push    hl
  55. ;    push    de
  56.  
  57.     ld    hl,0000        ; Zero out HL
  58.     push    hl        ; Use it to clear IX & IY first
  59.     pop    ix
  60.     push    hl
  61.     pop    iy
  62.     add    ix,sp        ; Store incoming SP in IX
  63.     ld    a,(hl)        ; Get byte at 0000h
  64.     di            ; Disable interrupt system
  65.     ld    (hl),0c9h    ; Poke a RET at 0000h
  66.     rst    0        ; "CALL" it
  67. me:    ld    (hl),a        ; Replace the original byte
  68.     dec    sp        ; Adjust SP
  69.     dec    sp
  70.     ei            ; Interrupts OK again
  71.  
  72.     pop    hl        ; Get ANYWHERE+ME from stack
  73.     ld    de,anywhere-me    ; Signed difference in DE
  74.     add    hl,de        ; HL pts to ANYWHERE
  75.  
  76. ; Bridger's neat word-wide PRL/SPR relocator begins here,
  77. ; slightly modified to save the byte count and bitmap start
  78.  
  79. reloc:
  80.     push    bc        ; Byte count to stack - b/m
  81.     push    hl        ; ANYWHERE to stack
  82.     exx
  83.     pop    de        ; Set DE' to relocation base of code
  84.     pop    bc        ; Set BC' to byte count - b/m
  85.      if    prl
  86.     dec    d        ; -100H for PRL version
  87.      endif
  88.     exx
  89.     inc    h        ; Adjust HL to code start - b/m
  90.     di
  91.     ld    sp,hl
  92.     dec    sp
  93.     add    hl,bc
  94.     ld    e,00000001b    ; Init. rotation counter byte
  95.     ex    de,hl        ; Bitmap start to DE
  96.     add    iy,de        ; Get bitmap start in IY - b/m
  97.     ex    de,hl        ; Bitmap start back to HL
  98.  
  99. rloop:    ld    a,b        ; Anything left to process?
  100.     or    c
  101.     jr    z,rdone        ; Branch ahead if done
  102.     dec    bc        ; Decrement 16-bit byte counter
  103.     rrc    e        ; Rotate right, bit 7 = carry
  104.     jr    nc,rsame    ; If bit reset, same bitmap byte
  105.  
  106.     ld    d,(hl)        ; Otherwise get byte from bitmap
  107.     inc    hl        ; Point to the next one
  108. rsame:    rlc    d        ; Rotate left, bit 0 = carry
  109.     jr    nc,noof        ; No carry means no relocation
  110.  
  111.     exx            ; Go to alt. regs.
  112.     pop    hl        ; Get value in HL'
  113.     add    hl,de        ; Add in relocation base
  114.     push    hl        ; Put back relocated value
  115.     exx            ; Back to primary regs.
  116.  
  117. noof:    inc    sp        ; Increment pointer to code
  118.     jr    rloop        ; Loop around
  119.  
  120. rdone:    ld    sp,ix        ; Recover incoming SP
  121.     ei
  122.  
  123. ; Now overlay the bitmap area with our move & run routine - b/m
  124. ; We could recover saved registers other than BC & IY here
  125. ; e.g.:
  126. ;    pop    de
  127. ;    pop    hl
  128.  
  129.     exx            ; Go to alt. registers
  130.     push    iy        ; Get bitmap start into HL'
  131.     pop    hl
  132.      if    prl
  133.     inc    d        ; Adjust runtime origin if PRL
  134.      endif
  135.     ld    (hl),0edh    ; Move LDIR to (HL')
  136.     inc    hl
  137.     ld    (hl),0b0h
  138.     inc    hl
  139.     ld    (hl),0d9h    ; EXX opcode next
  140.     inc    hl
  141.     ld    (hl),0c3h    ; JP opcode next
  142.     inc    hl
  143.     ld    (hl),e        ; Then ANYWHERE, as JP's operand
  144.     inc    hl
  145.     ld    (hl),d
  146.     ld    h,d        ; Copy LDIR dest. in DE' to HL'
  147.     ld    l,e
  148.     inc    h        ; "Compute" LDIR source
  149.     jp    (iy)        ; Branch to MOVER & the program
  150.  
  151. ; This code gets moved to (and executed in) the bitmap area
  152. ;
  153. ;mover:    ldir            ; Move source to dest.
  154. ;    exx            ; To primary regs.
  155. ;    jp "real"_anywhere    ; Branch to the program
  156.  
  157.     end
  158.