?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1.     OPT --syntax=abfw
  2.     DEVICE  ZXSPECTRUM48, $5D00
  3.  
  4.     ; prepare the code from address 0 to have table of offsets "from current address"
  5.     ; (but store the resulting code from $8000)
  6.     ORG     $8000
  7.     DISP    $0000
  8.     RELOCATE_START
  9.  
  10. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  11. ;; relocator code, using address in BC as where the code did land
  12. ;; ("RANDOMIZE USR xyz" will provide BC=xyz)
  13. ;; the relocator will use the RELOCATE_TABLE data to adjust all instructions
  14. ;; as needed for the actual address where the code was loaded
  15. ;; (the relocator itself doesn't produce any relocation data)
  16. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  17.  
  18. relocator_code:
  19. ; start of relocator
  20.     ASSERT 0 < relocate_count   ; (for zero relocation_count the relocator is not needed!)
  21.     ; BASIC sets BC to the address of start (after "RANDOMIZE USR x" BC=x upon entry)
  22.         di
  23.     ; preserve current SP into IX
  24.         ld      ix,0
  25.         add     ix,sp
  26.     ; set SP to the relocation table data
  27.         ld      hl,relocator_table-relocator_code   ; offset from start to the table
  28.         add     hl,bc                               ; absolute address of table
  29.         ld      sp,hl
  30.     ; process the full table of relocation data (A + A' is counter of relocation values)
  31.         ld      a,1+high relocate_count
  32.         ex      af,af
  33.         ld      a,1+low relocate_count
  34.         jr      .relocate_loop_entry
  35. .relocate_loop_outer:
  36.         ex      af,af
  37. .relocate_loop:
  38.     ; relocate single record from the relocate table
  39.         pop     hl
  40.         add     hl,bc       ; HL = address of machine code to modify
  41.         ld      e,(hl)
  42.         inc     hl
  43.         ld      d,(hl)      ; DE = value to modify
  44.         ex      de,hl
  45.         add     hl,bc       ; relocate the value
  46.         ex      de,hl
  47.         ld      (hl),d      ; patch the machine code in memory
  48.         dec     hl
  49.         ld      (hl),e
  50. .relocate_loop_entry:
  51.     ; loop until all "relocate_count" records were processed
  52.         dec     a
  53.         jr      nz,.relocate_loop
  54.         ex      af,af
  55.         dec     a
  56.         jr      nz,.relocate_loop_outer
  57.     ; restore SP
  58.         ld      sp,ix
  59. ; end of relocator
  60.  
  61. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  62. ;; "user code" - some code which needs to be relocated after loading at some
  63. ;; dynamic address (the relocation is done by code above, the following code
  64. ;; is just small graphics effect using some hard-coded addresses which need
  65. ;; relocation - as demonstration of the functionality)
  66. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  67.  
  68.     ; user code (will be relocated by relocator)
  69. start:
  70.     ; black border
  71.         xor     a
  72.         out     (254),a
  73.     ; clear VRAM
  74.         ld      hl,$4000
  75.         ld      de,$4001
  76.         ld      bc,$1800
  77.         ld      (hl),l
  78.         ldir
  79.         ld      (hl),$40|4  ; bright green ink on black paper
  80.         ld      bc,$300-1
  81.         ldir
  82.     ; print the graphics with "SjASMPlus" bitmap
  83.         ld      hl,gfx_data
  84.         ld      d,high $4800    ; $4800 address
  85.         ld      a,8
  86. draw_line
  87.         ld      e,3*32 + 12 ; put it almost into middle of screen
  88.         ld      bc,gfx_data.lineSz
  89.         ldir
  90.         inc     d
  91.         dec     a
  92.         jp      nz,draw_line
  93.     ; keep the graphics scrolling around forever
  94. scroll_loop:
  95.         ei
  96.         halt
  97.         di
  98.         ld      (.restore_sp),sp
  99.         ld      sp,scroll_addresses
  100.         ld      c,8
  101. .one_line:
  102.         pop     hl
  103.         ld      a,(hl)      ; first byte value (to wrap around)
  104.         pop     hl
  105.         ld      b,gfx_data.lineSz
  106.         rla
  107. .one_line_loop:
  108.         rl      (hl)
  109.         dec     hl
  110.         djnz    .one_line_loop
  111.         dec     c
  112.         jp      nz,.one_line
  113. .restore_sp EQU $+1
  114.         ld      sp,0
  115.         jp      scroll_loop
  116.  
  117. gfx_data:
  118.     DG  -***--**----*-----***--*-----*-*****--**----------------
  119.     DG  **--*-**---***---**--*-**---**-**--**-**----------------
  120.     DG  **---------***---**----***-***-**--**-**-**--**--****---
  121.     DG  -***--**--**--*---***--**-*-**-*****--**-**--**-**------
  122.     DG  ---**--*--*****-----**-**-*-**-**-----**-**--**--***----
  123.     DG  *--**--*-**----*-*--**-**---**-**-----**-**--**----**---
  124.     DG  -***---*-**----*--***--**---**-**------**-*****-****----
  125.     DG  -----**-------------------------------------------------
  126. .lineSz EQU     ($ - gfx_data)/8
  127.  
  128. scroll_addresses:
  129. vram_line_first_byte = $4800 + 3*32 + 12
  130.     DUP     8
  131.         DW  vram_line_first_byte                        ; first byte of line
  132.         DW  vram_line_first_byte + gfx_data.lineSz - 1  ; last byte of line
  133. vram_line_first_byte = vram_line_first_byte + $100
  134.     EDUP
  135.  
  136. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  137. ;; relocation data table is at the end of the code block
  138. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  139.  
  140. relocator_table:
  141.     RELOCATE_TABLE
  142.  
  143. ; total size of code block
  144. code_size   EQU     $ - relocator_code
  145.     RELOCATE_END
  146.     ENT
  147.  
  148. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  149. ;; BASIC loader for TAP file (in include file)
  150. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  151.  
  152.     INCLUDE "relocation_basic.i.asm"
  153.  
  154.     MakeTape "relocate.tap", "relocate", $8000, code_size
  155.  
  156. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  157. ;; ZX48 SNA file for debugging (enable by "IF 1" change)
  158. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  159.  
  160.     IF 0    ; DEBUG use "1" to produce ZX48 snapshot file (simpler to debug in CSpect)
  161.         SAVESNA "relocate.sna", $8000
  162.     ENDIF
  163.