; =======================================================
; Ocean-240.2
;
; CP/M BIOS
;
; Disassembled by Romych 2025-09-09
; =======================================================

    INCLUDE "equates.inc"
    INCLUDE "ram.inc"
    INCLUDE "mon_entries.inc"

    DEFINE CHECK_INTEGRITY
    
    IFNDEF  BUILD_ROM
        OUTPUT bios.bin
    ENDIF

    MODULE  BIOS

    ORG 0xD600

; -------------------------------------------------------
; BIOS JUMP TABLE
; -------------------------------------------------------
boot_f:
    JP   bios_boot
wboot_f:
    JP   bios_wboot

; -------------------------------------------------------
; console status to reg-a
; -------------------------------------------------------
const_f:
    JP   MON.non_con_status

; -------------------------------------------------------
; console character to reg-a
; -------------------------------------------------------
conin_f:
    JP   MON.mon_con_in

; -------------------------------------------------------
; console character from c to console out
; -------------------------------------------------------
conout_f:
    JP   MON.mon_con_out

; -------------------------------------------------------
; list device out
; -------------------------------------------------------
list_f:
    JP   MON.mon_char_print

; -------------------------------------------------------
; punch device out
; -------------------------------------------------------
punch_f:
    JP   MON.mon_serial_out

; -------------------------------------------------------
; reader character in to reg-a
; -------------------------------------------------------
reader_f:
    JP   MON.mon_serial_in

; -------------------------------------------------------
; move to home position, treat as track 00 seek
; -------------------------------------------------------
home_f:
    JP   home

; -------------------------------------------------------
; select disk given by register c
; -------------------------------------------------------
seldsk_f:
    JP   sel_disk
settrk_f:
    JP   set_trk
setsec_f:
    JP   set_sec

; -------------------------------------------------------
; Set DMA address from BC
; -------------------------------------------------------
setdma_f:
    JP   set_dma
read_f:
    JP   read
write_f:
    JP   write
listst_f:
    JP   list_st
sectran_f:
    JP   sec_tran

; -------------------------------------------------------
; Reserved
; -------------------------------------------------------
    JP   warm_boot
    JP   warm_boot

; -------------------------------------------------------
; Tape read
; -------------------------------------------------------
tape_read_f:
    JP   MON.mon_tape_read

; -------------------------------------------------------
; Tape write
; -------------------------------------------------------
tape_write_f:
    JP   MON.mon_tape_write

; -------------------------------------------------------
; Tape wait block
; -------------------------------------------------------
tape_wait_f:
    JP   MON.mon_tape_wait

    JP   warm_boot                                  ; r8

disk_a_size   DW  192                               ; 192k disk A size
disk_b_size   DW  720                               ; 720  disk B size
disk_c_size   DW  720                               ; 720  disk C size
disk_b_tracks DB  80
disk_c_tracks DB  80

; -------------------------------------------------------
; cold start
; -------------------------------------------------------
bios_boot:
    LD   HL, (bdos_ent_addr)                        ; 0xba06
    LD   DE, 0x10000-CCP_RAM.bdos_enter_jump        ; 0x45fa
    ADD  HL, DE                                     ; 0xba06+0x45fa=10000
    LD   A, H
    OR   L
    JP   Z, bios_signon

    ; >> r8
    LD   HL, (bios_var0)                            ; if bios_var0 = 0xaaaa (initialized)
    LD   DE, 0x5556
    ADD  HL, DE                                     ; 0xaaaa+0x5556=0x10000 if initialized
    LD   A, H
    OR   L
    JP   Z, bios_signon                             ; if initialized, go to logon, skip init
    ; <<

    ; Init DMA buffer
    LD   HL, dma_buffer                             ; 0x8000
    LD   B, DMA_BUFF_SIZE                           ; 0x80
.init_dma_buff:
    LD   (HL), FILE_DELETED                         ; 0xE5
    INC  HL
    DEC  B
    JP   NZ, .init_dma_buff

    ; Init RAM disk
    LD   HL, dma_buffer
    LD   DE, 0x0000
    LD   B, 8

