PCjr Hardware/ROM questions

Hardware questions and modifications
Post Reply
jason
Posts: 110
Joined: Tue Aug 26, 2008 3:48 pm

PCjr Hardware/ROM questions

Post by jason »

Hey everyone,

I've been trying to better understand how my PCjr works at a hardware level. I'm very familiar with higher level programming languages (C,C++,Pascal,Smalltalk,BASIC,etc.) and even MIPS assembly and had OS courses many years ago, but x86 assembly and how exactly all the hardware works has always been a mystery to me since I've had my PCjr since I was a wee little one. So, I'm hoping someone can shed some light on some high level questions I have.
  1. Is there a good document/book that describes at the hardware level how the PCjr boots up? i.e. power gets turned on and obviously it reads the BIOS and executes/sets up some things, but I'm very fuzzy on the details. Maybe the technical reference is good for this, I haven't had time to look yet.
  2. related, is how the cartridges interact with this. It is my understanding that cartridges can be run like regular programs, or even replace the BIOS outright.
  3. I read part of the technical reference section for how the cartridges work, specifically page 2-108/2-110 where it describes the 0x55 0xAA bytes that it expects at the start of a cartridge, then I looked at some PCjr cartridge ROMS and noticed that they don't all start with this sequence. So I'm guessing that BIOS replacements/additions follow a different scheme? Is that documented anywhere? (This is really just curiosity on my part, I have no plans to write a BIOS, lol).
  4. It is also my understanding that the PCjr has 2 32k BIOS chips, one of which is the main BIOS which I presume it boots off of, and then the other contains BASIC? Is that correct? If so, why is there a BASIC cartridge for the PCjr, what does that actually buy you?
  5. I only very vaguely understand what IRQs and DMAs do, is there a good place to read up on that?
Thanks!
Brutman
Site Admin
Posts: 1331
Joined: Sat Jun 21, 2008 5:03 pm
Contact:

Re: PCjr Hardware/ROM questions

Post by Brutman »

You probably want to get comfortable and get very cozy with the Technical Reference manual. Another good option would be to join us the next time we do a video chat.

Here are some short answers to your questions to get you started:
  • The technical reference has some of this. You need to read about the x86 architecture too. The short story is that at power on the system resets and the CPU starts executing code at a pre-determined address. (The code is in ROM.) That starts the booting process. The early part of the boot process is concerned with setting up the hardware and doing some minimal testing to ensure nothing is totally broken.
  • The machine scans for cartridges later in the boot process. Cartridges look very similar to BIOS extensions on ISA cards. Cartridges that replace the system BIOS are not BIOS extensions, so they don't follow those rules. (They use some trickery on the address lines to replace the system BIOS outright.)
  • The system has two ROM chips holding the 64K of BIOS code. I'm pretty sure that BASIC is just somewhere in the chips, and it did not get it's own full chip. The BASIC that is built in is the Cassette BASIC. "Disk" BASIC adds some functions for interacting with DOS. Cartridge BASIC adds even more functions. IBM could have just built those functions into the included ROM chips, but then they would have missed a chance to sell a $75 cartridge. ;-0 It also might not have fit in the two 32K ROM chips.
  • IRQ = "Interrupt Request" .. it's a wire on a device (a chip) that allows that device to signal the CPU that it needs to do something urgently. Kind of like having your two year old come to you to tell you they need to go to the bathroom. If you ignore the interrupt you might be dealing with a mess. ;-0
  • DMA = "Direct Memory Access", and generally does not exist on a PCjr. It's a fancy way of copying bytes around the system *without* using the main CPU.
Expanding on IRQ for a little bit ... when I was a teenager I would write code to talk to a modem, and the code was constantly reading an I/O address to see if a new byte of data was available. That's basically the same as saying "Are we there yet?" and getting "No" for an answer, until you finally get to where you are going. Setting up an interrupt allows you to tell the modem to signal via an interrupt that a new byte of data has come in. Then you can go back and have your program do something else useful instead of spinning, waiting for the next byte to come in. When the next byte does come in the UART flips a wire on, signaling to the CPU that it needs attention. The CPU jumps to an interrupt handling routine (which you provided as part of the setup), does what it needs to do with the byte, and then jumps back to where it left off.

That's all a gross simplification, but you should get the idea from it.


Mike
ImperatorBanana
Posts: 20
Joined: Sat Mar 06, 2021 9:12 am

Re: PCjr Hardware/ROM questions

Post by ImperatorBanana »

I've been looking into it as I'm designing cartridges to fool around with, Tech Reference (Appendix A) has the full BIOS listing which is the primary source of truth. It's commented really well, though with 8088 ASM being a bit of a bear (in my opinion :lol: ) it can be tough.

