F: 6502.SYS code

The following two sections of code are 'specials' for the 512. In both cases the code was actually saved in a live machine and disassembled, so as to ensure complete accuracy and to permit mernory addresses to be included in the listings, as both sections of code are position dependent. (i.e. slightly dirty and self modifying). DisassembIy was also used for two other reasons. First for 6502.SYS it was done to produce a source listing which looks more like a normal assembly code program to 6502 users, necessitated by the reason given below. The OSWORD &FA code was disassembled from a live system for the simple reason that neither source code nor source documentation was available in any form other than the input parameter spedfications detailed in chapter 6. The strange techniques employed in this code are due to two factors. The first is that Acorn commonly used relative addressing so as to make the code relocatable as far as possible, eg:

*0 clear A
BEQ so-where Branch sc-where - always

The second is that all Acorn 6502 code appears to be produced using MASM, which simply does not produce the same effidency as hand written assembly code.

The first listing is of the tube handling code which resides in the 6502.SYS file on the DOS boot disc. Interestingly, the original source was actually written in DOS and assembled using a cross-assembler the source for which looks slightly strange if you are not familiar with 8086 assembler.

The reason a DOS cross-assembler was used was that it appears from other information we cannot publish that the source code was at one time intended to be easily modifiable for use by other hardware than a BBC rnicro and a 512!!

The first section of code is the program from 6502.SYS proper, while following it there is the patch which resides at &2300 to handle the OSWORD &FA, which was originally also in 6502.SYS. OSWORD &FA was removed from disc for practical reasons as well as 'neatness'.

The code was separated so it could be put into the 512's boot ROMS to enable it to assist virtually irrunediately with the rapid tube transfers used on initial system start-up, rather than itself first having to be '*LOAD'ed from an ADFS disk, which would look untidy and of course would take longer.

6502.SYS provides the main support for cross-tube dialogue between the 512 and the host for the majority of 512 operations. Only when a tube claim or release is called for, or a completely standard MOS or filing system function is required, is the tube host code, resident in pages 4 to 6 of the host called.

6502.SYS source listing

TUBE handling code for the Master $12

This code uploads to the 512 during initial system boot.

The boot strap loader looks for a file 6502.SYS in the root directory of the DOS+ boot disk and uploads it to the 512's MX alonq with DOS+.

Before initialisinq the system it downloads this code to 6502 memory at offset 2800.
It then sets the naer vector to point to the code's first executable instruction at 2803

To make the code accessible to the boot-strap loader:

  1. Assemble code at offset &2800 and save to disc
  2. Boot DOS+
  3. '~SAVE' the assembled machine code tile from the ~~ Thicrn~a dine to the file 6502.SYS in the root directory of the DOS+ boot disc.
NOTE - that scras of the code here is position critical and much of it is also time critical.
Various addresses and data declarations for the 6502 MOS calls and hardware interfaces follow. 
ken - &EC new ks~ press in zero page
- 'ED old key press in zero ~aqe

