?login_element?

Subversion Repositories NedoOS

Rev

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

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