avatar_OffseT

UniDOS, the new multi-device AMSDOS replacement

Started by OffseT, 15:51, 24 January 21

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

OffseT

#300
Even if I could own all existing hardware devices, I wouldn't have time to create a DOS node for any single existing one.
That's the reason why UniDOS is an opened DOS where anyone can create a new DOS node to support any new device.

I already created DOS nodes for most common devices, which can be used as a reference for new ones.
So, if you need support for a specific device, just do it! 8)

On my side, I also have to focus on UniDOS itself, many features are still to be added to the core ROM.
No new DOS nodes from my side are planned at the moment.

zhulien

#301
@GUNHED I am happy to share my DOSNODE code so far if you want it as a starting point - some bits are a challenge, but... it is more an understanding of how it works than it actually being difficult.  I think the most difficult bit might be how to match the code you have currently for the Dobbertin into the right DOSNODE APIs in the best way.  The DOSNODE APIs are pretty reasonable though.  There is also other DOSNODE full source available from the UniDOS official site.

I'm wondering... rather than use a very old legacy 20mb HDD (is it an MFM one?) wouldn't someone be better to make a new microcontroller circuit that might be compatible but... maps to a hardfile on an SDCARD or similar?  I think you suggested in the M4 card before - but that is up to @Duke.  I believe the Symbiface 3 does something like this right?

GUNHED

Well, I'm very busy with my own OS. However if somebody already made a DOS-NODE I can help with all stuff like: Read DIRectory, read/write file, erase/rename file and so on. Also I can help with technical things.

Speaking of technical things: It's very easy, basically you only need to read/write a sector. And all you need to do is to tell the controller which sector, cylinder, head you want to use. That's it.  :)

The idea of UniDOS is great, but it won't work if it's not supporting all mass storage devices imho. Because then we end up to need different DOS again. So I hope that one day some cool coder will also do a DOS-Node for the HD20 hard-disc. BTW: It was and still is the most often sold mass storage device for CPC (regarding storage space bigger than a floppy disc).
(One of the reasons for me to make FutureOS was to have everything in one OS - to eliminate the need to switch between DOS/OS all the time).
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

Prodatron

Quote from: GUNHED on 13:22, 09 August 23The idea of UniDOS is great, but it won't work if it's not supporting all mass storage devices
UniDOS supports most of the actual mass storage devices.
It probably works much better than something that almost only supports storage devices from the 80s.

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

eto

Quote from: GUNHED on 13:22, 09 August 23So I hope that one day some cool coder will also do a DOS-Node for the HD20 hard-disc.
It probably has to be someone who owns a HD20 and is interested to use it with UniDOS. 


zhulien

what is the current price of a HD20 secondhand if someone has one?

eto

Quote from: zhulien on 10:12, 15 August 23what is the current price of a HD20 secondhand if someone has one?
I have some saved searches on Ebay with daily notifications since early 2020. I can't remember that a single one was offered. 

But that is no surprise. It's a wonder if such an old hard drive is still working and honestly I would not put any relevant data on it.

GUNHED

#307
Quote from: zhulien on 10:12, 15 August 23what is the current price of a HD20 secondhand if someone has one?
Well, users owning such a device will probably not sell it, because it's a real gem.
However, now there is support of the HD20 with Symbiface III. So if you own an SF3 then you can already use the HD20. More information in the SF3 creators group at slackbot.

Support of the HD20 in UniDOS would push the idea of supporting any kind of mass storage.
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

Prodatron

Can you present this SF3 support on the XzX and show the important (CP/M?) software, which is supporting the HD20? Would be interesting.

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

GUNHED

#309
Quote from: Prodatron on 21:43, 17 August 23Can you present this SF3 support on the XzX and show the important (CP/M?) software, which is supporting the HD20? Would be interesting.
Everybody can go to the slack group of the SF3 / RSF3 and there join the HD20 emu group.
There you can get an firmware update (see thread) and the HD20 image.

After installing the image on USB:/HD20/ and installing X-DDOS as (active DOS) ROM you can use commands like !CPM,4 (5, 6, 7) to start different CP/M versions. The software is all right there, as long as you know you CP/M basics like user numbers. Also the Z system is on this image - the Unix for the CP/M Plus (CPC in this case).

The HD20 emulation team can be joined here:
https://app.slack.com/client/TCVGGRXPH/C03M0GS1BJS
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

Prodatron

Looking forward to your presentation! :)

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

eto

I would also love to see what you can do with it and what all the software is, that supports the HD20. Never saw it, never heard of it and I am lacking the imagination, what all that could be. 

A presentation with real examples, maybe a short video, would be awesome.

GUNHED

Quote from: Prodatron on 21:58, 17 August 23Looking forward to your presentation! :)
Thanks for being supportive - the HD20 emulation deserves it!  :)
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

