WBOOT   EQU      0
BDos    EQU      5
MaxFunc EQU     58
MaxBios EQU     33
;*****************************************************************
;       функция 61
;
; DE содержит адрес блока параметров:
;
; db #функции
; dw вектор для установки           ;если здесь -1, то просто получение
; на выходе - вектор установленный (прежний). Если (-1) - значит
; неправильный номер функции.
; номера функций должны лежать в пределах 1-57   (для BIOS)
; или от 80Н-8СH для прерываний
;*****************************************************************

; данные векторов: 0 означает отсутствие функции
        dw     WbInit          ;мифическая функция 0 - инициализация железа
                               ;замене не подлежит
BiosVect:
        dw     Fbase1##         ;при вызове вызывается WbInit!
        dw     Wboot_##        ;Wboot - это в резидентном CCP
        dw     CONST##         ;статус консоли
        dw     CONIN##         ;ввод символа с кносоли в (А)
        dw     CONOUT##        ;вывод символа на консоль из (А)
        dw     LIST##          ;вывод символа на принтер
        dw     PUNCH##         ;вывод символа на посл. интерфейс
        dw     READER##        ;прием символа с посл. интерфейса
        dw     HOME##          ;restore
        dw     SELDSK##        ;выбор диска
        dw     SETTRK##        ;установка #трека
        dw     SETSEC##        ;установка #сектора
        dw     SETDMA##        ;установка вектора DMA
        dw     READ##          ;операция чтения
        dw     WRITE##         ;операция записи
        dw     LISTST##        ;готовность принтера
        dw     SECTRAN##       ;пересчет логического номера в физ.

; дополнительная часть, с функции 17 по 34, предназначены для
; функций расширенного биоса.
; Все эти функции должны содержать инициализирующую часть,
; поскольку они все будут вызываться при каждом теплом старте

DeviceVect:
        dw      0              ; функция 17
        dw      0              ; функция 18
        dw      0              ; функция 19
        dw      0              ; функция 20
        dw      0              ; функция 21
        dw      0              ; функция 22
        dw      0              ; функция 23
        dw      0              ; функция 24
        dw      0              ; функция 25
        dw      0              ; функция 26
        dw      0              ; функция 27
        dw      0              ; функция 28
        dw      0              ; функция 29
        dw      0              ; функция 30
        dw      0              ; функция 31
        dw      0              ; функция 32
        dw      0              ; функция 33
        dw      0              ; функция 34
        dw      Fun35##        ; функция 35
        dw      Fun36##        ; функция 36
        dw      0              ; функция 37
        dw      0              ; функция 38
        dw      0              ; функция 39
        dw      0              ; функция 40
        dw      0              ; функция 41
        dw      0              ; функция 42
        dw      0              ; функция 43
        dw      0              ; функция 44
        dw      0              ; функция 45
        dw      0              ; функция 46
        dw      0              ; функция 47
        dw      Ccp##          ; функция 48, вызов CCP

; следущая порция зарезервирована под вектора данных, таких как
; конец свободной памяти и т.д.

SBdos:  dw      .begin##    ; функция 49, конец свободной памяти
        dw      0              ; функция 50
        dw      0              ; функция 51
        dw      0              ; функция 52
        dw      0              ; функция 53
        dw      0              ; функция 54
        dw      0              ; функция 55
        dw      0              ; функция 56
        dw      0              ; функция 57


; процедура установки (и получения ) вектора
SetVector::
        ldax d                 ;# функции
        cpi  MaxFun
        jc   SetBios
        sui  80h
        jnc  SetInt
SetErr:
        mvi     a,255
        inx     d
        stax    d
        inx     d
        stax    d               ; недопустимый номер вектора
        ret                     ; пока заглушка: недопустимый вектор
; устанавливаем вектор BIOS'a
SetBios:
        lxi h,BiosVect
ChVect::
        mov c,a
        mvi b,0
        dad b
        dad b           ; address
        xchg

        inx h
        mov c,m
        ldax d          ; старый вектор
        mov m,a         ; младший байт

        inx h
        mov b,m         ; новый   вектор
        inx d
        ldax d
        mov m,a         ; старший байт

        xchg            ;test for -1
        inx b
        mov a,c
        ora b
        rz              ; просили только взять
        dcx b
        mov m,b
        dcx h
        mov m,c         ; set new vector
        ret
;**********************************************************************
; устанавливаем вектор прерывания
; это должно относиться к BIOS
;**********************************************************************

MaxInt   EQU  12
TabInt   EQU  0f7c8h

SetInt:
         cpi  MaxInt
         jnc SetErr
         di
         lxi  h,TabInt
         call ChVect
         ei
         ret

;***********************************************************************
;
;                   конец функции 61
;
;***********************************************************************




