?login_element?

Subversion Repositories NedoOS

Rev

Rev 1615 | Rev 1984 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.     MODULE Dos
  2. ; API methods
  3. ESX_GETSETDRV = #89
  4. ESX_FOPEN = #9A
  5. ESX_FCLOSE = #9B
  6. ESX_FSYNC = #9C
  7. ESX_FREAD = #9D
  8. ESX_FWRITE = #9E
  9.  
  10. ; File modes
  11. FMODE_READ = #01
  12. FMODE_WRITE = #06
  13. FMODE_CREATE = #0E
  14.  
  15.     ; MACRO esxCall func
  16.     ; rst #8 : db func
  17.     ; ENDM
  18.        
  19. ;id = 0 файл не открыт
  20. ;id = 1 файл для чтения
  21. ;id = 2 файл для записи
  22. ;id = 3 файл для записи тип TRD
  23. ;id = 4 файл для записи тип SCL
  24.  
  25. ; HL - filename in ASCIIZ
  26. loadBuffer:
  27.     ld b, Dos.FMODE_READ: call Dos.fopen
  28.     push af
  29.         ld hl, outputBuffer, bc, #ffff - outputBuffer : call Dos.fread
  30.         ld hl, outputBuffer : add hl, bc : xor a : ld (hl), a : inc hl : ld (hl), a
  31.     pop af
  32.     call Dos.fclose
  33.     ret
  34.  
  35.  
  36. ; Returns:
  37. ;  A - current drive
  38. ; getDefaultDrive: ;нигде не используется
  39.     ; ld a, 0 : esxCall ESX_GETSETDRV
  40.     ; ret
  41.  
  42.  
  43.  
  44. ; Opens file on default drive
  45. ; B - File mode
  46. ; HL - File name
  47. ; Returns:
  48. ;  A - file stream id
  49. fopen:
  50.     ; push bc : push hl
  51.     ; call getDefaultDrive
  52.     ; pop ix : pop bc
  53.     ; esxCall ESX_FOPEN
  54.     ; ret
  55.         ld a,b
  56.         cp FMODE_READ ;если режим открытие файла
  57.         jr z,fopen_r
  58.         cp FMODE_CREATE
  59.         jr z,fopen_c ;если режим создание файла
  60.         jr fopen_err ;иначе выход
  61.        
  62. fopen_r ;открытие существующего файла на чтение (id=1)
  63.                         call format_name ;
  64.                         ld      c,#13 ;move file info to syst var
  65.             call    #3d13
  66.             ld      c,#0a ;find file
  67.             call    #3d13
  68.             ld      a,c
  69.                         cp              #ff
  70.                         jr              z,fopen_err ;если не нашли файла
  71.             ld      c,#08 ;read file title
  72.             call    #3d13
  73.             ;ld      hl,loadadr ;куда
  74.             ld      de,(#5ceb) ;начало файла сектор дорожка
  75.             ld      (f_r_cur_trk),de
  76.  
  77.             ld      a,(#5cea)
  78.             ld      (f_r_len_sec),a ;длина в секторах
  79.             ;or      a
  80.             ;ret     z    ;выход если пустой
  81.  
  82.             ; ld      de,(fcurtrk) ;текущие сектор дорожка
  83.             ; ld      (#5cf4),de ;восстановим
  84.                         xor a
  85.                         ld              a,1
  86.                         ld (f_r_flag),a ;флаг что файл для чтения открыт
  87.                         ;id канала будет 1
  88.         ret
  89.        
  90. fopen_err
  91.         xor a ;если никакой файл не открыли, то id = 0
  92.         scf ;флаг ошибки
  93.         ret
  94.  
  95.  
  96. fopen_c ;создание нового файла (id=2-4)
  97.         call format_name ;
  98.         ;выясним, не образ ли это для разворачивания
  99.     ld hl, trdExt1 : call CompareBuff.search : and a : jr nz, fopen_c_trd
  100.     ld hl, trdExt2 : call CompareBuff.search : and a : jr nz, fopen_c_trd
  101.         ld hl, sclExt1 : call CompareBuff.search : and a : jr nz, fopen_c_scl
  102.     ld hl, sclExt2 : call CompareBuff.search : and a : jr nz, fopen_c_scl
  103.  
  104.        
  105. fopen_c_2       ;создание произвольного файла
  106.         jr              fopen_err ;пока отключено
  107.  
  108.         ; ld      c,#13 ;move file info to syst var
  109.     ; call    #3d13
  110.         ; ld de,256 ;запишем пока 1 сектор
  111.         ; ld hl,#4000 ;возьмём случайные данные из экрана
  112.     ; ld      c,#0b ;запись файла CODE
  113.     ; call    #3d13
  114.     ; ld      a,c
  115.         ; cp            #ff
  116.         ; jr            z,fopen_err ;если ошибка
  117.                
  118.     ; ld      de,(#5ceb) ;начало файла сектор дорожка
  119.     ; ld      (f_w_cur_trk),de
  120.     ; ld      a,(#5cea)
  121.     ; ld      (f_w_len_sec),a ;длина в секторах
  122.         ; xor a ;id канала будет 2
  123.         ; ld a,2
  124.         ; ld (f_w_flag),a ;флаг что файл для записи открыт
  125.         ; ret          
  126.        
  127.  
  128.  
  129.  
  130.  
  131. fopen_c_trd     ;открытие файла для разворачивания образа trd (id=3)
  132.         ld a,(#5D19) ;номер дисковода по умолчанию
  133.         add a,"A"
  134.         ld (write_ima_d),a ;подставим букву в запросе
  135.     ld hl, write_ima
  136.     call DialogBox.msgBox ;предуреждение
  137. WAITKEY_trd    
  138.         ld              a,(23556)
  139.         cp 255
  140.         JR Z,WAITKEY_trd        ;ждём любую клавишу
  141.        
  142.         ld      de,0 ;начало сектор дорожка
  143.     ld      (#5cf4),de
  144.         xor a
  145.         ld (sec_shift),a ;переменная
  146.         ld hl,0
  147.         ld (f_w_len+0),hl
  148.         ld (f_w_len+2),hl
  149.         ld a,3 ;id канала
  150.         ld (f_w_flag),a ;флаг что trd для записи открыт
  151.         ret
  152.  
  153.  
  154.  
  155.  
  156. fopen_c_scl     ;открытие файла для разворачивания образа scl (id=4)
  157.         ld a,(#5D19) ;номер дисковода по умолчанию
  158.         add a,"A"
  159.         ld (write_ima_d),a ;подставим букву в запросе
  160.     ld hl, write_ima
  161.     call DialogBox.msgBox ;предуреждение
  162. WAITKEY_scl    
  163.         ld              a,(23556)
  164.         cp 255
  165.         JR Z,WAITKEY_scl        ;ждём любую клавишу
  166.        
  167.         ld      de,0 ;начало сектор дорожка
  168.     ld      (#5cf4),de
  169.        
  170.         ld hl,cat_buf ;очистить место для каталога дискеты
  171.         ld de,cat_buf+1
  172.         ld (hl),0
  173.         ld bc,9*256-1
  174.         ldir
  175.        
  176.         call scl_parse ;запуск цикла сборки образа
  177.        
  178.         xor a
  179.         ld (sec_shift),a ;переменная
  180.         ;ld (scl_que),a
  181.         ld hl,0
  182.         ld (f_w_len+0),hl
  183.         ld (f_w_len+2),hl
  184.         ld a,4 ;id канала
  185.         ld (f_w_flag),a ;флаг что scl для записи открыт
  186.         ret    
  187.  
  188.  
  189.  
  190. ; A - file stream id
  191. fclose:
  192.     ;esxCall ESX_FCLOSE
  193.         ; push af
  194. ; WAITKEY2      XOR A:IN A,(#FE):CPL:AND #1F:JR Z,WAITKEY2
  195.         ; pop af
  196.         cp 4 ;если scl
  197.         jr nz,fclose2
  198.         ld hl,sec_buf ;
  199.         ld b,1
  200.         call scl_write_buf ;допишем остаток scl, если есть
  201.        
  202. fclose2
  203.         xor a ;как бы закрываем все файлы
  204.         ld (f_r_flag),a
  205.         ld (f_w_flag),a
  206.     ret
  207.  
  208.  
  209.  
  210.  
  211. ; A - file stream id
  212. ; BC - length
  213. ; HL - buffer
  214. ; Returns
  215. ;  BC - length(how much was actually read)
  216. fread: ;(id=1)
  217.     ; push hl : pop ix
  218.     ; esxCall ESX_FREAD
  219.         ; push af
  220.         ; ld a,4
  221.         ; out (254),a
  222. ; WAITKEY       XOR A:IN A,(#FE):CPL:AND #1F:JR Z,WAITKEY
  223.         ; xor a
  224.         ; out (254),a
  225.         ; pop af
  226.  
  227.         cp 1 ;id = 1?
  228.         jr nz,fread_no_chek ;выход если номер потока не = 1
  229.         ld a,(f_r_flag)
  230.         or a
  231.         jr nz,fread_chek ;файл уже открыт?
  232. fread_no_chek ;выход с ошибкой
  233.         xor a
  234.         scf ;флаг ошибки
  235.         ld bc,0 ;ничего мы не считали
  236.         ret
  237.        
  238. fread_chek
  239.         push bc
  240.         ld bc,(f_r_len_sec-1) ;загружаем файл целиком, не смотря на то, сколько байт было запрошено
  241.     ld      c,5 ;read читаем целыми секторами
  242.         ld de,(f_r_cur_trk)
  243.     call    #3d13      
  244.         pop bc ;возвратим, что сколько запрашивали, столько и считали байт
  245.         xor a ;флаги сбросим
  246.     ret
  247.  
  248. ; A - file stream id
  249. ; BC - length
  250. ; HL - buffer
  251. ; Returns:
  252. ;   BC - actually written bytes
  253. fwrite: ;
  254.     ; push hl : pop ix
  255.     ; esxCall ESX_FWRITE
  256.        
  257.         ; push af
  258.         ; ld a,2
  259.         ; out (254),a
  260. ; WAITKEY1      XOR A:IN A,(#FE):CPL:AND #1F:JR Z,WAITKEY1
  261.         ; xor a
  262.         ; out (254),a
  263.         ; pop af
  264.  
  265.         cp 2 ;id = 2?
  266.         jr z,fwrite_chek ;проверка id потока
  267.         cp 3 ;id = 3?
  268.         jr z,fwrite_chek_trd ;проверка id потока
  269.         cp 4 ;id = 4?
  270.         jp z,fwrite_chek_scl ;проверка id потока
  271.  
  272.        
  273. fwrite_no_chek ;выход с ошибкой
  274.         xor a
  275.         scf ;флаг ошибки
  276.         ld bc,0 ;ничего мы не записали
  277.         ret
  278.        
  279. fwrite_chek ;запись произвольного типа файла
  280.         jr fwrite_no_chek ;пока отключено
  281.         ; ld a,(f_w_flag)
  282.         ; or a
  283.         ; jr z,fwrite_no_chek ;файл уже открыт?
  284.         ; ld (temp_bc),bc
  285.         ; ;ld bc,(f_r_len_sec-1) ;
  286.     ; ld      c,6 ;пишем целыми секторами
  287.         ; ld de,(f_w_cur_trk)
  288.     ; call    #3d13    
  289.         ; ld bc,(temp_bc) ;возвратим, что сколько запрашивали, столько и считали байт
  290.         ; xor a ;флаги сбросим
  291.     ; ret
  292.  
  293.  
  294.  
  295.  
  296.  
  297. fwrite_chek_trd ;запись trd файла (разворачивание образа)
  298.         ; ld a,2
  299.         ; out (254),a
  300. ; WAITKEY_t     XOR A:IN A,(#FE):CPL:AND #1F:JR Z,WAITKEY_t
  301.         ; xor a
  302.         ; out (254),a
  303.         ld a,(f_w_flag)
  304.         or a
  305.         jr z,fwrite_no_chek ;файл уже открыт?
  306.         ld (temp_bc),bc ;длина
  307.         ld (temp_hl),hl ;адрес данных
  308.         ld a,b
  309.         or c
  310.         jr z,fwrite_no_chek ; если длина 0, то выход
  311.        
  312.         ; ld a,b
  313.         ; or a
  314.         ; jr nz,testt1
  315.         ; nop
  316.        
  317. ; testt1
  318.        
  319.         xor a
  320.         ld (sec_part),a ;обнулить переменные
  321.         ld (sec_shift2),a
  322.         ld (sec_shift2+1),a
  323.         ld (sec_shift_flag),a
  324.         ld (write_end_flag),a ;
  325.        
  326.  
  327.         ld a,(sec_shift)
  328.         or a
  329.         jr z,fwrite_trd3 ;если смещения нет, то первую часть пропустим
  330.        
  331.  
  332.         ld c,a
  333.         ld b,0
  334.         ld hl,(temp_bc) ;проверка заполнится ли целый сектор
  335.         add hl,bc
  336.        
  337.         ld a,1
  338.         ld (write_end_flag),a ;флаг что не нужно дописывать остаток
  339.        
  340.         ld a,h
  341.         or a
  342.         jr nz,fwrite_trd4
  343.         ld a,1
  344.         ld (sec_shift_flag),a ;флаг что не заполнен сектор
  345.        
  346. fwrite_trd4    
  347.         ld hl,sec_buf ;буфер последнего сектора  
  348.         add hl,bc ;на этой точке остановились
  349.         ex de,hl
  350.         ld hl,(temp_hl) ;присоединим начало данных в конец предыдущих
  351.         ; ld a,c
  352.         ; or a
  353.         ; jr nz,fwrite_trd2
  354.         ; inc b ;коррекция
  355. ; fwrite_trd2          
  356.         ; ld c,a
  357.         xor a
  358.         sub c
  359.         ld c,a ;сколько осталось перенести до заполнения сектора
  360.         ld (sec_shift2),bc ;сохраним сколько добавили байт
  361.         ldir
  362.  
  363.         ld a,(sec_shift_flag)
  364.         or a
  365.         jr nz,fwrite_trd3 ;если сектор ещё не заполнен писать не будем
  366.  
  367.         ld hl,sec_buf
  368.         ld de,(#5cf4)
  369.         ;ld (f_w_cur_trk),de    ;запомним позицию
  370.     ld      bc,#0106 ;пишем 1 сектор из буфера
  371.     call    #3d13      
  372.         ld a,c
  373.         cp 255
  374.         jp z,fwrite_no_chek ;выход если ошибка  
  375.  
  376.         xor a
  377.         ld (write_end_flag),a ;флаг что нужно дописывать остаток  
  378.         ; ld de,(f_w_cur_trk) ;если сектор ещё не заполнен, останемся на старой позиции
  379.         ; ld (#5cf4),de
  380.         ; ld b,1 ;на сектор вперёд
  381.         ; ld de,(f_w_cur_trk)
  382.         ; call calc_next_pos
  383.         ; ld (f_w_cur_trk),de  
  384.  
  385. fwrite_trd3    
  386.         ld hl,(temp_hl) ;запишем остаток данных
  387.         ;ld a,(sec_shift)
  388.         ;ld c,a
  389.         ;ld b,0
  390.         ld bc,(sec_shift2)
  391.         add hl,bc ;с этой точки пишем
  392.         ld (temp_hl2),hl ;сохраним начало записи второго сектора
  393.        
  394.         ld hl,(temp_bc) ;вычисление на чём остановимся в этот раз
  395.         and a
  396.         sbc hl,bc ;вычтем то, что добавили к первому сектору
  397.         ld c,l
  398.         ld b,h
  399.         jr nc,fwrite_trd5
  400.         ld b,0 ;коррекция если вышел минус
  401. fwrite_trd5
  402.         ld hl,(temp_hl)
  403.         add hl,bc
  404.        
  405.         ld de,outputBuffer
  406.         and a
  407.         sbc hl,de
  408.        
  409.         ld a,l
  410.         ld (sec_shift),a ;смещение на следующий раз
  411.         ;ld hl,(temp_hl)       
  412.        
  413.  
  414.         ; or a
  415.         ; jr z,fwrite_trd1
  416.         ; inc b  ;коррекция количества секторов
  417.        
  418.         ld a,b ;нужна проверка на количество секторов!!!
  419.         ld (sec_part),a ;запомним сколько секторов во второй части
  420.        
  421.         ;ld a,b
  422.         or a
  423.         jr z,fwrite_trd1 ;если размер данных меньше сектора, то пропустим запись
  424.        
  425.         ld hl,(temp_hl2)
  426.         ;push bc
  427.         ld de,(#5cf4)
  428.     ld      c,6 ;пишем целыми секторами
  429.     call    #3d13      
  430.         ld a,c
  431.         ;pop bc
  432.         cp 255
  433.         jp z,fwrite_no_chek ;выход если ошибка
  434.         ; ld de,(f_w_cur_trk)
  435.         ; call calc_next_pos
  436.         ; ld (f_w_cur_trk),de
  437.        
  438.         xor a
  439.         ld (write_end_flag),a ;флаг что нужно дописывать остаток  
  440.        
  441. fwrite_trd1    
  442.         ld a,(write_end_flag) ;нужно записывать остаток?
  443.         or a
  444.         jr nz,fwrite_trd_ex ;не нужно
  445.  
  446.         ld hl,(temp_hl2) ;сохраним незаписанный остаток
  447.         ld a,(sec_part)
  448.         ld b,a
  449.         ld c,0
  450.         add hl,bc
  451.         ld de,sec_buf
  452.         ld bc,256
  453.         ldir
  454. ;fwrite_trd2   
  455.  
  456.        
  457. fwrite_trd_ex  
  458.         ld bc,(temp_bc) ;возвратим, что сколько запрашивали, столько и записали байт
  459.         ;посчитаем общую длину записанного
  460.         ld hl,(f_w_len)
  461.         add hl,bc
  462.         ld (f_w_len),hl
  463.         jr nc,fwrite_trd_ex1
  464.         ld hl,(f_w_len+2)
  465.         inc hl
  466.         ld (f_w_len+2),hl
  467.        
  468. fwrite_trd_ex1
  469.         xor a ;флаги сбросим
  470.     ret
  471.  
  472.  
  473.  
  474.  
  475.  
  476. ;------------------scl----------------------
  477. fwrite_chek_scl ;запись scl файла (разворачивание образа)
  478.         ; ld a,2
  479.         ; out (254),a
  480. ; WAITKEY_t     XOR A:IN A,(#FE):CPL:AND #1F:JR Z,WAITKEY_t
  481.         ; xor a
  482.         ; out (254),a
  483.         ld a,(f_w_flag)
  484.         or a
  485.         jp z,fwrite_no_chek ;файл уже открыт?
  486.         ld (temp_bc),bc ;длина
  487.         ld (temp_hl),hl ;адрес данных
  488.         ld a,b
  489.         or c
  490.         jp z,fwrite_no_chek ; если длина 0, то выход
  491.        
  492.         ; ld a,b
  493.         ; or a
  494.         ; jr nz,testt1
  495.         ; nop
  496.        
  497. ; testt1
  498.        
  499.         xor a
  500.         ld (sec_part),a ;обнулить переменные
  501.         ld (sec_shift2),a
  502.         ld (sec_shift2+1),a
  503.         ld (sec_shift_flag),a
  504.         ld (write_end_flag),a ;
  505.        
  506.  
  507.         ld a,(sec_shift)
  508.         or a
  509.         jr z,fwrite_scl3 ;если смещения нет, то первую часть пропустим
  510.        
  511.  
  512.         ld c,a
  513.         ld b,0
  514.         ld hl,(temp_bc) ;проверка заполнится ли целый сектор
  515.         add hl,bc
  516.        
  517.         ld a,1
  518.         ld (write_end_flag),a ;флаг что не нужно дописывать остаток
  519.        
  520.         ld a,h
  521.         or a
  522.         jr nz,fwrite_scl4
  523.         ld a,1
  524.         ld (sec_shift_flag),a ;флаг что не заполнен сектор
  525.        
  526. fwrite_scl4    
  527.         ld hl,sec_buf ;буфер последнего сектора  
  528.         add hl,bc ;на этой точке остановились
  529.         ex de,hl
  530.         ld hl,(temp_hl) ;присоединим начало данных в конец предыдущих
  531.         ; ld a,c
  532.         ; or a
  533.         ; jr nz,fwrite_scl2
  534.         ; inc b ;коррекция
  535. ; fwrite_scl2          
  536.         ; ld c,a
  537.         xor a
  538.         sub c
  539.         ld c,a ;сколько осталось перенести до заполнения сектора
  540.         ld (sec_shift2),bc ;сохраним сколько добавили байт
  541.         ldir
  542.  
  543.         ld a,(sec_shift_flag)
  544.         or a
  545.         jr nz,fwrite_scl3 ;если сектор ещё не заполнен писать не будем
  546.  
  547.         ld hl,sec_buf
  548.         ;ld de,(#5cf4)
  549.         ;ld (f_w_cur_trk),de    ;запомним позицию
  550.     ld      b,#01 ;пишем 1 сектор из буфера
  551.     call    scl_write_buf      
  552.         ; ld a,c
  553.         ; cp 255
  554.         ; jp z,fwrite_no_chek ;выход если ошибка
  555.  
  556.         xor a
  557.         ld (write_end_flag),a ;флаг что нужно дописывать остаток  
  558.         ; ld de,(f_w_cur_trk) ;если сектор ещё не заполнен, останемся на старой позиции
  559.         ; ld (#5cf4),de
  560.         ; ld b,1 ;на сектор вперёд
  561.         ; ld de,(f_w_cur_trk)
  562.         ; call calc_next_pos
  563.         ; ld (f_w_cur_trk),de  
  564.  
  565. fwrite_scl3    
  566.         ld hl,(temp_hl) ;запишем остаток данных
  567.         ;ld a,(sec_shift)
  568.         ;ld c,a
  569.         ;ld b,0
  570.         ld bc,(sec_shift2)
  571.         add hl,bc ;с этой точки пишем
  572.         ld (temp_hl2),hl ;сохраним начало записи второго сектора
  573.        
  574.         ld hl,(temp_bc) ;вычисление на чём остановимся в этот раз
  575.         and a
  576.         sbc hl,bc ;вычтем то, что добавили к первому сектору
  577.         ld c,l
  578.         ld b,h
  579.         jr nc,fwrite_scl5
  580.         ld b,0 ;коррекция если вышел минус
  581. fwrite_scl5
  582.         ld hl,(temp_hl)
  583.         add hl,bc
  584.        
  585.         ld de,outputBuffer
  586.         and a
  587.         sbc hl,de
  588.        
  589.         ld a,l
  590.         ld (sec_shift),a ;смещение на следующий раз
  591.         ;ld hl,(temp_hl)       
  592.        
  593.  
  594.         ; or a
  595.         ; jr z,fwrite_scl1
  596.         ; inc b  ;коррекция количества секторов
  597.        
  598.         ld a,b ;нужна проверка на количество секторов!!!
  599.         ld (sec_part),a ;запомним сколько секторов во второй части
  600.        
  601.         ;ld a,b
  602.         or a
  603.         jr z,fwrite_scl1 ;если размер данных меньше сектора, то пропустим запись
  604.        
  605.         ld hl,(temp_hl2)
  606.         ;push bc
  607.         ;ld de,(#5cf4)
  608.     ;ld      c,6 ;пишем целыми секторами
  609.     call    scl_write_buf      
  610.         ;ld a,c
  611.         ;pop bc
  612.         ; cp 255
  613.         ; jp z,fwrite_no_chek ;выход если ошибка
  614.         ; ld de,(f_w_cur_trk)
  615.         ; call calc_next_pos
  616.         ; ld (f_w_cur_trk),de
  617.        
  618.         xor a
  619.         ld (write_end_flag),a ;флаг что нужно дописывать остаток  
  620.        
  621. fwrite_scl1    
  622.         ld a,(write_end_flag) ;нужно записывать остаток?
  623.         or a
  624.         jr nz,fwrite_scl_ex ;не нужно
  625.  
  626.         ld hl,(temp_hl2) ;сохраним незаписанный остаток
  627.         ld a,(sec_part)
  628.         ld b,a
  629.         ld c,0
  630.         add hl,bc
  631.         ld de,sec_buf
  632.         ld bc,256
  633.         ldir
  634. ;fwrite_scl2   
  635.  
  636.        
  637. fwrite_scl_ex  
  638.         ld bc,(temp_bc) ;возвратим, что сколько запрашивали, столько и записали байт
  639.         ;посчитаем общую длину записанного
  640.         ld hl,(f_w_len)
  641.         add hl,bc
  642.         ld (f_w_len),hl
  643.         jr nc,fwrite_scl_ex1
  644.         ld hl,(f_w_len+2)
  645.         inc hl
  646.         ld (f_w_len+2),hl
  647.        
  648. fwrite_scl_ex1
  649.         xor a ;флаги сбросим
  650.     ret
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657. scl_write_buf ;заполнение промежуточного буфера
  658.         push bc ;сколько пакетов указано в b
  659.         ld de,scl_buf ;перенесём сектор во временный буфер
  660.         ld bc,256
  661.         ldir
  662.         ld (scl_temp_hl2),hl ;сохраним адрес данных
  663.         ld a,(scl_que) ;проверим флаг что нужны данные
  664.         or a
  665.         jr z,scl_write_buf_ret ;не будем вызывать парсер если не нужны
  666.         ld hl,scl_write_buf_ret ;адрес возврата
  667.         push hl
  668.         ld hl,(scl_parse_ret_adr) ;адрес для продолжения основного цикла сборки
  669.         jp (hl) ;отдадим пакет 256 байт парсеру
  670. scl_write_buf_ret
  671.         ld hl,(scl_temp_hl2)
  672.         pop bc
  673.         djnz scl_write_buf
  674.  
  675.         ret
  676.        
  677.        
  678.        
  679. scl_parse ;разбор образа scl в trd, основной цикл
  680.         ;получить первый сектор
  681. ;запрос порции данных по 256 байт
  682.         ld (scl_temp_hl),hl
  683.         ld (scl_temp_de),de
  684.         ld (scl_temp_bc),bc
  685.         ld a,1
  686.         ld (scl_que),a ;включим флаг что нужны данные
  687.         ld hl,scl_parse_ret ;сохраним адрес возврата
  688.         ld (scl_parse_ret_adr),hl
  689.         ret ;вернёмся для ожидания данных
  690. scl_parse_ret  
  691.         xor a
  692.         ld (scl_que),a
  693.         ld hl,(scl_temp_hl)
  694.         ld de,(scl_temp_de)
  695.         ld bc,(scl_temp_bc)
  696.        
  697.         ld de,scl_buf ;проверка метки образа
  698.         ld hl,scl_sign
  699.         ld b,8
  700. scl_parse_chk
  701.         ld a,(de)
  702.         cp (hl)
  703.         jr nz,scl_parse_chk_no
  704.         inc hl
  705.         inc de
  706.         djnz scl_parse_chk
  707.         jr scl_parse_chk_ok
  708. scl_parse_chk_no ;если не совпало, значит плохой образ
  709.     ld hl, scl_err
  710.     call DialogBox.msgBox ;предуреждение
  711.         xor a
  712.         ld (scl_que),a ;выключим флаг что нужны данные
  713.         ld a,4 ;закроем файл
  714.         call fclose
  715.         ret
  716. scl_parse_chk_ok ;сигнатура правильная
  717.  
  718. ;формирование каталога
  719.         ld a,(scl_buf+8)
  720.         ld (scl_files),a ;всего файлов
  721.         ld (scl_cat_cycl),a ;цикл
  722.         ld hl,scl_buf+9 ;адрес первого заголовка
  723.         ld de,cat_buf ;адрес формируемого каталога trd
  724. scl_parse_cat2 
  725.         ld b,14 ;14 байт одна запись
  726. scl_parse_cat  
  727.         ld a,(hl)
  728.         ld (de),a
  729.         inc de
  730.         inc l ;адрес увеличиваем только в пределах младшего регистра
  731.         jr nz,scl_parse_cat1
  732.         ;тут пора запросить следующий сектор
  733. ;запрос порции данных по 256 байт
  734.         ld (scl_temp_hl),hl
  735.         ld (scl_temp_de),de
  736.         ld (scl_temp_bc),bc
  737.         ld a,1
  738.         ld (scl_que),a ;включим флаг что нужны данные
  739.         ld hl,scl_parse_ret1 ;сохраним адрес возврата
  740.         ld (scl_parse_ret_adr),hl
  741.         ret ;вернёмся для ожидания данных
  742. scl_parse_ret1
  743.         xor a
  744.         ld (scl_que),a
  745.         ld hl,(scl_temp_hl)
  746.         ld de,(scl_temp_de)
  747.         ld bc,(scl_temp_bc)
  748.        
  749. scl_parse_cat1
  750.         djnz scl_parse_cat
  751.         inc de
  752.         inc de
  753.         ld a,(scl_cat_cycl)
  754.         dec a
  755.         ld (scl_cat_cycl),a
  756.         jr nz,scl_parse_cat2
  757.        
  758.         ld (scl_temp_hl),hl ;запомнить где остановились
  759.        
  760. ;подсчёт секторов и дорожек
  761.         push ix
  762.         ld a,(scl_files)
  763.         ld de,#0100 ;данные с первой дорожки
  764.         ld ix,cat_buf
  765.         ld (ix+14),e
  766.         ld (ix+15),d
  767.         ld hl,0 ;общее количество секторов
  768. scl_cacl
  769.         ld (scl_cat_cycl),a ;цикл
  770.         ld a,(ix+13) ;длина файла в секторах
  771.         ld c,a
  772.         ld b,0
  773.         add hl,bc ;секторов
  774.        
  775.         ld bc,16
  776.         add ix,bc
  777.         ld b,a
  778.         call calc_next_pos
  779.         ld a,(scl_cat_cycl)
  780.         cp 1
  781.         jr z,scl_cacl2 ;в последний раз пропусим
  782.         ld (ix+14),e
  783.         ld (ix+15),d
  784. scl_cacl2
  785.         dec a
  786.         jr nz,scl_cacl
  787.         ;теперь узнаем первый свободный сектор
  788.         ld a,(ix+13) ;длина файла в секторах
  789.         ld c,a
  790.         ld b,0
  791.         add hl,bc
  792.         ; ld b,a
  793.         ; call calc_next_pos
  794.         ld (cat_buf+8*256+#e1),de ;Первый свободный сектор и дорожка на дискете
  795.         ld de,16*159
  796.         ex de,hl
  797.         and a
  798.         sbc hl,de
  799.         ld (cat_buf+8*256+#e5),hl ;Число свободных секторов на диске
  800.         pop ix
  801.  
  802.  
  803.        
  804. ;запись содержимого файлов
  805.         ld a,(scl_files) ;всего файлов
  806.         ld (scl_cat_cycl),a ;цикл
  807.         ld hl,cat_buf+13 ;адрес размер секторов файла
  808.         ld (cat_cur_adr),hl
  809.  
  810.         ld hl,#0100 ;начиная с первой дорожки
  811.         ld (#5cf4),hl
  812. scl_parse_file2
  813.         ld hl,(scl_temp_hl) ;адрес данных
  814.         ld de,(cat_cur_adr) ;адрес сектор дорожка файла
  815.         ;dec de
  816.         ld a,(de) ;количество секторов, цикл
  817.         ld c,a
  818. scl_parse_file3
  819.         ld de,scl_buf2 ;адрес ещё одного буфера
  820.         ld b,0 ;256 байт один сектор, цикл
  821. scl_parse_file 
  822.         ld a,(hl)
  823.         ld (de),a
  824.         inc de
  825.         inc l ;адрес увеличиваем только в пределах младшего регистра
  826.         jr nz,scl_parse_file1
  827.         ;тут пора запросить следующий сектор
  828. ;запрос порции данных по 256 байт
  829.         ld (scl_temp_hl),hl
  830.         ld (scl_temp_de),de
  831.         ld (scl_temp_bc),bc
  832.         ld a,1
  833.         ld (scl_que),a ;включим флаг что нужны данные
  834.         ld hl,scl_parse_ret2 ;сохраним адрес возврата
  835.         ld (scl_parse_ret_adr),hl
  836.         ret ;вернёмся для ожидания данных
  837. scl_parse_ret2
  838.         xor a
  839.         ld (scl_que),a
  840.         ld hl,(scl_temp_hl)
  841.         ld de,(scl_temp_de)
  842.         ld bc,(scl_temp_bc)
  843.        
  844. scl_parse_file1
  845.         djnz scl_parse_file
  846.         ld (scl_temp_hl),hl    
  847.         ld (scl_temp_bc),bc
  848.        
  849.         ld hl,scl_buf2 ;;запишем один сектор
  850.         ld  de,(#5cf4)
  851.     ld      bc,#0106 ;
  852.     call    #3d13      
  853.         ; ld a,c
  854.         ; cp 255
  855.         ; jp z,fwrite_no_chek ;выход если ошибка
  856.         ld hl,(scl_temp_hl)
  857.         ld bc,(scl_temp_bc)
  858.        
  859.         dec c
  860.         jr nz,scl_parse_file3
  861.        
  862.         ld hl,(cat_cur_adr) ;адрес сектор дорожка файла
  863.         ; ld e,(hl)
  864.         ; inc hl
  865.         ; ld d,(hl)
  866.         ld bc,16
  867.         add hl,bc ;на следующий файл
  868.         ld (cat_cur_adr),hl    
  869.        
  870.        
  871.         ld a,(scl_cat_cycl)
  872.         dec a
  873.         ld (scl_cat_cycl),a
  874.         jr nz,scl_parse_file2   ;на следующий файл
  875.        
  876.        
  877.  
  878. ;формирование системного сектора №9 (8)
  879.         ;
  880.         ;ld (cat_buf+8*256+#e1),a ;// #E1 Первый свободный сектор на дискете
  881.         ;
  882.         ;ld (cat_buf+8*256+#e2),a ;// #E2 Первый свободный трек
  883.         ld a,#16
  884.         ld (cat_buf+8*256+#e3),a ;// #E3 16 80 дорожек, 2 стороны
  885.         ld a,(scl_files)
  886.         ld (cat_buf+8*256+#e4),a ;// #E4 Общее количество файлов записанных на диск
  887.         ;
  888.         ;ld (cat_buf+8*256+#e5),a ;// #Е5,Е6 Число свободных секторов на диске
  889.         ;ld (cat_buf+8*256+#e6),a
  890.         ld a,#10
  891.         ld (cat_buf+8*256+#e7),a ;// #E7 Код  #10,определяющий принадлежность к TR-DOS   
  892.  
  893.         ld hl,f_name ;запишем имя диска, взяв для этого имя файла
  894.         ld de,cat_buf+8*256+#f5 ;// #F5-#FC Имя диска в ASCII формате
  895.         ld bc,8
  896.         ldir
  897.        
  898.         ld hl,cat_buf ;запишем каталог на диск
  899.         ld de,0
  900.     ld      bc,#0906 ;
  901.     call    #3d13      
  902.         ; ld a,c
  903.         ; cp 255
  904.         ; jp z,fwrite_no_chek ;выход если ошибка
  905.         ret
  906.  
  907.  
  908. ;-----------scl end --------------------
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.    
  919. ; A - file stream id
  920. ; fsync:
  921. ;     esxCall ESX_FSYNC
  922.     ; ret
  923.  
  924.  
  925. ; HL - name (name.ext)
  926. ; Returns:
  927. ; HL - name (name    e)
  928. format_name ;подгоняет имя файла под стандарт trdos (8+1)
  929.  
  930.         ;сначала попробуем убрать из пути подпапку, если она есть
  931.         ld (temp_hl),hl ;сохраним адрес исходного имени
  932.         ld b,#00 ;не больше 255 символов       
  933. format_name5   
  934.         ld a,(hl)
  935.         cp "/" ;если есть подпапка
  936.         jr z,format_name_path_yep
  937.         ld a,(hl)
  938.         cp "." ;если ещё не дошли до расширения
  939.         jr nz,format_name6
  940.         ld hl,(temp_hl) ;если дошли до расширения, то путей нет, вернёмся на начало имени
  941.         jr format_name_7 ;на выход
  942. format_name6
  943.         inc hl
  944.         djnz format_name5
  945.        
  946. format_name_path_yep ;нашли
  947.         inc hl ;пропустим знак "/"
  948.        
  949. format_name_7  
  950.  
  951.  
  952.         push hl ;очистим место для нового имени
  953.         ld hl,f_name
  954.         ld de,f_name+1
  955.         ld (hl)," "
  956.         ld bc,8
  957.         ldir
  958.         pop hl
  959.  
  960.         ld bc,#09ff ;длина имени 9 символов
  961.         ld de,f_name ;куда
  962. format_name2   
  963.         ld a,(hl)
  964.         cp "."
  965.         jr nz,format_name1
  966.         inc hl
  967.         ld a,(hl)
  968.         ld (f_name+8),a ; и в конце первую букву расширения
  969.         ex de,hl ;сохраним адрес исходного расширения
  970.         jr format_name_e
  971. format_name1
  972.         ldi
  973.         djnz format_name2
  974.        
  975.         ;если имя длинное, пропустим лишнее до расширения
  976.         ld b,#00 ;не больше 255 символов       
  977. format_name3   
  978.         ld a,(hl)
  979.         cp "."
  980.         jr nz,format_name4
  981.         inc hl
  982.         ld a,(hl)
  983.         ld (f_name+8),a ; и в конце первую букву расширения
  984.         ex de,hl ;сохраним адрес исходного расширения
  985.         jr format_name_e
  986. format_name4
  987.         inc hl
  988.         djnz format_name3
  989.        
  990. format_name_e ;выход
  991.         ld hl,f_name ;вернём результат
  992.         ret
  993.  
  994. ; DE - trk/sec
  995. ; B - sectors step
  996. ; Returns:
  997. ; DE - trk/sec 
  998. calc_next_pos           ;вперёд на N секторов  
  999.                         ;ld b,4
  1000.                         ;ld  de,(#5ceb)
  1001. calc_next_pos2         
  1002.                         inc e
  1003.                         ld a,e
  1004.                         cp 16
  1005.                         jr c,calc_next_pos1
  1006.                         inc d
  1007.                         ld e,0
  1008. calc_next_pos1
  1009.                         ;ld (#5ceb),de
  1010.                         djnz calc_next_pos2
  1011.                         ret
  1012.                        
  1013.  
  1014. ;testt db "123.trd"
  1015. write_ima db "Insert disk to drive "
  1016. write_ima_d db "A. "
  1017.                 db "All data will be lost!",0
  1018.                
  1019. trdExt1 db ".trd", 0
  1020. trdExt2 db ".TRD", 0
  1021.  
  1022. sclExt1 db ".scl", 0
  1023. sclExt2 db ".SCL", 0
  1024.  
  1025. f_name ds 9 ;имя файла
  1026. f_r_cur_trk dw   0 ;текущие сектор-дорожка файла на чтение
  1027. f_r_len_sec db 0 ;длина файла на чтение в секторах
  1028. f_r_flag db 0 ;флаг что открыт файл на чтение
  1029.  
  1030. f_w_cur_trk dw   0 ;текущие сектор-дорожка файла на запись
  1031. f_w_len_sec db 0 ;длина файла на запись в секторах
  1032. f_w_flag db 0 ;флаг что открыт файл на запись
  1033. f_w_len ds 4 ;длина записанных данных
  1034. write_end_flag db 0 ;флаг что нужно записать остаток
  1035.  
  1036. temp_bc dw 0 ;хранение регистра
  1037. temp_hl dw 0 ;хранение регистра
  1038. temp_hl2 dw 0 ;хранение регистра
  1039.  
  1040. sec_shift db 0 ;указатель на каком байте остановлена запись
  1041. sec_shift2 db 0 ;указатель на каком байте остановлена запись (остаток)
  1042. sec_part db 0 ;сколько секторов во второй порции для записи
  1043. sec_shift_flag db 0 ;флаг что буфер сектора не заполнен
  1044.  
  1045. ;секция scl
  1046. scl_sign db "SINCLAIR" ;метка
  1047. scl_que db 0 ;флаг запроса порции данных
  1048. scl_err db "SCL image error!",0
  1049. scl_parse_ret_adr dw 0; адрес возврата в цикл
  1050. scl_cat_cycl db 0 ;переменная цикла
  1051. scl_files db 0 ;всего файлов
  1052. scl_temp_hl dw 0;;хранение регистра
  1053. scl_temp_hl2 dw 0;
  1054. scl_temp_de dw 0;
  1055. scl_temp_bc dw 0;
  1056. cat_cur_adr dw 0;
  1057. ;scl end
  1058.         align 256 ;временно
  1059.         ;по адресу #4000 шрифт
  1060. cat_buf equ #4800 ;буфер для кататога диска 9*256
  1061. sec_buf equ cat_buf + 9*256 ;буфер сектора для записи 256
  1062. scl_buf equ sec_buf + 512 ;промежуточный буфер 256
  1063. scl_buf2 equ scl_buf + 512 ;промежуточный буфер 256
  1064.  
  1065.     ENDMODULE