GUNHED

#313
Quote from: eto on 12:01, 18 August 23I would also love to see what you can do with it and what all the software is, that supports the HD20. Never saw it, never heard of it and I am lacking the imagination, what all that could be.

A presentation with real examples, maybe a short video, would be awesome.
Yes, a video would be nice. We got quite some experts regarding CPC videos in this forum. Personally I don't own such professional equipment though.

And...
https://www.cpcwiki.eu/index.php/Dobbertin_Harddisc#Software_using_the_Dobbertin_Harddrive
http://futureos.de --> Get the revolutionary FutureOS (Update: 2023.11.30)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> Get the RSX-ROM for LambdaSpeak :-) (Updated: 2021.12.26)

Prodatron


Quote from: eto on 12:01, 18 August 23Never saw it, never heard of it and I am lacking the imagination, what all that could be.
Here the same.


Quote from: eto on 12:01, 18 August 23A presentation with real examples, maybe a short video, would be awesome.
I will do a video next weekend when TFM is doing his HD20 presentation on the XzentriX.


Quote from: GUNHED on 12:56, 18 August 23Personally I don't own such professional equipment though.
It's called "smartphone".

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

SkulleateR

What is the correct way to access real Floppy Drives with UniDOS ?

In the readme it says, real drives can be accessed with DFA: and DFB: but I cannot access them ...

Right now I'm using it with an Albireo SD, so everything is mapped to SD:

If I try a LOAD"DFA:TEST.BAS" it says Bad command
IDRIVE,"A","DFA:" also results in a Bad command

If I call Idrive I can see both physical drives are set to SD:

I can of course set the drives to any directory on the sd card, that's no problem but I need to access the real disk drives ... any hints ?

m_dr_m

You are correct, DFA: and DFB: are the proper device names.
Do you see them under "Available Devices" when doing |DRIVE ?

Is AMSDOS still in ROM 7 and UNIDOS under ROM 7? (1 to 6)
Or alternatively in ROM 15 if UNIDOS occupies ROM 7?
As per Documentation.


OffseT

Quote from: SkulleateR on 21:32, 09 December 23What is the correct way to access real Floppy Drives with UniDOS ?
DFA:/DFB: are actually the proper DOS device names.
"Bad command" happens when you access a non-existing device.
As stated by Madram, you need to have AMSDOS or ParaDOS installed, because UniDOS rely on them to provide floppy support.

If AMSDOS or ParaDOS is available, UniDOS should display "integrated" during boot, otherwise, it will display "standalone".

You can also check the devices detected by each node using |NODE RSX. Without parameter it will display all the detected DOS nodes; and if you provide one, it will display the list of the detected devices by the provided node number.

For instance:
|NODE,<number of UniDOS ROM> will list the devices UniDOS detected internally. If AMSDOS is installed, you will see DFA:/DFB:. If not, they won't appear.

|DRIVE itself works a bit differently. It will display the devices which are available from all the detected DOS nodes at the time it is issued. In that case, DFA:/DFB: will only appear if AMSDOS is installed and a floppy disc is inserted.

SkulleateR

Seems I got a hickup in the Rom installation ... did it all from scratch and now it is working :)

zhulien

A bit lost :D

If anybody has some time to look at the following code, much appreciated - 2 issues I don't yet get...

1. the wrong description against some drives when performing a |drive command
2. the way examine and examine next work - currently wondering why I get 100s of TESTFILE rather than 1, I was using location #BE80 as a flag (not intended to stay that way).

The node is supposed to have 4 drives, if you for example change A drive to be VIDEO (load "VIDEO:") then |DRIVE should list the correct names etc... if you then save"ANYTEXT" it will literally put ANYTEXT on the screen - but also some junk for some reason.

org #c000

 ;write direct #C000, #0a

CODE_START:

ROMType db 2; 1 (secondary ROM) or 2 (expansion ROM)

ROMMark db 1; It is customary that the version of a ROM
ROMVer db 4; is displayed in the form M VR
ROMRev db 1; (i.e. 1.00 here)