;***********************************************************************
; Эта процедура пока не имеет никаких параметров. Она должна вызываться
; при каждом теплом старте. Она устанавливает в нужное состояние
; все вектора и вызывает функции инициализации процедур 17-47
; Признаком функции инициализации служит значение подфункции (255).
; Возвращает управление тому, кто вызывал.
;***********************************************************************


WBInit::
        lhld    SBdos
        lxi     d,DeviceVect
        lxi     b,0c311h
loopWV:
        dcx     d
        dcx     h
        ldax    d
        mov     m,a
        dcx     d
        dcx     h
        ldax    d
        mov     m,a
        dcx     h
        mov     m,b
;        mvi     a,2
;        cmp     c
;        jnz      skjmp
;        dcx     d
;        dcx     d       ; пропускаем WbInit! теперь нет
skjmp:
        dcr     c
        jnz     loopWV  ; устанавливаем защиту от перекрытия
        shld    Bdos+1
        inx     h
        inx     h
        inx     h
        shld    WBoot+1
        mov     a,b
        sta     WBoot
        sta     BDos    ; set cp/m vectors

; теперь вызываем INIT
        call    Init##  ; это вызывается BIOS, после уст. векторов
        lxi     h,InitBlock
        mvi     a,17    ; set start point
LoopWI:
        mov     m,a
        push    psw
        push    h
        xchg
        call    CallBios
        pop     h
        pop     psw
        inr     a
        cpi     MaxBios
        jc      LoopWI
        ret               ; возвращаем управление.
InitBlock:
        db      0       ; номер функции
        db    255       ; это код подфункции инициализации
;***********************************************************************
;               конец инициализации теплого старта
;***********************************************************************

;*****************************************************************
;       функция 50  -  вызов процедур БИОСа и драйверов устройств
; вызываются функции с номера 1 по 57. Параметры - регистровая пара
; DE содержит адрес блока параметров. Если вызывается функция 0 -
; управление получает процедура инициализации БДОС. Как правило
; ее вызывает процедура теплого старта.
; Функция различает обращение к биосу и расширенному биосу.
; Различие заключается в блоке параметров. При обращении к биосу
; блок параметров выглядит следующим образом ( списано с микродос):
;----------------------------------------------------------------------
; db #функции
; dw регистр А   (на самом деле, похоже, этого нет, и данные
; dw (рег. BC)    возвращаются в регистре. Пока сделаем как
; dw (рег. DE)    в микродосе я реассемлировал, а там будет видно)
; dw (рег. HL)     (как расширение)
; при этом результат ( состояние регистров после работы функции )
; переписываются перед возвращением в указанный блок параметров.
; Функциями БИОС считаются функции 1 - 16.
;-----------------------------------------------------------------------
;
; Блок параметров расширенного БИОС выглядит следующим образом:
;
; db #функции БИОСа
; db #подфункции. Этот байт также используется флаг успешности вызова
; dw параметр 1
; dw параметр 2
; dw параметр 3   (как расширение)
; и т.д.
; Номера функций расширенного БИОС должны лежать в пределах 17-48
; Постулируется, что байт #подфункции 255 вызывает инициализацию функции
; БИОС. Если имеет место попытка вызова несуществующей функции, номер
; функции меняется на 1 (попытка проинициализировать несуществующую
; функцию не считается ошибкой). При повторном вызове - Wboot
; Передача параметров в функцию и обратно осуществляется через блок
; параметров согласно правилам, принятым при написании данной функции.
; Регистры для передачи параметров не используются.
;*****************************************************************
CallBios::
; стек не трогаем !!!
         ldax    d
         ora    a
         jnz NotCStart
         lhld BiosVect-2
         pchl
NotCStart:
        cpi     57+1
        jnc     CallErr         ; слишком большой номер функции
        add     a               ; *2
        mov     c,a
        mvi     b,0
        lxi     h,BiosVect      ; начало векторов функций
        dad     b               ; получили адрес вектора in HL
        mov     a,m
        inx     h
        mov     h,m
        mov     l,a             ; HL содержит адрес функции, DE - блок параметров
        ora     h
        jz      CallErr         ; вызываемая функция не установлена

        mov     a,c             ; restore 2 * #func
        cpi     34              ; func # 17
        jnc     Abios           ; вызов расширенной БИОС

        xchg
        inx     h               ; начинаем брать параметры  (BC)
        mov     c,m
        inx     h
        mov     b,m
;       inx     h               ; вроде в Микродосе сделано так!
;       mov     a,m
;       inx     h
;       mov     h,m             ; пока хватит, а там будет видно
;       mov     l,a
        xchg
Abios:  pchl                    ; вызываем функцию, аргументы уже загружены

CallErr:
                                ; DE указывал на блок параметров
        mvi     a,1             ; теплый старт
        stax    d               ; неправилный вызов функции
        ret                     ; чтобы не тратить байты
;***********************************************************************
;
;                   конец функции 50
;
;***********************************************************************

        end

               конец функции 50
;
;*****