Z80 Retro #28 - CP/M BIOS READ Function First Draft

Поделиться
HTML-код
  • Опубликовано: 25 окт 2024
  • You can support this channel on Patreon! / johnsbasement
    This video is part of a RUclips playlist/series: • Z80 Retro
    Implement enough of the BIOS READ routine to boot the OS and run programs.
    The github repos seen in this video:
    github.com/joh...
    Related project hardware repos:
    github.com/joh...
    github.com/joh...
    A Hackaday page for Z80 Retro! projects:
    hackaday.io/pr...
    Music used in this video (Vibe Tracks, Alternate) was downloaded from the RUclips Audio Library: www.youtube.co...
    #Z80
    #CPM
    #retrocomputer
    #BIOS

Комментарии • 42

  • @davidblackuk
    @davidblackuk 2 года назад +1

    I'm really enjoying this series so, so much. It's right in my ball park, z80 assembly and operating systems (started as a games programmer on the spectrum and CPC, both z80s and the CPC ran CPM+). Realy love your presentation style. Keep up the great work, I appreciate it!

    • @JohnsBasement
      @JohnsBasement  2 года назад +1

      Thanks!
      Ya know, I had an hour to kill the other day and ended up creating the field layout and a movable paddle for an ANSI color-terminal version of Breakout! It just fell together nicely.
      Your words are just the kind of encouragement that I need to draw up the logic for the world's simplest physics engine to make the ball work! :-D

  • @BFLmouse
    @BFLmouse 2 года назад

    Watching the end of that, I was thinking of an old saying that "On a clear disk, you can seek forever"

  • @JohnDlugosz
    @JohnDlugosz Год назад

    44:00 Arcades in the late '70's: My parents disliked such things so I never really got to look around to see the selection... but when in the mall waiting for a movie, I somehow got my Mom to be interested in a flying game. The screen was not generated electronically, but was done with actual moving models.
    An early computerized game was a driving game that just showed dots on either side of the lane to define where you had to keep the car, and it would go faster and faster until you eventually crashed.
    An early game was "space zap", and the cabinet was decorated with PCB traces! It had four directions to shoot and you had to press a direction button and a fire button.
    Of course, before any of these started to appear, there were pinball machines. They morphed from electromechanical to gradually take on electronic aspects, first of all the score display.
    But the grandfather of video games is "Space War". I saw one in an arcade, and it must have been an actual PDP-11 (or whatever it ran on; I forgot) modified to take coins. To choose options, there was a hexpad! You had to add up the options you wanted and enter it as a hexadecimal number. When Asteroids came out, I could see a clear family resemblance, not only in the shape of the ship and the background stars, but the manner in which it broke apart when the player died.

    • @JohnsBasement
      @JohnsBasement  Год назад

      That driving game myst gave been "Night Rider".
      🤔 I've never seen one that used models for a display.
      What did a pdp11 cost back in the day? Only 1000000 plays and the rest is pure profit! 😂

  • @randallrouth9029
    @randallrouth9029 2 года назад +1

    If I understand correctly, CP/M has an 8MB limit. But those 8 megabytes can be anywhere on the SD. If you read the partition table and save the 32 bit LBAs you could fill the SD card with partitions. You can associate 4 byte offsets to each supported drive.
    With all that said, you are a smart man and have already thought of that.

    • @JohnsBasement
      @JohnsBasement  2 года назад

      Lets give credit where credit is due... The Alteration guide's discussion of deblocking algorithm discusses a primitive variation of this. So I'm just "standing on the shoulders of giants." (I think Sir Isaac said that.)
      Merging your observation with the alt guide notes on putting multiple 8MB logical drives on one physical drive gives us multiple logical drives in one SD card partition.
      Max supported number of CP/M drives = 16.
      16 * 8 = 132 which is why I made my SD partition 132MB.
      Future BIOS upgrades will include 16 logical drives on the SD.

    • @randallrouth9029
      @randallrouth9029 2 года назад

      @@JohnsBasement But you would not need to limit yourself to 16 drives. You just can't have more than 16 at one time.
      You could have 30 or 40 disk images on the SD.
      You could have a keyboard escape sequence that would bring up a menu of partitions and the drive letters to assign them to.
      All this code and work space could be in "Bank 14". You would however need to tell the BDOS that you changed disks.

    • @JohnsBasement
      @JohnsBasement  2 года назад +1

      @@randallrouth9029 As long as the BDOS also knows about the change. I'm thinking you'll probably need a warm boot if you switch disks or change any of the disk parm headers/blocks.

    • @randallrouth9029
      @randallrouth9029 2 года назад

      @@JohnsBasement You would know better than me. I mostly used TRS-DOS. But don't recall needing to warm boot after changing floppies.

    • @JohnDlugosz
      @JohnDlugosz Год назад

      @@randallrouth9029 CP/M had provisions for changing the media within a drive, keeping the same params. It even had problems using a single-sided disk in a double-sided drive because what it doesn't like is the params changing.
      Swapping imagines with identical parms can look like swapping media in the unchanging drive. So, still drive A: just now with all different content.

  • @DJSures
    @DJSures Год назад

    Thanks, John. Your video series was useful for my nabu cloud cp/m. Credit given!

    • @JohnsBasement
      @JohnsBasement  Год назад

      Hey! Thanks!
      CP/M meant a LOT to me back in the day! It and my home-brew S100 boards were my daily driver all the way through college, graduate school, and then some until I had to get a PC in 1988 so I could run specific programs for work.
      Keep up the good work on the NABU series!

    • @DJSures
      @DJSures Год назад

      @@JohnsBasement Thanks! I'm glad you're enjoying it - i sure am. Just released the cloud cp/m today if you want to check it out. a few bugs here and there, but the best way to find them is to let ppl break it :D

    • @JohnsBasement
      @JohnsBasement  Год назад

      @@DJSures I might have to do a port for my Retro board I've been thinking about network-connectrd disks for a while.

  • @willofirony
    @willofirony 2 года назад +1

    Trust me, this video is as good and exciting as any adventure. I too, was facscinated by text adventures. There were a bunch of them written for the TRS-80 by Douglas Adams (no, not he of hitchhiker's guide to the galaxy fame). Now these were "impossible" to copy on the cassette tape storage versions of the model 1. Which was good protection against piracy. Unfortunately, in those days, commercially produced cassettes were audible copies that would 'decay'' after many loads. So, it made sense to make digital copies on the computer. The protection used by the adventure programs was to fill the entire user memory space, thus leaving no room for a copying program. I noticed that user memory started at 0x4300 but the ROM containing the I/O and Basic interpreter ended at 0x37E0. So, with a little reverse engineering and a lot of "What happens if I change this", I discovered that most of this sytem RAM was a table of vectors for expansion of the Basic interpreter. Some of the vectors seemed to be essential. This left patches of usable memory enough to load an adventure, keep the entry address and write a new tape with the image of all the user memory, provided I skipped over the essential vectors and control blocks.

  • @rene-jeanmercier6517
    @rene-jeanmercier6517 2 года назад

    Excellent John ! Regards, RJM

  • @JohnDlugosz
    @JohnDlugosz Год назад

    before 4:19 : I thought you could make a variation of the SPI read routine that would read and ignore the unwanted sectors, and would store the desired sector into the provided 128-byte buffer.
    This could be a fully general routine, where it's given the starting byte (the number of bytes to ignore first) and read length (the number to save) and it of course ignores the rest of the sector.

    • @JohnsBasement
      @JohnsBasement  Год назад

      I considered and abandoned the idea. Try it and see how it performs. My expectation of the access patterns from the BDOS are that making such a change would perform poorly.

  • @SimonJackson13
    @SimonJackson13 Год назад

    The SAM Coupe had some nice CP/M disk images. Not sure of format, but the emulator loaded them.

  • @JohnDlugosz
    @JohnDlugosz Год назад

    27:50 instead of shifting HL left 7 times, start by putting the disk_sector in H and 0 in L, and shifting right once. Even using register A to do the work, it will be a lot fewer instructions and fast instructions too (not doing a 16-bit ALU operation which serializes it as two 8-bit operations).

    • @JohnsBasement
      @JohnsBasement  Год назад

      What shift instructions can be used with hl?

    • @SteveJohnson314
      @SteveJohnson314 10 месяцев назад

      @JohnDlugosz, I like your idea of having the disk_sector in H. I had a similar idea.
      @JohnsBasement Here is code to replace the 7 x ADD HL, HL instructions:
      SRL L ; Save LSB in carry and shift 2nd LSB right one bit
      LD H, L ; Move shifted 2nd LSB to H
      RR L ; Move carry to MSB
      The original code takes up 7 bytes and executes in 77 clock cycles. The replacement code takes 5 bytes and executes in 20 clock cycles.

  • @randallrouth9029
    @randallrouth9029 2 года назад +1

    Could you move the block of instructions after .boot_msg. to after .bios_stack_lo:? You don't want to overrun your stack, but if you do, less important text would be preferable to SD data or other control blocks?

    • @JohnsBasement
      @JohnsBasement  2 года назад

      Yes. But overflowing it into anything should be considered a complete disaster.
      The right way to do it is the count the exact number of stack levels and every function requires and it's worst case and then document that and then look at your entire call stack and make sure that there's always enough stack space for the worst case. Anything else will likely fail in some weird way and result in an unrecognizable situation, making it very difficult to debug, especially over the phone!
      In an early draft project, I usually just allocate 10 times more stack than I expect I'll ever need and when I'm done developing and debugging I go back and recheck accounting out everything.

  • @linuxninja
    @linuxninja 2 года назад

    I about choked on my drink when I saw the repetitive ADD HL,HL - I'm not an assembly language programmer by any stretch of the imagination (although I had to write my own terminal program in machine code on a TRS-80 Model III when I upgraded to a 2400bps modem - since the CompuServ cassette was hard-coded to 300bps), and ROM II BASIC at 2MHz couldn't keep up with 2400bps. (I was around 11 or 12 years old I think). Using BASIC, I POKED the machine code into RAM, then did a system CALL to the first location, which allowed me to write a BASIC program that could be loaded from tape to bootstrap my machine language program to dial-up BBSes at 2400bps. My Model III didn't have disk drives, so I was stuck with BASIC and a cassette. Which also means I didn't have an assembler, so I had to hand-assemble the code using the index of the Assembly Language Programming for the TRS-80 book.
    Anyway, couldn't you bit shift left to multiply by 2 each shift, 7 shifts would give you *128 ??

    • @JohnsBasement
      @JohnsBasement  2 года назад

      Wow! The heights we reached in our teens!!
      I had access to a full TRS-80 w/floppy drive at school. But my first home made S-100 box had a ribbon cable reaching out to a perf board with 32 dip switches and no LEDs! (Im not sure whats worse! 🤣)
      As for the adds, in theory shifting would work too. But These are no 16 - bit shift instructions on the Z80. So....

    • @linuxninja
      @linuxninja 2 года назад

      @@JohnsBasement So I guess the ADD instructions are just easier, then. Don't know Z80 assembly, so didn't know about the lack of 16-bit shift. I'd probably, just as a matter of "See? It can be done!" write a loop to shift H and L, and OR H with 0x01 when Carry is set after shifting L. That's a lot harder, isn't it? (I assume Carry gets set if you shift L and the high bit was set.) This would be 'poor man's' way to do 16-bit shift, but that'd eat a lot of cycles. Yeah, stick with the ADDs. Reminds me of building two half-adders using logic gates, feeding the carry into the 2nd half-adder. Love watching your work with Z80, and I hope to eventually build a kit. Right now, I just want to get an emulator going and re-learn the stuff I've forgotten, and learn all the things I missed out on. (I do have sdl2trs running, and I've been able to play some old TRS-80 cassette games.)

    • @JohnsBasement
      @JohnsBasement  2 года назад

      @@linuxninja Yes indeed! Often you must decide if you want to make the code neat, tidy, and slow or less obvious as to the intent, confusing, and fast.

    • @JohnDlugosz
      @JohnDlugosz Год назад

      Assembling by hand using an index of instructions (on paper):
      Yes, that's the way to learn in. Ever find yourself unconsciously writing the hex code instruction instead of the nmemonic when filling out a coding sheet? This is how you gain the awe inspiring legendary ability the read a hex dump.

    • @JohnDlugosz
      @JohnDlugosz Год назад +1

      @@linuxninja You don't OR in a conditional branch... to do a multi-byte shift you shift WITH C the least byte, then shift the next byte without changing C.
      (For right shift, you start with the greatest byte).
      In this case shifting right _once_ would be more efficient.

  • @DennoWiggle
    @DennoWiggle Год назад

    for some reason I can't get the ddt command 'd' to display anything. Other commands such as 'l' equal to list is working. Any ideas?
    -lf100
    F100 IN 00
    F102 ANI 80
    F104 ORA E
    F105 RLC
    F106 MOV E,A
    F107 RET
    F108 PUSH D
    F109 CALL F08D
    F10C LDA F143
    F10F ANI FD
    F111 ORI 01
    -df100
    -

    • @JohnsBasement
      @JohnsBasement  Год назад

      Strange indeed. Did you figure it out? I'd like to know what happened.

    • @DennoWiggle
      @DennoWiggle Год назад

      @@JohnsBasement I figured out the root cause to be something I did. Duh.
      Short story - I'm using a simple uart to telnet convertor that I wrote for an ESP2866 using telnet in character mode. My telnet client on the PC replaces "
      " with "
      \0". The retro board receives a 0d 00 instead of just 0d. This seems to be a telnet protocol thing. For now I filter out "\0" in the telnet server and it all works. I guess I should improve the telnet server but I didn't initially want to implement the full protocol.
      I suspect there is a difference in timing between the "l" command in ddt and the "d" command. I say this because as soon as I added a call to "hexdump_a" in "con_rx_char" in sio.asm (for debug) the 'd' command suddenly started working and I could see the command operating normally.
      All good now and I enjoyed adding debug to the serial port in z80 assembly code. It was simple to do thanks to the structure and documentation of your code. :)

    • @JohnsBasement
      @JohnsBasement  Год назад

      @@DennoWiggle There's one that I never saw coming!! 🤣 Glad to know that you are out of the woods.

  • @randallrouth9029
    @randallrouth9029 2 года назад

    is there a reason that you prefer the "JP $" to "HALT". I know that they both nowhere from there but are there any benefits to one over the other?

    • @JohnsBasement
      @JohnsBasement  2 года назад

      I do when I'm lazy 😁
      The right way to do it is:
      X: halt
      jp x
      The halt will run a continuous stream of M1 cycles. The jp $ will run a continuous stream of longer sequences of M1 M2 M3... (on phone right now, can't remember if JP is 3 or 4 cycles.)
      Anyway.... The halt will allow for a shorter IRQ latency. And it will also assert the halt pin while it waits (if that matters.)

    • @randallrouth9029
      @randallrouth9029 2 года назад

      @@JohnsBasement I don't see it as lazy. It is 4 character either way. I just assumed that one was better than the other.