;LAST UPDATE: 21.03.2020 savelij
include ../../macros.a80
include ../../global_vars.a80
include ../../define.a80
include ../../evodos_vars.a80
STACK EQU 0X0DFF
OLD_IF EQU STACK-WORD*2
OLD_AF EQU STACK-WORD
;команда выхода и переход на обработчик
JP_EMU MACRO ADDRESS
DUPL ADDRESS-$,0;XFF
OUT (EXIT_PORT),A
JP ADR_ADDRESS
ENDM
;генерация адресов для таблицы
LABEL_GEN MACRO ADDRESS
_ADDRESS EQU ($-TABLE_VIRT)/4
DW ADDRESS,ADR_ADDRESS.WORK
ENDM
;переход на обработчик с кодом адреса
EMU_JUMP MACRO ADDRESS
ADR_ADDRESS EQU $
LD (OLD_AF+1),A
LD A,_ADDRESS
JP WORKER
.WORK EQU $
ENDM
ORG 0
DUPL 0X0038-$,0;XFF
EI
RET
DUPL 0X006F-$,0;XFF
JP (HL)
JP_EMU 0X02BE ; OUT (0XFF), A
DUPL 0X801-$,0;XFF
;[таблица адресов перехвата и вызыватора обработчиков]
TABLE_VIRT LABEL_GEN 0X02BE ; OUT (0XFF), A
LABEL_GEN 0X1E3A ; OUT (0X3F), A
LABEL_GEN 0X1FDD ; IN A, (0X1F)
LABEL_GEN 0X1FF3 ; OUT (0XFF), A
LABEL_GEN 0X2000 ; OUT (0X1F), A
LABEL_GEN 0X2076 ; IN A, (0X1F)
LABEL_GEN 0X2085 ; OUT (0X3F), A
LABEL_GEN 0X208D ; OUT (0X5F), A
LABEL_GEN 0X2093 ; OUT (0X1F), A
LABEL_GEN 0X2099 ; IN A, (0X1F)
LABEL_GEN 0X20B1 ; IN A, (0XFF)
LABEL_GEN 0X20B8 ; OUT (C), D
LABEL_GEN 0X2740 ; IN A, (0X1F)
LABEL_GEN 0X2748 ; OUT (0X7F), A
LABEL_GEN 0X2A53 ; OUT (C), A
LABEL_GEN 0X2A71 ; OUT (0XFF), A MAGIC
LABEL_GEN 0X2A77 ; IN A, (0X1F) MAGIC
LABEL_GEN 0X2AD9 ; OUT (OXFF), A MAGIC
LABEL_GEN 0X2B25 ; IN A, (0X5F) MAGIC
LABEL_GEN 0X2C07 ; IN A, (0X5F) MAGIC
LABEL_GEN 0X2CD8 ; IN A, (0X5F) MAGIC
LABEL_GEN 0X2D75 ; OUT (0X5F), A MAGIC
LABEL_GEN 0X2D80 ; OUT (0X1F), A MAGIC
LABEL_GEN 0X2D87 ; IN A, (0X1F) MAGIC
LABEL_GEN 0X2F0C ; OUT (0XFF), A MAGIC
LABEL_GEN 0X2F1D ; OUT (0X5F), A MAGIC
LABEL_GEN 0X2F28 ; OUT (0X1F), A MAGIC
LABEL_GEN 0X2F2F ; IN A, (0X1F) MAGIC
LABEL_GEN 0X2F3C ; OUT (0XFF), A MAGIC
LABEL_GEN 0X2F4D ; OUT (0XFF), A MAGIC
LABEL_GEN 0X2F50 ; OUT (0X7F), A MAGIC
LABEL_GEN 0X2F57 ; OUT (0X1F), A MAGIC
LABEL_GEN 0X2F59 ; IN A, (0XFF)
LABEL_GEN 0X2FB1 ; OUT (0XFF), A
LABEL_GEN 0X2FC3 ; OUT (0X1F), A
LABEL_GEN 0X3C30 ; IN A, (0X1F)
LABEL_GEN 0X3D4D ; OUT (0XFF), A
LABEL_GEN 0X3D9A ; OUT (0X1F), A
LABEL_GEN 0X3DA6 ; IN A, (0XFF)
LABEL_GEN 0X3DB5 ; IN A, (0X1F)
LABEL_GEN 0X3DBA ; IN A, (0X1F)
LABEL_GEN 0X3DD5 ; OUT (0XFF), A
LABEL_GEN 0X3E30 ; IN A, (0X1F)
LABEL_GEN 0X3E3A ; IN A, (0X1F)
LABEL_GEN 0X3E44 ; OUT (0X7F), A
LABEL_GEN 0X3E4C ; OUT (0X7F), A
LABEL_GEN 0X3E50 ; IN A, (0X3F)
LABEL_GEN 0X3E78 ; IN A, (0X3F)
LABEL_GEN 0X3E7E ; OUT (0X3F), A
LABEL_GEN 0X3E87 ; IN A, (0X3F)
LABEL_GEN 0X3E95 ; OUT (0X3F), A
LABEL_GEN 0X3EB5 ; IN A, (0X1F)
LABEL_GEN 0X3EBC ; IN A, (0X3F)
LABEL_GEN 0X3EC9 ; OUT (0X1F), A
LABEL_GEN 0X3ECE ; IN A, (0XFF)
LABEL_GEN 0X3EDF ; OUT (0X1F), A
LABEL_GEN 0X3EF3 ; IN H, (C)
LABEL_GEN 0X3EF5 ; IN A, (0XFF)
LABEL_GEN 0X3EFE ; IN A, (0X7F)
LABEL_GEN 0X3F1B ; OUT (0X5F), A
LABEL_GEN 0X3F25 ; OUT (0X1F), A
LABEL_GEN 0X3F33 ; IN A, (0X1F)
LABEL_GEN 0X3F4D ; OUT (0X1F), A
LABEL_GEN 0X3F55 ; IN A, (0X3F)
LABEL_GEN 0X3F5A ; IX A, (0X5F)
LABEL_GEN 0X3F69 ; IN A, (0X3F)
LABEL_GEN 0X3F72 ; IN A, (0X5F)
LABEL_GEN 0X3FBC ; IN A, (0XFF)
LABEL_GEN 0X3FCA ; IN A, (0XFF)
LABEL_GEN 0X3FD1 ; OUTI
LABEL_GEN 0X3FD7 ; IN A, (0XFF)
LABEL_GEN 0X3FE5 ; IN A, (0XFF)
LABEL_GEN 0X3FEC ; INI
LABEL_GEN 0X3FF0 ; OUT (C), A
LABEL_GEN 0X3FF3 ; IN A, (C)
;[вызываторы перехвата]
;OUT (0XFF),A
EMU_JUMP 0X02BE
JP OUT_FF
;OUT (0X3F),A
EMU_JUMP 0X1E3A
JP OUT_3F
;IN A,(0X1F)
EMU_JUMP 0X1FDD
JP IN_1F
;OUT (0XFF),A
EMU_JUMP 0X1FF3
JP OUT_FF
;OUT (0X1F),A
EMU_JUMP 0X2000
JP OUT_1F
;IN A,(0X1F)
EMU_JUMP 0X2076
JP IN_1F
;OUT (0X3F),A
EMU_JUMP 0X2085
JP OUT_3F
;OUT (0X5F),A
EMU_JUMP 0X208D
JP OUT_5F
;OUT (0X1F),A
EMU_JUMP 0X2093
JP OUT_1F
;IN A,(0X1F)
EMU_JUMP 0X2099
JP IN_1F
;IN A,(0XFF)
EMU_JUMP 0X20B1
JP IN_FF
;OUT (C),D
EMU_JUMP 0X20B8
JP OUT_C_D
;IN A,(0X1F)
EMU_JUMP 0X2740
JP IN_1F
;OUT (0X7F),A
EMU_JUMP 0X2748
JP OUT_7F
;OUT (C),A
EMU_JUMP 0X2A53
JP OUT_C_A
;OUT (0XFF),A
EMU_JUMP 0X2A71
JP OUT_FF
;IN A,(0X1F)
EMU_JUMP 0X2A77
JP IN_1F
;OUT (0XFF),A
EMU_JUMP 0X2AD9
JP OUT_FF
;IN A,(0X5F)
EMU_JUMP 0X2B25
JP IN_5F
;IN A,(0X5F)
EMU_JUMP 0X2C07
JP IN_5F
;IN A,(0X5F)
EMU_JUMP 0X2CD8
JP IN_5F
;OUT (0X5F),A
EMU_JUMP 0X2D75
JP OUT_5F
;OUT (0X1F),A
EMU_JUMP 0X2D80
JP OUT_1F
;IN A,(0X1F)
EMU_JUMP 0X2D87
JP IN_1F
;OUT (0XFF),A
EMU_JUMP 0X2F0C
JP OUT_FF
;OUT (0X5F),A
EMU_JUMP 0X2F1D
JP OUT_5F
;OUT (0X1F),A
EMU_JUMP 0X2F28
JP OUT_1F
;IN A,(0X1F)
EMU_JUMP 0X2F2F
JP IN_1F
;OUT (0XFF),A
EMU_JUMP 0X2F3C
JP OUT_FF
;OUT (0XFF),A
EMU_JUMP 0X2F4D
JP OUT_FF
;OUT (0X7F),A
EMU_JUMP 0X2F50
JP OUT_7F
;OUT (0X1F),A
EMU_JUMP 0X2F57
JP OUT_1F
;IN A,(0XFF)
EMU_JUMP 0X2F59
CALL IN_FF
LD HL,EXIT_0X2F59
LD (ADR_EXIT),HL
JP UPDATE_AF
;OUT (0XFF),A
EMU_JUMP 0X2FB1
JP OUT_FF
;OUT (0X1F),A
EMU_JUMP 0X2FC3
JP OUT_1F
;IN A,(0X1F)
EMU_JUMP 0X3C30
JP IN_1F
;OUT (0XFF),A
EMU_JUMP 0X3D4D
JP OUT_FF
;OUT (0X1F),A
EMU_JUMP 0X3D9A
JP OUT_1F
;IN A,(0XFF)
EMU_JUMP 0X3DA6
JP IN_FF
;IN A,(0X1F)
EMU_JUMP 0X3DB5
JP IN_1F
;IN A,(0X1F)
EMU_JUMP 0X3DBA
JP IN_1F
;OUT (0XFF),A
EMU_JUMP 0X3DD5
JP OUT_FF
;IN A,(0X1F)
EMU_JUMP 0X3E30
JP IN_1F
;IN A,(0X1F)
EMU_JUMP 0X3E3A
JP IN_1F
;OUT (0X7F),A
EMU_JUMP 0X3E44
JP OUT_7F
;OUT (0X7F),A
EMU_JUMP 0X3E4C
JP OUT_7F
;IN A,(0X3F)
EMU_JUMP 0X3E50
JP IN_3F
;IN A,(0X3F)
EMU_JUMP 0X3E78
JP IN_3F
;OUT (0X3F),A
EMU_JUMP 0X3E7E
JP OUT_3F
;IN A,(0X3F)
EMU_JUMP 0X3E87
JP IN_3F
;OUT (0X3F),A
EMU_JUMP 0X3E95
JP OUT_3F
;IN A,(0X1F)
EMU_JUMP 0X3EB5
JP IN_1F
;IN A,(0X3F)
EMU_JUMP 0X3EBC
JP IN_3F
;OUT (0X1F),A
EMU_JUMP 0X3EC9
JP OUT_1F
;IN A,(0XFF)
EMU_JUMP 0X3ECE
JP IN_FF
;OUT (0X1F),A
EMU_JUMP 0X3EDF
JP OUT_1F
;IN H,(C)
EMU_JUMP 0X3EF3
JP IN_H_C
;IN A,(0XFF)
EMU_JUMP 0X3EF5
CALL IN_FF
LD HL,EXIT_0X3EF5
LD (ADR_EXIT),HL
UPDATE_AF LD A,(OLD_AF+1)
AND 0XC0
PUSH AF
POP HL
LD (OLD_AF),HL
RET
;IN A,(0X7F)
EMU_JUMP 0X3EFE
CALL INFF_BIT6
JP IN_7F
;OUT (0X5F),A
EMU_JUMP 0X3F1B
JP OUT_5F
;OUT (0X1F),A
EMU_JUMP 0X3F25
JP OUT_1F
;IN A,(0X1F)
EMU_JUMP 0X3F33
JP IN_1F
;OUT (0X1F),A
EMU_JUMP 0X3F4D
JP OUT_1F
;IN A,(0X3F)
EMU_JUMP 0X3F55
JP IN_3F
;IN A,(0X5F)
EMU_JUMP 0X3F5A
JP IN_5F
;IN A,(0X3F)
EMU_JUMP 0X3F69
JP IN_3F
;IN A,(0X5F)
EMU_JUMP 0X3F72
JP IN_5F
;IN A,(0XFF) ;запись сектора
EMU_JUMP 0X3FBC
JP WRITE_SECTOR
;IN A,(0XFF) ;запись сектора
EMU_JUMP 0X3FCA
JP WRITE_SECTOR
;OUTI ;запись сектора
EMU_JUMP 0X3FD1
JP WRITE_SECTOR
;IN A,(0XFF) ;чтение сектора
EMU_JUMP 0X3FD7
JP READ_SECTOR
;IN A,(0XFF) ;чтение сектора
EMU_JUMP 0X3FE5
JP READ_SECTOR
;INI ;чтение сектора
EMU_JUMP 0X3FEC
JP IN_INI
;OUT (C),A
EMU_JUMP 0X3FF0
LD BC,(OLD_BC)
LD A,(OLD_AF+1)
; ???
; OUT (C),A
; RET
LD D,A
JP WR_C_D
;IN A,(C)
EMU_JUMP 0X3FF3
LD BC,(OLD_BC)
; ???
IN A,(C)
PUSH AF
POP HL
LD (OLD_AF),HL
RET
;[стек и обработчики]
DUPL STACK-$,0;XFF
DW INT_BREAK
DUPL STACK+0X41-$,0;XFF
INT_BREAK PUSH AF
PUSH HL
PUSH DE
LD A,(FLAG_RW_BREAK)
AND A
JR NZ,IB1
LD HL,(OLD_IF)
LD L,0XFF
LD E,(HL)
INC HL
LD D,(HL)
LD HL,(OLD_SP)
DEC HL
LD (HL),D
DEC HL
LD (HL),E
LD (OLD_SP),HL
POP DE
POP HL
POP AF
EI
RET
IB1 PUSH BC
LD (INT_SP),SP
CALL READ_TMP_CPU12
CALL WRITE_CPU12
LD A,(OLD_PORT_BF)
OUT (PEVO_CONF),A
LD A,(OLD_IF+1)
LD I,A
LD HL,(OLD_AF)
PUSH HL
POP AF
LD HL,(OLD_SP)
LD DE,0X2A71 ; адрес возврата из обработчика прерывания внешней проги через OUT (0xFF),A
DEC HL
LD (HL),D
DEC HL
LD (HL),E
DEC HL
EX DE,HL
LD HL,OLD_IF+1
LD H,(HL)
LD L,0XFF
LD C,(HL)
INC HL
LD B,(HL)
EX DE,HL
LD (HL),B
DEC HL
LD (HL),C
LD SP,HL
LD HL,(OLD_HL)
LD DE,(OLD_DE)
LD BC,(OLD_BC)
LD A,(WR_FF) ; байтик для возврата через команду OUT (0xFF),A
EI
JP 0X2A53
INT_RET LD SP,0
INT_SP EQU $-2
IN A,(PEVO_CONF)
LD (OLD_PORT_BF),A
OR 1
OUT (PEVO_CONF),A
LD A,HIGH (STACK)
LD I,A
CALL WRITE_TMP_CPU12
POP BC
POP DE
POP HL
POP AF
RET
;выход из обработчика
EXIT_PAGE_FE LD A,(OLD_PORT_BF)
OUT (PEVO_CONF),A ;восстановление порта 0xBF
LD A,(OLD_IF+1)
LD I,A
LD HL,(OLD_AF)
PUSH HL
POP AF
LD HL,0 ;восстановление HL
OLD_HL EQU $-2
LD DE,0 ;восстановление DE
OLD_DE EQU $-2
LD BC,0 ;восстановление BC
OLD_BC EQU $-2
LD SP,0 ;восстановление SP
OLD_SP EQU $-2
JP 0
ADR_EXIT EQU $-2
DUPL STACK+0X101-$,0;XFF
;вход в обработчик
WORKER LD (NUM_ADR),A
LD (OLD_SP),SP
LD SP,STACK-WORD
LD A,I
JP PE,WORKER1
LD A,I
WORKER1 PUSH AF ;IF
IN A,(PEVO_CONF)
LD (OLD_PORT_BF),A ;порт BF
OR 1
OUT (PEVO_CONF),A
LD A,HIGH (STACK)
LD I,A
LD (OLD_HL),HL
LD (OLD_DE),DE
LD (OLD_BC),BC
LD HL,0
NUM_ADR EQU $-2
ADD HL,HL
ADD HL,HL
LD DE,TABLE_VIRT
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL) ;DE-адрес возврата из обработчика
INC HL
LD (ADR_EXIT),DE
LD E,(HL)
INC HL
LD D,(HL) ;DE-адрес обработчика
PUSH DE
LD HL,EXIT_PAGE_FE ;код выхода из обработчика
EX (SP),HL
JP (HL)
;[чтение/запись примонтированного диска]
MOUNT_RW LD HL,0X4000
ADD HL,SP
LD SP,HL
LD BC,WIN_A1
LD A,0X40
OUT (C),A
LD B,HIGH (WIN_P1)
LD A,RAM_EVODOS
OUT (C),A
LD A,(RDWR_MODE)
AND 0X80
LD L,A
LD A,(WR_FF)
AND 3
OR L
BIT 7,A
PUSH AF
LD HL,0X2A77
PUSH HL
LD HL,MNT_RW
PUSH HL
JP Z,0X2A53
LD HL,(OLD_HL)
LD DE,0X100
CALL COPY_BLOCK
LD (OLD_HL),HL
JP 0X2A53
PHASE $+0X4000
MNT_RW LD L,A
LD A,(PORT_3F+0X4000) ;взяли номер трека
ADD A,A ;сторон 2
LD D,A
LD A,(WR_FF+0X4000)
AND 0X10 ;проверка какая сторона диска
JR NZ,WRRDSECM1
INC D ;для стороны 1
WRRDSECM1 LD A,(PORT_5F+0X4000) ;взяли номер сектора
LD E,A ;D-трек, E-сектор
LD A,L
LD HL,0X4100
RST8 _MOUNTER,_RDWR_MOUNT
JP 0X3D2F
PHASE $-0X4000
RET_MNT_RW LD HL,-0X4000
ADD HL,SP
LD SP,HL
CALL WRITE_CPU12
POP AF
RET NZ
LD HL,0X100
LD DE,(OLD_HL)
CALL COPY_BLOCK
LD (OLD_HL),DE
RET
;[инфа для создания 9 сектора нового диска]
DSKINFO DB 0 ;+0XE1-номер первого свободного сектора
DB 1 ;+0XE2-номер первого свободного трека
DB 0X16 ;+0XE3-тип дискеты
DB 0 ;+0XE4-количество файлов на дискете
SECFREE DW 2544 ;+0XE5-количество свободных секторов
DB 0X10 ;+0XE7-идентификационный код TRDOS
DW 0 ;+0XE8-2 байта 0
DUPL 9," " ;+0XEA-9 байт 0X20
DB 0 ;+0XF3-1 байт 0
DB 0 ;+0XF4-количество удаленных файлов
DB "RAMDISKO" ;+0XF5-имя дискеты
DSK_END
DUPL 0X1000-$,0;XFF
VARS1
;[адреса перехвата]
JP_EMU 0X1E3A ; OUT (0X3F), A
JP_EMU 0X1FDD ; IN A, (0X1F)
JP_EMU 0X1FF3 ; OUT (0XFF), A
JP_EMU 0X2000 ; OUT (0X1F), A
JP_EMU 0X2076 ; IN A, (0X1F)
JP_EMU 0X2085 ; OUT (0X3F), A
JP_EMU 0X208D ; OUT (0X5F), A
JP_EMU 0X2093 ; OUT (0X1F), A
JP_EMU 0X2099 ; IN A, (0X1F)
JP_EMU 0X20B1 ; IN A, (0XFF)
JP_EMU 0X20B8 ; OUT (C), D
JP_EMU 0X2740 ; IN A, (0X1F)
JP_EMU 0X2748 ; OUT (0X7F), A
JP_EMU 0X2A53 ; OUT (C), A
;первая команда в обработчике MAGIC для возврата в пагу FE
; JP_EMU 0X2A71 ; OUT (0XFF), A
DUPL 0X2A73-$,0;XFF
JP INT_RET ;возвращение из обработчика INT
; JP_EMU 0X2A77 ; IN A, (0X1F)
DUPL 0X2A79-$,0;XFF
JP RET_MNT_RW ;возвращение после вызова RST 8
JP_EMU 0X2AD9 ; OUT (0XFF), A
JP_EMU 0X2B25 ; IN A, (0X5F)
JP_EMU 0X2C07 ; IN A, (0X5F)
JP_EMU 0X2CD8 ; IN A, (0X5F)
JP_EMU 0X2D75 ; OUT (0X5F), A
JP_EMU 0X2D80 ; OUT (0X1F), A
JP_EMU 0X2D87 ; IN A, (0X1F)
JP_EMU 0X2F0C ; OUT (0XFF), A
JP_EMU 0X2F1D ; OUT (0X5F), A
DUPL 0X2F24-$,0;XFF ; для адреса 0X2F4D
JP ADR_0X2F4D
JP_EMU 0X2F28 ; OUT (0X1F), A
JP_EMU 0X2F2F ; IN A, (0X1F)
JP_EMU 0X2F3C ; OUT (0XFF), A
DUPL 0X2F4D-$,0;XFF ; OUT (0XFF), A
OUT (EXIT_PORT),A
DB 0X18 ; JR 0X2F24
JP_EMU 0X2F50 ; OUT (0X7F), A
DUPL 0X2F57-$,0;XFF ; OUT (0X1F), A
OUT (EXIT_PORT),A
JR JUMP_0X2F57
JR JUMP_0X2F59 ; IN A, (0XFF)
EXIT_0X2F59 OUT (EXIT_PORT),A
JUMP_0X2F59 JP ADR_0X2F59
JUMP_0X2F57 JP ADR_0X2F57
JP_EMU 0X2FB1 ; OUT (0XFF), A
JP_EMU 0X2FC3 ; OUT (0X1F), A
DUPL 0X32A2-$,0;XFF
;[обработчики чтения/записи портов]
;[запись "A" в порт 0X1F]
OUT_1F LD A,(OLD_AF+1)
LD (WR_1F),A
CP 0X10
JR NC,OUT_1F_10
;00-0F команда восстановления
XOR A
LD (PORT_3F),A
JR INFF_BIT6
OUT_1F_10 CP 0X20
JR NC,OUT_1F_20
;10-1F команда поиска
LD A,(PORT_7F)
LD (PORT_3F),A
CALL DISK_NONE
LD A,0X80
JR C,INFF_BIT6_1
INFF_BIT6 XOR A
INFF_BIT6_1 LD (RD_1F),A
LD A,0XBF
LD (RD_FF),A
RET
OUT_1F_20 CP 0X40
JR NC,OUT_1F_40
;20-3F команда шаг в предыдущем направлении
LD A,(PORT_3F)
NAPRAVL NOP
LD (PORT_3F),A
JR INFF_BIT6
OUT_1F_40 CP 0X60
JR NC,OUT_1F_60
;40-5F команда шаг вперед
LD A,(PORT_3F)
INC A
LD (PORT_3F),A
LD A,0X3C ;INC A
LD (NAPRAVL),A
JR INFF_BIT6
OUT_1F_60 CP 0X80
JR NC,OUT_1F_80
;60-7F команда шаг назад
LD A,(PORT_3F)
DEC A
LD (PORT_3F),A
LD A,0X3D ;DEC A
LD (NAPRAVL),A
JR INFF_BIT6
OUT_1F_80 CP 0XA0
JR NC,OUT_1F_A0
;80-9F команда чтение сектора
JR INFF_BIT6;7
OUT_1F_A0 CP 0XC0
JR NC,OUT_1F_D0
;A0-BF команда запись сектора
JR INFF_BIT6
INFF_BIT7 XOR A
LD (RD_1F),A
LD A,0X7F
LD (RD_FF),A
RET
OUT_1F_D0 CP 0XD0
JR NC,OUT_1F_E0
;C0-CF чтение адреса
JR INFF_BIT6;7
OUT_1F_E0 CP 0XE0
JR NC,OUT_1F_F0
;D0-DF принудительное прерывание
LD A,0XBF
LD (RD_FF),A
RET
OUT_1F_F0 CP 0XF0
JR C,INFF_BIT6
;E0-EF чтение дорожки
JR INFF_BIT6
;[запись "A" в порт 0X3F]
OUT_3F LD A,(OLD_AF+1)
LD (PORT_3F),A
RET
;[запись "A" в порт 0X5F]
OUT_5F LD A,(OLD_AF+1)
LD (PORT_5F),A
RET
;[запись "A" в порт 0X7F]
OUT_7F LD A,(OLD_AF+1)
LD (PORT_7F),A
RET
;[запись "A" в порт 0XFF]
OUT_FF LD A,(OLD_AF+1)
LD (WR_FF),A
LD D,A
LD BC,0X00FF
JR WR_C_D
; ??? OUT (0XFF),A
; RET
;[запись "A" в порт (C)]
OUT_C_A LD A,(OLD_AF+1)
WRCA1 LD D,A
LD BC,(OLD_BC) ;если порт не TR-DOS
LD A,C
;определение в какой порт запись
CP 0X1F
JP Z,OUT_1F
CP 0X3F
JR Z,OUT_3F
CP 0X5F
JR Z,OUT_5F
CP 0X7F
JR Z,OUT_7F
CP 0XFF
JR Z,OUT_FF
CP LOW (WIN_A0)
JR Z,WRCA3
WR_C_D PUSH BC
LD BC,FDD_EMU_PORT
IN E,(C)
XOR A
OUT (C),A
POP BC
OUT (C),D
LD BC,FDD_EMU_PORT
OUT (C),E
RET
;[запись в порты ATM/PENTEVO]
WRCA3 LD A,B
LD HL,BB_CPU1
CP HIGH (WIN_A1)
JR Z,WRCA2
CP HIGH (WIN_P2)
JR Z,WRCA2
LD HL,BB_CPU2
CP HIGH (WIN_A2)
JR Z,WRCA2
CP HIGH (WIN_P2)
JR NZ,WR_C_D
WRCA2 LD E,B
PUSH DE
PUSH HL
CALL READ_CPU12
POP HL
POP DE
LD (HL),D
INC HL
LD (HL),E
JP WRITE_CPU12
;[запись "D" в порт (C)]
OUT_C_D LD A,(OLD_DE+1)
JR WRCA1
;[передача байта, команда OUTI]
OUT_OUTI LD HL,(BUFF_SECT)
EXX
LD A,(HL)
INC HL
EXX
LD (HL),A
INC HL
LD (BUFF_SECT),HL
RET
;[чтение порта 0X1F]
IN_1F LD A,(WR_1F)
AND 0XF0
CP 0X10
JR C,RD1F1
CP 0X20
JR C,RD1F3
CP 0XD0
JR Z,RD1F1
XOR A
JR RD1F2
RD1F3 LD A,(INDEX)
XOR %00000100
JR RD1F4
RD1F1 LD A,0X24
INDEX EQU $-1
RD1F4 XOR %00000010
LD (INDEX),A
RD1F2 LD (RD_1F),A
LD (OLD_AF+1),A
RET
;[чтение порта 0X3F]
IN_3F LD A,(PORT_3F)
LD (OLD_AF+1),A
RET
;[чтение порта 0X5F]
IN_5F LD A,(PORT_5F)
LD (OLD_AF+1),A
RET
;[чтение порта 0X7F]
IN_7F LD A,(PORT_7F)
LD (OLD_AF+1),A
RET
;[чтение порта 0XFF]
IN_FF LD A,(RD_FF)
LD (OLD_AF+1),A
RET
;[чтение в "H" из (С)]
IN_H_C LD A,(OLD_BC)
;[определение из какого порта чтение]
CP 0X1F
JR NZ,RDHC2
LD A,(RD_1F)
LD (OLD_HL+1),A
RET
RDHC2 CP 0X3F
JR NZ,RDHC3
LD A,(PORT_3F)
LD (OLD_HL+1),A
RET
RDHC3 CP 0X5F
JR NZ,RDHC4
LD A,(PORT_5F)
LD (OLD_HL+1),A
RET
RDHC4 CP 0X7F
JR NZ,RDHC5
LD A,(PORT_7F)
LD (OLD_HL+1),A
RET
RDHC5 CP 0XFF
JR NZ,RDHC6
LD A,(RD_FF)
LD (OLD_HL+1),A
RET
RDHC6 LD BC,(OLD_BC)
IN A,(C)
LD (OLD_HL+1),A
RET
;[чтение INI]
IN_INI LD A,(RD_1F)
LD HL,(OLD_HL)
DEC HL
LD (HL),A
INC HL
LD (OLD_HL),HL
LD HL,0X2A53
LD (ADR_EXIT),HL
JP INFF_BIT6
;[чтение сектора или портов]
READ_SECTOR LD A,(WR_1F)
AND 0X0F0
CP 0X80
JP C,INFF_BIT6
CP 0XC0
JR NZ,READ_SECTOR_1
LD A,(PORT_3F)
LD HL,(OLD_HL)
LD (HL),A ;номер дорожки
INC HL
LD (HL),0 ;номер стороны
INC HL
LD A,(PORT_5F)
LD (HL),A ;номер сектора
INC HL
LD (HL),0 ;размер сектора
INC HL
LD (HL),0 ;байт CRC
INC HL
LD (HL),0 ;байт CRC
INC HL
LD (OLD_HL),HL
LD HL,OLD_BC+1
LD A,(HL)
SUB 6 ;REG B - 6
LD (HL),A
LD HL,0X2A53
LD (ADR_EXIT),HL
JP INFF_BIT6
;[чтение сектора]
READ_SECTOR_1 XOR A
JR WRITE_SECTOR_1
;[запись сектора]
WRITE_SECTOR LD A,0XFF
WRITE_SECTOR_1 LD (RDWR_MODE),A
LD A,1
LD (FLAG_RW_BREAK),A
LD HL,(OLD_IF)
PUSH HL
POP AF
JP PO,DI_MODE ;прерывания разрешены?
CP 0X3F
JR Z,DI_MODE
HALT ;разрешены, ждем обработчик прерывания
DI_MODE CALL READ_CPU12 ;сохранение текущей конфигурации окон проецирования 1,2
CALL W_WR_RD_SECT
XOR A
LD (FLAG_RW_BREAK),A
LD HL,0X8090
LD (OLD_AF),HL ;эмуляция флага успешного чтения/записи сектора
LD HL,0X2A53
LD (ADR_EXIT),HL
JP WRITE_CPU12 ;восстановление конфигурации окон проецирования 1,2
;[чтение или запись сектора рамдиска]
W_WR_RD_SECT LD A,(WR_FF)
AND 3
INC A
LD B,A
LD A,%10000000
.L1 RLCA
DJNZ .L1
LD B,A
LD A,(COPY_VIRT_BITS)
AND B
JP NZ,MOUNT_RW ;работа с примонтированным образом
LD BC,WIN_A1
LD A,0X40
OUT (C),A
LD B,HIGH (WIN_P1)
LD A,RAM_RAMDISK
OUT (C),A ;страница заголовков рамдиска
LD A,(PORT_3F) ;взяли номер трека
ADD A,A ;сторон 2
LD C,A
LD A,(WR_FF)
AND 0X10 ;проверка какая сторона диска
JR NZ,WWRRD1
INC C ;для стороны 1
WWRRD1 LD B,HIGH (CPU1)+2 ;адрес начала инфы о секторах на дорожке
LD A,(PORT_5F) ;взяли номер сектора
LD L,A
LD H,0
WWRRD3 LD A,(BC)
LD D,A ;взяли номер сектора
INC B
LD A,(BC)
LD E,A ;взяли размер сектора
INC B
; LD A,D
; AND A
; JR Z,WWRRD_ERR
LD A,L
CP D
JR Z,WWRRD2
LD A,E
ADD A,H
LD H,A
JR WWRRD3
WWRRD2 LD A,E
RRCA
LD (SECTOR_SIZE),A ;размер найденного сектора
LD L,0
LD E,L
SRL H
RR L ;HL=смещение в блоках до найденного сектора
LD B,HIGH (CPU1)
LD A,(BC)
LD D,A
ADD HL,DE ;HL=смещение от начала страницы в блоках
INC B
LD A,(BC)
LD C,A ;смещение в страницах от начала рамдиска
LD A,H
CP HIGH (CPU1)
JR C,WWRRD5
SUB 0X40
LD H,A
INC C
;HL=смещение в странице до начала сектора
WWRRD5 LD A,C ;смещение до номера страницы, где указанный сектор начинается
ADD A,RAM_DATARAMD ;прибавили номер начала рамдиск и +1. в 0 странице рамдиска описатели секторов
LD (RDWR_PAGE),A ;сохранили номер вычисленной страницы
LD DE,(OLD_HL)
LD BC,(BB_CPU1)
LD A,C
LD C,LOW (WIN_A0)
OUT (C),A ;вернули стандартную 5 страницу
SP_RAMD9 LD A,D ;проверка границы откуда/куда копировать
CP HIGH (CPU2)
PUSH DE
LD DE,CPU1+HIGH (WIN_P1)
LD BC,WIN_A1 ;если верхние 32кб озу, то нужно включить в 1 окне проецирования
JR NC,SP_RAMD1
LD DE,CPU2+HIGH (WIN_P2)
LD B,HIGH (WIN_A2) ;если нижние 32кб озу, то нужно включить во 2 окне проецирования
SP_RAMD1 LD A,0X40
OUT (C),A
LD B,E
LD A,(RDWR_PAGE) ;номер вычисленной страницы озу
OUT (C),A ;включили вычисленную страницу
LD B,D ;старший байт адреса начала включенной страницы
POP DE
LD A,B
ADD A,H
LD H,A
LD A,(RDWR_MODE)
AND A
JR NZ,IN_ROM1
LD A,D
INC A
JR NZ,IN_ROM1
LD A,E
AND A
JR Z,IN_ROM1
IN_ROM4 NEG
LD C,A
LD B,0
LDIR
NEG
LD C,A
IN_ROM2 EX DE,HL
ADD HL,BC
EX DE,HL
ADD HL,BC
LD A,(SECTOR_SIZE)
JP SP_RAMD8_
IN_ROM1 LD A,D
CP HIGH (CPU1)
JR NC,IN_ROM3
LD A,(SECTOR_SIZE)
AND A
LD BC,0X80
JR Z,IN_ROM2
LD BC,0X100
JR IN_ROM2
IN_ROM3 CP HIGH (CPU2) ;проверка перехода границы страниц
JP NC,SP_RAMD3 ;если выше то сразу копируем
CP HIGH (CPU2)-1
JP C,SP_RAMD3 ;если ниже так же сразу копируем
LD A,E
AND A ;если сектор полностью укладывется до границы, то сразу копируем
JR Z,SP_RAMD3 ;иначе принудительно копируем в два приема
LD A,(RDWR_MODE) ;чтение или запись?
AND A
LD A,E ;младший байт адрес в блоке
JR Z,SP_RAMD4
EX DE,HL ;для записи меняем направление
SP_RAMD4 NEG
LD C,A ;копируем остаток до конца блока
LD B,0
LDIR
NEG
PUSH AF ;спрятали сколько осталось копировать из начала следующего блока
LD BC,(BB_CPU2)
LD A,C
LD C,LOW (WIN_A0)
OUT (C),A
LD B,HIGH (WIN_A1)
LD A,0X40
OUT (C),A
LD B,HIGH (WIN_P1)
LD A,(RDWR_PAGE)
OUT (C),A ;вычисленную страницу включаем в 1 окне проецирования
LD A,(RDWR_MODE) ;чтение или запись
AND A
JR Z,SP_RAMD5
LD A,D ;для записи
SUB 0X40 ;изменили адрес куда копировать на другое окно проецирования
LD D,A
JR SP_RAMD6
SP_RAMD5 LD A,H ;для чтения
SUB 0X40 ;изменили адрес куда копировать на другое окно проецирования
LD H,A
SP_RAMD6 POP AF
LD C,A ;сколько осталось скопировать байт
LD B,0
LDIR
LD A,(SECTOR_SIZE)
JR SP_RAMD8_
SP_RAMD3 LD A,(RDWR_MODE) ;чтение или запись
AND A
JR Z,SP_RAMD7
EX DE,HL ;для записи меняем направление
SP_RAMD7 LD A,(SECTOR_SIZE)
AND A
JR NZ,SP_RAMD8
CALL COPYHBLOCK ;для сектора размером 128 байт копируем половину и выходим
ECOPY_BLOCK LD A,(RDWR_MODE)
AND A
JR Z,ECOPY_BLOCK1
EX DE,HL
ECOPY_BLOCK1 LD (OLD_HL),DE
RET
SP_RAMD8 CALL COPY_BLOCK ;для сектора 256 байт копируем весь и выходим
SP_RAMD8_ DEC A
JR Z,ECOPY_BLOCK
LD (SECTOR_SIZE),A
LD A,(RDWR_MODE)
AND A
JR Z,SP_RAMD0
EX DE,HL
SP_RAMD0 LD A,0X3F
AND H
LD H,A
JP SP_RAMD9
COPY_BLOCK REPT 128
LDI
ENDM
COPYHBLOCK REPT 128
LDI
ENDM
RET
;[проверка наличия маркера рамдиска]
CMP_RAM_DISK CALL READ_CPU12
LD BC,WIN_P1
LD A,RAM_RAMDISK
OUT (C),A
LD HL,CPU1+0X3FFF
LD D,(HL)
DEC H
LD E,(HL) ;взяли байты для проверки маркера
CALL WRITE_CPU12
LD HL,"RD"
AND A
SBC HL,DE
RET Z ;если маркер на месте, то рамдиска не создаем
;[создание чистого рамдиска]
CREATE_TRDTABL LD BC,WIN_P1
LD A,RAM_RAMDISK ;нужна страница начала рамдиска, где будет таблица описателей
OUT (C),A
LD HL,CPU1
PUSH HL
LD DE,CPU1+1
LD BC,0X3FFF
LD (HL),L
LDIR ;очистили страницу
POP DE ;адрес начала страницы
LD HL,0 ;смещение в блоках и страницах
LD A,0XA0
ELT2 PUSH AF
LD BC,0X1000 ;счетчик номеров секторов и их номера
LD A,L
RRCA
RRCA
LD (DE),A ;смещение в блоках дорожки в странице
INC D
LD A,H
LD (DE),A ;смещение в страницах до дорожки
INC D
ELT1 INC C
LD A,C
LD (DE),A ;номер сектора
INC D
LD A,2
LD (DE),A ;размер сектора
INC D
DJNZ ELT1 ;вносим в таблицу все номера секторов с размерами
LD D,HIGH (CPU1) ;вернули указатель в начало
INC E ;для следующей дорожки
LD BC,0X40
ADD HL,BC ;переход к следующей дорожке
POP AF
DEC A
JR NZ,ELT2 ;повторяем для всех дорожек
LD HL,CPU1+0X3FFF
LD (HL),"R" ;вносим маркер рамдиска
DEC H
LD (HL),"D"
LD BC,WIN_P1
LD A,RAM_DATARAMD
OUT (C),A
LD HL,CPU1
LD DE,CPU1+1
LD BC,0X0FFF
LD (HL),L
LDIR
LD HL,DSKINFO
LD DE,CPU1+0X8E1
LD BC,DSK_END-DSKINFO
LDIR
;[восстановление конфигурации окон проецирования 1,2]
WRITE_CPU12 LD BC,(BB_CPU1)
LD A,C
LD C,LOW (WIN_A0)
OUT (C),A
LD BC,(BB_CPU2)
LD A,C
LD C,LOW (WIN_A0)
OUT (C),A
RET
;[чтение текущего конфига страниц проецирования 1,2]
READ_TMP_CPU12 LD HL,(BB_CPU1)
PUSH HL
LD HL,(BB_CPU2)
PUSH HL
CALL READ_CPU12
LD HL,(BB_CPU1)
LD (TMP_BB_CPU1),HL
LD HL,(BB_CPU2)
LD (TMP_BB_CPU2),HL
POP HL
LD (BB_CPU2),HL
POP HL
LD (BB_CPU1),HL
JR WRITE_CPU12
;[восстановление текущей конфигурации страниц проецирования 1,2]
WRITE_TMP_CPU12 LD BC,0
TMP_BB_CPU1 EQU $-2
LD A,C
LD C,LOW (WIN_A0)
OUT (C),A
LD BC,0
TMP_BB_CPU2 EQU $-2
LD A,C
LD C,LOW (WIN_A0)
OUT (C),A
RET
;[чтение конфигурации окон проецирования 1,2]
READ_CPU12 LD BC,RD_RAMNROM
IN L,(C) ;биты RAM & ROM
INC B
IN H,(C) ;биты DOS & 7FFD
ADD HL,HL
LD B,HIGH (RD_1WINA1)
IN A,(C)
CP 0XC0
JR NC,RWCPU1
LD E,A
LD D,HIGH (WIN_P1)
JR RWCPU2
RWCPU1 RLCA
RLCA
SLA L
RRA
SLA H
RRA
LD E,A
LD D,HIGH (WIN_A1)
RWCPU2 LD (BB_CPU1),DE
INC B
IN A,(C)
CP 0XC0
JR NC,RWCPU3
LD E,A
LD D,HIGH (WIN_P2)
JR RWCPU4
RWCPU3 RLCA
RLCA
SLA L
RRA
SLA H
RRA
LD E,A
LD D,HIGH (WIN_A2)
RWCPU4 LD (BB_CPU2),DE
RET
;[проверка наличия виртуального диска]
DISK_NONE PUSH HL
PUSH BC
CALL READ_CPU12
LD BC,WIN_A1
LD A,0X40
OUT (C),A
LD B,HIGH (WIN_P1)
LD A,RAM_RAMDISK
OUT (C),A
LD HL,CPU1+0X3FFF
LD A,(HL)
DEC H
CP "R"
SCF
JR NZ,DISK_NONE1
LD A,(HL)
CP "D"
SCF
JR NZ,DISK_NONE1
XOR A
DISK_NONE1 PUSH AF
CALL WRITE_CPU12
POP AF
POP BC
POP HL
RET
;на входе: H-адрес ячейки
; L-прочитанное значение
READCMOS PUSH BC
LD BC,CMOSD_SET_ADR
OUT (C),H
LD B,HIGH (CMOSD_RD_WR)
IN L,(C)
POP BC
LD A,L
AND A
RET
JP_EMU 0X3C30 ; IN A, (0X1F)
DUPL 0X3D2F-$,0;XFF
NOP
RET
JP_EMU 0X3D4D ; OUT (0XFF), A
JP_EMU 0X3D9A ; OUT (0X1F), A
JP_EMU 0X3DA6 ; IN A, (0XFF)
JP_EMU 0X3DB5 ; IN A, (0X1F)
JP_EMU 0X3DBA ; IN A, (0X1F)
JP_EMU 0X3DD5 ; OUT (0XFF), A
JP_EMU 0X3E30 ; IN A, (0X1F)
JP_EMU 0X3E3A ; IN A, (0X1F)
JP_EMU 0X3E44 ; OUT (0X7F), A
DUPL 0X3E49-$,0;XFF
JP ADR_0X3E4C ; для адреса 0X3E4C
; JP_EMU 0X3E4C ; OUT (0X7F), A
DUPL 0X3E4C-$,0;XFF
OUT (EXIT_PORT),A
JR 0X3E49
JP_EMU 0X3E50 ; IN A, (0X3F)
JP_EMU 0X3E78 ; IN A, (0X3F)
JP_EMU 0X3E7E ; OUT (0X3F), A
JP_EMU 0X3E87 ; IN A, (0X3F)
JP_EMU 0X3E95 ; OUT (0X3F), A
JP_EMU 0X3EB5 ; IN A, (0X1F)
JP_EMU 0X3EBC ; IN A, (0X3F)
JP_EMU 0X3EC9 ; OUT (0X1F), A
JP_EMU 0X3ECE ; IN A, (0XFF)
JP_EMU 0X3EDF ; OUT (0X1F), A
DUPL 0X3EF3-$,0;XFF ; IN H, (C)
OUT (EXIT_PORT),A
JR JUMP_0X3EF3
JR JUMP_0X3EF5 ; IN A, (0XFF)
EXIT_0X3EF5 OUT (EXIT_PORT),A
JUMP_0X3EF5 JP ADR_0X3EF5
; JP_EMU 0X3EF5 ; IN A, (0XFF)
JP_EMU 0X3EFE ; IN A, (0X7F)
JUMP_0X3EF3 JP ADR_0X3EF3
JP_EMU 0X3F1B ; OUT (0X5F), A
JP_EMU 0X3F25 ; OUT (0X1F), A
JP_EMU 0X3F33 ; IN A, (0X1F)
DUPL 0X3F40-$,0;XFF ; для адреса 0x3EF3
JP ADR_0X3EF3
JP_EMU 0X3F4D ; OUT (0X1F), A
JP_EMU 0X3F55 ; IN A, (0X3F)
JP_EMU 0X3F5A ; IN A, (0X5F)
JP_EMU 0X3F69 ; IN A, (0X3F)
JP_EMU 0X3F72 ; IN A, (0X5F)
JP_EMU 0X3FBC ; IN A, (0XFF) ;запись сектора
DUPL 0X3FC7-$,0;XFF
JUMP_0X3FF0 JP ADR_0X3FF0
JP_EMU 0X3FCA ; IN A, (0XFF) ;запись сектора
JP_EMU 0X3FD1 ; OUTI ;запись сектора
JP_EMU 0X3FD7 ; IN A, (0XFF) ;чтение сектора
JUMP_0X3FEC JP ADR_0X3FEC
JUMP_0X3FF3 JP ADR_0X3FF3
JP_EMU 0X3FE5 ; IN A, (0XFF) ;чтение сектора
; JP_EMU 0X3FEC ; INI ;чтение сектора
DUPL 0X3FEC-$,0;XFF
OUT (EXIT_PORT),A
JR JUMP_0X3FEC
; DUPL 0X3FF0-$,0 ; OUT (C), A
OUT (EXIT_PORT),A
DB 0X18 ; JR 0X3FC7
; DUPL 0X3FF5-$,0 ; IN A, (C)
OUT (EXIT_PORT),A
JP JUMP_0X3FF3
DUPL 0X3FF8-$,0
DB "EVOSFE"
DW DATA_VERS