.init_ram_dsk:
    PUSH BC
    CALL MON.ram_disk_write
    POP  BC
    INC  DE
    DEC  B
    JP   NZ, .init_ram_dsk

    ; Init user to 0 and drive to 0
    XOR  A
    LD   (cur_user_drv), A

    ; init bios variables
    CALL  bios_init_ilv                             ; r8

bios_signon:
    LD   SP, bios_stack
    ; Print CP/M hello message
    LD   HL, msg_hello
    CALL print_strz
    JP   bios_wboot

;bios_wboot:
;    LD   SP, bios_stack

; r8 >>
bios_init_ilv:
    LD   HL, bios_var0
    LD   DE, bios_ini_vals
    LD   C, 13
    CALL mov_dlhe_c
    LD   A, (disk_c_tracks)                            ; 0x50
    LD   (disk_c_tracks), A
    RET
; <<

; -------------------------------------------------------
; BIOS Warm start entry
; -------------------------------------------------------
bios_wboot:                                         ; r8

    LD   HL, (bios_var0)
    LD   DE, 0x5556                                 ; 0xaaaa + 0x5556 = 0x10000
    ADD  HL, DE
    LD   A, H
    OR   L
    CALL NZ, bios_init_ilv                          ; init if not initialized before
    LD   SP, bios_stack

    ; Move CPP from 0xC000 to 0xB200
    LD   HL, CCP_DST_ADDR
    LD   DE, CCP_SRC_ADDR
    LD   BC, CCP_SIZE
.move_ccp:
    LD   A, (DE)
    LD   (HL), A
    INC  DE
    INC  HL
    DEC  BC
    LD   A, B
    OR   C
    JP   NZ, .move_ccp

    ; Init variables with zeroes
    LD   HL, CPM_VARS.cpm_vars_start
    LD   BC, CPM_VARS.ccp_vars_size                 ; 213

.clr_cpm_vars:
    LD   (HL), 0x0
    INC  HL
    DEC  BC
    LD   A, B
    OR   C
    JP   NZ, .clr_cpm_vars

    LD   A, FILE_DELETED
    LD   (CPM_VARS.bdos_efcb), A                    ; mark empty FCB
    LD   A, low dma_buffer                          ; 0x80
    LD   (CPM_VARS.bdos_dmaad), A                   ; 0x0080

    ; Move DPH + DPB to RAM
    LD   HL, CPM_VARS.DPH_RAM
    LD   DE, dph_disk_a
    LD   BC, DPB_END-dph_disk_a                     ; 0x39 -> 57d

.move_dph:
    LD   A, (DE)
    LD   (HL), A
    INC  HL
    INC  DE
    DEC  BC
    LD   A, B
    OR   C
    JP   NZ, .move_dph

    LD   BC, dma_buffer                          ; DMA default buffer addr
    CALL setdma_f

    ; Setup JP to Warm boot after CPU reset
    LD   A, JP_OPCODE
    LD   (warm_boot), A
    LD   HL, wboot_f
    LD   (warm_boot_addr), HL

    ; Setup JP to BDOS entrance
    LD   (jp_bdos_enter), A
    LD   HL, CCP_RAM.bdos_enter_jump
    LD   (bdos_ent_addr), HL

    ; Disk A
    LD   HL, CPM_VARS.DPB_A_RAM
    LD   C, 0xf
    LD   DE, dpb_ram
    LD   A, (disk_a_size+1)
    OR   A
    JP   Z, .drv_a_192
    LD   DE, dpb_empty
.drv_a_192:
    CALL mov_dlhe_c

    ; Disk B
    LD   HL, CPM_VARS.DPB_B_RAM
    LD   C, 0xf
    LD   DE, dpb_flop_360k
    LD   A, (disk_b_size+1)
    CP   0x1
    JP   Z, .drv_b_360
    LD   DE, dpb_flop_720k
.drv_b_360:
    CALL mov_dlhe_c

    ; Disk C
    LD   HL, CPM_VARS.DPB_C_RAM
    LD   C, 0xf
    LD   A, (disk_c_size+1)
    CP   0x2                                        ; 720?
    JP   Z, .drv_c_720
    LD   DE, dpb_flop_360k
    ; bios_var3 != 0 -> move DPB 360k
    LD   A, (disk_sw_trk)
    OR   A
    JP   NZ, .drv_c_mov
    ; bios_var3 == 0 -> move DPB 720k
    LD   DE, dpb_flop_720k
    JP   .drv_c_mov
.drv_c_720:
    LD   DE, dpb_flop_720k
    ; bios_var3 != 0 -> move DPB 720k
    LD   A, (disk_sw_trk)
    OR   A
    JP   NZ, .drv_c_mov
    ; bios_var3 == 1 -> move DPB 360k
    LD   DE, dpb_flop_360k
.drv_c_mov:
    CALL  mov_dlhe_c
    XOR   A
    LD    (CPM_VARS.slicer_has_data),A
    LD    (CPM_VARS.slicer_uninited_count),A
    LD    A,(cur_user_drv)
    LD    C,A
    ; go to CCP
    JP    CCP_DST_ADDR

; -------------------------------------------------------
; Move C bytes from [DE] to [HL]
; -------------------------------------------------------
mov_dlhe_c:
    LD   A,(DE)                                     ; [DE]->[HL]
    LD   (HL),A
    INC  HL
    INC  DE
    DEC  C
    JP   NZ, mov_dlhe_c
    RET

list_st:
    XOR  A
    RET

; -------------------------------------------------------
; Select disk
; Inp: C - disk,
;      E - active drive flag
; Out: HL -> DPH
; -------------------------------------------------------
sel_disk:
    LD   HL, 0x00
    LD   A, C
    CP   CTRL_C
    RET  NC

    LD   (CPM_VARS.cur_disk), A
    OR   A
    JP   Z, .get_dph_addr                           ; skip next for disk 0 - RAM disk
    LD   A, E                                       ; selected disk map
    AND  0x1                                        ; bit 0 is set if disk already selected
    JP   NZ, .get_dph_addr
    ; Reset disk
    LD  (CPM_VARS.slicer_has_data), A
    LD  (CPM_VARS.slicer_uninited_count), A
    ; calc DPH address of new drive
.get_dph_addr:
    LD  L, C
    LD  H, 0x0
    ADD HL, HL                                      ; *2
    ADD HL, HL                                      ; *4
    ADD HL, HL                                      ; *8
    ADD HL, HL                                      ; *16 (size of DBH)
    LD  DE, CPM_VARS.DPH_RAM
    ADD HL, DE
    RET

; -------------------------------------------------------
; move to track 00
; -------------------------------------------------------
home:
    LD   A, (CPM_VARS.cur_disk)
    OR   A
    JP   Z, .is_default
    LD   A, (CPM_VARS.slicer_need_save)
    OR   A
    JP   NZ, .is_default
    LD   (CPM_VARS.slicer_has_data), A              ; set to 0, no data

.is_default:
    LD   C, 0                                       ; set track to 0

; -------------------------------------------------------
; set track address (0..76) for subsequent read/write
; -------------------------------------------------------
set_trk:
    LD   HL, CPM_VARS.curr_track
    LD   (HL), C
    RET

; -------------------------------------------------------
; set sector address (1,..., 26) for subsequent read/write
; -------------------------------------------------------
set_sec:
    LD   HL, CPM_VARS.curr_sec
    LD   (HL), C
    RET

; -------------------------------------------------------
; set subsequent dma address (initially 80h)
; -------------------------------------------------------
set_dma:
    LD   L, C
    LD   H, B
    LD   (CPM_VARS.dma_addr), HL
    RET

sec_tran:
    LD   L, C
    LD   H, B
    RET

; -------------------------------------------------------
; read track/sector to preset dma address
; -------------------------------------------------------
read:
    LD   A, (CPM_VARS.cur_disk)
    OR   A
    JP   NZ, read_phys                               ; for physical disk use special routine
    CALL ram_disk_calc_addr
    CALL MON.ram_disk_read
    XOR  A
    RET

; -------------------------------------------------------
; write track/sector from preset dma address
; -------------------------------------------------------
write:
    LD   A, (CPM_VARS.cur_disk)
    OR   A
    JP   NZ,write_phys
    CALL ram_disk_calc_addr
    CALL MON.ram_disk_write
    XOR  A
    RET

; -------------------------------------------------------
; Calculate address for current sector and track
; -------------------------------------------------------
ram_disk_calc_addr:
    LD   HL, CPM_VARS.curr_track
    ; HL = cur_track * 16
    LD   L, (HL)
    LD   H, 0x0
    ADD  HL, HL
    ADD  HL, HL
    ADD  HL, HL
    ADD  HL, HL
    ; DE = HL + cur_sec
    EX   DE, HL
    LD   HL, CPM_VARS.curr_sec
    LD   L, (HL)
    LD   H, 0x0
    ADD  HL, DE
    EX   DE, HL
    ; store address
    LD   HL, (CPM_VARS.dma_addr)
    RET

read_phys:
    CALL read_phys_op
    RET

write_phys:
    CALL write_phys_op
    RET

read_phys_op:
    XOR A
    ; reset counter
    LD   (CPM_VARS.slicer_uninited_count), A
    LD   A, 0x1
    LD   (CPM_VARS.tmp_slicer_operation), A         ; 0 - write; 1 - read
    LD   (CPM_VARS.tmp_slicer_can_read), A          ; enable read fron disk
    LD   A, 0x2
    LD   (CPM_VARS.tmp_slicer_flush), A             ; disable flush data to disk
    JP   base_read_write

write_phys_op:
    XOR  A
    LD   (CPM_VARS.tmp_slicer_operation), A
    LD   A, C
    LD   (CPM_VARS.tmp_slicer_flush), A
    CP   0x2
    JP   NZ, .mode_ne_2
    LD   A, 0x10                                    ; 2048/128
    LD   (CPM_VARS.slicer_uninited_count), A
    LD   A, (CPM_VARS.cur_disk)
    LD   (CPM_VARS.slicer_uninited_disk), A
    LD   A, (CPM_VARS.curr_track)
    LD   (CPM_VARS.slicer_uninited_track), A
    LD   A, (CPM_VARS.curr_sec)
    LD   (CPM_VARS.slicer_uninited_sector_128), A
.mode_ne_2:
    LD   A, (CPM_VARS.slicer_uninited_count)
    OR   A
    JP   Z, slicer_read_write
    DEC  A
    LD   (CPM_VARS.slicer_uninited_count), A
    LD   A, (CPM_VARS.cur_disk)
    LD   HL, CPM_VARS.slicer_uninited_disk
    CP   (HL)
    JP   NZ, slicer_read_write
    LD   A, (CPM_VARS.curr_track)
    LD   HL, CPM_VARS.slicer_uninited_track
    CP   (HL)
    JP   NZ, slicer_read_write
    LD   A, (CPM_VARS.curr_sec)
    LD   HL, CPM_VARS.slicer_uninited_sector_128
    CP   (HL)
    JP   NZ, slicer_read_write
    INC  (HL)
    LD   A, (HL)
    CP   36                                         ; Sectors per track
    JP   C, .no_inc_track
    LD   (HL), 0x0
    LD   A, (CPM_VARS.slicer_uninited_track)
    INC  A
    LD   (CPM_VARS.slicer_uninited_track), A

.no_inc_track:
    XOR  A
    LD   (CPM_VARS.tmp_slicer_can_read), A
    JP   base_read_write

; --------------------------------------------------
slicer_read_write:
    XOR  A
    LD   (CPM_VARS.slicer_uninited_count), A
    INC  A
    LD   (CPM_VARS.tmp_slicer_can_read), A

