```        .assume ADL=1

XDEF    _octant_1_main,_octant_1_side
XDEF    _octant_2_main,_octant_2_side
XDEF    _octant_3_main,_octant_3_side
XDEF    _octant_4_main,_octant_4_side
XDEF    _octant_5_main,_octant_5_side
XDEF    _octant_6_main,_octant_6_side
XDEF    _octant_7_main,_octant_7_side
XDEF    _octant_8_main,_octant_8_side
XREF    _shared_struct,_map,_wall,__imulu,_init_map_pointer

XDEF	__indcallhl
__indcallhl:
jp	(hl)

_ray_x  equ     _shared_struct
_ray_y  equ     _shared_struct+3
_dxdy   equ     _shared_struct+6
_dydx   equ     _shared_struct+9
_test_x equ     _shared_struct+12
_test_y equ     _shared_struct+15

ray_x  equ     0
ray_y  equ     3
dxdy   equ     6
dydx   equ     9
test_x equ     12
test_y equ     15

MAP_WIDTH       equ     16

; octant layout
;
;    \     |     /
;     \ 6  | 7  /
;      \   |   /
;       \  |  /
;    5   \ | /   8
;         \|/
;----------+-----------
;         /|\
;    4   / | \   1
;       /  |  \
;      /   |   \
;     / 3  | 2  \
;    /     |     \

_octant_1_side:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)
jr      octant_1_side

_octant_1_main:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)

; Octant 1: mainly going right (X increasing), also down (Y increasing)
octant_1_main:
ld      hl,(iy+ray_y)           ; ray_y += dy/dx
ld      bc,(iy+dydx)            ; secondary direction, advance fractional amount
octant_1_main_hl:
ld      (iy+ray_y),hl
inc     (iy+ray_x+2)            ; ray_x += 0x10000, main direction, advance to next vertical line

inc     de                      ; also adjust map pointer for one block X
ld      a,(de)
or      a
ld      (_wall),a
ret     nz                      ; exit if wall present

; test if we will cross a horizontal line before the next vertical line
octant_1_side:
ld      hl,(iy+ray_y)           ; test_y = ray_y + dy/dx
ld      bc,(iy+dydx)            ; secondary direction, advance fractional amount
ld      (iy+test_y),hl
ld      a,(iy+ray_y+2)
cp      (iy+test_y+2)           ; continue if ipart(test_y) != ipart(ray_y)
jr      z,octant_1_main_hl

ld      hl,MAP_WIDTH
ld      a,(hl)
ex      de,hl                   ; advance wall pointer by one row
or      a
jr      z,octant_1_main         ; continue if no wall present

ld      (_wall),a               ; save wall type
ld      hl,(iy+ray_y)
ld      de,0
ld      d,h
ld      e,l                     ; DE = fpart(ray_y)
ld      hl,10000h
xor     a
sbc     hl,de                   ; HL = 0x10000 - fpart(ray_y)
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l                       ; HL = (0x10000 - fpart(ray_y)) >> 5
ld      bc,(iy+dxdy)
call    __imulu                 ; HL = ((0x10000 - fpart(ray_y)) >> 5) * dx/dy

xor     a
add     hl,hl                   ; shift AHL left 2
rla
rla
ld      (iy+test_x),hl          ; shift right 8 bits (net shift right 6)
ld      (iy+test_x+3),a
ld      hl,(iy+test_x+1)

ld      de,(iy+ray_x)
ld      (iy+ray_x),hl           ; point of intercept with horizontal line

lea     hl,iy+ray_y             ; Y coordinate is following horizontal line
xor     a
ld      (hl),a
inc     hl
ld      (hl),a
inc     hl
ld      a,(iy+test_y+2)
ld      (hl),a
ret

_octant_8_side:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)
jr      octant_8_side

_octant_8_main:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)

; Octant 8: mainly going right (X increasing), also up (Y decreasing)
octant_8_main:
ld      hl,(iy+ray_y)           ; ray_y -= dy/dx
ld      bc,(iy+dydx)            ; secondary direction, advance fractional amount
xor     a
sbc     hl,bc
octant_8_main_hl:
ld      (iy+ray_y),hl
inc     (iy+ray_x+2)            ; ray_x += 0x10000, main direction, advance to next vertical line

inc     de                      ; also adjust map pointer for one block X
ld      a,(de)
or      a
ld      (_wall),a
ret     nz                      ; exit if wall present

; test if we will cross a horizontal line before the next vertical line
octant_8_side:
ld      hl,(iy+ray_y)           ; test_y = ray_y - dy/dx
ld      bc,(iy+dydx)            ; secondary direction, advance fractional amount
xor     a
sbc     hl,bc
ld      (iy+test_y),hl
ld      a,(iy+ray_y+2)
cp      (iy+test_y+2)           ; continue if ipart(test_y) != ipart(ray_y)
jr      z,octant_8_main_hl

ld      hl,-MAP_WIDTH
ld      a,(hl)
ex      de,hl                   ; advance wall pointer by one row
or      a
jr      z,octant_8_main         ; continue if no wall present

ld      (_wall),a               ; save wall type
ld      de,(iy+ray_y)
ld      hl,0
ld      h,d
ld      l,e                     ; HL = fpart(ray_y)
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l                       ; HL = (0x10000 - fpart(ray_y)) >> 5
ld      bc,(iy+dxdy)
call    __imulu                 ; HL = ((0x10000 - fpart(ray_y)) >> 5) * dx/dy

xor     a
add     hl,hl                   ; shift AHL left 2
rla
rla
ld      (iy+test_x),hl          ; shift right 8 bits (net shift right 6)
ld      (iy+test_x+3),a
ld      hl,(iy+test_x+1)

ld      de,(iy+ray_x)
ld      (iy+ray_x),hl           ; point of intercept with horizontal line

lea     hl,iy+ray_y             ; Y coordinate is following horizontal line
xor     a
ld      (hl),a
inc     hl
ld      (hl),a
ret

_octant_2_side:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)
jr      octant_2_side

_octant_2_main:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)

; Octant 2: mainly going down (Y increasing), also right (X increasing)
octant_2_main:
ld      hl,(iy+ray_x)           ; ray_x += dx/dy
ld      bc,(iy+dxdy)            ; secondary direction, advance fractional amount
octant_2_main_hl:
ld      (iy+ray_x),hl
inc     (iy+ray_y+2)            ; ray_y += 0x10000, main direction, advance to next horizontal line crossing

ld      hl,MAP_WIDTH
ld      a,(hl)
ex      de,hl                   ; advance wall pointer by one row
or      a
ld      (_wall),a
ret     nz                      ; exit if wall present

; test if we will cross a vertical line before the next horizontal line
octant_2_side:
ld      hl,(iy+ray_x)           ; test_x = ray_x + dx/dy
ld      bc,(iy+dxdy)            ; secondary direction, advance fractional amount
ld      (iy+test_x),hl
ld      a,(iy+ray_x+2)
cp      (iy+test_x+2)           ; continue if ipart(test_x) != ipart(ray_x)
jr      z,octant_2_main_hl

inc     de                      ; advance wall pointer by one column
ld      a,(de)
or      a
jr      z,octant_2_main         ; continue if no wall present

ld      (_wall),a               ; save wall type
ld      hl,(iy+ray_x)
ld      de,0
ld      d,h
ld      e,l                     ; DE = fpart(ray_x)
ld      hl,10000h
xor     a
sbc     hl,de                   ; HL = 0x10000 - fpart(ray_x)
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l                       ; HL = (0x10000 - fpart(ray_x)) >> 5
ld      bc,(iy+dydx)
call    __imulu                 ; HL = ((0x10000 - fpart(ray_y)) >> 5) * dy/dx

xor     a
add     hl,hl                   ; shift AHL left 2
rla
rla
ld      (iy+test_x),hl          ; shift right 8 bits (net shift right 6)
ld      (iy+test_x+3),a
ld      hl,(iy+test_x+1)

ld      de,(iy+ray_y)
ld      (iy+ray_y),hl           ; point of intercept with vertical line

lea     hl,iy+ray_x             ; X coordinate of following vertical line
xor     a
ld      (hl),a
inc     hl
ld      (hl),a
inc     hl
inc     (hl)
ret

_octant_7_side:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)
jr      octant_7_side

_octant_7_main:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)

; Octant 7: mainly going up (Y increasing), also right (X increasing)
octant_7_main:
ld      hl,(iy+ray_x)           ; ray_x += dx/dy
ld      bc,(iy+dxdy)            ; secondary direction, advance fractional amount
octant_7_main_hl:
ld      (iy+ray_x),hl
dec     (iy+ray_y+2)            ; ray_y -= 0x10000, main direction, advance to next horizontal line crossing

ld      hl,-MAP_WIDTH
ld      a,(hl)
ex      de,hl                   ; advance wall pointer by one row
or      a
ld      (_wall),a
ret     nz                      ; exit if wall present

; test if we will cross a vertical line before the next horizontal line
octant_7_side:
ld      hl,(iy+ray_x)           ; test_x = ray_x + dx/dy
ld      bc,(iy+dxdy)            ; secondary direction, advance fractional amount
ld      (iy+test_x),hl
ld      a,(iy+ray_x+2)
cp      (iy+test_x+2)           ; continue if ipart(test_x) != ipart(ray_x)
jr      z,octant_7_main_hl

inc     de                      ; advance wall pointer by one column
ld      a,(de)
or      a
jr      z,octant_7_main         ; continue if no wall present

ld      (_wall),a               ; save wall type
ld      hl,(iy+ray_x)
ld      de,0
ld      d,h
ld      e,l                     ; DE = fpart(ray_x)
ld      hl,10000h
xor     a
sbc     hl,de                   ; HL = 0x10000 - fpart(ray_x)
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l                       ; HL = (0x10000 - fpart(ray_x)) >> 5
ld      bc,(iy+dydx)
call    __imulu                 ; HL = ((0x10000 - fpart(ray_y)) >> 5) * dy/dx

xor     a
add     hl,hl                   ; shift AHL left 2
rla
rla
ld      (iy+test_x),hl          ; shift right 8 bits (net shift right 6)
ld      (iy+test_x+3),a
ld      de,(iy+test_x+1)

ld      hl,(iy+ray_y)
sbc     hl,de
ld      (iy+ray_y),hl           ; point of intercept with vertical line

lea     hl,iy+ray_x             ; X coordinate of following vertical line
xor     a
ld      (hl),a
inc     hl
ld      (hl),a
inc     hl
inc     (hl)
ret

_octant_3_side:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)
jr      octant_3_side

_octant_3_main:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)

; Octant 3: mainly going down (Y increasing), also left (X decreasing)
octant_3_main:
xor     a
ld      hl,(iy+ray_x)           ; ray_x -= dx/dy
ld      bc,(iy+dxdy)            ; secondary direction, advance fractional amount
sbc     hl,bc
octant_3_main_hl:
ld      (iy+ray_x),hl
inc     (iy+ray_y+2)           ; ray_y += 0x10000, main direction, advance to next horizontal line crossing

ld      hl,MAP_WIDTH
ld      a,(hl)
ex      de,hl                   ; advance wall pointer by one row
or      a
ld      (_wall),a
ret     nz                      ; exit if wall present

; test if we will cross a vertical line before the next horizontal line
octant_3_side:
xor     a
ld      hl,(iy+ray_x)           ; test_x = ray_x - dx/dy
ld      bc,(iy+dxdy)            ; secondary direction, advance fractional amount
sbc     hl,bc
ld      (iy+test_x),hl
ld      a,(iy+ray_x+2)
cp      (iy+test_x+2)           ; continue if ipart(test_x) != ipart(ray_x)
jr      z,octant_3_main_hl

dec     de                      ; advance wall pointer by one column
ld      a,(de)
or      a
jr      z,octant_3_main         ; continue if no wall present

ld      (_wall),a               ; save wall type
ld      de,(iy+ray_x)
ld      hl,0
ld      h,d
ld      l,e                     ; HL = fpart(ray_x)
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l                       ; HL = (0x10000 - fpart(ray_x)) >> 5
ld      bc,(_dydx)
call    __imulu                 ; HL = ((0x10000 - fpart(ray_y)) >> 5) * dy/dx

xor     a
add     hl,hl                   ; shift AHL left 2
rla
rla
ld      (iy+test_x),hl          ; shift right 8 bits (net shift right 6)
ld      (iy+test_x+3),a
ld      hl,(iy+test_x+1)

ld      de,(iy+ray_y)
ld      (iy+ray_y),hl           ; point of intercept with vertical line

lea     hl,iy+ray_x             ; ray_x &= 0xFF0000
xor     a
ld      (hl),a
inc     hl
ld      (hl),a
ret

_octant_6_side:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)
jr      octant_6_side

_octant_6_main:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)

; Octant 6: mainly going up (Y decreasing), also left (X decreasing)
octant_6_main:
xor     a
ld      hl,(iy+ray_x)           ; ray_x -= dx/dy
ld      bc,(iy+dxdy)            ; secondary direction, advance fractional amount
sbc     hl,bc
octant_6_main_hl:
ld      (iy+ray_x),hl
dec     (iy+ray_y+2)            ; ray_y -= 0x10000, main direction, advance to next horizontal line crossing

ld      hl,-MAP_WIDTH
ld      a,(hl)
ex      de,hl                   ; advance wall pointer by one row
or      a
ld      (_wall),a
ret     nz                      ; exit if wall present

; test if we will cross a vertical line before the next horizontal line
octant_6_side:
xor     a
ld      hl,(iy+ray_x)           ; test_x = ray_x - dx/dy
ld      bc,(iy+dxdy)            ; secondary direction, advance fractional amount
sbc     hl,bc
ld      (iy+test_x),hl
ld      a,(iy+ray_x+2)
cp      (iy+test_x+2)           ; continue if ipart(test_x) != ipart(ray_x)
jr      z,octant_6_main_hl

dec     de                      ; advance wall pointer by one column
ld      a,(de)
or      a
jr      z,octant_6_main         ; continue if no wall present

ld      (_wall),a               ; save wall type
ld      de,(iy+ray_x)
ld      hl,0
ld      h,d
ld      l,e                     ; HL = fpart(ray_x)
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l                       ; HL = (0x10000 - fpart(ray_x)) >> 5
ld      bc,(iy+dydx)
call    __imulu                 ; HL = ((0x10000 - fpart(ray_y)) >> 5) * dy/dx

xor     a
add     hl,hl                   ; shift AHL left 2
rla
rla
ld      (iy+test_x),hl          ; shift right 8 bits (net shift right 6)
ld      (iy+test_x+3),a
ld      de,(iy+test_x+1)

ld      hl,(iy+ray_y)
sbc     hl,de
ld      (iy+ray_y),hl           ; point of intercept with vertical line

lea      hl,iy+ray_x            ; ray_x &= 0xFF0000
xor     a
ld      (hl),a
inc     hl
ld      (hl),a
ret

_octant_4_side:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)
jr      octant_4_side

_octant_4_main:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)

; Octant 4: mainly going left (X decreasing), also down (Y increasing)
octant_4_main:
ld      hl,(iy+ray_y)           ; ray_y += dy/dx
ld      bc,(iy+dydx)            ; secondary direction, advance fractional amount
octant_4_main_hl:
ld      (iy+ray_y),hl
dec     (iy+ray_x+2)            ; ray_x -= 0x10000, main direction, advance to next vertical line

dec     de                      ; also adjust map pointer for one block X
ld      a,(de)
or      a
ld      (_wall),a
ret     nz                      ; exit if wall present

; test if we will cross a horizontal line before the next vertical line
octant_4_side:
ld      hl,(iy+ray_y)           ; test_y = ray_y + dy/dx
ld      bc,(iy+dydx)            ; secondary direction, advance fractional amount
ld      (iy+test_y),hl
ld      a,(iy+ray_y+2)
cp      (iy+test_y+2)           ; continue if ipart(test_y) != ipart(ray_y)
jr      z,octant_4_main_hl

ld      hl,MAP_WIDTH            ; advance wall pointer by one row
ld      a,(hl)
ex      de,hl
or      a
jr      z,octant_4_main         ; continue if no wall present

ld      (_wall),a               ; save wall type
ld      hl,(iy+ray_y)
ld      de,0
ld      d,h
ld      e,l                     ; DE = fpart(ray_y)
ld      hl,10000h
xor     a
sbc     hl,de                   ; HL = 0x10000 - fpart(ray_y)
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l                       ; HL = (0x10000 - fpart(ray_y)) >> 5
ld      bc,(iy+dxdy)
call    __imulu                 ; HL = ((0x10000 - fpart(ray_y)) >> 5) * dx/dy

xor     a
add     hl,hl                   ; shift AHL left 2
rla
rla
ld      (iy+test_x),hl          ; shift right 8 bits (net shift right 6)
ld      (iy+test_x+3),a
ld      de,(iy+test_x+1)

ld      hl,(iy+ray_x)
sbc     hl,de
ld      (iy+ray_x),hl           ; point of intercept with horizontal line

lea     hl,iy+ray_y             ; Y coordinate is following horizontal line
xor     a
ld      (hl),a
inc     hl
ld      (hl),a
inc     hl
inc     (hl)
ret

_octant_5_side:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)
jr      octant_5_side

_octant_5_main:
ld      iy,_shared_struct
ld      de,(_init_map_pointer)

; Octant 5: mainly going left (X decreasing), also up (Y decreasing)
octant_5_main:
ld      hl,(iy+ray_y)           ; ray_y -= dy/dx
ld      bc,(iy+dydx)            ; secondary direction, advance fractional amount
xor     a
sbc     hl,bc
octant_5_main_hl:
ld      (iy+ray_y),hl
dec     (iy+ray_x+2)            ; ray_x -= 0x10000, main direction, advance to next vertical line

dec     de                      ; also adjust map pointer for one block X
ld      a,(de)
or      a
ld      (_wall),a
ret     nz                      ; exit if wall present

; test if we will cross a horizontal line before the next vertical line
octant_5_side:
ld      hl,(iy+ray_y)           ; test_y = ray_y + dy/dx
ld      bc,(iy+dydx)            ; secondary direction, advance fractional amount
xor     a
sbc     hl,bc
ld      (iy+test_y),hl
ld      a,(iy+ray_y+2)
cp      (iy+test_y+2)           ; continue if ipart(test_y) != ipart(ray_y)
jr      z,octant_5_main_hl

ld      hl,-MAP_WIDTH           ; advance wall pointer by one row
ld      a,(hl)
ex      de,hl
or      a
jr      z,octant_5_main         ; continue if no wall present

ld      (_wall),a               ; save wall type
ld      de,(iy+ray_y)
ld      hl,0
ld      h,d
ld      l,e                     ; HL = fpart(ray_y)
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l
srl     h
rr      l                       ; HL = (0x10000 - fpart(ray_y)) >> 5
ld      bc,(iy+dxdy)
call    __imulu                 ; HL = ((0x10000 - fpart(ray_y)) >> 5) * dx/dy

xor     a
add     hl,hl                   ; shift AHL left 2
rla
rla
ld      (iy+test_x),hl          ; shift right 8 bits (net shift right 6)
ld      (iy+test_x+3),a
ld      de,(iy+test_x+1)

ld      hl,(iy+ray_x)
sbc     hl,de
ld      (iy+ray_x),hl            ; point of intercept with horizontal line

lea     hl,iy+ray_y              ; Y coordinate is following horizontal line
xor     a
ld      (hl),a
inc     hl
ld      (hl),a
ret```