keyvec - &22B The keyboard vector
oswrch - aFFEE Console (screen) ontput
osbfte - &FFF4 General MOS call entry
userv - ~2OO user vector
brkv - &202 The break vector
irqvl - &204 Interrupt requeSt 1
eventvec - &220 The event vector
tube_entry - &40~ c1aAjn~re1ease/pro4raTh tube n"I
ic~ge - &rsoo ban, addrena of SHEILA
erte_addr - &FE00 eels CRTC address register
crtc_data - &FE01 'e45 CRTC data register
unerport - &FEEC user-port data I-a
up_rdwrt - &FEE2 User-port data direction
AcRu - &Ftea 6522 auxiliary control register
Ihtu - &FEED Iaterruflt flag register
IrRn - &FEGD Interrupt flag register
IERU - &FESE Interrupt enable register
Master fdc base - &24
Master_fdn_stat - &28
Master_fdc_data - &2B
BBC_fdc_base - &80
BBC_fdc_stat - &84
BBC_fda_data - &e7
tubeaistat - &ttto Register 1 status
tubenidata - ~FEE1 Register 1 data
tube~stat - &FEE2 Register 2 status
tubefldata - &FEE3 Register 1 data
tuben3stat - aFERA Register 3 statue
tubefladata - Register S data
tubsR4stat - aFEES Register 4 status
tubeR4data - &FU7 Register A data
GRAPH_OSWOafl - fast graphics update
nrsK_oswonn - STE hard disk read~write (unirr.lemented)
CRTC OSSIORD - SFC curmor, soft scroll, mouse etc
FDC_OSSORD - iFfl seek/read/write
RESEflVZfl - bik xfer onward
usfind - &FFCE o~nIclose file
osgbpb - &FFfl1 read~vrite open file
filefdc_atri - 0 select drivt/flt-flhl~.
fdc_atat - 4 nRC, INDEX,RMV,~C, -
fda_=td - 4 REsTORS~sEEKIRtAn/WRrTE fdc_trek - S 0-79
fda sect - 6 1-10
tdc_data - 7 data for PEAfl/watT~, track for SEEK
nnd code &OnOO MM! handler location - FIXEnt
=r_stat - &0D02 direction patch location
nrni rd - &ODOB direction patch location wr aODOE direction ~atch location
nmiwso &A0 temporary status storage
nadwal - &A1 end of ccrmnand semaphore
nmiwsfl &AS
nmiws3 &AS
nmiws4 - &A4
nTniws5 = &A5
nrniwsS &Ae
nn!ws7 &A7
fdc bans - nmiwso indirect all accesses to FDC
fdo base 10 - nmiwso
fdc base_hi - nmiwsl
2100 JMP &2500 not one of the following
so j~ to OSWOTID ~FA code
2e0a atp .0-il_OSSORD graphics update?
2005 REQ &262B ~--4 to_gra~h_'trite
2107 CbtP &~cRTC_OSWORD cursor OSSORD?
Zecs %zQ ~2O26 beq to_nuword_fe
260B CMP &~DIs~_oswonn hard disk OSWOflfl?
280D BEC $2825 b&~q to_oaword_fe
2B0r CMP *TDc_osWOstn floppy disk contro~lnr OSNORD?
2B11 EEC &le2E beq to_onvord_fda
2613 JkP &2600 else default code
n-ny RESERVED FOR TRANSIENT STORAGE Temporary storage for FDC operations
2S16 cpa_dras EQUD C
281A tam_statu. EQUB 0
211Th &~rw aid ~fl C
2S1e .s,ctor_count 501,3 0
2am error_-sir EQUB 0
2S1E ran_c-rd EQUB 0
261r &~vatchdogl EQUB 0
2020 -watchdogz scum 0
screen address mn~d mouse pointer co-ordinates
2S21 &~moua.jr~hi tat's 0
2022 &~mau5e~~lo taun 0
2S23 mouse_x_hi ECUB 0
2S24 won,._x_10 SOUTh 0
The following code overcomes the liatted brancbin4 range of conditional it-s from the initial 
entry by converting them to direct unconditional jumps to OSWORD fe
2B25 JMP &2c2r J~ to CO-On RTS
to osgord tc
2S2e JMP ~2A7F write 6B~5 data - atip onword_fc
2B2a JMP ~29r8 Graphics output - 5~ graph_write
to osuord fdc
282t axp &28E0 Floppy disk - j~ caword_fdc
~sS1 aMp &2Arc J~ to event handler - eventeode
2834 JMP &2ne0 J~ to nouirql
**ttt~ The main operational mutinca now follow
get one byte fr~ register 2
2837 LDA tubeUZatat Teat bit 7 of n 5tatus
2S3A BPL &2940 Not set - branch to tu$~_oavrch
2B3C LDA tube~data Read fl data
20SF a's
-tube oswrch
2640 LDA tubeRlatat Test bit 7 of Ri statu5
2eI~ SPL get~oata J~ to getfl if set
2S4S LDA tubeRidata Read Ri data
2646 JSR os'&~rch write character
264n JMP tube_osvrch Repeat; write on. byte to register 2
write fl
284e SIT tubePUstat Test bit 6 of fl stat
2851 avc write_~ Not set - loop until it is!
2853 STA tnbe~data write 't2 data
2856 RTS
Get one byte fr~ register C
read RI
2057 BIT tubeRcatat Teat bit 7 of Re stat
2e5A BPL read_Ra Not 5et - loop nntil it is!
2S5c LDA tubencoata asad R4 data
2asF RTS
write one byte to register 4
'trite RI
2S60 BIT tubea4stat test bit ~ of R4 stat
2e63 BVC write_Rd Not set - 1o~ until it is!
2S~5 STA tuben4data write RI data
29~ a's
write one byte to register I
write al
2069 BIT tubenistat Teat bit 6 or Ri stat
286C BVC write_Ri Not set - loop until it i5'&~
2S6t STA tubenidata write RA data
2671 RTS
Foe OSSORD for "1)1770 5 1~4" r's'~ floppy controller
the floppy controller uses five registers
0 special control latch
4 ca-and/status
5 track register
6 sector register
7 data register
.fdc exec
2B72 InA *0
2S7~ S~A i2a1A sta ram_etatus ensure clear initially
2e77 WY *7 idy &~fdc_data - ensure drq not pending
2879 LDA C&AO},Y ida (ido_base ,y
2R75 JSR ~et&2data
287t STA &2a1n eta error_mask - save tar dSsk mt.
2981 JSR qet~data
2864 StA &2e1c sta sector_count - multi sector count
20S7 Jsrt getfldata jar getnidata - read coinmand from 1R6
289A STA &281E sta rain_cmr'd - for multi sector xfer
296D JSR &2072 jsr tube~rograrn - set dm addr in 186
zego LDY 44 lay &~fdc_mand
2092 rflA &291E ida ram
2895 STA (&AO).Y ata (fac_base},y - send cur-and to f&
2897 mm *&co I. it group S~4
2899 CMP *&CO were top two bits set 7
209e BNE &26cE bne fdc_e7 - No! leava to interrupt .
289n InA &~&3C
2S~r STA &2SiF sta watebdogi
28fl InA 40
2BA4 STA &2620 sta watchdoq2
20k? TAX Set up tic-out Counter5
2SAS WY *4 idy *fdc_stat - point to atatus reg
-fdc el
2SAA flEx
2SAn BNE s2SAA Loop fdc_ci until status goam busy
.fdc e2
2SAn LDA $1 I Te5t busy flaq
2SAr AND t'AO~~Y ANn (fac_base~,y in the status register
~INC! - the foliowina insttuction must not lie
on an a&Irtas where the bottom 3 bits are set
zael nno s28c5 Branch fdc_e4 If no longer busy
2Bn3 DEC &2820 dec watchdog2
29B6 BNE &2SAA bne fda_el
28RS nEC &2e1F dec watchdogl
2mB mit aQOXA bne fdc_ci - else tall thru on timeout
20nn Ink faFF and return a timeout error
28SF BWE &zecs bne fdc_es (will always branch)
-fdc e4
28C1 WY *4 Arty itdc_stat - get the status
2SCS LOA c&AO) ,Y ida (fdc_base ry
.fdc es
2Bc5 STA &281A Save status for return in ram_status .fdc_eS
2Bc6 SET Disable interrupts
2Sc9 asa 'nAEF generate mc event to return status
2S00 CLI Enable inter~pta
28CD RTS and return
.tdc e7
2Sct BPL &2SDF bpl fdc_e9 - ctp 1 co-wade return now
2Sn0 u)y *0 Others don't, no load ti'tSout counters
2sn2 Wx *0
fda as
28n4 LDA ~~9t6 ida status~nding and check Fnc atatna
28fl7 ENS &2scs bne fdc_e6 - it finished return status
2Sn9 flEx Ir not finished decrement counter
28DA mm &29D4 Not done, btanch fdc_en - wait a while
28nc oty
28nn BrIE &2eD4 bne fdc_es it still not co-lete. else
.fdc eg
2Sflr RTS Timer event returns status
mc OSWORD proper
&~OSWORD fdc
28E0 CLI , Enable interrupts again
28E1 cw Ensure operation in binary
29E2 asa qetfldata Read tube RZ data - get a cormnd
28E5 WrE aQete , It > 0 jnp to tube call 1 - else- - -
fdc OSWORD ret
28g7 RTS , Done!
I The5e routines claim or release the tube, set up the l'70 addresses for the host taacbine, 
or write data to nemory mapped 1-0 In SHEILA.
tube call 1
29E6 CKP &~i Master 128 co~nd?
2eEA BITE &28F3 No! - Try tube_call_2 CB/B+
Qote jsrt tube_setup Get tube params - store at rw_cmd &281B
2OEr JSR move_NM:_data Copy and adapt nmi routine
26r2 Jsn &293A jar Master_setup - set up regs
26r5 Jsn &2872 jsr fdc_exec - qet and execute connand
2SFe JMP &26E0 OMP csword_tdc - get another byte
tube call 2
2er9 t *2 aec ~'~+' coninand?
nero ant tube_call_3 no! - Try tube_call_3
28FF JSR tube_setup Get tube params - store at rw_cmd a2a1n
2~O2 Jsn move_NMI data copy and adapt the nm* routine
2905 Jsn &2932 jar nBc_setup - set up reqa for BBC
290S JSR &2972 jsr fdc_exec get and e~ecute command
290s JMP &28E0 imp OSWORD_fda get another byte tube call S
a(p *3 Claim tube required? 2910 BNE tnbe_call 4 No! try tube_call_4
2912 asa &2983 jar anti_claim - qet control of rynit
2915 JSK &2956 Get tube - ist tube_claim
2918 J,(p &26E0 JKp osuord_fac - get another byte
tube call_4
2919 CMP #4 Release tubs?
2910 nt;E &2926 No! branch other_out~ut
291r JSR &2s7n jsr tube_release - give up tube
2922 JSk &2990 Call fluff_release give up NMI
2925 Jxp &26E0 JMP onward_fdc - qet another byte
2929 TAX port n-er in x
2929 JaR qet~data Read tube ~ data - get data byte
292c STA &FEOO,X atore in 4o~age, X - write it to ~rt
292F Jnp 62BEQ 3Wp onward_fdc - qet anothet byte
2932 'Dx &~&e4 Sec_f& stat
2g34 Kny &~&87 sBc_fdc_data
2~36 Lok IaSO nnc_fdc_bane
293S -E '2940 bne Setupi - always
293A LOX &~&26 Manter_fdc_stat
293c Lay &~~2n Master_fdc_data
2~3R LDA &~&24 Master_fdc_base
2940 STA &Ao sta fdc_base_lo - patch for indirection
2942 LDA farE Load in~age (Sheila) high byte
2944 STA ski sta fdc_base_hi
2946 S7X &n02 str rflfti_stat - Patch nini status read
2e49 JSR geta2data Are we perfcrminq write?
2g4c EKO &2952 zero is No! go to setup2 for read
294E STY aDot sty nifli wr - patch the rual write code
2951 RTS
2952 STY aDDS sty stat_rd - patch the nrni read code
2955 RTS
2956 InA #&Cl A 1~3 to claim tube
2~5S Jsft tube_entry Call tube data transfer at &4O~
295R flea tube claim If c-C tailed, repeat until success
295n RTS
295E LCX SD Fill in dma address
.fdc amal
~96O csn getn2data Read tube R2data - get 1 Cf 4 bytes
2~6a STA &2816,x Store it in epra_dina,x
2966 IflX
2967 crx *4 Done 4 times?
2969 Sflt &2960 No! - Repeat fac dinal
2968 JSR getn2data Read tube n2da~a get nw coffrnand
296s STA &2a1B Store tube n2data at rw-Crnd
2971 RTS
2972 tflA &2s1n A - stored rw cmd - dna claimer type
2975 IsX *&16 sot X to cflra_dma low byte
2977 WY t&29 Set Y to cpm_dran high byte
29?9 asa tube_entry call tube data transfer at &406
297c RTS
-tube release
297D LDA &~&ei A - 129 to release tube
297r JSR tube_entry call tube code at &406 - release tube
2982 RTS

These routines claim or release NMI ownership according to whether tube data transfer is to take place or disc access is required. In practical terms only one of three facilities can be the current NMI owner, the disc system, the network handler (econet), or the tube. A copy of this routine's NMI code is kept at nmi_image (29DB) and transferred to page &D when NMI ownership is required. The routines are called by the code in tube_call_1 to tube_call_4.

.nu~i claim
2993 LLA iSAF Set n~ paged ROM service request
29e5 LnX *&C for N"r clajaL
2987 WY ISFF
2~s9 JSR oubyte Claim NMI routine
29S0 STY s299A Store oriqinal IlMI RON No- at nmi owner
risi release
2990 ~r &299A Load Y with original ami_owner
299a LDA &~~8r set up Paged Row serviec re~est
2995 tox &~as for NMI release
299~ JKP osbyte Release NMI to previous owner
299A ~Un 0
move N'S' data
~)( Move 32 bytes of NMI data to page 6D
.rmd nut
2990 IDA &29na.x ida n~i_irftaqe,x - (saved orig IlMI data)
29A0 STA &0DOO,x ata rud_code.x (Restore to NMI paqe &0
2~A3 flEx Completed 32 tim..?
29A4 SPL &299D No! - repeat tram nini_nut
29A6 ft~s
-nmi next sect
29A7 WY 94 idy tfdc_stat - status req offset
29A9 Lox (iAo~~Y ida (fac_base),y - qet the status
29as STA &281A sta ram_status - save for return status
291& AND &281D and error_mask - any error bits on?
29n1 nNt &29n5 bne ntai next exit - Yes' - abort it
29B3 LDA ~2BlE Ida ram_cmnd-test for groupi (seek ea
29e6 Ert &29D5 bpl arni_next_exit - Yes! Then finished
2~SS u)A &2810 ida sector_count -get remaining sectors
~~SS CMF 41 c~ *1 - is it the last one?
29BD BEQ a2SDS beq nri_next_exit - signal final mt
29nr DEC &261c * dec sectot connt - count down sectors
29c2 WY 56 ldy &~tdc_sect
29c4 LDA (~AO),Y ida cfdc_base~,y - get the sector req
29c6 CLO Clear carry tlaq
29C7 AbC *1 Move to next sector
2909 STA (&AO~.Y sta (tdc_base~,y - and insert new value
29GB LDA &2S1E ida ram_0=4 get read~write
29CE AND &~&F3 Remove head settle delay
29D0 WY &~4 Idy &~tdc_crand
29n2 STA (&AO},Y sta (fdc_base),y - fire off again
29D4 RTS
.nni next exit
29D5 LDA &~SFF Flag an FDC event
~9D7 STA &29F6 Set status~nding to return statu5
2~nA RTS
aBNE pni save context onoo
29nc LDA SEECO 6945 address register ODOl
29Dr Ann Get error bits 0n04
29E1 CKp &~3 + Busy ~ ODOS
2StS mm ~2SED Final interrupt - nimi_exit ODOR
29E5 LDA tuben3data tither this or the next inn ODOA
2~tS StA tabertadata patcb.d to paint to FDC ODin
fl9En puk Restore context 0Db
29Ec RTI Return from interrupt onli
29~ TYA 01)12
aSEK Pr" Save Y onla
29Er JSR &29A7 Next sector or finish 0014
2S72 PEA Restore context 0017
29F3 TAY Restore y ODiS
2SFA era Restore a 001~
Z9r5 RTI Return fr~ interrupt OnlA
29r~ EQUB C onin
- return
29F7 RTS Return from OSWORD
Copy bit patterns to 6502 for block write & ~raphics
This part of the code fills 6502 screen RAM with bit patterns sent across by the 186. 
This can either be font bytes in a1~ha ~de or virtual graphics screen bytes in graphics 
mOde Operations are: 
a) send screen address MSB - or zero to sto~
b) send screen address LSB
c) send S font bytes, Ct 1 byte for background~space fill
d) send sync byte - or iFF to repeat from a)
a wait for sync response f) increment pointer, qo to C
2SFS eLr Enable interrupts
QSFS cLD Ensure we operate in binary
next addr hi
29rA JSR qet~data nead fl for hi-byte until data received
29FD SEQ &29F7 no data? - finished - go to RTS
29FF S~A ~71 Store n content. at zero page &71
next addr 10
2AO~ LDA tube~stat Read '12 status until ready
2A04 BPL &2301 Not ready? - repeat, branch
next addr 10
2A06 LDA tube~data Read 't2 for 10-byte
2A09 TAr and keep in Y
2A0A LDA *0 Clear low byte
230c STA &?O Zero ~7O (real low byte is in Y)