; --------------------------------------------------
base_read_write:
    XOR  A
    LD   (CPM_VARS.tmp_slicer_result), A
    LD   A, (CPM_VARS.curr_sec)
    OR   A
    RRA
    OR   A
    RRA
    LD   (CPM_VARS.tmp_slicer_real_sector), A
    LD   HL, CPM_VARS.slicer_has_data
    LD   A, (HL)
    LD   (HL), 0x1
    OR   A
    JP   Z, .no_data
    LD   A, (CPM_VARS.cur_disk)
    LD   HL, CPM_VARS.slicer_disk
    CP   (HL)
    JP   NZ, .pos_diff
    LD   A, (CPM_VARS.curr_track)
    LD   HL, CPM_VARS.slicer_track
    CP   (HL)
    JP   NZ, .pos_diff
    LD   A, (CPM_VARS.tmp_slicer_real_sector)
    LD   HL, CPM_VARS.slicer_real_sector
    CP   (HL)
    JP   Z,calc_sec_addr_in_bfr
.pos_diff:
    LD   A, (CPM_VARS.slicer_need_save)
    OR   A
    CALL    NZ, slicer_save_buffer                  ; save buffer if needed
.no_data:
    LD   A, (CPM_VARS.cur_disk)
    LD   (CPM_VARS.slicer_disk), A
    LD   A, (CPM_VARS.curr_track)
    LD   (CPM_VARS.slicer_track), A
    LD   A, (CPM_VARS.tmp_slicer_real_sector)
    LD   (CPM_VARS.slicer_real_sector), A
    LD   A, (CPM_VARS.tmp_slicer_can_read)
    OR   A
    CALL NZ,slicer_read_buffer
    XOR  A
    LD   (CPM_VARS.slicer_need_save), A

; --------------------------------------------------
calc_sec_addr_in_bfr:
    LD   A, (CPM_VARS.curr_sec)
    AND  0x3
    LD   L, A
    LD   H, 0
    ADD  HL, HL
    ADD  HL, HL
    ADD  HL, HL
    ADD  HL, HL
    ADD  HL, HL
    ADD  HL, HL
    ADD  HL, HL                                     ; *128
    LD   DE, CPM_VARS.slicer_buffer
    ADD  HL, DE
    EX   DE, HL
    LD   HL, (CPM_VARS.dma_addr)
    LD   C, 0x80
    LD   A, (CPM_VARS.tmp_slicer_operation)
    OR   A
    JP   NZ, .no_save
    LD   A, 0x1
    LD   (CPM_VARS.slicer_need_save), A
    EX   DE, HL
.no_save:
    LD   A, (DE)
    INC  DE
    LD   (HL), A
    INC  HL
    DEC  C
    JP   NZ, .no_save
    LD   A, (CPM_VARS.tmp_slicer_flush)
    CP   0x1
    LD   A, (CPM_VARS.tmp_slicer_result)
    RET  NZ
    OR   A
    RET  NZ
    XOR  A
    LD   (CPM_VARS.slicer_need_save), A
    CALL slicer_save_buffer
    LD   A, (CPM_VARS.tmp_slicer_result)
    RET

; --------------------------------------------------
slicer_save_buffer:
    CALL slicer_get_floppy_args
    LD   C, 0xA6                                    ; VG93 CMD
    CALL MON.write_floppy
    LD   (CPM_VARS.tmp_slicer_result), A
    RET

; --------------------------------------------------
slicer_read_buffer:
    CALL slicer_get_floppy_args
    LD   C, 0x86                                    ; VG93 CMD
    CALL MON.read_floppy
    LD   (CPM_VARS.tmp_slicer_result), A
    RET

; --------------------------------------------------
slicer_get_floppy_args:
    LD   HL, CPM_VARS.tmp_buff9
    LD   A, (CPM_VARS.slicer_disk)
    DEC  A
    JP   Z, .non_interleave
    LD   HL, interleave_0
