Jump to content

ivop

Members
  • Posts

    3,338
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by ivop

  1. https://www.linusakesson.net/software/sidreloc/index.php
  2. Found another one. This time in the official DRI's XSUB (eXtended SUBmit): lda bdos+1 cpi 06h jnz loaderr Hopefully that one works okay!
  3. That's disappointing. I just found this: Perhaps reading works well enough (with retries?) to make a copy to a real floppy? It needs extended memory, but I assume that's not a problem with your 1090 memory expansion
  4. Could you make a sector copy to a real floppy and try that? Edit: if you have only one real drive, you could boot from that, swap disks, and then press CTRL-C, assuming your CONIN routines passes along <32 characters.
  5. I see. I'd forgotten about that as I always use SIO directly. I just noticed a bug in my CP/M-65 code. DDEVIC always needs to be set to $31, and SIO adds DUNIT to it. Well, they don't support multiple drives yet, so it never failed Back to your code. I assume write.com fails? After which command does it fail? (make_file, write_sequential, or close?)
  6. Shouldn't that be JSR SIOV ? ($E459). You also need to set DBYTLO/HI to 128, and DSTATS data direction. You could basically copy most of my code from CP/M-65:
  7. Here's a disk image that might help you debugging this problem Source: Expected output: Edit: BTW are you sure the disk is writable? I don't know what RespeQt's defaults are. Might be R/O. writetest.atr
  8. Great! Just for fun, you could mount my sample bootdisk.atr as drive B: and do DIR there. Then try DUMP DUMP.COM And STAT DSK: Edit: and test writing to disk with PIP FOO.COM=DUMP.COM and then FOO FOO.COM
  9. The 16 bytes are the ATR header. Also, the 79th sector starts after 3*26=78 sectors, which is 78*128=9984 bytes ($2700). With the ATR header, that's file offset 10000 (0x2710). From the bootdisk.atr that was made with mkfs.cpm and the diskdefs following your spec (boottrk 3):
  10. You are not using the original DRI source code. BDOS starts with a six byte serial, and jmp BDOSE (the entry point) is after that. In a lot of versions it's just six zeroes, sometimes the second byte is 16H to indicate it's version 2.2 of CP/M. It's indeed used to find the BDOS entry for applications to call, but it's also used to determine MEMTOP (MSB used only), and sometimes to calculate the beginning of CCP. I have seen code doing a hardcoded BDOS vector - 00806H = start of CCP. For example The Amsterdam Compiler Kit (ACK) does that. Original code from January 1980: The original CCP source code has support for conditional assembly of it serial number: I used the vanilla sources to build CP/M for my 8080 emulator, and they are the same .SYS files I included in the cpm1090.zip file I posted here for you earlier. My builds are in the cpm22 directory in the atari8080 github repo. The original is here: https://github.com/brouhaha/cpm22/ . The only thing they did is convert it from the ancient 8080 ASM.COM format to something more modern. The assembler you need is linked to in the description. Edit: fixed to -00806H Also found the code in boot.s in ACK:
  11. VT52 is easiest implemented as a state machine on the Atari side. No need to buffer characters. If you would do it in CONOUT at the Z80 side, you would need to devise a method to signal all the different VT52 "instructions" to the Atari, defeating the purpose. It's the Atari side that needs to manipulate the display.
  12. Yes, that's possible. But he Atari would still behave funny with the three line buffer and all. And the E: handler is very slow. This is what my first CP/M-65 BIOS did, too. But when I compared DUMP DUMP.COM between the Atari and the BBC, I quickly decided to ditch the E: handler and write a dumb terminal. If you look just at conout (the TTY driver, ignore the screen driver), it's really very simple. I reused the row and column addresses the Atari OS uses. I see. Googling around it seems they are harder to get than Z80s. So that's not a useful replacement either.
  13. At first I would stick to using mkfs.cpm and cpmcp to copy files to it, and then prepend the ATR header. If there are enough users really wanting to copy files directly from a DOS 2.5 disk to a cpmfs disk, it might be worth the trouble to write a specific utility for that. Probably a DOS utility, as CP/M cannot read the boot sectors via its BIOS. I hardly think it's worth the trouble. How many reserved tracks does the Indus CP/M use? I think being able to boot with stock hardware (800XL, 1050, 1090) has its merits.
  14. No need to cannibalize hardware IMHO. Looking at Aliexpress/eBay there are tons of refurbished Z80s available for as low as $1 each. Don't know how the "fake" situation is with Z80s though. I recall 6502s are sometimes mislabeled, like a 6502B actually being an A. Yeah, I remember the first time I got the A> prompt with my emulator. That's an exiting moment Good you found it. I prototyped my 8080 emulator in C and noticed that sectors start at 0, so I was prepared when I did the 6502 code. No, that won't work. The Atari E: handler does all sorts of things with high ASCII characters (clear screen, bell at the end of line 3, clear up to 3 lines etc.) which might interfere with CP/M working properly. It's best to have a true dumb terminal that bypasses the E: handler. To get WordStar 3.3 working, you can manually configure that to do VT52, which is very easy. WS only needs position cursor (ESC Y col row). The rest is optional. Don't know about later WS, because 3.3 was the last 8080 version. But VT52 should be enough and has a very limited command set (http://gunkies.org/wiki/VT52 , CP/M-65 implementation: https://github.com/davidgiven/cpm65/blob/master/apps/vt52drv.asm , Atari dumb terminal is in its bios https://github.com/davidgiven/cpm65/blob/master/src/arch/atari800/atari800.S , 80 columns software driver is at https://github.com/davidgiven/cpm65/blob/master/src/arch/atari800/utils/tty80drv.S). Edit: forgot to mention. Regarding the Z80 situation, looking at the notification (https://www.mouser.com/PCN/Littelfuse_PCN_Z84C00.pdf ) it's only the Z80 that's discontinued. Not sure how much effort it takes, but you could upgrade to the DIP-64 Z180. The added DMA would be useless, and the new instructions won't be used, but while you're at it, you might want to break out the build-in UART to a connector. Edit2: https://www.zilog.com/docs/z180/ps0140.pdf
  15. Hi, It's a pity the DIP and PLCC versions are discontinued, but I suppose they won't be hard to get anytime soon. Even NMOS 6502 are plenty available as NOS and refurbished. I see you used a RE'd Z80 source for BDOS and CCP. In theory that's fine, but I would not remove the 6 bytes serial at the beginning of BDOS and move BDOSE to $xx00. Some applications rely on it being $xx06 and the zero page vector ending with $06. IIRC ACK compiled applications have that dependency. If I were you, I'd just stick to DRI vanilla source code. You won't gain a full page of memory savings anyway, and it's advised to have each component page aligned. The cross-platform utilities are here: http://www.cpm.z80.de/download/cpm2-plm.zip . Most include source, too. I don't think you wasted three weeks on this. It's great to see you got to the CCP prompt! Most of the work seems done. Now you "only" need some form of proper terminal emulation and you can run WordStar
  16. Relog disks before operations is not as trivial as it may seem and can be slow, if possible at all. Opening and closing files is expensive, hence a lot of applications keep their files open until program termination. Also note that BDOS does not know if there are any files open. That info is all in user space (File Control Blocks). I recently read an anecdote from somebody that was working at a company where at least once a week an employee came at his desk with a ruined floppy. To avoid to have to manually retrieve (some of) the data each time, he modified the BIOS of all their workstations to run a timer interrupt that checked the floppy drive's open/close sensor every 100ms. If somebody opened the drive after boot, a big warning would be displayed urging the user to put back the SAME disk again, and would not continue until the drive was closed again, hopefully with the same disk inside. After that, the reports of ruined floppies dropped to zero.
  17. There is no CP/M RAM disk standard. There's not a standard to how banked memory was done. CP/M 3 supported banked memory, but their implementations varied wildly, ranging from 4kB to 32kB of bankable RAM. Similar to how there is not one disk format. Each system had their own disk format, and if they supported a RAM disk, it was in their custom BIOS implementation. I have seen drive M: (for "memory" I suppose) or drive P: (last one available). But since your goal is four drives (A:-D:) you could just as easily use E:. As all disk access goes through the Atari OS SIO routines, it's much easier to mount several ATR disk images with SIDE or another PBI IDE implementation and have your SSED disk images on a CF or SD card. Just as fast, and non-volatile. You can even boot from them. RAM disks are obsolete IMO. Well except for initramfs during Linux boot I suppose CP/M is also not capable of mixing floppy formats, as the disk layout is fixed in memory. And swapping disks is also a thing. Never swap a disk in the middle of an application or it will ruin your filesystem. The only way to swap disks is when CCP is running and after a swap press control-C to restart CCP so it logs in the new disk. If you forget the last step, it might ruin the newly inserted disk.
  18. Here's a skeletal with build system. It now generates a zero-filled file for bios.sys. You have to supply your own bios.asm and build rule in the Makefile. Typing 'make' builds the bootblock, creates the CP/M FS with that bootblock, copies some files to it, and creates an ATR image from CP/M disk image. Bootblock.s contains several instances of ; XXX your code here, as you are more knowledgeable about how to switch off/on the Z80. Hope this helps Edit: for inspiration: https://github.com/ivop/atari8080/blob/main/8080.s starting at line 2234 (absolute sector calculation, handling bank overflow, e.g. you read 128 bytes to $7ff0 in bank 2). and https://github.com/davidgiven/cpm65/blob/master/src/arch/atari800/atari800.S starting at line 941 for sector read/write code. TTY code uses K: for keyboard in. For CONOUT you can use E: as a start. Once you get the A> prompt and can run DUMP DUMP.COM, you can look into a proper 'dumb' CP/M terminal and finally an ADM-3a or VT52 terminal emulation. Edit2: the bank overflow trick uses up to 127 bytes after the bank ends. On read, I just read into memory past $8000, detect overflow, select next bank, and copy the number of overflown bytes to $4000. On write, I check overflow, select next bank, copy X number of bytes from $4000 to $8000, select previous bank, write 128 bytes from e.g. $7ff0. cpm1090.zip
  19. Why? If you followed my example there is no need for special Z80 code to load BDOS and CCP. Everything is loaded in one go by the Atari OS during boot, then copy BDOS+BIOS to Z80 RAM, set 0000H vector, and run. The only thing the Z80 BIOS has to do is signal LoadCCP during WBOOT, similar to how you signal ConsoleStatues, and ReadSector, etc.. You also do not have to keep track of at which sector something is located, everything is handled automatically by mads. The bootblock is just sector 1-78 (maximum, can be smaller) that contains "everything everywhere all at once" If you want, I can create a larger example that you only have to fill in with the I/O code.
  20. Python is mostly used as a wrapper around C++ machine learning libraries. With PyTorch, CuPy, Theano, PyCuda, TensorFlow, etc. and a proper GPU you get thousands of threads instead of just a few with a CPU. Things like evaluating the proposed images can be done in parallel per pixel, i.e. thousands of pixels are evaluated simultaneously. We are speaking of at least a 100x increase in speed compared to evaluating pixel by pixel as it is now. And switching between different optimizers is easy.
  21. Strictly speaking, the directory sectors count for the disk capacity, the reserved tracks do not: sectors = (number_of_tracks - reserved_tracks) * sectors_per_track blocks_on_disk = sectors * 128 / block_size Yes, this is exactly what I tried to explain earlier with the mads example 'ins'-ing the .SYS files The Atari OS boot code can load up to 255 sectors to consecutive memory. No need for padding between the Atari code and CCP+BDOS+BIOS.SYS. Aligning to page boundaries is slightly faster though, as lda abs,x is 25% longer (5 cycles instead of 4) if you cross a page boundary. CCP = $e400 CCP_BANKEDRAM = $4000 + (CCP & $3fff) ; in BANK3 copy_ccp: lda #BANK3 sta BANKREG ldx #0 copy_loop: .rept 6 lda CCP_LOWRAM+#*256,x sta CCP_BANKEDRAM+#*256,x .endr inx bne copy_loop ; ... more code .align $0100 CCP_LOWRAM: ins 'CCP.SYS' Agreed. I don't think that's even necessary.
  22. You could try my Linux fork at https://github.com/ivop/RastaConverter Started 12 years ago, and has a lot of fixes (compiler warnings fixed, deprecated code replaced). Never got around to create a proper patch to send upstream though. I recently merged the new Sheddy code. It has Link Time Optimization enabled (faster), and it also supports Profile Guided Optimization. For the latter, type make pg first, run rastaconv-pg for a few minutes with real world data to collect profile data, then run make pu to build the final binary rastaconv-pu.
  23. Ah, I see. We had a different definition of disk capacity. I also counted block 0 where the directory lives. That would do a full re-initialization of BDOS each warm boot. Back in the day, BOOT (cold) fell through to the WBOOT code and was something like this: BOOT: ; do cold boot stuff ; load BDOS ; fallthrough WBOOT: ; do warm boot stuff ; load CCP ; run CCP If you let the Atari copy BDOS+BIOS and set 0000H before starting the Z80, the load BDOS step can be omitted. But in the end it does not really matter. When I was debugging my 8080 emulator prototype in C I had BOOT and WBOOT copy both BDOS and CCP each time, and that works as well. But it would be over three times slower to copy BDOS, too. Nice! That's including buffers and DPH/DPB I suppose? Edit: premature post... sigh.
  24. If you reserve 3 tracks (0-2), you have 37 tracks for the filesystem, not 36. So 37*26*128 /1024 = 120 blocks. Where did the 1152 come from in your drive storage capacity? Also, I would make the order CCP, BDOS, BIOS. That way you can copy BDOS and BIOS to shared memory in a single copy loop. They do not have to be sector aligned, although being page aligned could speed up your copy loop. Note that the size of the BIOS is $ffff-$fa00+1 = 1536 bytes. But that doesn't matter for the rest of the calculations. Edit: diskdef for your format: diskdef atari1090ed seclen 128 tracks 40 sectrk 26 blocksize 1024 maxdir 64 boottrk 3 os 2.2 end Edit2: Disk Parameter Block calculations: ; atari1090ed number_of_tracks = 40 reserved_tracks = 3 sectors_per_track = 26 block_size = 1024 dirents = 128 if block_size = 1024 block_shift = 3 elseif block_size = 2048 block_shift = 4 elseif block_size = 4096 block_shift = 5 elseif block_size = 8192 block_shift = 6 elseif block_size = 16384 block_shift = 7 endif block_mask = (1 << block_shift) - 1 checksum_buffer_size = (dirents + 3) / 4 sectors = (number_of_tracks - reserved_tracks) * sectors_per_track blocks_on_disk = sectors * 128 / block_size allocation_vector_size = (blocks_on_disk + 7) / 8 directory_blocks = (dirents * 32) / block_size allocation_bitmap = (0ffffh << (16 - directory_blocks)) & 0ffffh if directory_blocks = 0 error "Directory must be at least one block in size!" endif if (dirents * 32) # block_size != 0 error "Directory is not an even number of blocks in size!" endif if blocks_on_disk < 256 if block_size = 1024 extent_mask = 000h ; %00000000 elseif block_size = 2048 extent_mask = 001h ; %00000001 elseif block_size = 4096 extent_mask = 003h ; %00000011 elseif block_size = 8192 extent_mask = 007h ; %00000111 elseif block_size = 16384 extent_mask = 00fh ; %00001111 endif else if block_size = 1024 error "Cannot use a block size of 1024 on a large disk!" elseif block_size = 2048 extent_mask = 000h ; %00000000 elseif block_size = 4096 extent_mask = 001h ; %00000001 elseif block_size = 8192 extent_mask = 003h ; %00000011 elseif block_size = 16384 extent_mask = 007h ; %00000111 endif endif dpblk: dw sectors_per_track db block_shift db block_mask db extent_mask dw blocks_on_disk - 1 dw dirents - 1 db (allocation_bitmap & 0ff00h)>>8 db (allocation_bitmap & 000ffh) dw checksum_buffer_size dw reserved_tracks dirbf: ds 128 ; can be the same for multiple disks chk00: ds checksum_buffer_size all00: ds allocation_vector_size
  25. Perhaps you can get one of these? https://www.amazon.com/JANSANE-PL2303TA-Serial-Console-Raspberry/dp/B07D9R5JFK/ref=sr_1_9?crid=288FWF02G11QF&dib=eyJ2IjoiMSJ9.mmFSFgBLhSyBOomkkUq4yGiGWlh3AaGYTCkOhDC2QZduSly4-Yzhl7JdHD-4CC81nIkrAl-ofLD96FOelis17PeCkBgfwUyNj9ZLgnkbq_EQczRxgiPwHyjuUM0_Bw7XgI-CWE8h6yANbhuw0D76JcVjP0mPFiDhxfOSjJXQHOYfv39TE2FoFuo_n_vK6g4Q2moOMGeTJvVCS0BEAVnT77NzsfdN4CVbS6fQ7Xm0N84.GkiLOa55xzFbxdRgzi-yOANRtstWuqF82ZkybvnwkLk&dib_tag=se&keywords=usb+ttl+serial&qid=1712539626&sprefix=usb+ttl+serial%2Caps%2C195&sr=8-9 Wired to the SIO port you should be able to run RespeQt. Otherwise you are making it a lot more difficult for yourself than necessary, writing a CP/M writer in Basic and all that. Create the raw disk image by concatenating the 54 sectors boot block with (720-54)*128 zeroes and use mkfs.cpm and cpmcp to put other files there, like PIP.COM, STAT.COM, etc... Prepend ATR header for 720 sectors of 128 bytes. Boot from that or sector copy to a blank disk. If you leverage the Atari OS boot mechanism, it'll load the first three tracks (54 sectors) automatically somewhere in memory. Most of the time $0700, but that is not a requirement. Also 3 boot sectors is not fixed, you can set that to 54. After that you can fast memcopy the Z80 code in place (BIOS and BDOS), and let WBOOT trigger a LoadCCP command to the Atari, which memcopies the CCP in place. This is not far off from what Atari did with their implementation. In mads that would be something like: opt h- org $0700 .byte 0 .byte 54 .word $0700 .word main main: ; code here ; copy $1400 bytes from BDOS to shared memory at $ec00 ; start Z80 loop: ; wait for IO request, dispatch with jump table or several cmp's ... ; in LoadCCP call, copy $0800 bytes from CCP to $e400 in shared memory .... jmp loop CCP: ins 'ccp.sys' ; $0800 bytes, at $e400 in shared memory BDOS: ins 'bdos.sys' ; $0e00 bytes, at $ec00 in shared memory BIOS: ins 'bios.sys' ; $0600 bytes, at $fa00 in shared memory If you don't want to or are unable to get a SIO2PC capable cable and want to use your 1090 ROM method, you can also, depending on the amount of ROM available, create the CP/M disk as described earlier, not turn it into an ATR, but just copy as much from the beginning of the disk image file to the ROM and write the ROM contents to a blank formatted disk with (Turbo) Basic. You can check if all the files you copied to the CP/M disk fit by first creating the FS on a non-zero padded file (just specify a non-existent disk.img file) and see how large it becomes after cpmcp. cpmcp does not expand the image file to the actual FS size. BTW with mkfs.cpm -f yourformatindiskdefs -b bootblock.bin disk.img you can automatically include the boot block created with mads. Hope this'll save you some time
×
×
  • Create New...