This wasn't going to be simple a modification with some switches or a print he told me. We had to exchange the ROM chips for some EPROM we programmed (burned) our self. If you are like me, then you don't know too much about your computer so I will only explain you the parts that I understood.
The TRS-80 has a Z80 microprocessor instead of an Intel 8088, 80386, Pentium and so on. The PC has Bios chips while the TRS-80 has ROM chips with a bios program and Basic in only 12K. The ROMs in the TRS-80 were programmed by Microsoft and they still own the copyrights of the code. To switch the ROMs we needed EPROM chips and some rewiring in the Model I. This is how the TRS-80 ROM divides the 64K memory:
With no Disk Basic loaded you have 64- 21=43kbytes left and with Disk Basic 64-26=39K. Note that I have omitted the character H in the next story. It saves me typing and trouble with Microsoft I hope, while I am not allowed to publish their ROM source but I can't explain the working of our EPROM without some insights in Bill Gates (and Allen Paul) their ROM. The ROM chip starts:
0000 DI
0001 XOR A
0002 JP 0674
DI is to disable interrupts. The computer must not be interrupted during this important initialization process. XOR A will reset the A register. This important register will read 0. Now the program jumps to 0674.
0674 OUT (FF),A The port FF (cassette port) is reset with 0 (from register A)
0676 LD HL,06D2
0679 LD DE,4000
067C LD BC,36
067F LDIR
That's how the Rom places the control block data for us at 4000 and the next bytes. That is where we can change them, as 4000 is Ram memory.
0681 DEC A
0682 DEC A
0683 JRNZ 0676
To be sure that the control block data is at the right place, the Rom repeats this process 128 times (starting from 0 to 256 in steps of 2 (DEC A DEC A)) As we will need every byte, remember this place where we can win a byte by just slowing down the TRS-80 a bit. Delete DEC A and the TRS-80 will repeat the process 256 times instead of 128 times and while doing this the TRS-80 will be 0.1 of a second slower at starting up. But every byte counts.
0685 LD B,27
0687 LD DE,(A)
0688 INC DE
0689 DJNZ 0687
This resets 27H bytes at 4036-4062. Now here comes an important part, as we want to intercept the keyboard to test the BREAK-key and other keys as well.
068B LD A,(3840) 3840=decimal 14400 (keyboard memory)
068E AND 4 is it the BREAK-key ?
0690 JP NZ,0075
0693 LD SP,407D this is the new stack area (can be replaced)
Here we will start with our intercept. The command at 0693 can be replaced. If the BREAK-key not has been pressed than the computer will test if you do have an E.I. locked on. If no Expansion Interface can be found a jump is made to 0075 where a clever routine tests all sort of things. It's there to find eleven bytes!!
0696 LD A,(37EC) floppy command/status
0699 INC A look for -1 or 0 by first
069A CP 02 incrementing and comparing with 2
069C JP C,0075 Nice done Bill and Allen!!
But here they missed some thing. Luckily for us, so we can gain two more bytes.
069F LD A,01 to select drive 0
06A1 LD (37E1),A select drive 0
06A4 LD HL,37EC (also see 0696) disk drive command/status
06A7 LD DE,37EF data register of the floppy drive
06AA LD (HL),03 3 in 37EC will restore and track 0
At 0696 we could load HL with 37EC and than perform a LD A,(HL). That's one byte longer, but afterwards we can gain three bytes because HL still contains 37EC. Profit two bytes!
06AC LD BC,0000
06AF CALL 0060 Hey Bill, BC is 0000 already. Look at 067F and 0683, so here we can spare three bytes.
06B2 BIT 00,(HL) to do the FDC busy test
06B4 JR NZ,06B2 repeat un-till ready
06B6 XOR A
06B7 LD (37EE),A zero sector register FDC
06BA LD BC,4200 But Bill! B is still zero, so LD C 42 would be good enough and wins another byte
06BD LD A,8C
06BF LD (HL),A put (read) sector 0 track 0 at 4200-4455
Again we can win a byte here by just LD (HL),8C instead of LD A,8C and than LD (HL),A. Now the last control to see if the data is ready, and if so read it.
06C0 BIT 01,(HL) test data ready
06C2 JR Z,06C0
06C4 LD A,(DE) get next byte from floppy to reg. A
06C5 LD (BC),A from reg. A to 4200 and further
06C6 INC C C=00 to FF; BC 4200-42FF
06C7 JR NZ,06C0 entire sector?
As you see, just 256 bytes will be read, regardless of the size of sector 0! These 256 bytes are at 4200-42FF, that is in RAM memory. At last!!
06CA JP 4200
Lets resume: We saw that the ROM lets the Z80 search for the BREAK-key at the keyboard. If no BREAK-key has been found and there is no E.I. (Expansion Interface) attached to your system than sector 0 track 0 is placed byte by byte at 4200-42FF. After this the Z80 jumps to 4200 to boot from floppy. So this is what we have to do. Make a new ROM which searches for the BREAK-key or some other (special?) key. If no key has been pressed the hard disk should restore and write sector 0, head 0 of track 0 to 4200 and further. We had (I still have) a MFM 20 MB hard disk tied to my TRS-80 Model I. The controller is a WD1002-05 (Western Digital). The controller can be program to work with ports C8-CF. The hardware part can be found on this website. Here is the program scheme Rence constructed to start the HDD:
CALL drive_ready
LD A,20
CALL drive_command
LD HL,4200
LD BC,00C8
INIR
JP 4200
drive_command OUT (CF),A
drive_ready IN A,(CF)
AND C0
XOR 40
JR NZ,drive_ready
RET
CALL drive_ready is needed to test the HD ready. To do this we read CF (status) in register A. Than we AND C0 to test bit 6 and 7 both on 1. So 1 and 1 is busy and ready . Than we XOR 40 to see if the status says 0 and 1. The WD1002-05 needs this double checking instead of simple testing the busy (bit 7) bit.
With LD A,20 and the CALL_drive command we give the read sector command to the controller. Now we load HL with 4200 to INIR the port C8 for 256 times. INIR will look in reg. C which port to read and in reg. B for how many times to loop and HL where to write to. From the documentation of the WD1002-05 we learned the meaning of the ports C8- CF CF is the status/command port and C8 is the sector data port.
I read a article in TRS-Times Volume 7 no.1 where Roy Beck gave some extra information about all the ports and the details of the WD 1001/1010 HD controllers. By the way, most of the text your reading right now appeared in COMPUTER NEWS80.
This is what we have so far for the moment. The ROM finds a HDD and reads 256 bytes from head 0 sector 0 cylinder 0 and transfers this bytes to 4200-42FF. Now the program continues at 4200 where the boot sector should be. Format a hard disk, put the boot sector on sector 0 track 0 and start your TRS-80 Model I. The boot sector program should tell the computer to continue to read from the HDD.
Apparat (the designers of Newdos80 and Newdos2.5) never thought the ROM would ever change to read a HDD so they never wrote a boot sector for the Model I. Well here is one from my friend Rence:
Without going into details too far the boot sector above tells the computer to go ahead reading from disk (in this case that is the hard disk). The computer should watch out for text (e.g. the name of a program), data and programs. Texts should be omitted. Data must be place a the right place (pdrive table etc.) and program commands should be run. Low format your hard disk and use Superzap (SCOPY command) to copy the boot sector at the right place on the hard disk.
Before I start explaining the new ROM and the difference between the old and the new in detail, let me remark two things. The Boot sector is made for Newdos. Newdos uses a pdrive table also for it's hard disk drive, even if it is only a rudimentary one. The last three bytes in the boot sector should contain the bytes 6, 3 and 7 of the pdrive of the starting disk (in this case the hard disk). Byte number three of the boot sector contains the granule number of the directory. So remember to adapt those four bytes if necessary.
| OLD ROM | NEW ROM |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
From 0000 to 0060 nothing has been changed. As the ROM jumps to 0674, we will jump there also. At 0674 and 0675 we had to take two bytes in advance so our listing is two bytes longer than the original. But at 0682 we regained our first byte so our listing will be only one byte larger then Bill's. The new TRS-80 will start up in 1.2 in stead of 1.1 seconds, that 1 sec extra comes from the waiting loop at CALL 0060. At 0692 we used BIT 2,A instead of AND 04 on 068E (old ROM). Both instructions tests bit 2 in register A. Bit 2 indicates if the BREAK-key is pressed. At that moment address 3840 (decimal 14400) resides in register A. By using AND 04 the other bits in reg. A are set to zero. By just testing bit two the reg. A remains what it is, giving us the opportunity to test the keyboard address 3840 again. This we did with RLA. RLA will test the left bit which represents the SPACE-BAR. We looked for an extra byte in this area several times in many different ways but didn't find one minding the fact that we had to walk in pace again at 06CC. At 0694 we do a jump to Basic Level II if the BREAK-key has been pressed during reset. At 0697 we jump to starting with floppy routine if a SPACE-BAR has been pressed during reset. From 0699 to 069C we do some testing for a hard disk drive. If not found we start with floppy and if there is no floppy than we start with Level II on 06A4.
By now our listing is about eleven bytes larger. You can compare 069F (new ROM) with 0696 (old ROM). But lets get back to 069F (new ROM). This is the starting point for the floppy disk routine while the comparing code in the old ROM starts at 0696. We did the following tide programming. - At 06B0 we did a CALL without putting BC 0000. We know BC is zero already so we gained three bytes. - At 06B7 there is no need to zero A. A is zero already and can be placed in HL directly gaining an other three bytes. - At 06B9 just load B with 42. C still is zero. Another byte profit. - At 06BB we pushed BC so the stack became 4200. Now we can replace the JP 4200 by only a simple RET giving us a byte. - At 06BC we placed 8C directly in (HL). Bingo an other byte. - By loading DE with 37EE and an INC we gained our last byte here. As I stated our listing was one byte larger. But at 069F we use LD HL, 37EC in combination with LD A, (HL). These are four bytes in stead of the correspond ending LD A,(37EC) at 0696. But as we can omit the LD HL, 37EC at 06A4 we gain two bytes to fill our total needs.
If purely inserted, the program scheme to start the HDD would have taken 28 bytes. The text MEMSIZE R/S L2 BASIC occupies 23 bytes. At the end of the ROM there are 6 bytes left. But it can't be done. Replacing the code gives no redundancy in the contrary. We ended to need at least 34 bytes. That's why de code had to be shortened and put at several places. To be sure that register pair BC would ended on C800 Rence did the following. He loaded BC with 06CE. Due to OUT(C),A- DEC C-DJNZ 010B all ports will be loaded with zero, even two ports extra. The bulk of code is placed at 0105 where the Memsize text formerly resided. An other piece of the code is placed at 0066, well to be honest at 006A. The original ROM uses the code starting at 0066 to test whether you have a floppy drive, an E.I. or not. It is the starting point if you press the reset button at the rear of the computer keyboard. This is known as the "warm start". This code has been reduce to 4 bytes (XOR A, DEC A and JR 0000) allowing us to use eleven bytes. This gives some incompatibility with the old ROM. So to run BASIC Level II you now must to do a "cold start" as the routine at 0066 will simply load A with zero, reset the zero flag and jump to 0000 in stead of jumping to Level II (JP 06CC). If you want to go from DOS to Level II Basic for some special reason you have to do a "cold start" or write a "Boot Level II" program (JP 0000) or mount an extra "cold start reset button". I can not imagine a TRS-80 user with a HDD ROM without E.I. or floppy at least. So if you reset I think you want to use at least your floppy drive. Note that the new ROMs always reinitialize the first piece of RAM (4000-4062).
We had to change to more places in the old ROM. At 00B5 and at 00FC the old ROM points to the "MEMSIZE" and "R/S L2 BASIC" text. These two addresses now points to the new places were this texts resides. One last thing. A piece of the new (shortened) text "Mem. R/S L2.." resides at 0471 and following bytes. Originally this was the place were the TRS-80 changed every lowercase letter into a uppercase letter. So with this new ROMs you can work with lowercase even in Basic Level II. But does there exist a TRS-80 user with floppy drive but without a lowercase modification?