Login

Subversion Repositories NedoOS

Rev

Rev 1469 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

      if 0
TEMP_SEC EQU #5CF4
SEC_LEN EQU #5CEA
SECTOR  EQU #5CEB
TRACK   EQU #5CEC
FILENAME EQU #5CDD
FILEEXT  EQU #5CE5
FREE EQU #E5 ;смещение в секторе 9, где
;находится количество свободных секторов
FREESECT EQU #E1; смещение в секторе 9,
;где находится первый свободный трек и
;сектор
      endif

      if 0
       IF atm
TRDOS
        PUSH AF
        PUSH BC
        PUSH HL
        CALL ATMOFF
        POP HL
        POP BC
        POP AF
        CALL #3D13
        PUSH AF
        PUSH BC
        PUSH HL
        CALL ATMON
        POP HL
        POP BC
        POP AF
        RET
       ELSE
TRDOS   EQU #3D13
       ENDIF
     endif

dosunit
          SCF
          RET


st_close

         LD A,(tsflag)
         AND A
         CALL NZ,ts_close
         SCF
         RET


dosinit
;0x705C содержит имя файла с точкой, в конце 0xff,'$'
;хэндл файла надо сохранить в STORY
;потом переделать имя файла в 8.3 с точкой, в конце 0xff,'$'
     if 1
     else

         LD B,8    ;Заполняем восмью
         LD HL,FILENAME ;пробелами
MET7     LD (HL),#20 ;имя файла
         INC HL
         DJNZ MET7

;Перенос информации в область
;переменных DOS'а
      LD BC,FILENAME ;Нормально рабо-
      LD HL,#705C ;тающий, безглючный
MET6  LD A,(HL) ;определитель имени
      CP #FF
      JP Z,END1 ;Точка должна быть
      CP "." ;только одна
      JP NZ,MET5

      LD BC,FILEEXT
      INC HL
      LD A,(HL)

MET5  LD (BC),A
      INC BC
      INC HL
      JP MET6

END1
         AND A
      PUSH BC
      POP HL
      LD BC,FILENAME
      SBC HL,BC
      LD A,L ;количество байтов маски

;Поиск файла в каталоге по
;маске "имя.ext"
      LD C,#0A
      LD (23814),A
      CALL TRDOS

;Чтение полного заголовка файла
      LD A,C
      LD (STORY),A
      LD C,#08
      CALL TRDOS