ROMRSX dw RSXTable

 jp InitROM
 jp DOSNode_Init ; implemented, 1, called once, A = 1
 jp DOSNode_CheckDrive ; implemented, 3, called once, HL = Streamer, Return 0
 jp DOSNode_GetStatus ; implemented, 4, called once, A = 0
 jp DOSNode_GetName ; implemented, 2, called 8 times, A = 0 to 7
 jp DOSNode_GetDesc ; implemented, 6, called once, A = 0
 jp DOSNode_GetFreeSpace ; implemented, 5, called once, A = 0
 jp DOSNode_InOpenStream
 jp DOSNode_InReadStream
 jp DOSNode_InCloseStream
 jp DOSNode_InSeekStream
 jp DOSNode_OutOpenStream ; implemented
 jp DOSNode_OutWriteStream ; implemented
 jp DOSNode_OutCloseStream ; implemented
 jp DOSNode_OutSeekStream
 jp DOSNode_Examine
 jp DOSNode_ExamineNext
 jp DOSNode_Rename
 jp DOSNode_Delete
 jp DOSNode_CreateDir
 jp DOSNode_SetProtection
 jp DOSNode_Format
 jp DOSNode_SetFileDate
 jp DOSNode_Void
 jp DOSNode_Void
 jp DOSNode_Void
 jp DOSNode_ReadRTC
 jp DOSNode_WriteRTC
 jp DOSNode_OpenNVRAM
 jp DOSNode_CloseNVRAM
 jp DOSNode_ReadNVRAM
 jp DOSNode_WriteNVRAM
 jp DOSNode_SeekNVRAM
 ; You can add your personal RSX here (if ROM type 1)

RSXTable
 str "STREAMER"
 str "DOS Node"

 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80
 db #80

 ; You can add your personal RSX here (if ROM type 1)
 db 0; End of the RSX table

        ; Actual ROM code starts here
InitROM: cp a
 ret
 
BYTES_FREE_HW equ #00ff ; high word
BYTES_FREE_LW equ #ffff ; low word
DAC_DELAY equ 4 ; slow dac playing a bit
PORT_AMDRUM equ #ff
PORT_MMACHINE equ #f8f0

MC_PRINT_CHAR equ #bd2b
TXT_OUT_CHAR equ #bb5a

Drive_AUD equ #0
Drive_PRN equ #1
Drive_TLK equ #2
Drive_VID equ #3

DriveNames:
DriveNameAUD: db "AUDI", "O" + #80, 0, Drive_AUD
DriveNamePRN: db "PRIN", "T" + #80, 0, Drive_PRN
DriveNameTLK: db "TAL", "K" + #80, 0, Drive_TLK
DriveNameVID: db "VIDE", "O" + #80, 0, Drive_VID
 db 0

DriveDescAUD: db "Audio Device", "s" + #80, 0
DriveDescPRN: db "Printer Device", "s" + #80, 0
DriveDescTLK: db "Talking Device", "s" + #80, 0
DriveDescVID: db "Video Device", "s" + #80, 0

AUD_AMDRM: db "AMDRUM    ", 0
AUD_MMACH: db "MMACHINE  ", 0
PRN_7BIT: db "7BIT      ", 0
TALK_SSA1: db "SSA1      ", 0
TALK_DKTRONIC: db "DKTRON    ", 0
VID_ASCII: db "ASCII      ", 0

;
; Initialize the noeud DOS
;
; Input  - A = initialization status (see flags Init_*)
;              Bit0 = 1 if the CPC is doing a cold boot
;              Other bits are unused
; Output  - If Carry = 1 then the node was intialized
;          If Carry = 0 then the node could not be initialized
; Altered - AF

DOSNode_Init: xor a
 jp DOSNode_Success

;
; Check if a drive name is handled by the DOS node
;
; Input  - HL = pointer to the drive name
;                (bit 7 could be set on some character and mush be ignored)
;          C = length of the drive name
; Output - If Carry = 1 a drive was found in the node
;                A = physical drive number
;          If Carry = 0 the drive was not found in the node
; Altered - AF

DOSNode_CheckDrive:
 push de
 push hl
 ld de, DriveNames
 ex de, hl
 call ListGetIDByName
 pop hl
 pop de
 jp nz, DOSNode_Fail
 jp DOSNode_Success

;
; Return a drive status
;
; Input  - A = drive number
; Output  - If Carry = 1 a status was returned
;                A = status of the drive (see flags flags Media_*)
;                    Bit0 = 1 if a media is inserted in the drive
;                    Bit1 = 1 if the media support directories
;                    Bit2 = 1 if the media is write protected
;                    Bit3 = 1 if the media is removable
;                    Bit4 = 1 if the media is a stream (linear read/write only)
;                        $$$ and BAK filesis then disabled
;                    Bit5 = 1 if the media can be reached by the new UniDOS API
;                    Other bits are unused
;          If Carry = 0 then the drive is unknown and no status was returned
; Alteted - AF

DOSNode_GetStatus:
 cp Drive_AUD
 jr z, DOSNode_GetStatusEnd

 cp Drive_PRN
 jr z, DOSNode_GetStatusEnd

 cp Drive_TLK
 jr z, DOSNode_GetStatusEnd

 cp Drive_VID
 jr z, DOSNode_GetStatusEnd

 jp DOSNode_Fail

DOSNode_GetStatusEnd:
 ld a, %000110001
 jp DOSNode_Success

