I wanted to demonstrate my TRS-80 Model I working with a 20 MB hard disk drive, but I sadly had to admit that I had no Newdos2.5 starting disk with me. As this happened on a meeting of the user group I just asked some prawn member if it was possible to have my Model I booting in Newdos2.5 from the hard disk. Several weeks later I took my Model I with the hard disk drive to someone called Rence and we planned the specs.
  1. The TRS-80 should boot from the hard disk in Newdos2.5 
  2. Using the BREAK-key while booting should put us in BASIC level II with the Memory Size?
  3. Using any other key while booting should give the possibility to start up with a floppy disk.
  4. The TRS-80 should not be altered.

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.

Compare the old and the new ROM

OLD ROM NEW ROM
0000 F3 DI
0001 AF XOR A
0002 C37406 JP 0674
     
0060 0B DEC BC
0061 78 LD A,B
0062 B1 OR C
0063 20FB JR NZ,0060
0065 C9 RET
     
0066 310006 LD SP,0600
0069 3AEC37 LD A,(37EC)
006C 3C INC A
006D FE02 CP 02
006F D20000 JP NC,0000
0072 C3CC06 JP 06CC
0075 118040 LD DE,4080
     
     
     
     
00B5 210501 LD HL,0105
     
00FC 210E01 LD HL,0l0E
     
0105 4D454D DEFM 'MEM'
0108 205349 DEFM ' SI'
010B 5A45 DEFM 'ZE'
0l0D 00 DEFB 00
010E 522F53 DEFM 'R/S'
0111 204C32 DEFM 'L2'
0114 204241 DEFM 'BA'
0117 534943 DEFM 'SIC'
011A 0D DEFB 0D
011B 00 DEFB 00
     
     
0471 FE40 CP 40
0473 3808 JR C,04D7
0475 D640 SUB 40
0477 FE20 CP 20
0479 3802 JR C,047D
047B D620 SUB 20
047D CD4105 CALL 0541
     
2FFB DEC3 SBC C3
2FFD C344B2 JP B244
     
     
0674 D3FF OUT 0FF), A
0676 21D206 LD HL,06D2
0679 110040 LD DE,4000
067C 013600 LD BC,0036
067F EDB0 LDIR
0681 3D DEC A
0682 3D DEC A
0683 20F1 JR NZ,0676
0685 0627 LD B,27
0687 12 LD (DE), A
0688 13 INC DE
0689 10FC DJNZ 0687
068B 3A4038 LD A,(3840)
068E E604 AND 04
0690 C27500 JP NZ,0075
0693 317D40 LD SP,407D
0696 3AEC37 LD A,(37EC)
0699 3C INC A
069A FE02 CP 02
069C DA7500 JP C,0075
069F 3E01 LD A,01
06A1 32E137 LD(37E1), A
06A4 21EC37 LD HL,37EC
06A7 llEF37 LD DE,37EF
06AA 3603 LD(HL), 03
06AC 010000 LD BC,0000
06AF CD6000 CALL 0060
06B2 CB46 BIT 0,(HL)
06B4 20FC JR NZ,06B2
06B6 AF XOR A
06B7 32EE37 LD(37EE), A
06BA 010042 LD BC,4200
06BD 3E8C LD A,8C
06BF 77 LD(HL), A
06C0 CB4E BIT 1,(HL)
06C2 28FC JRZ,06C0
06C4 1A LD A,(DE)
06C5 02 LD(BC), A
06C6 0C INC C
06C7 20F7 JR NZ,06C0
06C9 C30042 JP 4200
     
     
     
     
     
     
06CC 01181A LD BC,lA18
06CF C3AEl9 JP l9AE
06D2 Jump Table  
0000 F3 DI
0001 AF XOR A
0002 C37406 JP 0674
     
0060 0B DEC BC
0061 78 LD A,B
0062 B1 OR C
0063 20FB JR NZ,0060
0065 C9 RET
     
0066 AF XOR A
0067 3D DEC A
0068 1898 JR 0000
006A D3CF OUT(0CF),A
006C DBCF IN A,(0CF)
006E E6C0 AND C0
0070 EE40 XOR 40
0072 20F8 JRNZ, 006C
0074 C9 RET
0075 118040 LD DE,4080
     
00B5 21FB2F LD HL,2FFB
     
00FC 217304 LD HL,0473
     
0105 CD6C00 CALL 006C
0108 0lCE06 LD BC, 06CE
010B ED79 OUT (C),A
0l0D 0D DEC C
010E 10FB DJNZ 010B
0110 3E20 LD A, 20
0112 CD6A00 CALL 006A
0115 210042 LD HL,4200
0118 E5 PUSH HL
0119 EDB2 INIR
011B C9 RET
     
0471 180A JR 047D
0473 522F53 DEFM 'R/S'
0476 204C32 DEFM ' L2'
0479 2E2E DEFM '..'
047B 0D DEFB 0D
047C 00 DEFB 00
047D CD4105 CALL 0541
     
2FFB 4D656D DEFM 'Mem'
2FFE 2E DEFM '.'
2FFF 00 DEFB 00
     
0674 08 EX AF, AF'
0675 AF XOR A
0676 D3FF OUT (0FF),A
0678 21D206 LD HL,06D2
067B 110040 LD DE,4000
067E 013600 LD BC, 0036
0681 EDB0 LDIR
0683 3D DEC A
0684 20F2 JR NZ,0678
0686 0627 LD B,27
0688 12 LD (DE), A
0689 13 INC DE
068A 10FC DJNZ 0688
068C 317D40 LD SP, 407D
068F 3A4038 LD A,(3840)
0692 CB57 BIT 2, A
0694 2032 JRNZ, 06C8
0696 17 RLA
0697 3806 JR C,069F
0699 DBCF IN A,(0CF)
069B 3C INC A
069C C20501 JP NZ,0105
069F 21EC37 LD HL,37EC
06A2 7E LD A,(HL)
06A3 3C INC A
06A4 2822 JR Z, 06C8
06A6 3E01 LD A, 01
06A8 32E137 LD(37E1), A
06AB llEE37 LD DE,37EE
06AE 3603 LD (HL),3
06B0 CD6000 CALL 0060
06B3 CB46 BIT 0,(HL)
06B5 20FC JR NZ, 06B3
06B7 12 LD (DE),A
06B8 13 INC DE
06B9 0642 LD B,42
06BB C5 PUSH BC
06BC 368C LD (HL),8C>
06BE CB4E BIT 1, (HL)
06C0 28FC JR Z,06BE
06C2 1A LD A,(DE)
06C3 02 LD (BC), A
06C4 0C INC C
06C5 20F7 JR NZ, 06BE
06C7 C9 RET
06C8 08 EX AF, AF'
06C9 CA7500 JP Z,0075
06CC 01181A LD BC,lA18
06CF C3AEl9 JP l9AE
06D2 Jump Table  

Press here to go back

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?

lowing. 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?