Cartridge headers differing: Are you looking at raw dumps of cartridges or .jrc files? If .jrc, be aware that they have an extra header of 512 bytes inserted as part of the dumping process that isn't on the real cartridges. That header needs to be stripped/skipped if you're trying to look at the data in a disassembler and have the addresses line up (or you're trying to burn the image to a custom cartridge). The raw cartridge data should follow one of the 3 formats specified in (2-107 thru 2-113) depending on what type of cartridge it is (IPL, DOS add-in commands, or BASIC programs). Cartridges can also replace either or both of the System ROMs (in which case all bets are off since they can override the BIOS routines that check for the header in the first place), or there might be some weirdo cartridges out there that get used by a DOS executable, another cartridge, or hardware add-in card in some proprietary way. From what I can tell, the field of cartridges is pretty barren.

To add onto Brutman's comments:
A-109: FFFF0h appears to be the first instruction executed by the 8088, which in our case is a JMP OFFSET RESET (relative to the beginning of the cartridge)
A-7: F0043h, RESET label - where the BIOS starts doing its tests and initializations of the built-in hardware
A-20: F07E0h, where the BIOS starts looking for optional ROMs every 2K from C0000h-EFFFFh (C0000h-CFFFFh [most likely sidecars] with a CRC, D0000h-EFFFFh cartridges with a Checksum). If it finds one with the signature and valid crc/checksum, it executes the exposed instruction or return statement (header bytes 3-5). An IPL cartridge is expected to have that instruction as a jump to its INIT function, where it's expected to configure the int 18h vector to point to the cartridge MAIN/Entry routine and then just return to the BIOS, but a few of the simpler cartridges just take control and never look back.
A-26 - F0B1Bh, Bootstrap - BIOS checks to see if the diskette drive contains a bootable floppy, if not it calls int 18h (int 18h by default points to Cassette BASIC[built into the sysplane], otherwise if something like a cartridge game overrode it, it transfers control to the cartridge MAIN/Entry routine
A-73: FEB51h, ROM_CHECK checks the ROM for validity (calls CRC_CHECK or ROS_CHECK depending on if the current block is in the option rom space or cartridge rom space)
A-106: FFE71h, CRC_CHECK - the Checksum algorithm it's using for the cartridge space

If you are planning to put your own software own cartridges or romhack existing ones, the first hurdle to be aware of is getting the header and checksum right. If the BIOS doesn't see the signature it wants or the length/checksum doesn't line up, it won't like the cartridge. So far I've only played with writing IPL cartridges. Do be aware that it looks like IBM only expected to use the Cartridge slot for simple, static ROM cartridges. It is possible to do sneakier things (there's a cartridge slot SD Card reader that can be a bootable harddisk which is great), but there isn't a straightforward way to design it (compared to a GameBoy or Super Nintendo that were intentionally designed to have save-ram or co-processors in cartridges). Basically you just have the address lines/chip-selects (CPU -> Cartridge) and data lines (Cartridge -> CPU), which it only connects when the CPU attempts to read (it bus-isolates any write attempts from what I can tell).

Note 1: Technical Reference Appendix pages are references as A-7 style
Note 2: I'm using the absolute addresses (20 bits), but it's probably more common to see them in segment:offset format. An absolute address of F0043h would generally be referred to as F000:0043 (though if you're not familiar with the 8088's segmented addressing, know that there are a large number of ways to alias the same absolute address through different segment+offset pairs).
Note 3: It's a bit painful flipping through the tiny Tech Ref pages back and forth to follow the boot sequence. Someone did a decent job at disassembling the BIOS and putting it on GitHub (https://github.com/ricardoquesada/bios- ... r-bios.lst). It's not perfect but it is searchable. I think the Tech Ref on archive.org is also searchable but it's hit or miss.
jason
Posts: 110
Joined: Tue Aug 26, 2008 3:48 pm

Re: PCjr Hardware/ROM questions

Post by jason »

Brutman" wrote: You probably want to get comfortable and get very cozy with the Technical Reference manual. Another good option would be to join us the next time we do a video chat.
Yeah, actually I was really sad when I finally found that thread 1 day after the last video meetup you guys had! I've since subscribed to that thread so as to try to not miss the next! My time to read forums is somewhat limited these days but I try to keep up from time to time.

Thanks for the suggestions. I'll read the tech ref when I have some time and see what new questions crop up.

Thanks for the info about the BASIC cartridge too, I was always curious about what exactly it's purpose was, but as a kid I just always left it in the machine as I busily typed in every BASIC program I could find in any books I had :).

Yeah, I found the full BIOS listing and it's great that it's commented so well, although I don't know x86 assembly enough to know a lot of what it's doing...yet. I also found the BIOS listing you posted from GitHub with the comments added, that's definitely easier to search than searching inside the tech reference, which is hit or miss.

For cartridges I was looking at raw dumps. I believe the quicksilver cartridge may have been one I looked at from these forums. But yes, I did see some others which had obvious headers on them.

Has anyone written a small program to help calculate the CRC values for cartridges? I did briefly look for the routine in the BIOS and found it but am not familiar enough to determine exactly what it is doing, although I bet it's fairly basic.
ImperatorBanana
Posts: 20
Joined: Sat Mar 06, 2021 9:12 am

Re: PCjr Hardware/ROM questions

Post by ImperatorBanana »

Has anyone written a small program to help calculate the CRC values for cartridges? I did briefly look for the routine in the BIOS and found it but am not familiar enough to determine exactly what it is doing, although I bet it's fairly basic.
So the entry of interest is in the BIOS is:
FFE71h (A-106), CRC_CHECK/generation routine, which according to the comment is a CRC polynomial of the form X16 + X12 + X5 + 1.

I haven't bothered to work out what the algorithm is actually doing in more mathematical form, but since the BIOS had the literal implementation, I emulated all the raw register behaviors and instructions in C and it works:
https://github.com/ImperatorBanana/PCJr ... irom_crc.c

My code does a little more than that: it strips any .JRC header if it exists, emulates* the BIOS behavior that checks for a ROMS every 2K bytes, and corrects each ROM chunk's CRC(hence the name multirom) that has a valid header. No idea of any commercial cartridges did it, but it's legal so I wanted to account for it and I had to confirm I could write a cartridge that told the BIOS to not check for any more ROMs after itself.

*I haven't confirmed if the BIOS hard-checks every 2K or if it says "Hey the current ROM is 8K, add 8K to the last header and continue checking from there." My code does the former but I'm like 63% sure it's the latter and will fix it eventually.
raphnet
Posts: 36
Joined: Thu Mar 26, 2020 5:52 pm
Location: Japan
Contact:

Re: PCjr Hardware/ROM questions

Post by raphnet »

jason wrote: Mon Jan 10, 2022 5:21 pmHas anyone written a small program to help calculate the CRC values for cartridges? I did briefly look for the routine in the BIOS and found it but am not familiar enough to determine exactly what it is doing, although I bet it's fairly basic.
I also wrote a tool, it is part of booterify, see jrromchk.c. It can read raw and jrc files, can update the CRC and update the size byte, and can output a .jrc (useful for testing in DOSbox) or raw binary for burning EPROMS. But it does not support multiroms like ImperatorBanana's tool (cool idea BTW!)... https://github.com/raphnet/booterify

An example of the tool in action is available here:
https://www.raphnet.net/electronique/pc ... x_en.php#5
Creator of SD-Cart JR. Please support my work by buying an original from me!
https://www.raphnet-tech.com/products/s ... /index.php
ImperatorBanana
Posts: 20
Joined: Sat Mar 06, 2021 9:12 am

Re: PCjr Hardware/ROM questions

Post by ImperatorBanana »

Haha nice! Definitely recommend using/looking at booterify over my dirty hack, booterify is way better (I find that writing my own tools is how I learn what the heck it's actually doing)! I did chuckle when I saw you had a function to implement the DOS print string interrupt because I ended up doing it as part of my experiments as well and assembly for that is pretty similar!

Turns out I had actually already fixed my multi-rom support it to behave like the BIOS before uploading it to GIT, the comment I had left in the code was just out of date lol. The BIOS sees if there's a valid signature at the current ROM pointer, if there is it adds the ROM length to the pointer, and if there isn't it adds 2K to the ROM pointer and checks again. I guess it's primarily a trivia point, but it means you could have 384 valid Option ROM chunks that the stock PCJr BIOS will validate and execute during boot (128 attached via sidecar and 256 via cartridge) :roll:. That would probably get some youtube views but otherwise doesn't have a huge amount of utility. Suppose you could make a small bootloader screen cartridge that loads at D0000 and says "Hey, you left a game in the other slot, do you want to boot to that game, or skip it and boot off of something else (diskette/cassette/basic)." I needed it because part of my lazy cartridge design relies on a sequence of reads to store data, and the BIOS performing the knock-knock check is a problem so I had to write a working dual-boot cartridge and then write INIT code in the first ROM to confirm I could trick the BIOS into not scanning the second one.

References: A-20 and A-73

PS - Big fan of SD-Cart JR!
jason
Posts: 110
Joined: Tue Aug 26, 2008 3:48 pm

Re: PCjr Hardware/ROM questions

Post by jason »

Thanks for the info! I understand C code just find so I can compare it to the assembly and probably learn something in the process!

And yes, actually I saw your page on booterify @ralphnet although I didn't notice that you had a crc check though. Thanks for the great page sharing the info.
jason
Posts: 110
Joined: Tue Aug 26, 2008 3:48 pm

Re: PCjr Hardware/ROM questions

Post by jason »

What I've found that is helping me get into this right now is reading "Compute's Mapping the IBM PC and PCjr". One of my co-workers knew I was working on my old jr and gave me his old copy. This is helping me get into how exactly the system operates although I need to go back to my copy of "Compute's Beginner's Guide to Machine Language on the IBM PC and PCjr" to understand the assembly language bits since that is something else I know little about.

The book on Mapping the IBM PC and PCjr references the DOS Technical Reference Manuals which I had a bit of trouble finding as I don't have a copy laying around and they seem difficult to locate anywhere (digitally or otherwise). However, I did stumble upon this site in case anyone else has ever tried to hunt them down.
http://bitsavers.trailing-edge.com/pdf/ibm/pc/dos/
Post Reply