;
; Return the name corresponding to a physical drive
;
; Input  - A = drive number
;          DE = address of a buffer of 8 bytes when to store the name
; Output  - If Carry = 1 the name was found
;                DE points to the first character after the end of the copied string
;                (the string is stored with the bit 7 of its last character set)
;          If Carry = 0 not description was found and the buffer is left unchanged.
; Altered - AF,DE

DOSNode_GetName:
 push hl
 
 cp Drive_AUD
 ld hl, DriveNameAUD
 jr z, DOSNode_GetNameCopy

 cp Drive_PRN
 ld hl, DriveNamePRN
 jr z, DOSNode_GetNameCopy

 cp Drive_TLK
 ld hl, DriveNameTLK
 jr z, DOSNode_GetNameCopy

 cp Drive_VID
 ld hl, DriveNameVID
 jr z, DOSNode_GetNameCopy

 pop hl
 jp DOSNode_Fail

DOSNode_GetNameCopy:
 call StrCopy
 pop hl
 jp DOSNode_Success
 
;
; Return the description corresponding to a physical drive
;
; Input  - A = drive number
;          DE = addess of the 32 bytes buffer where to store the description
; Ouput  - If Carry = 1 a description was found
;                DE points to the first character after the end of the copied string
;                (the string is stored with the bit 7 of its last character set)
;          If Carry = 0 not description was found and the buffer is left unchanged.
; Altered - AF,DE

DOSNode_GetDesc:
 push hl
 
 cp Drive_AUD
 ld hl, DriveDescAUD
 jr z, DOSNode_GetDescCopy

 cp Drive_PRN
 ld hl, DriveDescPRN
 jr z, DOSNode_GetDescCopy

 cp Drive_TLK
 ld hl, DriveDescTLK
 jr z, DOSNode_GetDescCopy

 cp Drive_VID
 ld hl, DriveDescVID
 jr z, DOSNode_GetDescCopy

 pop hl
 jp DOSNode_Fail

DOSNode_GetDescCopy:
 call StrCopy
 pop hl
 jp DOSNode_Success

;
; Return the free space on a physical drive
;
; Input  - A = drive number
; Output  - If Carry = 1 the routine is supported for this drive
;                If Z then the free space could be obtained
;                    BCDE = free space in kilo-bytes
;                If NZ then an error occured
;                    A = error code
;          If Carry = 0 then the routines is invalid for this drive
; Altered - AF,BC,DE

DOSNode_GetFreeSpace:
 cp Drive_AUD
 jr z, DOSNode_GetFreeSpaceEnd

 cp Drive_PRN
 jr z, DOSNode_GetFreeSpaceEnd

 cp Drive_TLK
 jr z, DOSNode_GetFreeSpaceEnd

 cp Drive_VID
 jr z, DOSNode_GetFreeSpaceEnd

 jp DOSNode_Fail

DOSNode_GetFreeSpaceEnd:
 ld bc, BYTES_FREE_HW
 ld de, BYTES_FREE_LW
 xor a
 jp DOSNode_Success

;
; Open the input stream
;
; Input  - A = drive number
;          HL = pointer to the normalized name
;              note, if the drive is of type stream then this name can
;              contain 11x&ff in case where no file name was provided
;              by the user (when he uses the anonymous reference ".");
;              the routine should then just open the just encountered
;              file on the stream and can optionally update the name
;              if it could be obtained from the stream itself
;          DE = pointer the normalized path
;          The pointed memory is always located in the current ROM/RAM space area
; Ouput  - If Carry = 1 the routine is supported for the provided drive
;                If Z then a file was opened
;                If NZ then no file could be opened
;                    A = error code
;              In any case, the routine might truncate the provided normalized path to match the nearest parent
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_InOpenStream:
 jp DOSNode_Fail

;
; Read from the input stream
;
; Input  - A = drive number
;          HL = address where to stored the read data
;          DE = number of bytes to read
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then data could be read
;                    DE = number of bytes read
;                If NZ then a error occured
;                    A = error code
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF,DE

DOSNode_InReadStream:
 jp DOSNode_Fail

;
; Close the input stream
;
; Input  - A = drive number
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the stream was properly closed
;                If NZ then the stream was closed with an error
;                    A = error code
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_InCloseStream:
 jp DOSNode_Fail

;
; Change the position into the input stream
;
; Input  - A = drive number
;          DEHL = new position in the input stream
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the new position could be reached
;                If NZ then an error occured
;                    A = error code
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_InSeekStream:
 jp DOSNode_Fail