.non_interleave:
    LD   A, (CPM_VARS.slicer_real_sector)
    ADD  A, L
    LD   L, A
    LD   E, (HL)
    LD   A, (CPM_VARS.slicer_track)
    LD   D, A
    LD   HL, CPM_VARS.slicer_buffer
    LD   A, (CPM_VARS.slicer_disk)
    RET


; -------------------------------------------------------
; Print zerro ended string
; Inp: HL -> string
; -------------------------------------------------------
print_strz:
    LD   A, (HL)
    OR   A
    RET  Z
    LD   C, A
    PUSH HL
    CALL conout_f
    POP  HL
    INC  HL
    JP   print_strz

msg_hello:
    DB   ASCII_ESC, "6", "0"                            ; 40x25 cursor on
    DB   ASCII_ESC, "8", "3"                            ; set palette
    DB   ASCII_ESC, "5", 33, 37                         ; set cursor r,c
    DB   ASCII_ESC, "4", "1"                            ; set color
    DB   ASCII_ESC, "1", 22, 226, 226, 252, 1           ; draw fill rect x1,y1,x2,y2,m
    DB   ASCII_ESC, "4", "0"                            ; set color
    DB   ASCII_ESC, "1", 30, 230, 219, 248, 1           ; draw fill rect x1,y1,x2,y2,m
    DB   ASCII_ESC, "4", "3"                            ; set color
    DB  "OKEAH-240 CP/M (V2.2) REL.8'\r\n\n"
    DB   ASCII_ESC, "4", "2", 0                         ; set color


; --------------------------------------------------
; Disk parameters blocks in ROM (DPBs)
; Tables of memory that describe the characteristics
; of discs on our system. There is one DPB for each
; disc type

; ----------------------------------------
; Block size | No of sectors | BSH | BLM |
; ----------------------------------------
;     1K     |  8            |  3  | 7   |
;     2K     |  16           |  4  | 15  |
;     4K     |  32           |  5  | 31  |
;     8K     |  64           |  6  | 63  |
;     16K    |  128          |  7  | 127 |
; ----------------------------------------

; -------------------------------------
; Block size|      Extent mask  (EXM) |
;           | Small disk | Large disk |
; -------------------------------------
;     2K    |      1     |     0      |
;     4K    |      3     |     1      |
;     8K    |      7     |     3      |
;    16K    |     15     |     7      |
; -------------------------------------
; CKS - number of dir sectors to check before write, 0 for HDD

; For RAM-Disk 192k
dpb_ram:
    DW  16                                          ; SPT Sector (128b) per track (16d)
    DB  3                                           ; BSH 1k
    DB  7                                           ; BLM 1k;  Allocation block size = (BLM + 1) * 128 = 1k
    DB  0                                           ; EXM extent mask
    DW  191                                         ; DSM Disk size blocks - 1
    DW  31                                          ; DRM Dir elements - 1
    DB  10000000b                                   ; AL0 Dir map byte 1
    DB  00000000b                                   ; AL1 Dir map byte 2
    DW  0x0008                                      ; CKS checksum vector size (8 sectors=1k)
    DW  0x0000                                      ; OFF (tracks reserved for system)

dpb_empty:
    DS  15, 0xff

; For FLOPPY 720k
dpb_flop_720k:
    DW  36                                          ; SPT Sector (128b) per track 36 * 128 = 18KB
    DB  4                                           ; BSH 2k
    DB  15                                          ; BLM 2k;  Allocation block size = (BLM + 1) * 128 = 2k
    DB  0                                           ; EXM extent mask
    DW  359                                         ; DSM Disk size blocks - 1 (359d)
    DW  127                                         ; DRM Directory entries - 1 (127d)
    DB  11000000b                                   ; AL0 Dir map byte 1 (2 dir blk)
    DB  00000000b                                   ; AL1 Dir map byte 2
    DW  32                                          ; CKS checksum vector size (32 sectors = 2k)
    DW  0x0000                                      ; OFF (No of tracks reserved for system)