;Перенос из дескриптора в #705c
;Нужно для нормального вывода на экран
;имени файла, а не его огрызка
      LD HL,#705C
      LD C,#14
      CALL TRDOS
      LD A,(#7065)
      LD (#7066),A
      LD A,(#7064)
      LD (#7065),A
      LD HL,#7064
      LD (HL),"."

      LD HL,#7067
      LD (HL),#FF ;Такие требования
      INC HL      ;идут в ZXZVM +3
      LD (HL),"$"
    endif
      SCF
      RET




st_reload
;???
      XOR A ; в 6-й банке (буфер) ничего
      LD (BUFMEM),A ;нет
      LD HL,(REAL_LEN2) ;восстанавливаем
      LD (REAL_LEN),HL ;реальную длину

    if 1
    else
      LD A,(STORY) ;считывание заголовка
      LD C,#08
      CALL TRDOS
    endif


      CALL RRR ;считываем первые 64 Кб
;z-памяти (динамическая память)

      SCF
      RET


st_open


MET4  LD A,(BANKM) ;На всякий случай
      LD (TEMPBANKA),A ;запоминаем какая
;банка и в каком режиме была включена
    if 1
      ld hl,0x705C
      ld d,h
      ld e,l
      ld a,0xff
      ld b,1
      cpir
      dec hl
      push hl
      inc (hl);0x00 для ASCIIZ

      OS_OPENHANDLE
      ld a,b
      ld (STORY),a

      OS_GETFILESIZE ;dehl=file size
        ld l,h
        ld h,e
          LD (REAL_LEN),HL
          LD (REAL_LEN2),HL

      pop hl
      dec (hl);0xff как было
     
    else
      LD A,(STORY)
      LD C,#08
      CALL TRDOS
      LD A,(SEC_LEN)
      CP #FF ;Сравниваем, а не нужна ли
;проверка на наличие дополнительных
;файлов к основному (ext = 0,1,2,...)
      LD E,A
      LD D,#00
      LD (REAL_LEN),DE
      LD (REAL_LEN2),DE
      CALL Z,real_len

      LD A,(STORY) ;Т.к. после вызова
      LD C,#08 ;real_len дескриптор мог
      CALL TRDOS ;измениться восстанав-
;ливаем дескриптор основного файла
      LD HL,(SECTOR) ;трек и сектор
      LD (FILE_BEGIN),HL ;начала файла
    endif

RRR   LD HL,BankN
      LD (WHERE),HL
;сюда переходим при рестарте


MET3
       ;LD DE,(SECTOR) ;FIXME?
;помещаем информацию о треке и
;секторе файла

       LD HL,(WHERE)
       LD A,(HL)
       CP BANKN_TERMINATOR;#02
       JR Z,LOADED64K ;Загружены все
;банки (не только 64к), переход на конец
;загрузки файла

       CALL selmem; Переключаем страницу
;для загрузки в нее данных

       INC HL
       LD (WHERE),HL

       LD HL,(REAL_LEN)
       LD BC,#0040
; #40 = 64 сектора = страница
;количество секторов файла
       AND A
       SBC HL,BC
       JR Z,MET2
       JR C,MET2
       LD (REAL_LEN),HL
       
    if 1
      ld hl,0x4000
      ld de,0xc000
      ld a,(STORY)
      ld b,a
      OS_READHANDLE
    else
       LD B,64
       LD A,(TRACK)
       ADD A,#04
       LD (TRACK),A
       CALL READ ;DE брали из переменной TR-DOS, т.е. продолжаем читать файл
    endif

       JP MET3


MET2   LD A,(REAL_LEN) ;Все влезло в
;доступные банки, посему загружаем
;остаток и спокойно идем дальше
    if 1
      ld hl,0x4000
      ld de,0xc000
      ld a,(STORY)
      ld b,a
      OS_READHANDLE
    else
       LD B,A
       CALL READ
    endif

LOADED64K  LD A,(TEMPBANKA)
           CALL selmem

           LD A,BANKN_TERMINATOR;#02 ;для возможности
           LD (BankN+4),A ;restart'а
           SCF
           RET

     if 0
READ   LD HL,#C000 ;Чтение группы
       LD C,#05    ;секторов
       CALL TRDOS
       RET
     endif


     if 0
real_len
         LD A,#30   ;Загоняем начальное
          LD (EXT),A ;расширение '0'

          LD HL,#705C ;переносим инфор-
          LD C,#14 ;мацию из дескриптора
;файла в адрес #705c
          CALL TRDOS
          LD A,(STORY)
          LD (TEMPSTORY),A

CYCLE3    LD A,(TEMPSTORY)
          INC A
          LD (TEMPSTORY),A
          LD C,#08 ;Считываем следущий
          CALL TRDOS;за игровым файл
;для дальнейщей его проверки
          LD HL,#705C
          LD DE,FILENAME
          LD B,8
CYCLE2    LD C,(HL) ;Цикл проверки
          LD A,(DE) ;Сравниваем имена
          SUB C
          RET NZ
          INC HL
          INC DE
          DJNZ CYCLE2
          LD A,(DE) ;Проверяем правиль-
          LD C,A ;ность расширения
          LD A,(EXT)
          SUB C
          RET NZ
          LD A,(EXT)
          INC A
          LD (EXT),A
          LD DE,(SEC_LEN)
          LD D,#00
          LD HL,(REAL_LEN)
          ADD HL,DE
          LD (REAL_LEN),HL
          LD (REAL_LEN2),HL
          JR CYCLE3
     endif


     if 0
st_peek

        IF bigmem
        PUSH HL
        ENDIF
         PUSH BC
         PUSH DE
         PUSH IX

;Вставить проверку на ошибку

         LD A,H
         LD HL,TEMP
         LD (HL),A
         LD A,E

         RRD
         LD A,(HL)

         AND #FC
;#x0,#x1,#x2,#x3 -> #x0
;#x4,#x5,#x6,#x7 -> #x4
;#x8,#x9,#xA,#xB -> #x8
;#xC,#xD,#xE,#xF -> #xC

         LD (BUFMEM),A

         LD DE,(FILE_BEGIN)
         ADD A,D
         LD D,A

         LD B,64    ;Загрузка в буфер
         LD HL,#C000 ;нужной части памя-
         LD C,#05    ;ти
         CALL TRDOS

         DI

         LD HL,(HL_)

         POP IX
         POP DE
         POP BC

        IF bigmem
         POP HL
        ELSE
         LD HL,(HL_)
        ENDIF

         RET
     endif

;;;;;;
; Открытие и закрытие файла-отгрузки
;


      if 0
init_name
;hl=name
         LD C,#13 ;Переносим имя из
           CALL TRDOS ;HL в системную
;область TR-DOS'а

          LD A,#FF ;Находим конец имени
          LD HL,FILENAME
          LD BC,#0009
          CPIR
          LD B,C
          INC B
          DEC HL

CYCLE4    LD A,#20 ;и забиваем #FF и
          LD (HL),A ;далее пробелами
          INC HL
          DEC B
          JR NZ,CYCLE4

          LD A,"!" ;устанавливаем рас-
          LD (FILEEXT),A ;ширение '!'
          RET
      endif
;;;;;
;;;;;;;
p3read
        PUSH AF
        PUSH HL
        PUSH BC
        PUSH DE
        PUSH IX
       XOR A
       LD (WHAT),A
       CALL driver

       POP IX
       POP DE
       POP BC
       POP HL
       POP AF

       SCF
       RET
;;;;;;
p3write

        PUSH AF
        PUSH HL
        PUSH BC
        PUSH DE
        PUSH IX

        LD A,#01
        LD (WHAT),A
        CALL driver

        POP IX
        POP DE
        POP BC
        POP HL
        POP AF
        SCF
        RET
;;;;;;
p3rmem
        PUSH AF
        PUSH HL
        PUSH BC
        PUSH DE
        PUSH IX

        LD A,#02
        LD (WHAT),A
        CALL driver

        POP IX
        POP DE
        POP BC
        POP HL
        POP AF
        SCF
        RET
;;;;;;;
p3wmem
        PUSH AF
        PUSH HL
        PUSH BC
        PUSH DE
        PUSH IX

        LD A,#03
        LD (WHAT),A
        CALL driver

        POP IX
        POP DE
        POP BC
        POP HL
        POP AF
        SCF
        RET

;;;;;;;;;;

p3opn
         PUSH AF ;сохраняем все регистры
       PUSH HL ; (на всякий случай)
       PUSH BC
       PUSH DE
       PUSH IX
     if 0
       LD A,#09 ;маска в 9 символов
       LD (23814),A
     endif

       LD A,B ;b=0 - открыть файл
       AND A  ;b=1 - создать файл

       JR NZ,createe

read ;для отгрузок
;hl=name
     if 1
       ld d,h
       ld e,l
       ld a,0xff
       ld b,1
       cpir
       dec hl
       push hl
       inc (hl) ;0x00 для ASCIIZ
       OS_OPENHANDLE
       pop hl
       dec (hl) ;0xff как было
       or a
       JR nz,NO_FILE
       LD A,b ;запоминаем
       LD (OPENFILE),A ;его
       ld hl,0
       ld (SECT),hl ;запоминаем начало файла
       
     else
       CALL init_name
       LD C,#0A ;получаем номер файла
       CALL TRDOS
       LD A,C ;запоминаем
       LD (OPENFILE),A ;его
       CP #FF
       JR Z,NO_FILE

       LD C,#08   ;считываем полную
       CALL TRDOS ;информацию о нем

       LD HL,(SECTOR) ;запоминаем
       LD (SECT),HL   ;начало файла
     endif
       XOR A ;устанавливаем естественно
       LD (SMESH),A ;смещение (внутри сектора) в ноль

       POP IX
       POP DE
       POP BC
       POP HL
       POP AF
       SCF
       RET

NO_FILE POP IX
        POP DE
        POP BC
        POP HL
        POP AF
        AND A
        RET

createe ;для отгрузок

        LD A,(tsflag)
        AND A
        CALL NZ,ts_close

     if 1
      ;jr $
       ld d,h
       ld e,l
       ld a,0xff
       ld b,1
       cpir
       dec hl
       push hl
       inc (hl) ;0x00 для ASCIIZ
       OS_CREATEHANDLE
       pop hl
       dec (hl) ;0xff как было
       ;or a
       ;JR nz,NO_FILE
       LD A,b ;запоминаем
       LD (OPENFILE),A ;его
       ld hl,0
       ld (SECT),hl ;запоминаем начало файла
       
     else
        CALL init_name

        LD C,#12
        CALL TRDOS

        LD HL,#0000 ;создание заголовка
        LD DE,#0001 ;файла
        LD C,#0B
        CALL TRDOS


        LD HL,(SECTOR) ;запоминание на-
        LD (FILEBEG),HL ;начального
        LD (SECT),HL ;сектора

        LD A,#09 ;установление маски
        LD (23814),A ;длиной в 9 байт
        LD C,#0A ;получение номера файла
        CALL TRDOS ;в каталоге
        LD A,C
        LD (OPENFILE),A
     endif

        XOR A ;установление смещения в
        LD (SMESH),A ;ноль

        POP IX
        POP DE
        POP BC
        POP HL
        POP AF
        SCF
        RET
;;;;;;
      if 0
NO17SEC LD A,L ;дабы не было 17-го
        CP 16  ;сектора
        RET C
        SUB 16
        LD L,A
        INC H
        RET
      endif

;;;;
;Close file
;
p3clse
        PUSH AF
        PUSH HL
        PUSH BC
        PUSH DE
        PUSH IX

        LD A,(WHAT);если для открытия
        AND A ;файла, то сразу переход
        JR Z,FOR_OPEN ;на конец

      if 1
       ld a,(OPENFILE)
       ld b,a
       OS_CLOSEHANDLE
      else
        LD HL,(SECT) ;получаем информа-
        INC HL ;цию о следущем свободном
;секторе
        CALL NO17SEC

        LD (SECT),HL

        LD DE,#0008 ;считываем
        LD BC,#0105 ;9-й (системный)
        LD HL,BUFFER ;сектор
        CALL TRDOS

        LD HL,(SECT)
        LD (BUFFER+FREESECT),HL
;записываем первый свободный трек
;и сектор

        LD DE,(FILEBEG)
        LD A,H ;длина файла в треках
        SUB D  ;без секторов

;!!!

        SLA A ;получаем количество
        SLA A ;секторов
        SLA A
        SLA A

        SUB E ;получаем полное
        ADD A,L;количество секторов
        DEC A

        PUSH AF
        LD B,#00 ;вычисляем количество
        LD C,A   ;свободных секторов
        LD HL,(BUFFER+FREE)
        AND A
        SBC HL,BC

        LD (BUFFER+FREE),HL

        LD HL,BUFFER ;сохраняем измене-
        LD BC,#0106  ;ный 9-й сектор
        LD DE,#0008
        CALL TRDOS


        LD A,(OPENFILE) ;получаем
        LD C,#08 ;полную информацию о
        CALL TRDOS ;открытом файле

        POP AF
        INC A  ;сохраняем длину файла
        LD (SEC_LEN),A ;в секторах

        LD A,(OPENFILE) ;записываем
        LD C,#09 ;измененный дескриптор
        CALL TRDOS ;файла
     endif
FOR_OPEN XOR A ;на всякий случай
         LD (OPENFILE),A

        POP IX
        POP DE
        POP BC
        POP HL
        POP AF
        SCF
        RET
;;;;;;
SMESH_ADD
        LD B,#00
        LD A,(SMESH)
        LD C,A
        ADD HL,BC
        RET


;;;;;;;;;

load1
                ;переносим из
        LD HL,BUFFER ;буфера нужную
        CALL SMESH_ADD
        LD DE,(ADRESS) ;нам информацию
        LD BC,(BUFLEN)

        LDIR
        JP CONTINUE

load2
        LD HL,BUFFER ;переносим из
        CALL SMESH_ADD ;буфера нужную
        LD DE,(ADRESS) ;нам информацию
        LD BC,(BUFLEN)

        LD A,C ;а не ноль ли в BC
        OR B
        JR Z,MMM

CYCLE1  LD A,(HL) ;этот цикл является
        EX DE,HL ;фактически ldir'ом,
        CALL poke1 ;только для z-memory
        EX DE,HL

        INC HL
        INC DE
        DEC BC

        LD A,C
        OR B
        JR NZ,CYCLE1

MMM     JP CONTINUE


save1
                ;переносим информацию из памяти
        LD DE,BUFFER ;в буфер
        EX DE,HL
        CALL SMESH_ADD
        EX DE,HL
        LD BC,(BUFLEN)
        LD HL,(ADRESS)
        LDIR

      if 1
        ld hl,(SECT)
        ld d,0
        ld e,h
        ld h,l
        ld l,d;0
        ld a,(OPENFILE)
        ld b,a
        OS_SEEKHANDLE
        ld de,BUFFER
        ld hl,0x0100
        ld a,(OPENFILE)
        ld b,a
        OS_READHANDLE
      else
        LD BC,#0106 ;записываем сектор
        LD DE,(SECT)
        LD HL,BUFFER
        CALL TRDOS
      endif
        JP CONTINUE

save2
                ;переносим информацию из памяти
        LD DE,BUFFER ;в буфер
        EX DE,HL
        CALL SMESH_ADD
        EX DE,HL
        LD HL,(ADRESS)
        LD BC,(BUFLEN)

        LD A,C
        OR B
        JR Z,MMM1

CYCLE5  CALL peek64 ;этот цикл
        EX DE,HL ;фактически является
        LD (HL),A ;ldir'ом
        EX DE,HL

        INC HL
        INC DE
        DEC BC

        LD A,B
        OR C
        JR NZ,CYCLE5

      if 1
        ld hl,(SECT)
        ld d,0
        ld e,h
        ld h,l
        ld l,d;0
        ld a,(OPENFILE)
        ld b,a
        OS_SEEKHANDLE
        ld de,BUFFER
        ld hl,0x0100
        ld a,(OPENFILE)
        ld b,a
        OS_READHANDLE
      else
        LD BC,#0106 ;записываем сектор
        LD DE,(SECT)
        LD HL,BUFFER
        CALL TRDOS
      endif
MMM1    JP CONTINUE



;;;;;;;;;;;;;;;;;;;;
;
;Read/write savefile
;
driver
        LD      A,B ;если передали
        OR      C   ;длину = 0, то сразу
        SCF         ;выход
        RET     Z

        LD (ADRESS),HL ;сохраняем нужную
;для считывания адрес (куда считывать)
        LD (LENGTH),BC ; и длину
;(сколько)

next
        LD HL,#0100 ;получаем в HL
        LD A,(SMESH)
        LD B,#00
        LD C,A ;количество байт до
        AND A ;конца сектора
        SBC HL,BC

        LD (BUFLEN),HL
        LD BC,(LENGTH)
        AND A
        SBC HL,BC ;сколько байт нужно
        JR C,metka ;считать?
        LD (BUFLEN),BC

metka

      if 1
        ld hl,(SECT)
        ld d,0
        ld e,h
        ld h,l
        ld l,d;0
        ld a,(OPENFILE)
        ld b,a
        OS_SEEKHANDLE
        ld de,BUFFER
        ld hl,0x0100
        ld a,(OPENFILE)
        ld b,a
        OS_READHANDLE
      else
        LD BC,#0105 ;считываем один сектор
        LD HL,BUFFER ;в нужный буфер
        LD DE,(SECT)
        CALL TRDOS
      endif

        LD A,(WHAT)
        CP #00
        JP Z,load1; чтение в память из файла
        CP #01
        JP Z,save1; запись из памяти в файл
        CP #02
        JP Z,load2; чтение в Z-памяти в файл
        CP #03
        JP Z,save2; запись из Z-памяти в файл

CONTINUE  LD HL,(ADRESS) ;устанавливаем
          LD BC,(BUFLEN) ;следущий адрес
        ADD HL,BC ;считывания
        LD (ADRESS),HL

        LD A,(SMESH) ;а также другое
        LD H,#00
        LD L,A
        ADD HL,BC ;смещение в секторе
        LD A,L
        LD (SMESH),A

        LD A,H ;и другой номер сектора
        LD H,#00
        LD L,A
        LD BC,(SECT)
        ADD HL,BC
        ;CALL NO17SEC
        LD (SECT),HL

        LD BC,(BUFLEN) ;и уменьшаем
        LD HL,(LENGTH) ;общую длину
        AND A ;считывания
        SBC HL,BC
        LD (LENGTH),HL

        LD A,H ;а не равна ли длина
        OR L   ;нулю
        SCF
        RET Z ;если она равна нулю, то
;возврат
        jp next

;
;;;;;;;;;;;;;;;;;;;;;
;
;Transcript functions (отгрузки)
;
ts_open

        CALL ZXNAME
        LD A,H
        OR L
        SCF
        RET Z
        LD B,#01
        CALL p3opn
        RET NC
        LD A,#01
        LD (tsflag),A
        SCF
        RET

;;;
ts_close

         LD A,(tsflag)
         OR A
         SCF
         RET Z

         PUSH HL ;Т.к. участвует и при
         PUSH BC ;создании файла
         PUSH DE

         LD HL,#0003
         CALL ts_char
         RET NC

         LD A,(SMESH)
         LD C,A
         LD B,#00
         LD HL,BUFFER
         ADD HL,BC

CYCLE9   LD A,#20 ;' '
         LD (HL),A
         INC HL
         INC C
         JR NZ,CYCLE9

         CALL full_buffer
         LD A,#01
         LD (WHAT),A
         LD HL,(SECT)
         DEC HL
         LD (SECT),HL
         CALL p3clse
         RET NC
         XOR A
         LD (tsflag),A

         POP DE
         POP BC
         POP HL

         SCF
         RET
;;;
ts_char

        LD A,(tsflag)
        OR A
        SCF
        RET Z
        LD A,(cwin)
        OR A
        SCF
        RET Z

        LD A,L
        PUSH AF
        LD HL,BUFFER
        LD B,#00
        LD A,(SMESH); В SMESH в данном
        LD C,A ;случае хранится смещение
        ADD HL,BC ;в BUFFER (от 0 до FF)
        POP AF
        LD (HL),A
        INC C
        CALL Z,full_buffer
        LD A,(SMESH)
        INC A
        LD (SMESH),A

        SCF
        RET

full_buffer
      if 1
        ld a,(OPENFILE)
        ld b,a
        ld hl,(SECT)
        ld d,0
        ld e,h
        ld h,l
        ld l,d;0
        OS_SEEKHANDLE ;dehl=shift
        ld a,(OPENFILE)
        ld b,a
        ld hl,0x0100
        ld de,BUFFER
        OS_WRITEHANDLE
        LD HL,(SECT)
        inc hl
        LD (SECT),HL
      else
        LD BC,#0106
        LD DE,(SECT)
        LD HL,BUFFER
        CALL TRDOS
        LD HL,(TEMP_SEC)
        LD (SECT),HL
      endif
        RET


OPENFILE DB #00 ;Номер открываемого
;файла

LENGTH DB #00,#00
;Длина какую надо считать/записать

ADRESS DB #00,#00
;Куда надо записывать/откуда считывать

SECT   DB #00,#00
;Номер трека и сектора последовательного файла (или номер сектора в файле)

BUFFER DB #00
       DUP 255
        DB #00
       EDUP
;Буфер для Save/Load

BUFLEN DB #00,#00
;Длина из буфера, которую надо перенести

SMESH  DB #00
;Смещение внутри сектора (от 0 до FF)

WHAT DB #00 ; для чтения или для
;записи нужно это? 0=чтение; 1=запись

;FILEBEG DB #00,#00 ;начало файла-отгрузки
;;;;;;;;;;;;;;;;;;

      if 0
EXT DB #30; проверочное расширение
; сначала равно '0'
      endif

WHERE DB #00,#00; используется при
;начальной загрузке и рестарте (адрес в BankN+)

STORY DB #00 ;Номер игрового файла (хэндл)


BUFMEM DB #00 ; А для какого адреса
;Z-machine забита 6-я банка :
;содержится младшая часть E и старшая H

REAL_LEN DB #00, #00 ; действительная
;длина в секторах

      if 0
TEMPSTORY DB #00 ;номер файла для прове-
;рки: не является ли он продолжением
;игрового

FILE_BEGIN DB #00,#00 ;трек и сектор
;начала игрового файла. Используется для
;подсчета длины файла при закрытии
;потока
      endif

; ИСПОЛЬЗУЕТСЯ ДЛЯ RESTART'А
REAL_LEN2 DB #00,#00

tsflag
        DEFB 0
;Transcripting on or off?