Writing to the screen is optimised for maxirnum possible speed, hence these routines are written 'longhand and so avoid the use of counters, instructions to decrement them and the tests to check when the loop is complete. Spaces are further optimised because they are the most frequently written character and only need a sinqle fill byte. They are therefore the easiest to write too as no reading of tubendata is required between bytes. transfer_loop1 writes spaces, transfer_loop2 other bytes.

2AOE LDA tubenstat Read n2 status - wait for vayne byte
2A11 BPL &2AOE Repeat until S bytes ready in ni buffer
2A13 LDA tuben2data Read R2 data-remove sync byte~cbeck chr
2A16 SEQ s2A43 If 0 qo to transfer_1c0p2 - qet S bytes
2A1B OMP *&F~ ~ither a space or the end of output
2A1A EEC &29FA aFF-end. branch next_addr_hi to repeat
2A1C LDA tubeRidata Read al data for sflace fill pattern
2AiF STA (&70} ,Y * and move same byte into main screen RAM
2~~1 INY S times an fast an ponsible
2fl2 STA (&70}.Y
2A21 INY
2~~5 STA (s7O ,Y
2A27 INY
2A28 STA C&70 ,Y
2112 STA (&70),Y
2fl9 INY
2A2E STA (670 ,Y
2A30 rNY
SASi STA (&70 r
2A34 STA (&70) Y
2A37 BNE &2AOt wait for sync unless on page boundary
2A39 rNC &71 Increment hiqh byte first
2A3n flPL &2AOE check for wrap around - bpl
2A3n LDA t'40 40 back to bottom of screen
2A3F STA '71 by resetting hi byte
2A41 SME a2A0E cuickest j~ to transfer_loopi
2A43 LDA tubauldata Read Ri data - 1st byte - 7 left
2A4~ STA c&703 ,Y
2A49 LDA tubeuldata Read at data - 2nd byte - 6 left
2A4c STA (&10) ,y
2A4t INY
234r LDA tubeRld&ta Road RI data - 3rd byte - 5 lett
2An2 STA (~7O~.Y
2MS InA tubealdata Read Ri data 4th byte - 4 left
2A56 STA (&70),Y
2A55 LDA tubealdata Read ni data - 5th byte - S jeit
2ASE STA (&70 ,r
2A60 INY
ZASt Ink tubealdata Read at data - 6th byte - 2 left
2A64 STA (&70).Y
2A6~ INY
2A67 LDA tubenidata Read Ri data - 7th byte - 1 left
2A6A STA (&70) .Y
2A6c Iwc
2A6fl LDA tubealdata Read ni data - 8th byte - buffer empty
2A70 STA (&70 ,Y (unless already re-filled by lee
2A72 INY
2A7S nnE &2AOE gait for sync unless on page boundary
2A~S INC &71 Increment high byte first
2A77 BPL &2A0E Check wrap around - b~1 transfer_loopt
2A79 LDA &~&40 Go back to bottorft of screen
2A7B STA &71 by resettin4 hi byte
2A7D mm &2A0E Branch to transfer_loopi- - - alway5
at? OSWORn - programs CaT controller. handles initialisation
onward fc
2A7F JsR get112data Get CaT controller tegister number
2Ae2 ~r &2A90 Return on 'FE
2Aa4 STA 'rEDO write 6845 CRTC address register
2AS7 JSfl getfldata Get data byte for 6945
2AAA S~A &rECl write 6945 Cfl~C data register
2A9D JMP &2A7? Repeat until &rr received
onward to 1
2A90 TAX Get cornand code
2A91 INX In it aFF?
2A92 nrc exit Yes! - finished
2A94 rRx Is it arE?
2A95 BNE &2Aoc bn, onward_fc_2 - initialise ~ouse code
2A97 SE: set interrn~t disable
2A9e LnA ir~1 Load oric;inal mt. 1 vector la-byte
2A~n S~A &2aeA Store in oldirqt+1
2A9E LDA irqvl+1 Load original mt - 1 vector hi-byte
2AA1 s,!A &2nen Store in oldirql+2
2AA4 LDA &~newirql+1 "OD 25e new_i~ low byte
2AA6 STA irqvt Stare in 'Rd vector low byte
2AA9 LDA *newirql fl&v 256 new_lrq high byte
2AAB STA irq;ri+1 Store in rRo} vector hiqh byte
2AAE CLI re-enable interrupts
2AAF LDA SO Enable user-port input
2n1 STA ~rE62 Store An up_rdvrt - userport data dir
2AB4 LDA &~&98 enable CB1, CB2 interru~ts
2As6 S?A artet wrtte interrupt enable register
2An9 LDA &FE6fl Read auxiliary control register values
2ABC AND Si leave PA, disable Pn latching a timers
2ABE STA aFE6B write auxiliary control register
2A01 LDA aFEEC Read peripheral control register
2AC4 AND #&F Clear Cal, can bits
2Ac6 STA &FESC write peripheral control register
2Ac9 JIW &2A7r J~ OSWORD_ic to wait for cormaends
-onward fc 2
2ACC nix is it 'FO (intercept events~?
2ACD mm &2AE6 bne os~ord_te_3 - No, continue
2ACF LDA eventvec Yest~ - load event vector low byte
2AD2 STA oldevent+1 Store it
2An5 LDA eventvec+1 Load event vector high byte
2AD8 STA oldevent+2 store it
2ADB LDA Inewevent Mon 256 Load new event low byte
2ADn STA evontyoc Replace oriqinal
2AE0 LDA taewevent DIV 256 Load new event high byte
2AE2 STA aventwc+1 Replace original
2A&5 JMP &~A7r Jump o5word_fc to wait for cor-ands
onword fc S
2AE6 "ix is it arc (waa write mouse port
2AE9 mm exit No! - continne
2AEB JMP &2A7r rest - next coninand
2AEE RTS return from OSIfORD
ide event
QAEF LDX &261A icix ram_status - mc status ret~d in x
2Ar2 WY *0 zero Y for no',
2Ar4 STY &29F6 zero the status~nding flag
2AF7 LDA faA Generate event 10 - wa result waiting
2AF9 EQUB &4C JMP instruction - for saved_vector
-event 10 Jump address of oriqinal event code
2Arn EQUB 0
2AFC CMP *4 Event 4 Cvmync)?
2AFE BNE &2AF9 Not - branch oldevent
2B00 LDA &29r6 Read Status~ndInq - FnC status 0/s?
~flOS BEQ &2308 no! - Continue
2B05 Jart &2AEF asa fdc_event to ret-pending FflC status
2308 JsR keyscan asa sHFT~cTRL scary at &2n7n
snoB PH? save etatus flags on stack
250c LDA keyl Read current ~ey ~ressed
2HO~ Ann i&7F Clear top bit
2B10 PLP Recover statu3 flags from stack
2B11 pHP then re-save them again for SHIFT
2B12 BPL anere Branch no_etri if CTRL not pressed
2B~4 OFLA &~&8O CTRL was pressed - set top bit
no ctrl
2316 TAX store current key in x
2B17 LnA key2 Read last key pressed
2B19 AND &~a7r Clear top bit
2pm Pt? Recall scan status for SHIFT
neic nvc &2a20 Branch no_ahift if SMIFT not pressed
2a1E eRA isso SHIFT was pressed - set top bit
no shift
2B20 ~AY store last key in Y
2B21 LDA *4 Re-load vsync event
2B2a asa &2AF9 Re-issue original event
The current key (if any in now in X - The top bit always set
if CONTflOL was pressed, even when no other key was pressed. 
The previous key, (if any) is floe in Y - The top bit always set 
SHIFT waz pressed. even when there is no previous key press.
2B26 asa read_n4 Read tube a4 data
2329 BEQ &~B7A exit if n4 - zero - finished
2n2n TAX store in x
2n2c flEx Decretnent n4 value
2B2D BNE &~ssE Pt4 was > 1 - go to asyne_mouse

2B2F JSR read_n4 Read tube aA data - get 6945 req. addr.
2BS2 STA &FEOO write 6045 CRTC address reginter
2BS5 asa read n4 Flead tube R4 data - get the data byte
2B30 STA 'FEC! write 6845 Cfl~C data register
283B JMP &2B26 aepeat async_cointand
ZB3E flEX 2 - mouse
2n3F HIrE &2R64 flA was > 2 - go to asyne_leds
2B4i LDA arAX fl4 wan 2 - read arax
2544 pnp Store flags for z
2a45 LDA userport Read unerport
2B4S eLp Recover z flag
2a49 BEC &2n4F Not AKX, tr~ba11?-brancb asyric_mouse_1
2n45 ROL A AMX buttons ate top bits
2n4c Rot A so trove them to the bottom
2B4E ROL A bits 5, 6 and 7 are now 0, 1. 2
&~async_mOuse 1
2B4F AND *7 mask off the buttons
2B51 EOR 57 invert the bits
2553 Jsn write_at write tube nidata to send to 1S~
2B56 IDX 43 set count for 4 bytes of co-orda
&~async_mouse 2
2n~S ~A &2e21,x acad monSeft!~hi.x
2953 asa write al write tube aldata - send mouse data
295E flEx from &2821
285r Ept &2958 four times So branch asyno_nouse_2 if
2R61 abip &2n26 JMP async_cc~and
-asyno leds
2365 BNE &2526 z4>3 - read tube aqain at asyne_co-and
2B67 JsR read k4 Read tube nadata
2B6A TAX put in x
2n6n LDA saca set up FX 202 - write keyboard status
2B6D LDY #0 Y - 0, X paramter from RA
2n6F ask osbyte set keyboard statua according to R4
2B72 LDA t&76 set up FX lie
2874 JSR osbyte Set keyboard LEDs
2377 JKP &~B26 3)4? asyric_command
-keyscan scans shift and control key presses
2n7n etc clear carry and overflow flags to
2a7c CLV , indicate botb SHIFT+CTRL scan re~ired
297D a}qp (keyvec Exit through orig- Sibri vector routine,

X and Y must be preserved here. The original contents of A are preserved by the Has, in zero page &FC. 'rhia also must be reloaded before exiting - with an RTI it we process the interrupt . or if we j~ to the original vector because we're not interested

2B00 LnA &FESD Load Ant flag register - in it 'muse?
2flS3 AND tale rnask-00011000 -cnl and c32 active edqe?
2B85 aflE &2n8c AL leant one - qo to new_ir~code
2n87 LDA &FC Not CB1 not Cfl2 - restore A, foraet it
.oldirql Drop thru to here on any other mt
2369 EQUB &40 JMP - for saved_original vector
-ir~1c saved it- address of oriq md code
2neA aRK
Zafin BRK
- new~ir~code
2360 STA &2e2A ~asked mt flags in RAM in itt_copy
2B6F LDA userport Load VIA input reg S - tracker ball?
2B92 STA s2c2n store it at orb_copy
2n95 AND fals Mask it - these bits always hi for ANX
2B97 OMP noth set?-if either low mINT be t~ball
2B99 BEQ &QnAA Yes! - AMX no new_ir~code2
~fl9fl LnA *0 Mark as tracker ball by atorinq 0
QflSfl STA &2c27 in AMX to override default
2BA0 LDA IS y quad signal is different to default
2BA2 STA &2c28 store it in RAM - tn rousey~qnad
2BA5 ~A Islo and S quad signal is different too
2nA7 STA s2c29 store it in RAM in mouse_x_quad
2BAA tDA &2c2A masked mt flaq req copy - ifr_copy
23AD Ann &~&1o 'qank with 00010000 is it x?
2nAF BEC &2BnF No! - must be Y, branch new~ir~cnde5
2BB1 LDA &2c2E Get pezi~heral control copy - fler_copy
2flR4 EOR lab Invert pos~neg edge bit
2flfle STA &2C2E Store in per_copy - update Pcn edge
23B9 LDA &2CSC toad x_edge - get edge triggering mode
2BBC FOR #aFF Invert it
2nnE STA &2c20 re-store in x_edge
2nd EOR &202B ouad sig, orb_copy, invert if pos edqe
2nc4 AND &2c2e X component in rnousejt~q'aad
2nc7 BNE &2flfl4 necrease? - Yes - branch new_iz~code3
2nc9 INC &2824 Increment the low byte - monse_x_lo
2ncc BNE &ZBDS and if that beco~s a - new~ir~code5
23CE INC &2823 Inc the bi~h edqe - TROUSC_x_hi too
2nn1 JMP &2BDF Jump to new~iz~code5 for Y component
new ir~code3
~Bfl4 IDA &2824 Dec - so load the low eaqe - rouse_r_la
2nD1 BNE &23DC If not 0 jump new_ir~code4, skip
2~n9 nEC &2923 Decrement of mouse X hi
2BDC DEC &2824 Decrement raouse X lo
2BDF IDA a2C2A Read masked mt flag contents- ifr_copy
2BE2 AND &~a Is there any input from Y?
2nEc flRO &2C14 No! - jtirap new~ir~code8
2BE6 LDA a2C2E Get peripheral ctrl register - per_copy
2nES EOR &~&40 Invert pos~neg bit
2n~s STA &2C2E Update peripheral etri req - PC?_COPY
2nEE LDA &2c20 Get edqe triggering mode - y_edqe
2nF1 Eon SaFF myort It
2nF3 STA &2c2D Store in y_edge
2nF6 EOR &2c~B Quad 5143. Invert it pr's - orb.co~y
2BF9 AND s2c2S Look at mouse~~quad
2nFc "~y &2009 Incr~nt? - No! branch new~ir~codeG
2nrE INC &~S22 Incr~~nt as per X motise~~1o
ZCOi mm s2c14 Not zero? - branch new~Ir~codee
2c0S INC &2821 Increment moune~~hi
2c06 axe &2C14 J~ new~ir~codea
2C09 LDA &2e22 Decrement as per X - mouse~~1o
2COC mm &2c11 Not zero? - branch new~ir~code7
2c0E DEC &2621 Decrement rnouse~~hi
2c11 nEC s2e22 Decrement mouse~~lo
2c14 LDA &FESC Read real peripheral control reqiater
2017 mm preserve the bo~tnm nibble but set
2c19 ORA &2c2E the remainder to our copy in pcr_Copy
2C10 STA aFEEC Re-write peripheral control register
'air LDA lila Load cHi and cB2 active edge bits
2021 STA &FEGD write IFR to clear our interrupt 
2c24 Lak &rc Recover A to intorru~t entry state
2c26 nTr Return from interrnpt
2c27 -arAX EQUn aFF default is AMX (0 - Tracker)
2c28 .rncuseflr~qnad EQUB 1 0Th - AM)C, (OS - Tracker
2c2~ mouse_x_quad ECUB 4 AMX, (10 Tracker)
2c2A -ifr_copy flaic RAM copy of Ira state
2C2B -orb_copy BRK RAM copy of user port B
2C20 K_e~e BUK defines pos/neq edqe triggering
2c2t -y_eaqe BEUC detines p05/nag edge triqqerinq
2C2E -pcr_copy flRK Local copy of PCR
osijord fe
2c2r RTS
NOTE:- A local copy of the pcripheral connrol register is
naintained at per_copy because someone Is reprograr~Inq the VIA when they shouldn't be, 
leading to mouse reversal suspect a Master 12a hardware prohlera (2?)
2C30 RTS not ir~1emented
-pad EQUB 0
t**~*~*~****t******* EMD OF CODE ~

OSWORD &FA source listing

It should be noted that major bugs exist in the OSWORD &FA code which are virtually guaranteed to cause problems when the function is called from DOS Plus. Users are therefore warned that they should proceed with extreme caution when testing new routines which call this code and should consider the following points if (i.e. when) problems are encountered.

First, the original designer of the code seerns to have been unaware of various differences between the three host machifles' MOS variables and functions. For example OSBYTE &n has no fundion in a model B or B+ but is cailed in the routine at &2517 to d'e& the current shadow setting. Also reading or writing the contents of ROMSEL at &FE30 may have undefined implications in a model B.

Worst than this however, is that certain areas in memory mapped I/C, specifically ACCCON at &PE34, are not common to all versions of host. An attempt to read ACCCON in any host except a Master produces a nonsense result. Although this is in itself harniless, the result of an attempt to write ACCCON in either a model B or B+ (as at &26E3) is totally unpredictable and will almost certainly cause an immediate crash.

The code shown here is downloaded from the 512's ROMS on either a hard or a soft break. It therefore does not vary with the host type and can be guaranteed to hang the system in a TnodeI B or B+ because of the instruction at &26E5 which attempts to re-instate ACCCON's contents as originally recorded at &251C.

In a Master 128 ACCCON is designated as read/write, but readers should be aware that in spite of this fact the CSWORD &FA routine is not reliable in a Master either. While investigating the disassembly

provides no clue as to a reason, in all the tests conducted by myself calling OSWORD &PA from DOS Plus hangs a Master 128 too!

In addition word transfers seem to be inconsistently unreliable. Single byte transfers of types 0 and I and page transfers (types 6 and 7) appear to be reliable provided that writing to ACCCON is prevented. However, word transfers from the 512 (type 2) sometimes do not function correctly, sometimes doing nothing at all (including the transfer) occasionally hanging the system.

On balance however, type two transfers probably function correctly more often than not. The fault is extremely obscure, but so far as testing has been able to determine, it appears to depend on a combination of both the host target address and the type of transfer performed the last time the routine was called.

The only consistent fact to emerge from lengthy tests is that if any specific type 2 transfer in a sequence of transfers does fail, it can be reproduced and will fail consistently unless one of the attendant conditions is changed. if this particular problem is encountered users are advised to avoid it if possible by changing the target address rather than anempting to find the cause.

&7o - LSB of parameter block in host RAM
&71 - MSB of parameter block in host RAM
&72 - storage of current paqed no~ number
&73 - Storage of current shadow setting
a74 Lsn of host RAM data address
675 - NS3 of host FIRM data address
&76 - MSS of 1en~th of data to be transferred
&77 - tse of lenqth of data to be transferred
flOT~&~- rarameters &76 and &77 are NOT in error- They
are reversed from the usual low-byte-high-byte format
Zero page 1105 variables
&F4 - romnum NOS copy of the current PtOM nuraber
Mos calls used by this code
osbyte &FrF4
SHEILA ~ty mapped I/O addresses
&FE30 - ronwel The paqe no'. select latch
&FE34 - acecon The paged ROM access control
Initia1 entry to thin code is after all other poanibilitien have been exhausted, 
by tirst the SOS. then by 6502&~sYs- 
If the call is not an OSWORD aFA control is passed to the sos default handler, 
giving the familiar 'Bad corrinand error which is passed acroas the tube as described 
in chapter 4-
2500 CLa clear carry for tube claim
2501 nad a2505 branch to oswc~ tent - alwaya
2503 flRK Contains the address of the Has
2504 nRK unknown OSWORD' default handler
&~oswotd teat
2505 alP taFA 1 15 this an OSNORD &FA?
2S07 BEQ a250C Yes - branch OSWORD_confirrw~d
2509 CMP (&2503) No - it- to default_handler
250c ST~ &70 Store low byte of paramter address
250E STY &71 store hi byte of parameter address
2510 PHA Stote A on the stack
2511 Ink &~&FB Set u~ OSBYTE 251 to read
2513 inX 40 the state of the host's currant
2515 WY &~&FF shadow/main RAM selection
2517 JSR osbyte Current settinq returned in x
2SlA STX &7a Store current shadow setting
251c LDA accoon Read contents of &FE34 in SHEILA
251r PHA Store it on the stack
-tube claim
2520 LDA jac? Load tube claim identifier (This
code pretends to be a video dine
2522 JSn tube_entry claim the tube
2525 SCC &2$20 Failed? - repeat till success
2527 WY $0 Index to para~ter 1
2529 LDA ('70) .Y Read total ni-er of parameters
2523 CMP &~&fl an - RAM access, jE paged RON access
252~ PEP Store flags - z - 0 means normal MM
252E LDA &F4 Read MOS co~y of curr- paqed flox nurter
2530 STA &72 Store in zero pa4C
2532 LDY &~&D rndex ot n~mory access byte parameter
2534 LDA (&70) ,Y Read ~mory access type byte
2536 TAX Transfer to x
253~ WY $2 Inde'r to host RAN address parameter
25S9 Ink (&7O~,Y need tsB of host memory addtess
25S3 STA &74 store in rero page base
25at INY Increment index
253E LDA &70) ,Y Read MSR of host memory address
2540 STA a75 store in zero page base
2542 PLP pnl1 flaqa stored at &2$2D
2543 BEQ a25a5 Branch on normal RAM access
2545 TXA Kernory access type byte to A
2546 pHA Store memory access type on stack
2547 nm 4&40 Isolate screen mnmOrv bit (Sm)
2549 BNE &255E Not ~ero means write screen RA)q only
254n TXA Recover access type byte aqain
254c AND &~&20 Inolate screen address bit (m~a}
254E UNE &2554 Not zero means use shadow screen
set main access
2550 rnx 40 zero in 'C
2552 EEC &2556 Branch select ram - always
-set ahadow access
2554 Wx *1 Set access for shadow screen
select rem
2556 LDA t&6c OSflr!E lOB sel. 3cr. for direct access
2558 asa osbyte on contents of 'C - 0 - rain, 1 - shadow
255a JMP '2577 Ju~ get_roTh_nun~er
255E rnA *&e4 OSBYTE 132 read top of user RAM (HIMEM)
2560 JSR osbyte ROturns X - low byte, Y - high byte
256j CPY laflO HI-i &E00o? Yes means shadow
256$ BNr &256F no - branch to shadow_test
2567 LDA #1 Load A with 1
2569 CKp &73 cor~are to current shadow setting
25~n nfl& &~554 Not equal branch to net-shadow_access
256D BEQ &2550 Branch set_main_access - a1~ays
2S6F LDA *2 Load A with 2
2571 CMP &73 Co~are to current 5hadcw setting
257S BNE &2550 Not equal - ~ranch to set_main_access
251$ BEQ &2564 Branch to set_shadow_access - always
.~et_rom nunber
2577 PM pull memory access typo trom stack
2576 TAX store in 'C
2579 AND &~&1O Isolate nOM type nunber (bit 4
2573 BNE &2565 Not zero - use clirrent no" nuriber
257D Tm Recover memory access type byte
257& Mm Isolate required RON nunber (bits 0-3)
2580 STA &F4 stare in MOS copy of ROM flo.
25B2 STA roawel Store at &FE30 in SHEILA
- RON_nnrnher set
2565 ~~Y &~&A Index at transfer lenqth paraneter
2567 InA (&70) ,Y Read LSfl of transfer lenqth
25S~ STA &77 Store in zero page
2585 INY Increment index to parameter Sn
25S0 LDA (&7O~,Y Read NSa of transfer length
Q5SE STA &76 Store in zero page
25g0 ORA &77 Check transfer length LSB NSfl - tero
2592 BNE &2596 Not zero - continue
2594 BEQ &2604 LSS = NSE - 0 means complete
2596 InA &77 Reload transter length Lse
2598 BEQ &259c Inteqral page transfer?
25SA Inc s76 No - Increment transfer length NSB
25~c my :ncrement index to flaraneter 'C
259t LDA (&70 ,Y Read transfer type (0 to 3, 6 or 7
259? PHA store transfer type on stack
25A0 IDA &7~ Reload transfer length Lsn
25~~ ~EC &25n5 It LSB - 0 transfer is whole paqsn
25A4 ILA 676 Load transfer length MSB
25A6 CMP #1 single page
25kg BNE &25n5 NC - it~s a multi-page
25AA PLA Recover tranater type from stack
25AS PRA and re-store for further time
25AC ~~~ Is it type 6 or 7 (256 byte transfer)
25AE BCC &25B5 Yes branch to get_address
2513 PTA Neither - qet transfer type
25n1 SEC Set the carry flag
25B2 SBC *6 subtract 6
25B4 PHA Store the resnit on the stack
2535 LDA &70 Load the low byte ~arareter address
25n~ CLC Clear carry
25n8 ADC #6 Add 6
25SA TAX Transfer to x
25nn LDA #0 Clear A
25an loc '71 Load the high byte parameter address
253F TAX Transfer to Y
25c0 PLA Recover the transfer type byte
2SC~ PHA and re-atore for further use
25c2 JSR tube_entry Call tube host code
25c5 LDX &77 LSB at transfer lenqth into r
25C7 PLA ~ecover transfer type
25c9 CLY 40 Clear Y
25CA CMP *0 Transfer type 0? Cl byte to host)
25cc BEQ &25EC Yes - branch to jur~~_type_0
250K CMP 41 Transfer type 1 (1 byte from host
2500 BEQ &2607 YES - branch to type_1_transfer
25D2 CMP #2 Transfer type 2 (2 bytes to host)
25D4 BEQ &261fr Yes - branch to type_2_transfer
25D6 CMP &~3 Transfer type 3 (2 bytes fror host
25DB BEQ &2e4A Yes - branch to type_a_transfer
2SDA CXP #6 ~ransfer type 6 (1 page to host
S5~C BRQ i2SEG branch to it-_type_6
2Sn~ ~~~ *7 Transfer type 7 (i paqe from host)
26E0 BEC &25E9 Branch to j~_type_7
25E2 LDA #0 must be finished
25E4 flZO a2604 indirect jump to release tube
.jump_type_ 6
25E5 JMP &2675 Long jump to type_ 6_transfer
25n9 JMP &2eA3 Long j~ to type_7 transfer
25Ec JSR &2SF4 waste some time
-type_zero transfer transfers single bytes from 512
to host at 24~secs(byte
25FF LDA tubeR3data Read data from tube register 3
25r2 STA (&74).Y Store it at indexed host address
25F4 JsR &2er4 waste some time
25F7 INC &74 Increment host address low byte
2SF~ ~~~ I If we havgn~t crossed a page boundary
25FB INC &75 else incr~nt the addrems high byte
25Fn DEx Decrement the count
25FE BNE &2SEF Finished 256 bytea? No - Re~at
2600 DEC &'' Decrenent '(SB at length
2602 BNE '25FF and go back for the next byte
2604 CMP &26nA J~ to release_tube
type_1 transfer Transfers single byte. from host to 512 at 24 usecs/byte
2607 IDA (&74 ,Y Read data frO~ host memory
2S09 STA tubea3dnta Write it to tube register S
26OC JSR &26r4 waste some time
260? INC &74 IncreTmOnt host address low byte
2611 BNE &2615 If we haven~t crossed a page boundary
2613 INC &75 Incre~nt the boat addreaa high byte
2615 ~EX and decrement the count
2616 BNE &2607 and go back for the next byte
261e DEC &7~ I Decreemnnt MSfl of ~enqth
261k mm &2c07 I Not tern - not finished
261c JMP Jump to release_tubO
type_2 transfer Transfers words from 512
to host at 26~secs~word
261r JsR &26F4 Waste some time
2622 LDA tuben3data Read data from tube register 3
2625 STA (&74) ,Y Store it at indexed boat address
2627 INC &74 Increment host address low byte
2629 ~~E &2620 If we haven't crossed a page boundary
262E INC &75 Incre~nt the host addresss high byte
262D NOP Delay for 2 cycles
262F NOP Delay for 2 cycles
262r tnA t~benSdata Read data fr~ tube register 3
2632 STA (s74) ,Y Store it at indexed host address
2634 INC &74 morement host address low byte
2636 BNE i26aA If we haven~t crossed a page boundary
26a0 INC &75 Increment the high address byte
263A JSR &26F3 waste 12 clock cycles
263D NOP Delay for 2 cycles
263E NOP Delay for 2 cycles
263F DEX decrement the count
2640 DEX decrement the count
2641 BNE &2622 Not zero? branch for next 2 bytes
2643 DEC 576 else decrement the MSfl of length
2645 BNE &2622 Not zero? branch fro next 2 bytes
2647 JMP a26flA Jua~ to release_tube
type_3 transfer ?!ransfers words frOTh host
to 512 at 2~jtseca~word
264A LDA (&74},Y Read data tr~ host rn-cry
264C STA tuben3data write it to tube register 3
2e4r INC &74 Increment host address low byte
2~5l DEC &2656 tf we haven't croaned a ~age boundary
2653 NOP Delay for 2 cycles
2654 B~R S265e Branch if page boundary crossed
2656 INC &75 rncrement the host address high byte
2656 ~~A a73 waste 5 cycles (loads shadow setting
265A ~~A (&74) ,Y Load tram indexed host a-cry
265C STA tubeaSdata write to tube regAster S
265? INC '74 Increment the low address byte
2661 BEQ &2666 If we haven't crossed a paqe boundary
2663 NOP Delay for 2 cycles
2664 BNE &2665 If "C haven't croased a page boundary
2666 INC &75 else increment the hi~h adarcan byte
2666 JSR &26F3 waste 12 clock cycles
266n DEX deore~nt the count
2G6c DEX decretment the count
266D ~~~ &264A Not zero? branch for next 2 bytes
266F DEC &76 else decrement the Msn of lenqth
2S71 BNE &2e4A Not zero? branch for next 2 bytes
2S7~ DEC &2EDA Branch to release_tube
-type_6_transfer Transfers 256 byte block from 512 to host at 1OLtnacs~byte
2675 3Sfl &26S4 waste some time
2678 LDA tube~data Read data frorfl tube register 3
267B STA (&74),Y store it at indexed host address
2S7n NOP nelay for 2 clock cycles
267E NOP Delay for 2 clock cycles
SelF NOP Delay for 2 clock cycles
2680 INY Increment the index
neal BNE &267a Branch get_tube_byte if < 256 bytes
2683 CPX 40 Have we finished?
2605 BNE &269a No - Repeat for next page
2687 DEC &76 Decrement MSS of length
2689 BEC ~26DA Branch to release_tube
- RspeRTSaae
Q6aB JSR &26cE Incr~nt 512 page address
266E LDA 46
2690 JMP &259r at- to set_transfer_type
2693 DEC '76 decrement MSB of length
2695 LDA &16 load LSB of length
2697 CMP Si Is this the last page?
2e99 BNE &266n No - branch to re~eRTSage
269B ASR &2sCe Incr~nt 512 page address
269E LDA *0 set type zero transfer
26A0 JMP &259F Jmp to set_transfer_type
-type_7 transfer
26A3 INA (&74 ,Y Read data fr~ hont netftory
26AS SXA tubensaeta write it to tube register 3
26A6 NOP Delay for 2 clock cycles
26A9 NOP Delar for 2 clock cycles
26AA NOP Delay for 2 clock cycles
26As INY Incrgrntnt index
26A0 BNE $26A3 branch type_7_transfer if C 256 bytea
26AE CPX to Is lenqth LSB - zero?
2630 ~~~ &26nE no - branch decrement_length_mb
26n2 DEC '76 Decrement ~ISfl of length
26n4 BEQ &2~DA If c~lnt, branch to release_tube
2636 JSR &2~cE Increment 512 page address
26ns LDA &~7 set transter type 7
2633 JMP ~259F ~ to set_transfer_type
26~~ BEc &76 decrement MSB of length
26C0 LDA S1~ Load MSB of lenqth
26C2 CMP *1 ra this the last page?
26C6 JSR &26CE Increment 512 page address
aec; LDA 41 Set transfer type 1
26CR JMP &259F JL- to set_transfer_type
increment_512_offset	Increments the MSB of 512's offset
			and the host adeirean by one page
26CR INC &75		Increments the host address high byte
QEDO INY #7		load index to parameter block
26D2 LDA (~7O~.Y	Load MSB of 512 address
26n4 CLC Clear carry
26n5 ~~~ Add 1 page to 512's segment offset
26n7 STA c'70}.Y Store at MSB of 512 offset address
2GD9 RTS Return
release tube
26DA IDA &a87 Load A for tube release
26Dc JSR tube_entry Call tube host code
26Dr LDA &72 Load original current no.' n-er
26E1 CMP xs it consistent with NOS?
26E3 BEQ &26eA Yes it~s OK - leave it
26E5 STA &r4 No - restore ~40S copy of ROM ni-er
26E7 STA roTRSel and restore ~FE3O in sHErn&
26~A PLA Recover contents of ACCOON
26~~ STA accoon and store at &FE34 in SHEIUL
2EEE ~~X 70 Restore x
26F0 ~~Y all aestote Y
26F2 PEA Restore A
26F3 RTS exit
26F4 JSR ~2Sr3 Occupies 24 clock cycles in all
~ End of OSWO~ &FA code ***tt******t****r,***