;
; Open the output stream
;
; Input  - A = drive number
;          HL = pointer to the normalized name
;          DE = pointer to the normalized path
;          The pointed memory is always located in the current ROM/RAM space area
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then a file was created
;                If NZ then no file was created
;                    A = error code
;              In any case, the routine might truncate the provided normalized path to match the nearest parent
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_OutOpenStream:
 cp Drive_AUD
 jp z, DOSNode_Success

 cp Drive_PRN
 jp z, DOSNode_Success

 cp Drive_TLK
 jp z, DOSNode_Success

 cp Drive_VID
 jp z, DOSNode_Success

 jp DOSNode_Fail

;
; Write into the ouput stream
;
; Input  - A = drive number
;          HL = address where are located the data to write
;          DE = number of bytes to write
; Sortie - If Carry = 1 the routine is supported for the provided drive
;                If Z then data could be written
;                    DE = nomber of written bytes
;                If NZ then an error occured
;                    A = error code
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF,DE

DOSNode_OutWriteStream:
 cp Drive_AUD
 jr z, DOSNode_OutWriteStream_AUD

 cp Drive_PRN
 jr z, DOSNode_OutWriteStream_PRN

 cp Drive_TLK
 jr z, DOSNode_OutWriteStream_TLK

 cp Drive_VID
 jr z, DOSNode_OutWriteStream_VID

 jp DOSNode_Fail

; ----------------------------------------

DOSNode_OutWriteStream_AUD:

 push hl
 push bc
 di

DOSNode_OutWriteStream_AUDLoop:

 ld b, DAC_DELAY

DOSNode_OutWriteStream_AUDLoop2:

 push bc
 
 ld c, (hl)
 ld b, PORT_AMDRUM
 out (c), c

 pop bc
 djnz DOSNode_OutWriteStream_AUDLoop2
 
 inc hl
 dec de
 
 ld a,d
 or e
 jr nz, DOSNode_OutWriteStream_AUDLoop

DOSNode_OutWriteStream_AUDEnd:
 ei
 pop bc
 pop hl
 jp DOSNode_Success

; ----------------------------------------

DOSNode_OutWriteStream_PRN:

 push hl

DOSNode_OutWriteStream_PRNLoop:
 ld a, (hl)
 ;call ValidateChar
 ;jr nc, DOSNode_OutWriteStream_PRNSkip

 call MC_PRINT_CHAR
 
;DOSNode_OutWriteStream_PRNSkip:
 inc hl
 dec de
 
 ld a,d
 or e
 jr nz, DOSNode_OutWriteStream_PRNLoop

DOSNode_OutWriteStream_PRNEnd:
 pop hl
 jp DOSNode_Success
 
; ----------------------------------------

DOSNode_OutWriteStream_TLK:
 jp DOSNode_Success

; ----------------------------------------

DOSNode_OutWriteStream_VID:

 push hl

DOSNode_OutWriteStream_VIDLoop:
 ld a, (hl)
 call ValidateChar
 jr nc, DOSNode_OutWriteStream_VIDSkip

 call TXT_OUT_CHAR
 
DOSNode_OutWriteStream_VIDSkip:
 inc hl
 dec de
 
 ld a,d
 or e
 jr nz, DOSNode_OutWriteStream_VIDLoop

DOSNode_OutWriteStream_VIDEnd:
 pop hl
 jp DOSNode_Success

;
; Close the output stream
;
; Input  - A = drive number
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the stream was properly closed
;                If NZ then the stream was closed with an error
;                    A = error code
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_OutCloseStream:
 cp Drive_AUD
 jp z, DOSNode_Success

 cp Drive_PRN
 jp z, DOSNode_Success

 cp Drive_TLK
 jp z, DOSNode_Success

 cp Drive_VID
 jp z, DOSNode_Success

 jp DOSNode_Fail

;
; Change the position into the output stream
;
; Input  - A = drive number
;          DEHL = new position in the ouput stream
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the new position could be reached
;                If NZ then an error occured
;                    A = error code
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_OutSeekStream:
 jp DOSNode_Fail

;
; Check that a file or directory exists and return associated information
;
; Input  - A = drive number
;          HL = pointer to the normalized name
;              If HL = 0 then it is the contents of the directory which has to be analyzed
;              and ExamineNext will be called next to retrieve each entry
;          DE = pointer to the normalized path
;          IX = buffer where to store last modification time and date
;          The pointed memory is always located in the current ROM/RAM space area
; Output  - If Carry = 1 the routine is supported for the provided drive
;
;                If HL was not 0 in input
;                    If Z then the file or directory exists
;                        A = protection bits of the file
;                            Bit 0 - Read-only
;                            Bit 1 - Hidden
;                            Bit 2 - System
;                            Bit 4 = Directory
;                            Bit 5 = Archived
;                        BCDE = Length of the file
;                        IX = buffer where last modification time and date of the entry were stored
;                            One 16-bit word with year (1978..9999)
;                            One byte with number of month (1..12)
;                            One byte with number of day in the month (1..28,29,30 or 31)
;                            One byte with hours (0..23)
;                            One byte with minutes (0..59)
;                            One byte with seconds (0..59)
;                    If NZ then the file or directory was not found
;                        A = error code
;
;                If HL was 0 in input
;                    If Z then the directory is ready to be examined through ExamineNext
;                    If NZ then an error occurred
;                        A = error code
;
;                In any case, the routine might truncate the provided normalized path to match the nearest parent
;
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_Examine:
 cp Drive_AUD
 jr z, DOSNode_Examine_AUD

 cp Drive_PRN
 jr z, DOSNode_Examine_PRN

 cp Drive_TLK
 jr z, DOSNode_Examine_TLK

 cp Drive_VID
 jr z, DOSNode_Examine_VID

 jp DOSNode_Fail