; For FLOPPY 360k
dpb_flop_360k:
    DW  36                                          ; SPT Sector (128b) per track 36 * 128 = 18KB
    DB  4                                           ; BSH 2k
    DB  15                                          ; BLM 2k;  Allocation block size = (BLM + 1) * 128 = 2k
    DB  1                                           ; EXM extent mask
    DW  179                                         ; DSM Disk size blocks - 1 (179d)
    DW  127                                         ; DRM Directory entries - 1 (127d)
    DB  11000000b                                   ; AL0 Dir map byte 1 (2 dir blk)
    DB  00000000b                                   ; AL1 Dir map byte 2
    DW  32                                          ; CKS checksum vector size (32 sectors = 2k)
    DW  0x0000                                      ; OFF (No of tracks reserved for system)

bios_ini_vals:
    DB  0xaa, 0xaa, 0, 0xff, 1, 8, 6, 4, 2, 9, 7, 5, 3

; --------------------------------------------------
; Disk parameters headers in ROM
; --------------------------------------------------
; Disk A RAM
dph_disk_a:
    DW  0                                           ; Sector translate table pointer
    DW  0, 0, 0                                     ; Scratchpad area
    DW  CPM_VARS.dir_buffer                         ; Directory buffer pointer
    DW  CPM_VARS.DPB_A_RAM                          ; DPB Pointer
    DW  CPM_VARS.CHK_VEC_A                          ; Check Vector pointer
    DW  CPM_VARS.AL_MAP_A                           ; Allocation map pointer

; Disk B Floppy
dph_disk_b:
    DW  0                                           ; Sector translate table pointer
    DW  0, 0, 0                                     ; Scratchpad area
    DW  CPM_VARS.dir_buffer                         ; Directory buffer pointer
    DW  CPM_VARS.DPB_B_RAM                          ; DPB Pointer
    DW  CPM_VARS.CHK_VEC_B                          ; Check Vector pointer
    DW  CPM_VARS.AL_MAP_B                           ; Allocation map pointer

; Disk C Floppy
dph_disk_c:
    DW  0                                           ; Sector translate table pointer
    DW  0, 0, 0                                     ; Scratchpad area
    DW  CPM_VARS.dir_buffer                         ; Directory buffer pointer
    DW  CPM_VARS.DPB_C_RAM                          ; DPB Pointer
    DW  CPM_VARS.CHK_VEC_C                          ; Check Vector pointer
    DW  CPM_VARS.AL_MAP_C                           ; Allocation map pointer

res_data:                                           ; offset 0xda28
    DB  1, 8, 6, 4, 2, 9, 7, 5, 3

DPB_END     EQU $
    DB  0x0e, 3


; -------------------------------------------------------
; Filler to align blocks in ROM
; -------------------------------------------------------
LAST        EQU     $
CODE_SIZE   EQU     LAST-0xD600
FILL_SIZE   EQU     0x500-CODE_SIZE

    DISPLAY "| BIOS\t| ",/H,boot_f,"  | ",/H,CODE_SIZE," | ",/H,FILL_SIZE," |"

    IFDEF CHECK_INTEGRITY
    ; Check integrity
    ASSERT bios_wboot = 0xd6a8
    ASSERT sel_disk = 0xd781
    ASSERT home = 0xd7a7
    ASSERT ram_disk_calc_addr = 0xd7eb
    ASSERT write_phys_op = 0xd81e
    ASSERT base_read_write = 0xd88a
    ASSERT calc_sec_addr_in_bfr = 0xd8e4
    ASSERT slicer_save_buffer = 0xd928
    ASSERT print_strz = 0xd95e
    ASSERT msg_hello = 0xd96b
    ASSERT dpb_ram = 0xd9af
    ASSERT dph_disk_a = 0xd9f8
    ASSERT res_data = 0xda28
    ENDIF

FILLER:
    DS  FILL_SIZE, 0xff

    ENDMODULE

    IFNDEF  BUILD_ROM
        OUTEND
    ENDIF
