> OswFE/src - Source for OSWORD &FE used by Z80Tube 2 H Saved in ADFS file '$.CPM.X' for BBC B/B+ and '$.CPM.Y' for Master (: 2 BUGS 3< There is a lot of redundancy and unused code. CF Checks for &FFFExxxx for screen memory, but never acts on it. 5P There are no changes for running on the Master. 7Z Master version doesn't use correct DRVSEL bitmap. ;d Master version uses wrong address for DRVSEL and FDC. Gn Master version reads drive speed from KBD links instead of NVRAM. x: G The code is quite weird. It looks like it was written by somebody E with little experience of the 6502 and more used to other CPUs, G particularly the way many bit flags are used in a single location C in a very non-6502 way, and low bits instead of the more 6502 F natural bit7/bit6, resulting in cumbersome code to set and reset F them. Data is thrown around between lots of different locations, = making it hard to keep track of what the code it doing. : @ OSWORD &FE does FM floppy disk access with 1770 controller % XY?0 = &12 inward block length & XY?1 = &03 outward block length = Followed by a modified OSWORD &72 SCSI command block:  XY?2 = returned result  XY!3 = addr  XY?7 = command " XY?8 = drive+sector b16-b20 " XY?9 = sector b8-b15 , XY?10= sector b0-b7 06 XY?11= sector count - what does &00 mean? =@ XY?12= drive reset flags, b7=drive 0, b6=drive 1, etc. @J XY?13= drive settings, XY?13=drive 0, XY?14=drive 1, etc. 7T Something is returned in the drive settings bytes ^: Dh &FE80 = Drive Control: 0 0 ~RESET NMI SDEN SIDE DS1 DS0 Dr &FE84 = Command/Status: MOTOR WPROT SPIN SNF CRC TRK0 IDX BSY | &FE85 = Track  &FE86 = Sector  &FE87 = Data : ) &2EF1 = Action, &10=Write, &11=Read  &2EF2 = Previous NMI owner + &2EF3 = Result - initially set to &00 ! &2EF4 = Saved stack pointer G &2EF5 = Disk step speed &00 or &03 for 1770:6ms/30ms 1772:2ms/6ms 3 &2EF6 = Disk write precompensation &00 or &02 . &2EFA = &00/&01 - never seems to be used : &2EFB = &80=Tube not being used, &81=Tube being used # &2EFC = Tube transfer address : , &0D56 = Drive write precomp &00 or &02  &0D57 = (track count?)  &0D58 = Sector b8-b15 & &0D59 = Sector b0-b7 0 &0D5A = : &0D5B = )D &0D5C = Drive step speed &00 or &03 N &0D5D = Tube flag $X &0D5E = Drive control settings b &0D5F = l: v &A0 = FDC result  &A1.b7= Read/Seek  b6=  b5= NMIs claimed  b4=  b3  b2  b1  b0= NMI error  &A2.b7 1 b6= check for next sector when NMI done  b5  b4  b3= not finished  b2  b1  b0= NMI completed  &A3 * &A4 = sector number 4 &A5 > &A6 = FDC command H &A7 R: \OSBYTE=&FFF4:USERV=&200 fctrl=&80:addr=&82 p: 1zrun%=&FFFF2A00:load%=&FFFF2A00:fname$="OswFE"  mcode% &700  P=0 1 P%=run%:O%=mcode% [OPT P*3+4 \ OSWORD &FE entry \ ---------------- .L2A00 2INX:INX :\ Step past header bytes =: :\ *BUG* will fail if &xxFE or &xxFF 2STX &80:STY &81 :\ Point to control block 3LDA #&80:STA L2EFB :\ Set Tube not being used *JMP L2A64 :\ Jump into code : .L2A0E (RTS :\ Never called : $.L2A0F .JSR L2C7D N8LDX #&00:JSR L2A59 :\ Write count in &A3 to track in &FE84 (looks wrong) BBINX:JSR L2A59 :\ Write sector in &A4 to sector in &FE85 MLINX:JSR L2A59 :\ Write track in &A5 to data in &FE86 (looks wrong) 5VCMP &A3 :\ Compare with count in &A3 `BEQ L2A3C .jLDA &A5 :\ Get track from &A5 tBNE L2A2A ~JMP L2C91 : .L2A2A 'ROR L2EFA:SEC:ROL L2EFA :\ Set bit0 LDA #&14:A &0D5C :\ 3STA &FE84 :\ Write command to FDC ;JSR L2C18 :\ Wait until command completed .L2A3C LDA &A5:STA &A3 LDA &A1 FROR A:BCC L2A48 :\ Not an FDC error, skip to check completion .L2A45 .JMP L2EA2 :\ Release and return  .L2A48 BIT &A1:BVS L2A56 :LDY #&05:LDA (&80),Y :\ Get command from control block H(CMP #&0B:BNE L2A56 :\ Not Seek/Park, skip to set NMI not completed A2BEQ L2A45 :\ Seek/Park, jump to release and return <.L2A56 ?FJSR L2C7D :\ Clear &A2 bit 0 - NMI not completed P: /Z\ Write to FDC register and ensure it holds d.L2A59 /nLDA &A3,X:STA &FE85,X :\ Write to register 1xCMP &FE85,X:BNE L2A59 :\ Loop until it stays RTS : \ OSWORD &FE entry \ ================ \ (&80)=>control block +2 .L2A64 .TSX:STX L2EF4 :\ Save stack pointer .LDA #&10:STA L2EF1 :\ Prepare action=&10 GJSR L2A75 :\ Prepare for the operation, seek 0 if needed DJSR L2CAA :\ Do the actual operation, returns with EQ =BEQ L2A45 :\ Jump to release and return result : 9\ (&80),Y points to an OSWORD &72 SCSI command block: \ &00 returned result \ &01 addr b0-b7 \ &02 addr b8-b15 "\ &03 addr b16-b23 ,\ &04 addr b24-b31 6\ &05 command @\ &06 drive+sector b16-b20 J\ &07 sector b8-b15 T\ &08 sector b0-b7 ^\ &09 sector count Oh\ &0A restore to track zero before starting, b7=drive 0, b6=drive 1, etc. r\ &0B drive 0 setting |\ &0C drive 1 setting .\ &0D+ reserved for drive 2 setting, etc. : .L2A75 6LDA #&00:STA L2EF3 :\ Set result to &00 CLDY #&01:LDA (&80),Y:STA &82 :\ Get address from control block 7INY:LDA (&80),Y:STA &83 :\ &82/&82 never used 0INY:LDA (&80),Y:TAX :\ X=&..XX.... 0INY:LDA (&80),Y :\ A=&XX...... AINX:BEQ L2A92 :\ address=&xxFFxxxx, check I/O BINX:BNE L2A96 :\ address<>&xxFExxxx, skip past .L2A92 8CMP #&FF:BEQ L2A99 :\ Check for &FFxxxxxx : \ Not &FFFFxxxx or &FFFExxxx .L2A96 &JSR L2B25 :\ Claim Tube &.L2A99 '0LDY #&05:LDA (&80),Y :\ Get command $:CMP #&08:BEQ L2AB1 :\ &08=Read %DCMP #&0A:BEQ L2AB8 :\ &0A=Write )NCMP #&0B:BEQ L2AB1 :\ &0B=Seek/Park @XLDA #&67:STA L2EF3 :\ Result=&67 - Unsupported FDD command .bJMP L2EA2 :\ Release and return l: v.L2AB1 9ROL L2EF1:SEC:ROR L2EF1 :\ Read/Seek, set action=&90 .L2AB8 9JSR L2AE9 :\ Set up disk controller speeds 'JSR L2AC1 :\ Set up NMIs 6JMP L2DEE :\ Jump to perform the action : .L2AC1 &JSR L2B0F :\ Claim NMIs 9LDA L2EF6:STA &0D56 :\ Disk write precomp &00 or &02 6LDA L2EF5:STA &0D5C :\ Disk step speed &00 or &03 LDA #&00 6STA &A0:STA &A2 :\ Clear result and NMI flags 3LDA L2EF1:A #&20 :\ Set Action to &30 or &B0 STA L2EF1:STA &A1 0 LDA L2EFB:STA &0D5D :\ Tube flag &80 or &81 .JMP L2B4E :\ Initialse NMI code  : *.L2AE9 4LDA #&00 5>STA L2EF6:STA L2EF5 :\ Set speed controls to &00 HLDA #&FF:LDX #&00 transfer address @ JSR &0406 &J LDA &A1 :\ Get action /T #&10:BEQ L2BA8 :\ No transfer to happen 7^ BIT &A1:BMI L2BA9 :\ Get action b7, jump if Read Fh LDY #&07 :\ Modify NMI code to write from Tube to disk r .L2B9F 9| LDA L2C43,Y:STA &0D0A,Y :\ Copy Tube code to NMI area  DEY:BPL L2B9F .L2BA8  RTS  : .L2BA9 E LDY #&07 :\ Modify NMI code to read from disk to Tube .L2BAB 9 LDA L2C4B,Y:STA &0D0A,Y :\ Copy Tube code to NMI area  DEY:BPL L2BAB:RTS  : .L2BB5 = BIT &A1:BMI L2BCE :\ Read to I/O, nothing to change @ LDY #&0D :\ Modify NMI code to write from I/O  .L2BBB = LDA L2C35,Y:STA &0D0A,Y :\ Copy I/O SAVE code to NMI area  DEY:BPL L2BBB & LDY #&02 0 .L2BC6 @: LDA (&80),Y:STA &0D0A,Y :\ Copy transfer address to NMI area D DEY:BNE L2BC6 N .L2BCE X RTS b : 3l \ FDC NMI routine, copied to NMI space at &0D00 3v \ =============================================  \ Defaults to IO LOAD code .L2BCF .L0D00  PHA 9 LDA &FE84: #&1F :\ Get FDC status, keep error bits > CMP #&03:BNE L0D1A :\ If not DRQ+BSY, completed or error .L0D0A 0 LDA &FE87:STA &FFFF :\ Fetch byte to memory . INC &0D0E :\ Update I/O address  BNE L0D18:INC &0D0F .L0D18 + PLA:RTI :\ Return from NMI  : ( \ FDC controller error or completion .L0D1A G #&58:BEQ L0D2C :\ Skip if no error bits set, must be completion + STA &A0 :\ Store as result * \ &08 CRC error in data 4 \ &10 Sector not found > \ &18 CRC error in ID H \ &40 Write protected 0R ROR &A1:SEC:ROL &A1 :\ Set bit 0, NMI error \ .L0D25 4f ROR &A2:SEC:ROL &A2 :\ Set bit 0, NMI completed +p PLA:RTI :\ Return from NMI z : ) \ Not an error, must be NMI completed .L0D2C 7 BIT &A2:BVC L0D25 :\ If bit6 set, exit completed , LDA &F4:PHA :\ Save current ROM & LDA #&00 :\ ROM number C STA &F4:STA &FE30 :\ Page in ROM (not needed, we are in RAM)  TXA:PHA:JSR L2D59  PLA:TAX:PLA ' STA &F4:STA &FE30 :\ Restore ROM + PLA:RTI :\ Return from NMI  \ End of NMI code  \ ===============  : :\ Wait until &A2.bit 0 is set indicating NMI completed .\ If &0D5D.bit4 set, allow Escape to abort .L2C18 +$LDA &A2:ROR A:BCC L2C1E :\ Jump forward -.RTS :\ &A2 changed, exit 8.L2C1E 3BLDA &0D5D :\ Get Escape-allowed flag CL #&10:BEQ L2C18 :\ &0D5D.b4=0, Escape not allowed, loop back 2VBIT &FF:BPL L2C18 :\ Loop back if no Escape &`LDA #&00:STA &FE80 :\ Reset 1770 0jLDA #&6F:STA &A0 :\ Result=&6F - Aborted .tJMP L2EA2 :\ Release and return ~: %\ Copied to NMI area for I/O SAVE .L2C35 9LDA &FFFF:STA &FE87 :\ Copy byte from memory to disk 3INC &0D0B :\ Update embedded address BNE L2C43:INC &0D0C : &\ Copied to NMI area for Tube SAVE .L2C43 *LDA &FEE5:STA &FE87 :\ Copy byte C->H 8BCS L2C51 :\ Skip past I/O address update : &\ Copied to NMI area for Tube LOAD .L2C4B * LDA &FE87:STA &FEE5 :\ Copy byte H->C .L2C51 8BCS L2C59 :\ Skip past I/O address update (: 2.L2C53 9<BIT &A1:BMI L2C64 :\ Check action b7, jump if Read FLDA &A3 P.L2C59 ;ZCMP #&14 :\ If <&14, convert to WriteSector .dLDA #&A0:BCC L2C66 :\ CMD=WriteOneSector 6nA &0D56:BNE L2C66 :\ Otherwise, CMD=Seek+PreComp x: .L2C64 *LDA #&80 :\ CMD=ReadSector .L2C66 ?STA &A6:JSR L2C7D :\ Clear &A6 bit 0 - NMI not completed ;LDA &A6:JSR L2C9E :\ If &2EFA.b0 set, set 'e' in CMD -STA &FE84:RTS :\ Write FDC command : \ Select side 2 \ ------------- .L2C74 4LDA &0D5E:A #&04 :\ Update DRVSEL with SIDE=1 STA &0D5E:RTS : .L2C7D ?ROR &A2:CLC:ROL &A2:RTS :\ Clear bit 0 - NMI not completed : ".L2C83 +,LDA &A2: #&F7:STA &A2 :\ Clear bit 3 - 6RTS @: J.L2C8A +TLDA &A2: #&FD:STA &A2 :\ Clear bit 1 - ^RTS h: r.L2C91 $|LDA #&00:STA &A3 :\ Set to 0 <A &0D5C:STA &FE84 :\ Do 'Restore', head=on, verify=off 9JMP L2C18 :\ Wait until completed or Abort : .L2C9E ROR L2EFA:BCC L2CA6 A #&04:CLC .L2CA6 ROL L2EFA:RTS : "\ Do the actual disk operation "\ ---------------------------- .L2CAA ;JSR L2A0F :\ Write &A3-&A5 to FE85-&FE87 'LDA &A2:A #&40:STA &A2 :\ Set bit6 LDY #&07 1LDA (&80),Y:STA &0D58 :\ Get sector b8-b15 0&INY:LDA (&80),Y :\ Get sector b0-b7 40INY:CLC:ADC (&80),Y :\ (sector b0-b7)+count :STA &0D59 /DBCC L2CC9:INC &0D58 :\ Increment carry N.L2CC9 ?X\ &0D58/&0D59=sector number after last sector, sector+count b: .lLDA &0D58:TAX :\ X=sectorend b8-b15 -vLDA &0D59 :\ A=sectorend b0-b7 8LDY #&FF:JSR L2E96 :\ DIV/MOD10, Y=track, A=sector >CMP #&00:BNE L2CDB :\ Not sector 0, not start of a track 7LDA #&0A :\ Use sector 10 as end sector .L2CDB 9\ Y=end track, A=end sector with &00 converted to &0A : 0LDY #&09:SEC:SBC (&80),Y :\ endsector-count >BCS L2CFF :\ No overflow, within one track 5LDA #&0A:SEC:SBC &A4 :\ 10-secnum = seccount ASTA &0D58 :\ Store as seccount for this track 1LDA (&80),Y:SEC:SBC &0D58 :\ count - seccount 0LDX #&00 :\ X=0, A=sectount =LDY #&FF:JSR L2E96 :\ DIV/MOD10, Y=track, A=sector 3STY &0D57:STA &0D59 :\ Y=tracks, A=sector 9 BPL L2D10 :\ Jump forward to continue : .L2CFF 2*LDY #&09:LDA (&80),Y:STA &0D58 :\ sector count 4LDA #&FF:STA &0D57 >LDA #&00:STA &0D59 H: R.L2D10 \LDA #&00:STA &0D5A -fINC &0D57 :\ Incr. track count ,pDEC &0D58 :\ Decr. sec. count BzLDX #&01:JSR L2A59 :\ Write sector in &A4 to sector in &FE86 @JSR L2C53 :\ Write read/write/seek command to FDC .L2D23 8JSR L2C18 :\ Wait until command completes LDA &A2 2 #&02:BEQ L2D3E :\ &A2 bit 1 clear, skip... ?JSR L2C7D :\ Clear &A2 bit 0 - NMI not completed +JSR L2C8A :\ Clear &A2 bit 1 4LDA #&54 :\ &54=StepIn+update+verify <A &0D5C:STA &FE84 :\ Write FDC command with step speed @INC &A3:BNE L2D23 :\ Incr. track, loop back to do another : .L2D3E LDA &A2 ( #&08:BEQ L2D73 :\ Finished, exit ?JSR L2C7D :\ Clear &A2 bit 0 - NMI not completed +JSR L2C83 :\ Clear &A2 bit 3 '$INC &A3 :\ Incr. track ).JSR L2C74 :\ Select SIDE=1 .8LDA #&04 :\ &04=Restore+verify 0BA &0D5C:STA &FE84 :\ Restore to track zero .LBPL L2D23 :\ Loop back for more V: 4`\ Called here from NMI code, operation completed 8j\ Check various things, and increment to next sector t.L2D59 ?~JSR L2C7D :\ Clear &A2 bit 0 - NMI not completed 3JSR L2D74 :\ Update track/sector/etc <TXA:BNE L2D68 :\ Not completed, write FDC command 9ROR &A2:SEC:ROL &A2 :\ Set &A2 bit 0 - NMI completed RTS : .L2D68 'JSR L2C8A :\ Clear bit 1 @LDA &A6:JSR L2C9E :\ Get FDC command, set bit 4 if needed 0STA &FE84 :\ Write command to FDC .L2D73 RTS : .L2D74 : LDA &0D58:BNE L2DDD :\ endsector not zero, jump to... 7LDA &0D57:BNE L2D8D :\ trackcount<>0, update track 9LDA &0D59:BNE L2D87 :\ sectorcount<>0, update sector 7(LDX #&00:BEQ L2DED :\ All done, return with X=&00 2: <.L2D87 3FDEC &0D59 :\ Decr. number of sectors APJMP L2DE0 :\ Write incremented sectornumber to FDC Z: d.L2D8D 9nLDA &0D5A:BNE L2DD7 :\ 2D90 D0 45 PE xROR L2EFA:SEC:ROL L2EFA 6LDA &FE85 :\ Get current track from FDC *CMP #&4F:BCC L2DBF :\ LDX #&FF :\ Prepare to return X=&FF - Not done .L2DE2 3INC &A4 :\ Increment sector number TXA:PHA BLDX #&01:JSR L2A59 :\ Write sector in &A4 to sector in &FE86 PLA:TAX .L2DED RTS : =\ Prepare to do a disk operation, NMIs claimed and set up =\ ------------------------------------------------------- .L2DEE 1&LDY #&06:LDA (&80),Y :\ Get drive+sector high 70STA &A6 :\ Store drive number in b5-b7 =: #&1F:BNE L2E5A :\ Keep sector b16-b20, jump if >&FFFF 9DBIT &A6:BVC L2E02 :\ Test drive b1 - drive 2,3,6,7 2NLDA #&65:STA &A0 :\ Result=&65 - Bad drive .XBNE L2E5E :\ Release and return b: l.L2E02 %vLDA &A6 :\ Get drive % #&20:BNE L2E0E :\ If 1,5 skip HLDA #&21 :\ This gives control= noRST+0+DDEN+SIDE0+0+DS0 HLDA #&29:BNE L2E12 :\ Drive 0,4 control = noRST+0+SDEN+SIDE0+0+DS0 .L2E0E HLDA #&22 :\ This gives control= noRST+0+DDEN+SIDE0+DS1+0 HLDA #&2A :\ Drive 1,5 control = noRST+0+SDEN+SIDE0+DS1+0 .L2E12 7STA &0D5E :\ Set drive selection setting EROR L2EFA:SEC:ROL L2EFA :\ Set bit0 of L2EFA - seems to be unused HJSR L2E49 :\ Get sector/track/side and check for overflow 1LDA &0D5E:STA &FE80 :\ Select drive and side 6ROR A:BCC L2E37 :\ bit0=0, drive 1, skip past : \ Drive 0/4 B LDY #&0B:LDA (&80),Y:STA &A3 :\ Get setting from length byte 0 @LDY #&0A:LDA (&80),Y:ROL A :\ Get flags byte, normally &00 9 BCC L2E48 :\ If XY+10.bit7=0, exit L*BCS L2E45 :\ If XY+10.bit7=1, call something and exit 4: >\ Drive 1/5 H.L2E37 CRLDY #&0C:LDA (&80),Y:STA &A3 :\ Data setting from length byte 1 @\LDY #&0A:LDA (&80),Y :\ Get flags byte, normally &00 -fROL A:ROL A :\ Get bit 6 9pBCC L2E48 :\ If XY+10.bit6=0, exit z: ;\ If drive bit set in XY?10, set &A3 from length?drive, E\ then ignore &A3 and restore to track zero, wait for completion. .L2E45 MJSR L2C91 :\ Restore to trck zero, wait for completion .L2E48 RTS : 1\ So, XY+10 used as a bitmap of extra actions 4\ %1xxxxxxx - drive 0 do a restore before action 4\ %x1xxxxxx - drive 1 do a restore before action : .L2E49 -LDY #&07:LDA (&80),Y :\ Get sector b8-b15 %CMP #&06:BCC L2E7A :\ <&600, ok 'BNE L2E5A :\ >&600, fail ,INY:LDA (&80),Y :\ Get sector b0-b7 %$CMP #&40:BCC L2E60 :\ <&640, ok ..L2E5A <8LDA #&61:STA &A0 :\ Result=&61 - Sector out of range B.L2E5E .LBNE L2EA2 :\ Release and return V: 2`\ Sector<&640 - valid sector for a floppy disk j.L2E60 tLDA &A1 <~ #&10:BEQ L2E7A :\ If no transfers, skip sector check ,LDY #&09:LDA (&80),Y :\ Get sector count /DEY:CLC:ADC (&80),Y :\ Add to start sector /BCS L2E74 :\ sec+num>&xxFF, fail ,CMP #&41:BCC L2E7A :\ sec+num<&641, ok .L2E74 5LDA #&63:STA &A0 :\ Result=&63 - Volume error .BNE L2EA2 :\ Release and return \ 9\ Ah ha, &61 Sector error is start sector>end of disk 1\ &63 Volume error is start+count>end of disk : +\ Sector<&600 - valid for a floppy disk .L2E7A - LDY #&07:LDA (&80),Y :\ Get sector b8-b15 TAX ,INY:LDA (&80),Y :\ Get sector b0-b7 <(LDY #&FF:JSR L2E96 :\ Y=sector DIV 10, A=sector MOD 10 52STA &A4:STY &A5 :\ Set disk sector and track ,<TYA:SEC:SBC #&50 :\ Check for side 1 *FBMI L2EA1 :\ Track<80, exit 0PSTA &A5 :\ Update with track-80 1ZJMP L2C74 :\ Jump to select SIDE=1 d: n\ / 10 x\ ---------- .L2E96 SEC:SBC #&0A:INY:BCS L2E96 ;DEX:BPL L2E96:ADC #&0A :\ Y=XA DIV 10, A=XA MOD 10 .L2EA1 RTS : 0\ Operation complete, release and set result 0\ ------------------------------------------ .L2EA2 )LDX L2EF4:TXS :\ Restore stack &LDA L2EF1 :\ Get action 2 #&20:BEQ L2ED7 :\ Skip if NMIs not claimed -LDA &0D5E :\ Get drive control /ROR A :\ Move DS0 into Carry 'LDA &A3 :\ Get a value <BCC L2EC3 :\ DS0=0, skip to deal with drive 1 ": ;,\ Store drive 0 byte in length.0 and clear bit7 in flag 46LDY #&0B:STA (&80),Y :\ Store value in (ctrl),11 )@LDY #&0A:LDA (&80),Y :\ Get (ctrl),10 0J #&7F:STA (&80),Y :\ Remove bit7 and update 3TBCS L2ECF :\ Skip past to get result ^: ;h\ Store drive 1 byte in length.1 and clear bit6 in flag r.L2EC3 4|LDY #&0C:STA (&80),Y :\ Store value in (ctrl),12 )LDY #&0A:LDA (&80),Y :\ Get (ctrl),10 0 #&BF:STA (&80),Y :\ Remove bit6 and update : .L2ECF 1LDA &A0:STA L2EF3 :\ Store returned result (JSR L2B1C :\ Release NMIs : .L2ED7 )JSR L2B43 :\ Release Tube LDY #&00 :LDA L2EF3:STA (&80),Y :\ Store result in control block +LDX &80:DEX:DEX :\ Get original X 3LDA L2EF3:BEQ L2EEC :\ Get result, skip if OK @A #&40 :\ Not OK, ORA with &40 to indicate FDD .L2EEC +LDY &81 :\ Get original Y /& #&7F:RTS :\ Drop bit7 and return C0\ Return value irrelevent as OSWORD handler restores original A :: 8D.L2EF1:EQUB &00 :\ Action, &10=Write, &90=Read /N.L2EF2:EQUB &00 :\ Previous NMI owner :X.L2EF3:EQUB &00 :\ Result - initially set to &00 0b.L2EF4:EQUB &00 :\ Saved stack pointer Vl.L2EF5:EQUB &00 :\ Disk step speed &00 or &03 for 1770:6ms/30ms 1772:2ms/6ms Bv.L2EF6:EQUB &00 :\ Disk write precompensation &00 or &02 /BRK :\ 2EF7 00 . /BRK :\ 2EF8 00 . /BRK :\ 2EF9 00 . =.L2EFA:EQUB &00 :\ &00/&01 - never seems to be used I.L2EFB:EQUB &00 :\ &81=Tube being used, &80=Tube not being used 2.L2EFC:EQUD &00000000 :\ Tube transfer address : \ WORDV entry \ =========== .exec% .L2F00 +JMP L2F05 :\ Jump to handler .L2F03 *EQUW 0 :\ oldUSERV store .L2F05 4CMP #&FE:BEQ L2F0C :\ If OSWORD &FE, skip past 1 JMP (L2F03) :\ Continue via oldUSERV *.L2F0C 34JMP L2A00 :\ Jump to OSWORD &FE code >: H\ Left-over data REQUS &2F7A-P%,0) 1\EQUS " SEEK " :\ 2F7A 20 53 45 45 SEE 1fEQUB &01 :\ 2F7E 4B 20 20 01 K . .pEQUB &14 :\ 2F82 14 . .zEQUB &00 :\ 2F83 00 . EQUS &2FC0-P%,0) 1EQUS " SOFT " :\ 2FC0 20 53 4F 46 SOF 1EQUB &01 :\ 2FC4 54 20 20 01 T . .EQUB &00 :\ 2FC8 00 . .EQUB &00 :\ 2FC9 00 . 1EQUS " TUBE " :\ 2FCA 20 54 55 42 TUB 1EQUB &01 :\ 2FCE 45 20 20 01 E . .EQUB &06 :\ 2FD2 06 . .EQUB &04 :\ 2FD3 04 . EQUS &3000-P%,0) ] GA$=fname$+" "+~mcode%+" "+~O%+" "+~(exec%&FFFF0000)+" "+~load% "Saving ";A$: "SAVE "+A$: