-
Posts
3,337 -
Joined
-
Last visited
-
Days Won
3
Content Type
Profiles
Forums
Blogs
Gallery
Events
Store
Posts posted by ivop
-
-
5 minutes ago, reifsnyderb said:
Ok. I just tried 3 other atr files. I know these work fine with Altirra. I am having similar problems with respeqt and the USB cable. I don't know if it's respeqt, the cable, or something else.
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
-
13 minutes ago, reifsnyderb said:
There is no consistent place it's been failing as it varies. The only thing consistent is that it the system gets farther along when the SIO speed is fast.
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.
-
23 minutes ago, reifsnyderb said:
I could have done JSR SIOV. But, I figured I'd use the resident disk handler as it's basically the same thing and requires fewer inputs.
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?)
-
1 hour ago, reifsnyderb said:
All of the disk I/O is going through Atari's Resident Disk Handler. What is odd is that I've been able to confirm that some of the writes are working.....but not all are working.
Here's the read/write code:
JSR DSKINV
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:
Spoilerzproc bios_READ
lda #$40 ; data direction receive
sta DSTATS
lda #SIO_READ_SECTOR
bne do_SIO
zendproczproc bios_WRITE
lda #$80 ; data direction send
sta DSTATS
lda #SIO_WRITE_SECTORdo_SIO:
sta DCOMND
lda #$31
clc
adc drive_number
sta DDEVIC
and #$0f
sta DUNITlda dma
sta DBUFLO
lda dma+1
sta DBUFHIlda #128
sta DBYTLO
lda #0
sta DBYTHIlda sector_num ; Atari starts counting at sector 1
clc
adc #1
sta DAUX1
lda sector_num+1
adc #0
sta DAUX2#ifdef ATARI_XL
jsr SIOV_wrapper
#else
jsr SIOV
#endiflda DSTATS
cmp #1
beq status_oksec
rtsstatus_ok:
clc
rts
zendproc
- 1
-
Here's a disk image that might help you debugging this problem
Source:
Spoiler#include <stdio.h>
#include <string.h>
#include <cpm.h>unsigned char buffer[128];
int main(int argc, char **argv) {
int i;cpm_fcb.ex = cpm_fcb.s1 = cpm_fcb.s2 = cpm_fcb.rc = 0;
memcpy(&cpm_fcb.f, "FOO BAR", 11);printf("Opening file\n");
if (cpm_make_file(&cpm_fcb)) {
printf("Error opening file, file exists?\n");
return 1;
}printf("Setting DMA\n");
cpm_set_dma(&buffer);printf("Filling buffer\n");
for (i=0; i<128; i++)
buffer[i] = i;printf("Writing buffer\n");
if (cpm_write_sequential(&cpm_fcb)) {
printf("Error writing to disk\n");
return 1;
}printf("Closing file\n");
if (cpm_close_file(&cpm_fcb)) {
printf("Error closing file\n");
return 1;
}printf("Done.\n");
return 0;
Expected output:
Spoiler64k CP/M vers 2.2
A>dir foo.bar
NO FILE
A>write
Opening file
Setting DMA
Filling buffer
Writing buffer
Closing file
Done.A>dir foo.bar
A: FOO BAR
A>dump foo.bar0000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0010 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
0020 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
0030 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
0040 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
0050 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
0060 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
0070 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7FEdit: BTW are you sure the disk is writable? I don't know what RespeQt's defaults are. Might be R/O.
- 1
-
14 minutes ago, reifsnyderb said:
Got it. I just tried the ccp.sys and bdos.sys on my boot disk image and it works. I can tell it's changed because if I try to get an empty directory the response is no all in caps. 🙂
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
-
1 hour ago, reifsnyderb said:
Track 3, Sector 1 should be Sector 79 on an Atari disk. So, that being said, and if my math is correct, sector 79 would start at offset 10112. The directory should have the user byte and filename first. So, I am thinking that the directory entries, and possibly files (?) all need shifted by 16 bytes.
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):
Spoiler....
000026D0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
000026E0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
000026F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
00002700 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
00002710 00 44 55 4D 50 20 20 20 20 43 4F 4D 00 00 00 04 .DUMP COM....
00002720 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00002730 00 53 54 41 54 20 20 20 20 43 4F 4D 00 01 00 29 .STAT COM...)
00002740 03 04 05 06 07 08 00 00 00 00 00 00 00 00 00 00 ................
00002750 00 50 49 50 20 20 20 20 20 43 4F 4D 00 00 00 3A .PIP COM...:
00002760 09 0A 0B 0C 0D 0E 0F 10 00 00 00 00 00 00 00 00 ................
00002770 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
00002780 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
00002790 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ....................
-
1 hour ago, reifsnyderb said:
I just started to take a look at this. I removed the serial number code from CCP. Did you mean to keep the serial number code in CCP as it's not in BDOS?
The beginning of BDOS is at $EC00. Should BDOS really start at $EC06? The BIOS would have to change the zero page vector to $EC06, of course.
I thought the purpose of having the zero page vector was so that applications could find BDOS.....
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:
Spoiler; serial number (not documented in original DRI source file)
db 0 ; OEM number, low byte
db 0 ; CP/M version, 16h = 2.2
db 0 ; OEM number, high byte
db 0,0,0 ; serial number, big-endian; enter here from the user's program with function number in c,
; and information address in d,e
jmp bdose ;past parameter block; ************************************************
; *** relative locations 0009 - 000e ***
; ************************************************
pererr: dw persub ;permanent error subroutine
selerr: dw selsub ;select error subroutine
roderr: dw rodsub ;ro disk error subroutine
roferr: dw rofsub ;ro file error subroutine
bdose: ;arrive here from user programs
xchg ;info=DE, DE=info
shld info
xchg
mov a,e ;linfo = low(info) - don't equThe original CCP source code has support for conditional assembly of it serial number:
Spoilerifndef noserial
serialize:
;check serialization
lxi d,serial ;check six bytes
lxi h,bdosl
mvi b,6
ser0: ldax d
cmp m
jnz badserial
inx d
inx h
dcr b
jnz ser0
ret ;serial number is ok
endif
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:
Spoiler! Now the 'heap'.
lhld 0x0006 ! BDOS entry point
lxi d, -0x806 ! offset to start of CCP
dad d
shld _cpm_ramtop
- 1
-
1 hour ago, reifsnyderb said:
I suppose the 3 character buffer could be handled either in the CP/M BIOS or in the Atari I/O. I think it would be much faster to do this in the CP/M BIOS.
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.
-
35 minutes ago, reifsnyderb said:
If only the ESC Y col row is needed, why not just intercept the command and tell the Atari OS to just re-position the cursor? The same could be done for any other VT52 cases.
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.
35 minutes ago, reifsnyderb said:Here's the current code to send the console output....
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.
42 minutes ago, reifsnyderb said:I didn't see that mouser is selling any DIP 64 Z-180 chips.
I see. Googling around it seems they are harder to get than Z80s. So that's not a useful replacement either.
-
22 minutes ago, reifsnyderb said:
This may be the easiest way to have files put on an ATR image by "injecting" the files to the correct location, in the image, and adding a directory entry. Does anyone have an opinion as to if this is the way to go with this or if the Atari should be involved? My personal opinion is that this is the easiest way to do this.
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.
12 minutes ago, kheller2 said:I think there was a large effort involved in getting the proper DD disks created for Indus and ATR. It might be better to stay in the DD format, but that wasn’t Atari’s direction with the 1090 or sweetpea.
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.
- 1
-
1 hour ago, reifsnyderb said:
I don't know what the supply will be. I really don't like relying on cannibalized hardware, either. Western Design sells the W65C02....so when I made the Happy Board there's a couple solder jumpers so all new hardware could be used.
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.
1 hour ago, reifsnyderb said:Yeah, I was rather elated to get the CCP prompt up. It responds as well. So, if I try the "dir" command, for example, it reads the directory region of the disk.
Yeah, I remember the first time I got the A> prompt with my emulator. That's an exiting moment
1 hour ago, reifsnyderb said:Since respeQt shows what sectors are being read, I also discovered that CP/M was initially reading one sector before the first sector. After some troubleshooting, to verify my track/sector to sector translation code was working correctly, I discovered that CP/M was passing a sector 0. So, there was an off-by-one error. I had to increment the sector number, to "fix" the off-by-one issue and get the correct sectors to be read. The documentation wasn't clear as to whether CP/M started with sector 0 or 1.
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.
1 hour ago, reifsnyderb said:Well, I was elated yesterday, at around 2:00pm, to get the prompt, have issues such as the CR/LF translation working, get keyboard input working, etc. Only hours later, I find out I am closing in on getting a CPU/Memory board for a soon to be discontinued CPU.
Oh, yeah, the 80 column card appears to work with the CP/M card as well. Maybe it will run WordStar as-is?
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
-
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
-
15 hours ago, _The Doctor__ said:
was there never a fix to autolog or just have a relog before disk operations. I might have recently forgot that step and killed a disk, face palm palm face.
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.
- 4
-
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.
- 1
- 1
-
1 hour ago, reifsnyderb said:
I started a response then realized I was thinking in CP/M terms of tracks and sectors. Meanwhile the Atari is only working with sectors. So, Yeah, it now makes more sense to just load it all into the Atari's RAM. I'll re-figure it.
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.
Spoiler$ make
dd if=/dev/zero of=bios.sys bs=256 count=6
6+0 records in
6+0 records out
1536 bytes (1,5 kB, 1,5 KiB) copied, 0,000375971 s, 4,1 MB/s
mads -o:bootblock.bin bootblock.s
Start bootblock: $0700
End code: $0802
Start data: $0900
End bootblock: $2580
Writing object file...
220 lines of source assembled in 3 pass
7808 bytes written to the object file
dd if=/dev/zero of=cpmfs.img bs=128 count=1040
1040+0 records in
1040+0 records out
133120 bytes (133 kB, 130 KiB) copied, 0,00365784 s, 36,4 MB/s
mkfs.cpm -b bootblock.bin -f atari1090ed cpmfs.img
cpmcp -f atari1090ed cpmfs.img cpm22/DUMP.COM cpm22/STAT.COM cpm22/PIP.COM \
0:
cpmls -f atari1090ed cpmfs.img
0:
dump.com
pip.com
stat.com
cat atrheader.dat cpmfs.img > bootdisk.atr
ls -l bootdisk.atr
-rw-rw-r-- 1 ivo ivo 133136 Apr 9 20:02 bootdisk.atr
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.
-
13 hours ago, reifsnyderb said:
Ok, I figure I'll lay out the disk like this:
; Disk layout: ; Track 0 Sector 1 Atari boot sector (Atari @ $0700) -- Note: Sectors 1-14 are loaded with the boot sector. ; Track 0 Sectors 1-2 CP/M BIOS Loader (Atari @ $0714 - $07FF) -- Loads CP/M BIOS into Z-80 RAM bank 3, $7A00 ; Track 0 Sectors 3-10 Atari CP/M I/O (Atari @ $0800 - $0BFF) -- 1k allocated, probably less is needed ; Track 0 Sectors 11-14 CP/M BIOS (Atari @ $0C00 $0DFF) -- 512 bytes allocated ; Track 1 Sectors 1-16 CCP - 2048 bytes starting at E400 (Z-80 RAM bank 3, $6400) ; Track 1 Sectors 17-26 BDOS - 1152 bytes starting at EC00 (Z-80 RAM bank 3, $6C00) ; Track 2 Sectors 1-19 BDOS - 2432 bytes ; Track 3 Sectors 1-16 Directory - 2048 bytes ; Track 3 Sectors 17-26 Data - 1152 bytes ; Track 4+ Data
(I still can't get the stupid indents to display right. 😞 )
I'll leverage the OS to load the Atari boot sector and include the CP/M BIOS loader, the Atari CP/M I/O code that handles the I/O between CP/M and the Atari OS, and the CP/M BIOS.
The CP/M BIOS loader code will set the Z-80 cold boot jump at $0000 (Z-80 RAM bank 0, $4000) and copy the already loaded CP/M BIOS (from $0C00 to $0DFF) to the Z-80 BIOS location at $FA00 (Z-80 RAM bank 3, 7A00).
Control will then be transferred to the Atari CP/M I/O code that will start the Z-80 and manage the I/O between the Z-80 and the Atari OS.
The CP/M BIOS will then load CCP and BDOS.
It's quite possible the Atari CP/M I/O code will take less than 1k. I'll reduce it's size if necessary.
I just need to add the CCP and BDOS loading code to the CP/M BIOS. Right now, the CP/M BIOS sits at 378 bytes. 🙂
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.
- 1
-
2 hours ago, snicklin said:
It is also a lot slower, so I wouldn't really be gaining anything there.
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.
- 2
-
30 minutes ago, reifsnyderb said:
Truthfully, I don't know how the directory track should be counted. I guess it can store data if there is space.
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
30 minutes ago, reifsnyderb said:Loading BDOS, during cold boot, and CCP, curing warm boot, is a good option as well. I am figuring that it doesn't take too long to load BDOS and the BIOS either way. One of my thoughts is to minimize the Atari code as much as possible. I was looking at the structure of the Atari boot sector and thinking that, if possible, the Atari code and BIOS code could all be loaded at the same time. This way, Atari's OS would load both and it would save some code on my end.
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'
30 minutes ago, reifsnyderb said:The 512 byte estimate doesn't include the buffers. I put the buffers in the last 512 bytes of free memory. Since there isn't any sign they have to be initialized with anything, their content doesn't matter. Worst case, I suppose I could clear the memory during cold boot.
Agreed. I don't think that's even necessary.
-
11 hours ago, GravityWorm said:
New version crashes 20% the time. Some memory fault. Something like segmentation fault or memory access violationYou 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.
- 3
-
1 hour ago, reifsnyderb said:
The extra 1152 bytes is the space in the directory track that isn't used by the directory.
I was counting the 40 tracks as track numbers 0 to 39. So, with 3 tracks used by the OS there are 36 tracks left.
Ah, I see. We had a different definition of disk capacity. I also counted block 0 where the directory lives.
1 hour ago, reifsnyderb said:I've been considering options on this one. Since a warm boot requires that the BIOS copy CCP back, why not have the BIOS copy both CCP and BDOS back in place? Since only the BIOS is involved in the warm boot, it wouldn't matter. So, I've been thinking that if the Atari installs the BIOS and sets the BIOS jump in the Z-80 memory at $0000, then the cold boot function would be ran first. The cold boot would then run part (most) of the warm boot code and install both CCP and BDOS.
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.
1 hour ago, reifsnyderb said:Yeah, my mistake. I found it after posting. Realistically, not all 1536 bytes would be loaded as the buffers would be at the end. I am currently guessing that the BIOS will be under 512 bytes.
Nice! That's including buffers and DPH/DPB I suppose?
Edit: premature post... sigh.
-
12 hours ago, reifsnyderb said:
Ok. I re-did my calculations as how to fit everything into the normal CP/M boot area. Keep in mind I am planning to use the 1050's density and a half format. Boot track layout is at the bottom.
; Calculations: ; ; Size of CCP = $EC00 - $E400 = $800 = 2048 bytes (16 sectors) ; Size of BDOS = $FA00 - $EC00 = $E00 = 3584 bytes (28 sectors) ; Size of BIOS = $FFFF - $FA00 = $5FF = 1535 bytes (12 sectors) ; Total size of CCP + BDOS + BIOS = $1BFF = 7167 bytes ; Bytes per Track: = 128 bytes * 26 sectors = 3328 bytes ; 128 byte sectors needed for CCP + BDOS + BIOS = 56 sectors ; Bytes per directory entry : 32 ; Directory entries per sector: 4 ; ; Directory entries are 32 bytes. 4 entries per 128 byte sector. ; ; Drive storage capacity = Tracks 4 to 40 + 1152 bytes ; = 36 * 3328 + 1152 = 119808 + 1152 = 120960 ; = 120960 / 1024 bytes per block = 118 = $76 ; ; Boot track layout: ; Track 0 Sectors 1-12 Atari boot sector, BIOS loader, and CP/M I/O - 1536 bytes max ; Track 0 Sectors 13-26 BIOS - 1535 bytes max starting at FA00 ; Track 1 Sectors 1-16 CCP - 2048 bytes starting at E400 ; Track 1 Sectors 17-26 BDOS - 1152 bytes starting at EC00 ; Track 2 Sectors 1-19 BDOS - 2432 bytes
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
- 2
-
Perhaps you can get one of these?
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
- 3
-
Looks good! Doing a little more on the Z80 side then I would have done, but it makes sense to not delegate some of the BIOS functions to the Atari (SELDISK and friends for example). Regarding loading BDOS from disk, I would make BDOS part of the initialization process. After that it never has to be loaded again. Lots of the original CP/Ms did that too. It's not supposed to be overwritten, ever. You also have a chicken and egg problem, because if there's no BDOS, you cannot read BDOS.SYS from the filesystem because there is no filesystem handler, which is BDOS. Regarding loading CCP.SYS, you can keep a copy in 6502 RAM and have WBOOT copy that over to the shared RAM. That's a lot faster.
To summarize, the Atari bootcode loads BDOS and BIOS into the shared RAM, and CCP in its own RAM, and starts running its mainloop. BIOS will request CCP to be copied during WBOOT.
Edit: I noticed you reserve only one byte for IOTrack, but that should be two bytes.
Edit2: changed observation on what to do at the Z80 side and what to delegate
- 2
CPM/Z-80 card for the 1090XL -- Calling anyone with Z-80 experience!
in Atari 8-Bit Computers
Posted · Edited by ivop
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!