DOSNode_Examine_AUD:
DOSNode_Examine_PRN:
DOSNode_Examine_TLK:
DOSNode_Examine_VID:
 ld a, 1 ; test code
 ld (#be80), a

 ld a, h ; examine directory via ExamineNext
 or l ;
 jp z, DOSNode_Success ;
 
 ; do something else
 xor a
 ld a, %00010000
 ld bc, 0
 ld de, 0

 jp DOSNode_Success

;
; Get the next entry from a directory being examined
;
; Input  - A = drive number
;          HL = pointer to the memory where to store the normalize name
;          IX = buffer where to store last modification time and date
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then an entry was found
;                    HL = pointer to the memory updated with the found normalized name
;                        A = protection bits of the file
;                            Bit 0 - Read-only
;                            Bit 1 - Hidden
;                            Bit 2 - System
;                            Bit 4 = Directory
;                            Bit 5 = Archived
;                        BCDE = Length of the file
;                        IX = buffer where last modification time and date of the entry were stored
;                            One 16-bit word with year (1978..9999)
;                            One byte with number of month (1..12)
;                            One byte with number of day in the month (1..28,29,30 or 31)
;                            One byte with hours (0..23)
;                            One byte with minutes (0..59)
;                            One byte with seconds (0..59)
;                If NZ then an error occurred
;                    A = error code (dsk_err_file_not_found indicates that all entries were examined)
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_ExamineNext:
 cp Drive_AUD
 jr z, DOSNode_ExamineNext_AUD

 cp Drive_PRN
 jr z, DOSNode_ExamineNext_PRN

 cp Drive_TLK
 jr z, DOSNode_ExamineNext_TLK

 cp Drive_VID
 jr z, DOSNode_ExamineNext_VID

 jp DOSNode_Fail

DOSNode_ExamineNext_AUD:
DOSNode_ExamineNext_PRN:
DOSNode_ExamineNext_TLK:
DOSNode_ExamineNext_VID:

 ld a, (#be80)
 or a
 jp z, DOSNode_Fail

 dec a
 ld (#be80), a
 
 ld de, DIRNAME
 ex de, hl
 ld bc, 11
 ldir
 
 xor a
 ld a, %00010000
 ld bc, 0
 ld de, 0
 jp DOSNode_Success

DIRNAME: db "TESTFILE  "

;
; Rename a file or a directory
;
; Input  - A = drive number
;          HL = pointer to the normalized name
;          DE = pointer to the normalized path
;          IX = pointer to the new normalized name
;          BC = pointer to the new normalized path
;          The pointed memory is always located in the current ROM/RAM space area
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the file or directory was renamed
;                If NZ then the file or directory could not be renamed
;                    A = error code
;                In any case, the routine might truncate the provided normalized path to match the nearest parent
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF
 
DOSNode_Rename: jp DOSNode_Fail

;
; Delete a file or a directory
;
; Input  - A = drive number
;          HL = pointer to the normalized name
;          DE = pointer to the normalized path
;          The pointed memory is always located in the current ROM/RAM space area
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the file or directory was deleted
;                If NZ then the file or directory could not be deleted
;                    A = error code
;                In any case, the routine might truncate the provided normalized path to match the nearest parent
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_Delete: jp DOSNode_Fail

;
; Create a directory
;
; Input  - A = drive number
;          HL = pointer to the normalized name
;          DE = pointer to the normalized path
;          The pointed memory is always located in the current ROM/RAM space area
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the directory was created
;                If NZ then the directory could not be created
;                    A = error code
;                In any case, the routine might truncate the provided normalized path to match the nearest parent
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_CreateDir:
 jp DOSNode_Fail

;
; Change the protection bits of a file
;
; Input  - A = drive number
;          HL = pointer to the normalized name
;          DE = pointer to the normalized path
;          B = Protections to modify
;          C = New protections
;                Bit 0 - Read-only
;                Bit 1 - Hidden
;                Bit 5 = Archived
;          Other bits are ignored
;          The pointed memory is always located in the current ROM/RAM space area
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the protections were modified
;                If NZ then the protections could not be modified
;                    A = error code
;                In any case, the routine might truncate the provided normalized path to match the nearest parent
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_SetProtection:
 jp DOSNode_Fail

;
; Change last modification time and date of a file or a directory
;
; Input  - A = drive number
;          HL = pointer to the normalized name
;          DE = pointer to the normalized path
;          IX = buffer where last modification time and date to use for the entry are stored
;              One 16-bit word with year (1978..9999)
;              One byte with number of month (1..12)
;              One byte with number of day in the month (1..28,29,30 or 31)
;              One byte with hours (0..23)
;              One byte with minutes (0..59)
;              One byte with seconds (0..59)
;          The pointed memory is always located in the current ROM/RAM space area
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the time and date were modified
;                If NZ then the time and date could not be modified
;                    A = error code
;                In any case, the routine might truncate the provided normalized path to match the nearest parent
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_SetFileDate:
 jp DOSNode_Fail
 
;
; Format a drive
;
; Input  - A = drive number
; Output  - If Carry = 1 the routine is supported for the provided drive
;                If Z then the drive was formatted
;                If NZ then format failed
;                    A = error code
;          If Carry = 0 then the routine is invalid for the provided drive
; Altered - AF

DOSNode_Format: jp DOSNode_Fail
 
;
; Read the contents of the real time clock
;
; Input  - IX = buffer where to store current time and date (7 octets)
; Output  - If Carry = 1 the the DOS node handles a relax time clock
;                IX = buffer where current time and date were stored
;                    One 16-bit word with year (1978..9999)
;                    One byte with number of the month (1..12)
;                    One byte with the number of the day in the month (1..28,29,30 or 31)
;                    One byte with hours (0..23)
;                    One byte with minutes (0..59)
;                    One byte with seconds (0..59)
;                A = number of the day in the week (1..7, from Monday to Sunday)
;          If Carry = 0 the the DOS node do not handle a real time clock
; Altered - AF

DOSNode_ReadRTC:
 jp DOSNode_Fail

;
; Write into the real time clock
;
; Input  - IX = buffer containing time and date to write into real time clock (7 bytes)
;              One 16-bit word with year (1978..9999)
;              One byte with number of the month (1..12)
;              One byte with the number of the day in the month (1..28,29,30 or 31)
;              One byte with hours (0..23)
;              One byte with minutes (0..59)
;              One byte with seconds (0..59)
; Output  - If Carry = 1 then the DOS node handles a real time clock
;              If Z then the contents of the real time clock was updated
;              If NZ then an error occurred
;                  A = error code
;          If Carry = 1 then the DOS node do not handle a real time clock
; Altered - AF

DOSNode_WriteRTC:
 jp DOSNode_Fail

;
; Open the non volatile memory
;
; Input  - C = opening mode
;                If 0 then the non volatile memory shall be opened with its current contents
;                If 1 then the non volatile memory shall be opened with its contents reset
; Output  - If Carry = 1 then the DOS node provides non volatile memory
;                If Z then the non volatile memory has been opened and is ready for usage
;                If NZ then a error occured
;                    A = error code
;          If Carry = 0 then the DOS node do not provide non volatile memory
; Altered - AF

DOSNode_OpenNVRAM:
 jp DOSNode_Fail

;
; Close and update the non volatile memory memory contents
;
; Input  - None
; Output  - If Carry = 1 then the DOS node provides non volatile memory
;                If Z then the non volatile memory was properly updated
;                If NZ then an error occured
;          If Carry = 0 then the DOS node do not provide non volatile memory
; Altered - AF

DOSNode_CloseNVRAM:
 jp DOSNode_Fail

;
; Read data from the non volatile memory
;
; Input  - HL = address where to write read data
;          DE = number of bytes to read
; Output  - If Carry = 1 then the DOS node provides non volatile memory
;                If Z then data were read
;                    DE = number of bytes read
;                If NZ then a error occured
;                    A = error code
;          If Carry = 0 then the DOS node do not provide non volatile memory
; Altered - AF,DE

DOSNode_ReadNVRAM:
 jp DOSNode_Fail

;
; Write data to the non volatile memory
;
; Input  - HL = address where a located data to write
;          DE = number of bytes to write
; Output  - If Carry = 1 then the DOS node provides non volatile memory
;                If Z then data were written
;                    DE = number of bytes written
;                If NZ then a error occured
;                    A = error code
;          If Carry = 0 then the DOS node do not provide non volatile memory
; Altered - AF,DE

DOSNode_WriteNVRAM:
 jp DOSNode_Fail

;
; Change the position in the non volatile memory
;
; Input  - DEHL = new position
; Output  - If Carry = 1 then the DOS node provides non volatile memory
;                If Z then the new position was reached
;                If NZ then a error occured
;                    A = error code
;          If Carry = 0 then the DOS node do not provide non volatile memory
; Altered - AF,DE

DOSNode_SeekNVRAM:
 jp DOSNode_Fail

DOSNode_Void: ret

DOSNode_Fail: ccf
 ret

DOSNode_Success:
 scf
 ret

 ; ------------------------- ListGetIDByName
 ; -- parameters:
 ; -- HL = address of list to find a string within
 ; -- DE = string to find
 ; --
 ; -- return:
 ; -- Z if found, NZ if not
 ; -- A = entry number of found item
 ; -- all other registers unknown

ListGetIDByName:
 ld a, (hl)
 or a
 jr z, ListGetIDByNameNotFound

 push de
 push hl
 call StrCompare
 pop hl
 call StrSkip
 pop de

 jr z, ListGetIDByNameFound
 
 inc hl
 inc hl
 jr ListGetIDByName
 
ListGetIDByNameFound:
 inc hl
 ld a, (hl)
 ret
 
ListGetIDByNameNotFound:
 xor a
 ret
 
 ; ------------------------- StrCompare
 ; -- parameters:
 ; -- HL = zero terminated string source of truth
 ; -- DE = string to compare
 ; --
 ; -- return:
 ; -- Z if equal, NZ if not
 ; -- all other registers unknown

StrCompare:
StrCompareLoop:
 ld a, (hl)
 or a
 ret z ; found it, return

 call ToUpper
 and #7f
 
 push af
 ld a, (de)
 call ToUpper
 and #7f
 ld b, a
 pop af
 
 cp b
 ret nz ; didnt find it, return
 inc hl
 inc de
 jr StrCompareLoop

 ; ------------------------- ToUpper
 ; -- parameters:
 ; -- A = character to make into uppercase
 ; --
 ; -- return:
 ; -- A = uppercase character
 ; -- all other registers preserved except flags

ToUpper: cp 'a'
 ret c
 cp 'z' + 1
 ret nc
 add a, 'A' - 'a'
 ret
 
 ; ------------------------- StrCopy
 ; -- parameters:
 ; -- HL = source string address
 ; -- DE = destination string address
 ; --
 ; -- return:
 ; -- HL = the address of the source string terminator
 ; -- DE = the address of the destination string terminator
 ; -- all other registers unknown

StrCopy:
 ld a,(hl)
 ld (de), a
 or a
 ret z ; end of string return
 inc hl
 inc de
 jr StrCopy
 
StrSkip: push af

StrSkipLoop:
 ld a,(hl)
 or a
 jr z, StrSkipEnd
 inc hl
 jr StrSkipLoop
 
StrSkipEnd: pop af
 ret

 ; ------------------------- ValidateChar
 ; -- parameters:
 ; -- A = character to validate
 ; --
 ; -- return:
 ; -- C if valid, NC if not
 ; -- all other registers preserved

ValidateChar:
 cp ' '
 jr c, DOSNode_Fail

 cp 'z'
 jr nc, DOSNode_Fail

 jp DOSNode_Success

CODE_END: ; ds #4000 - (CODE_END - CODE_START)

; save "STREAMER.ROM", #C000, #4000, AMSDOS


OffseT

The first thing you should check is that you only alter the registers indicated in the routine headers. UniDOS expects those. If you alter a register which is supposed to be preserved by the routine, some unpredictable things may happen.

zhulien

Just another feature request that st least the api could perhaps be added as stubs.

That is. New capability of random access

And new driver apis for seeking and such.  Random access should be on amsdos and never really was.  UniDOS is the only dos that sees the bigger picture to allow all devices to one day support it.

Prodatron

IIRC UniDOS already supports random file access.
Pulko Mandy is using this for streaming from a file in his VGM player for the Willy/OPL3 device.

GRAPHICAL Z80 MULTITASKING OPERATING SYSTEM

zhulien

Quote from: Prodatron on 19:39, 28 January 24IIRC UniDOS already supports random file access.
Pulko Mandy is using this for streaming from a file in his VGM player for the Willy/OPL3 device.
cool, i'm still stuck with my DOS node - same issue, not a clear documenation on how one API relates to another... one day i will get there.

OffseT

Quote from: zhulien on 13:33, 28 January 24That is. New capability of random access
This is actually already supported.

See additional APIs for read/write here:
https://unidos.cpcscene.net/doku.php?id=en:devel#cmd_cas_in_read_5

And as stated by @Prodatron it is used by the VGM player to stream data. It is also used by UniLoad to go thru the 1MB game database.

VGM player here:
https://framagit.org/shinra/vgmplay

Powered by SMFPacks Menu Editor Mod