ProDOS 203 Source code

This commit is contained in:
Rémy GIBERT 2019-04-29 22:36:58 +02:00
parent 9ec843b36e
commit 888438fb0b
16 changed files with 18624 additions and 0 deletions

View File

@ -0,0 +1,71 @@
NEW
AUTO 3,1
* object code = cclock_0
* Cortland clock driver
* $2F80-$2FFC moved to $D742
ofsC .EQ cclock_0-tclk_in offset to Cortland clock org
cclock_0 SHORT I,M 8 bit mode.
lda statereg state register.
sta savestate save for restore after tool call.
and #$CF clear the read/write aux memory bits.
sta statereg make it real
clc set e = 0 to set native mode
xce
LONG I,M 16 bit mode.
lda #$0000 zero out result space.
pha push 4 words for hex time result
pha
pha
pha
_ReadTimeHex
SHORT M back to 8 bit to get results from stack
lda savestate restore state register
sta statereg
pla pull off seconds and ignore
pla
sta p8time minutes
pla
sta p8time+1 hours
pla year
H2FB1 cmp #100 out of range?
bcc H2FB9 no, go ahead and store
sbc #$64 else put back in range.
bra H2FB1 try again
H2FB9 sta p8date+1 year
pla
inc a increment day for Prodos 8 format.
sta p8date day
pla month
inc a increment month for Prodos 8 format.
asl a shift month as it sits in between
asl a the year and day values.
asl a
asl a
asl a
ora p8date put all but the top bit of month
sta p8date value in the day byte.
rol p8date+1 put hi bit of month in low bit of year
pla pull of unused byte
pla pull off day of week. stack now clean.
sec go back to emulation mode
xce to continue with Prodos 8
rts
savestate .EQ *-ofsC
dc h'00' state of the state register
dc c'JIMJAYKERRY'
dc h'26' ampersand (Orca assembler doesn't like)
dc c'MIKE'
dc h'0000000000000000' pad 0's until length
dc h'0000000000000000' of driver = 125 bytes.
dc h'000000000000'
cclk_end .EQ * end of obj cclock_0.
dc h'000000' pad to page boundary
LONGI OFF
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.CCLK
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,960 @@
NEW
AUTO 3,1
* disk ii driver. object code = xrw_0
* critical timing requires page bound considerations for code and data.
* virtually the entire 'write' routine must not cross page boundaries.
* critical branches in the 'write', 'read', and 'read adr' subroutines
* which must not cross page boundaries are noted in comments.
* the cld at blockio must be present to determine bank of $D000
* $5300-5A00 moved to language card bank 1 at $D000
.OR $D000
blockio cld $D8 to flag language card bank 1 (main)
jsr rsetphse
lda q7l,x turn off write enable
nop
nop
jsr docheck
bcs L5334 branch if block # is out of range
ldy #$05
L5310 asl
rol ibtrk
dey
bne L5310
asl
bcc L531C
ora #$10 adjust for upper 4 bits of track
L531C lsr
lsr
lsr
lsr
pha save sector # across call
jsr regrwts
pla
bcs L5330 if error
inc buf+1
adc #$02
jsr regrwts get 2nd half of block
dec buf+1
L5330 lda ibstat
rts
L5334 lda #$27 i/o error
sec
rts
* read/write a track/sector
regrwts ldy #$01 retry count
sty seekcnt only one recalibrate per call
sta ibsect
lda unitnum get slot # for this operation
and #$70
sta A2L
* make sure other drives in other slots are stopped
jsr chkprev
* now check if the motor is on, then start it
jsr chkdrv
php save test results
lda #$E8
sta montimeh
lda unitnum determine drive 1 or 2.
cmp iobpdn same drive used before ?
sta iobpdn save it for next time.
php keep results of compare.
asl a get drive # into carry.
lda motoron,x turn on the drive.
bcc L5362 branch if drive 1 selected.
inx select drive 2.
L5362 lda drv0en,x
plp was it the same drive ?
beq L5372 yes.
plp indicate drive off by setting z-flag.
ldy #$07 150ms delay before stepping.
L536B jsr mswait
dey
bne L536B
php now zero flag set.
L5372 lda A4L make sure this command needs seeking.
beq L537C branch if status check.
lda ibtrk get destination track
jsr myseek and go to it.
* now at desired track. was the motor already on ?
L537C plp was motor on ?
bne L538E if so, don't wait.
* motor was off, wait for it to speed up
L537F lda #$01 wait 100us for each count in montime
jsr mswait
lda montimeh
bmi L537F count up to 0000
* motor should be up to speed,
* if it looks stopped then the drive is not present
jsr chkdrv is drive present ?
beq hndlerr branch if no drive
* now check: if it is not the format disk command,
* locate the correct sector for this operation
L538E lda A4L get command #
beq L53FD if 0 then status command
lsr a set carry = 1 for read, 0 for write.
bcs L5398 must prenibblize for write
jsr prenib16
L5398 ldy #$40 64 retries
sty retrycnt
L539D ldx A2L get slot #.
jsr rdadr16 read next address field.
bcc L53BE branch if read ok.
L53A4 dec retrycnt one less chance.
bpl L539D branch to retry.
lda #$27 anticipate a bad drive error.
dec seekcnt can only recalibrate once.
bne hndlerr
lda curtrk
pha save track
asl
adc #$10 pretend track is 8 > curtrk
ldy #$40
sty retrycnt reset retries to 64 max.
bne L53CC always.
* have now read an address field. make sure this is
* the correct track, sector and volume.
L53BE ldy track check track
cpy curtrk
beq L53D5 ok
* recalibrating from this track
lda curtrk preserve destination track
pha
tya
asl a
L53CC jsr settrk
pla
jsr myseek
bcc L539D always taken, go recalibrate
* drive is on right track, check volume mismatch
L53D5 lda sect is this the right sector ?
cmp ibsect
bne L53A4 no, try another sector.
lda A4L read or write ?
lsr the carry will tell.
bcc L53F4 branch if write
jsr read16
bcs L53A4 if bad read
L53E7 lda #$00
dc h'D0' bne branch never taken (skip 1 byte)
hndlerr sec
sta ibstat error #
ldx A2L slot offset
lda motoroff,x turn off
rts
L53F4 jsr write16 write nibbles
statdne .EQ *-ofsD
bcc L53E7 if no errors.
lda #$2B disk write protected.
bne hndlerr always
L53FD ldx A2L
lda q6h,x test for write protected
lda q7l,x
rol a write protect-->carry-->bit 0=1
lda q6l,x keep in read mode
jmp statdne
myseek .EQ *-ofsD
asl a assume two phase stepper
sta track save destination track * 2
jsr alloff turn all phases off to be sure.
jsr drvindx get index to previous track
lda iobpdn,x for current drive.
sta curtrk current position.
lda track where to go next.
sta iobpdn,x
jsr seek move head there
alloff .EQ *-ofsD
ldy #$03 turn off all phases before returning.
L5427 tya (send phase in acc)
jsr clrphase carry clear, phases should be turned off
dey
bpl L5427
lsr curtrk divide back down
clc
rts
* fast seek subroutine
*
* on entry:
* x = slot# times $10
* acc = desired half-track (single phase)
* curtrk = current halftrack
*
* on exit:
* a,y = uncertain
* x = undisturbed
* curtrk & trkn = final halftrack.
* prior = prior halftrack if seek was required.
* montimel,h are incremented by the # of 100us quantums required by
* seek for motor on time overlap.
*
* variables used: curtrk, trkn, countn, prior, A2L, montimel, montimeh
seek .EQ *-ofsD
sta trkn save target track.
cmp curtrk on desired track ?
beq L5487 yes, energize phase and return
lda #$00
sta trkcnt half track count.
L5440 lda curtrk save curtrk for delayed turnoff
sta prior
sec
sbc trkn delta-tracks.
beq L5483 branch if curtrk = destination
bcs mvout move out, not in.
eor #$FF calculate tracks to go.
inc curtrk increment current track (in).
bcc L545A always taken.
mvout adc #$FE calculate tracks to go.
dec curtrk decrement current track (out).
L545A cmp trkcnt
bcc L5462 and 'tracks moved'
lda trkcnt
L5462 cmp #$09
bcs L5468 if trkcnt > 8 then leave y alone (y=8)
tay else set acceleration index in y
sec
L5468 jsr setphase
lda ontable,y for 'ontime'
jsr mswait (100us intervals)
lda prior
clc for phaseoff
jsr clrphase turn off prior phase
lda offtable,y then wait 'offtime'
jsr mswait (100us intervals)
inc trkcnt count of 'tracks moved'
bne L5440 always taken
L5483 jsr mswait settle 25 msec
clc set for phase off
setphase .EQ *-ofsD
L5487 lda curtrk get current track
clrphase .EQ *-ofsD
and #$03 mask for 1 of 4 phases
rol a double for phaseon/off index
ora A2L
tax
lda phaseoff,x turn on/off one phase
ldx A2L restore x reg
rts and return
* 7-bit to 6-bit 'deniblize' table (16-sector format)
*
* valid codes are $96 to $FF only. codes with more than one pair of
* adjacent zeroes or with no adjacent ones (except bit 7) are excluded.
*
* nibles in the ranges of $A0-$A3, $C0-$C7, $E0-$E3 are used for
* other tables since no valid nibles are in these ranges.
dnibl .EQ *-ofsD aligned to page boundary minus $96
dc h'0004FFFF080CFF10'
dc h'1418'
twobit3 .EQ *-ofsD used in fast prenib as lookup for
dc h'008040C0FFFF' 2-bit quantities.
dc h'1C20FFFFFF24282C'
dc h'3034FFFF383C4044'
dc h'484CFF5054585C60'
dc h'6468'
twobit2 .EQ *-ofsD used in fast prenib.
dc h'00201030'
endmrks .EQ *-ofsD table using 'unused' nibbles:
dc h'DEAAEBFF' ($C4,$C5,$C6,$C7)
dc h'FFFFFF6CFF70'
dc h'7478FFFFFF7CFFFF'
dc h'8084FF888C909498'
dc h'9CA0'
twobit1 .EQ *-ofsD used in fast prenib.
dc h'0008040CFFA4'
dc h'A8ACFFB0B4B8BCC0'
dc h'C4C8FFFFCCD0D4D8'
dc h'DCE0FFE4E8ECF0F4'
dc h'F8FC'
* 6-bit to 2-bit conversion tables:
*
* dnibl2 abcdef-->0000FE
* dnibl3 abcdef-->0000DC
* dnibl4 abcdef-->0000BA
* origin = $D200 (page boundary)
* page align the following tables:
dnibl2 .EQ *-ofsD
dc h'00'
dnibl3 .EQ *-ofsD
dc h'00'
dnibl4 .EQ *-ofsD
dc h'00'
* 6-bit to 7-bit nibl conversion table
*
* codes with more than one pair of adjacent zeroes
* or with no adjacent ones (except B7) are excluded.
nibl .EQ *-ofsD
dc h'960200'
dc h'00970100009A0300'
dc h'009B0002009D0202'
dc h'009E0102009F0302'
dc h'00A6000100A70201'
dc h'00AB010100AC0301'
dc h'00AD000300AE0203'
dc h'00AF010300B20303'
dc h'00B3000002B40200'
dc h'02B5010002B60300'
dc h'02B7000202B90202'
dc h'02BA010202BB0302'
dc h'02BC000102BD0201'
dc h'02BE010102BF0301'
dc h'02CB000302CD0203'
dc h'02CE010302CF0303'
dc h'02D3000001D60200'
dc h'01D7010001D90300'
dc h'01DA000201DB0202'
dc h'01DC010201DD0302'
dc h'01DE000101DF0201'
dc h'01E5010101E60301'
dc h'01E7000301E90203'
dc h'01EA010301EB0303'
dc h'01EC000003ED0200'
dc h'03EE010003EF0300'
dc h'03F2000203F30202'
dc h'03F4010203F50302'
dc h'03F6000103F70201'
dc h'03F9010103FA0301'
dc h'03FB000303FC0203'
dc h'03FD010303FE0303'
dc h'03FF'
* nibl buffer 'nbuf2' must be on a page boundary !!!
nbuf2 .EQ *-ofsD nibl buffer for read/write of low
ds 86 2-bits of each byte.
ibtrk .EQ *-ofsD
dc h'00'
ibsect .EQ *-ofsD
dc h'00'
ibstat .EQ *-ofsD
dc h'00'
iobpdn .EQ *-ofsD
dc h'00'
curtrk .EQ *-ofsD
dc h'00'
dc h'00000000000000' for slots 1 thru 7
dc h'00000000000000' drives 1 & 2
retrycnt .EQ *-ofsD
dc h'00'
seekcnt .EQ *-ofsD
dc h'00'
trkcnt .EQ *-ofsD halftracks moved count.
countn .EQ *-ofsD 'must find' count.
last .EQ *-ofsD 'odd bit' nibls.
dc h'00'
csum .EQ *-ofsD used for address header cksum
dc h'00'
csstv .EQ *-ofsD
dc h'00'
sect .EQ *-ofsD
dc h'00'
track .EQ *-ofsD
montimel .EQ *-ofsD
dc h'00'
montimeh .EQ *-ofsD also 'volume'
dc h'00'
prior .EQ *-ofsD
dc h'00'
trkn .EQ *-ofsD
dc h'00'
* phase on, off time tables
* in 100 usec intervals (seek)
ontable .EQ *-ofsD
dc h'013028'
dc h'24201E1D1C1C'
offtable .EQ *-ofsD
dc h'702C'
dc h'26221F1E1D1C1C'
* mswait subroutine
*
* delays a specified number of 100 usec intervals for motor timing.
* on entry: acc holds number of 100 usec intervals to delay.
* on exit: acc = 0, x = 0, y = unchanged, carry set.
* montimel, montimeh are incremented once per 100 usec interval
* for motor on timing.
mswait .EQ *-ofsD
L5685 ldx #$11 delay 86 usec
L5687 dex
bne L5687
inc montimel
bne L5692
inc montimeh
L5692 sec
sbc #$01
bne L5685
rts
* read address field subroutine (16-sector format)
*
* reads volume, track and sector.
* on entry: x = slot# times $10, read mode (q6l,q7l)
* on exit: carry set if error, else if no error:
* acc=$AA, y=0, x=unchanged, carry clear,
* ccstv contains chksum,sector,track & volume read.
* uses temps: count,last,csum & 4 bytes at ccstv
* expects: original 10-sector normal density nibls (4-bit) odd bits then even.
* observe 'no page cross' warnings on some branches !!!
rdadr16 .EQ *-ofsD
ldy #$FC
sty countn 'must find' count
L569D iny
bne L56A5 low order of count.
inc countn (2k nibles to find address mark
beq rderr else error)
L56A5 lda q6l,x read nibl
bpl L56A5 *** no page cross ***
L56AA cmp #$D5 address mark 1 ?
bne L569D
nop nibl delay
L56AF lda q6l,x
bpl L56AF *** no page cross ***
cmp #$AA address mark 2 ?
bne L56AA if not, is it address mark 1 ?
ldy #$03 index for 4 byte read
L56BA lda q6l,x
bpl L56BA *** no page cross ***
cmp #$96 address mark 3 ?
bne L56AA if not, is it address mark 1
sei no interrupts until address is tested.
lda #$00 init checksum
L56C6 sta csum
L56C9 lda q6l,x read 'odd bit' nibl
bpl L56C9 *** no page cross ***
rol a align odd bits, '1' into lsb.
sta last save them.
L56D2 lda q6l,x read 'even bit' nibl
bpl L56D2 *** no page cross ***
and last merge odd and even bits.
sta csstv,y store data byte.
eor csum
dey
bpl L56C6 loop on 4 data bytes.
tay if final checksum non-zero,
bne rderr then error.
L56E6 lda q6l,x first bit-slip nibl
bpl L56E6 *** no page cross ***
cmp #$DE
bne rderr
nop delay
L56F0 lda q6l,x second bit-slip nible
bpl L56F0 *** no page cross ***
cmp #$AA
bne rderr
clc normal read ok
rts
rderr sec
rts
* read subroutine (16-sector format)
*
* reads encoded bytes into nbuf1 and nbuf2.
* first reads nbuf2 high to low, then nbuf1 low to high.
* on entry: x=slot# times $10, read mode (q6l,q7l)
* on exit: carry set if error, else if no error:
* acc=$AA, x=unchanged, y=0, carry clear.
* observe 'no page cross' on some branches !!
read16 .EQ *-ofsD
txa get slot #
ora #$8C prepare mods to read routine.
sta rd4+1 warning: the read routine is
sta rd5+1 self modified !!
sta rd6+1
sta rd7+1
sta rd8+1
lda buf modify storage addresses also
ldy buf+1
sta ref3+1
sty ref3+2
sec
sbc #$54
bcs L571F branch if no borrow
dey
L571F sta ref2+1
sty ref2+2
sec
sbc #$57
bcs L572B branch if no borrow
dey
L572B sta ref1+1
sty ref1+2
ldy #$20 32 tries to find
L5733 dey
beq L576D branch if can't find data header marks
L5736 lda q6l,x
bpl L5736
L573B eor #$D5 1st data mark
bne L5733
nop delay
L5740 lda q6l,x
bpl L5740
cmp #$AA 2nd data mark.
bne L573B if not, check for 1st again
nop
L574A lda q6l,x
bpl L574A
cmp #$AD 3rd data mark
bne L573B if not, check for data mark 1 again
ldy #$AA
lda #$00
L5757 sta pcl use z-page for keeping checksum
rd4 .EQ *-ofsD
L5759 ldx q6l+$60 warning: self modified
bpl L5759
lda dnibl-$96,x
sta nbuf2-$AA,y save the two-bit groups in nbuf.
eor pcl update checksum.
iny next position in nbuf.
bne L5757 loop for all $56 two-bit groups.
ldy #$AA now read directly into user buffer.
bne L5772 always taken.
L576D sec error
rts
ref1 .EQ *-ofsD
L576F sta $1000,y warning: self modified
rd5 .EQ *-ofsD
L5772 ldx q6l+$60 warning: self modified
bpl L5772
eor dnibl-$96,x get actual 6-bit data from dnib table.
ldx nbuf2-$AA,y get associated two-bit pattern
eor dnibl2,x and combine to form whole byte.
iny
bne L576F loop for $56 bytes.
pha save for now, no time to store...
and #$FC strip low bits.
ldy #$AA prepare for next $56 bytes
rd6 .EQ *-ofsD
L5788 ldx q6l+$60 warning: self modified
bpl L5788
eor dnibl-$96,x
ldx nbuf2-$AA,y
eor dnibl3,x
ref2 .EQ *-ofsD
sta $1000,y warning: self modified
iny
bne L5788 loop unil this group of $56 read
rd7 .EQ *-ofsD
L579C ldx q6l+$60 warning: self modified
bpl L579C
and #$FC
ldy #$AC last group is $54 long
L57A5 eor dnibl-$96,x
ldx nbuf2-$AC,y
eor dnibl4,x combine to form full byte
ref3 .EQ *-ofsD
sta $1000,y warning: self modified
rd8 .EQ *-ofsD
L57B1 ldx q6l+$60 warning: self modified
bpl L57B1
iny
bne L57A5
and #$FC
eor dnibl-$96,x checksum ok ?
bne L57CC error if not.
ldx A2L test end marks.
L57C2 lda q6l,x
bpl L57C2
cmp #$DE
clc
beq L57CD branch if good trailer
L57CC sec
L57CD pla place last byte into user buffer
ldy #$55
sta (buf),y
rts
* set the slot dependent track location
settrk .EQ *-ofsD
jsr drvindx get index to drive #
sta iobpdn,x
rts
* determine if motor is stopped
*
* if stopped, controller's shift register will not be changing.
* return y = 0 and zero flag set if it is stopped.
chkdrv .EQ *-ofsD
ldx A2L
chkdrv0 .EQ *-ofsD
ldy #$00 init loop counter.
L57DE lda q6l,x read the shift register.
jsr ckdrts delay
pha
pla more delay.
cmp q6l,x has shift reg changed ?
bne L57F0 yes, motor is moving.
lda #$28 anticipate error.
dey no, dec retry counter
bne L57DE and try 256 times.
ckdrts .EQ *-ofsD
L57F0 rts
drvindx .EQ *-ofsD
pha preserve acc across call
lda A4L+1
lsr a
lsr a
lsr a
lsr a
cmp #$08
and #$07
rol a
tax index to table.
pla restore acc
rts
* write subroutine (16 sector format)
*
* writes data from nbuf1 and buf. first nbuf2, high to low then direct
* from (buf), low to high. assumes 1 usec cycle time. self modified code !!
*
* on entry: x = slotnum times 16
*
* on exit: carry set if error (write protect violation).
* if no error, acc=uncertain, x=unchanged, y=0, carry clear.
write16 .EQ *-ofsD
sec anticipate write protect error
lda q6h,x
lda q7l,x sense write protect flag
bpl L580C
jmp wexit exit if write protected
* timing is critical. a one micro-second cycle time is assumed.
* number in () is how many micro-seconds per instruction or subroutine
L580C lda nbuf2
sta pcl
lda #$FF sync data.
sta q7h,x (5) goto write mode
ora q6l,x (4)
ldy #$04 (2) for five nibls
nop (2)
pha (3)
pla (4)
wsync pha (3) exact timing.
pla (4) exact timing.
jsr wnibl7 (13,9,6) write sync.
dey (2)
bne wsync (3-) must not cross page !
lda #$D5 (2) 1st data mark
jsr wnibl9 (15,9,6)
lda #$AA (2) 2nd data mark
jsr wnibl9 (15,9,6)
lda #$AD (2) 3rd data mark
jsr wnibl9 (15,9,6)
tya (2) zero checksum
ldy #$56 (2) nbuf2 index
bne L583D (3) branch always
* total time in this write byte loop must = 32us !!!
L583A lda nbuf2,y (4) prior 6-bit nibl
L583D eor nbuf2-1,y (5) xor with current
tax (2) index to 7-bit nibl
lda nibl,x (4) must not cross page boundary
ldx A2L (3) restore slot index
sta q6h,x (5) store encoded byte
lda q6l,x (4) handshake
dey (2)
bne L583A (3-) must not cross page boundary
* end of write byte loop
lda pcl (3) get prior nibl (from nbuf2)
wrefd1 .EQ *-ofsD
ldy #$00 (2) warning: load value modified by prenib.
wrefa1 .EQ *-ofsD
L5853 eor $1000,y (4) warning: address modified by prenib.
and #$FC (2) strip low 2 bits
tax (2) index to nibl table
lda nibl,x (4)
wrefd2 .EQ *-ofsD
ldx #$60 (2) warning: value modified by prenib.
sta q6h,x (5) write nibl
lda q6l,x (4) handshake
wrefa2 .EQ *-ofsD
lda $1000,y (4) prior nibl. warning: address modified by prenib.
iny (2) all done with this page ?
bne L5853 (3-) loop until page end.
lda pch (3) get next (precalculated & translated) nibl.
beq L58C0 (2+) branch if code written was page aligned.
lda A2H (3) get byte address of last byte to be written.
beq L58B3 (2+) branch if only 1 byte left to write.
lsr a (2) test for odd or even last byte (carry set/clear)
lda pch (3) restore nibl to acc.
sta q6h,x (5)
lda q6l,x (4)
lda A1L (3) = byte 0 of 2nd page xor'd with byte 1 if
nop (2) above test set carry.
iny (2) y=1
bcs L5899 (2+) branch if last byte to be odd.
wrefa3 .EQ *-ofsD
L5881 eor $1100,y (4) warning: address modified by prenib.
and #$FC (2) strip low 2 bits.
tax (2) index to nibl table
lda nibl,x (4) get nibl
wrefd3 .EQ *-ofsD
ldx #$60 (2) restore slot index. warning: modified by prenib
sta q6h,x (5)
lda q6l,x (4)
wrefa4 .EQ *-ofsD
lda $1100,y (4) warning: modified by prenib
iny (2) got prior nibl, point to next
wrefa5 .EQ *-ofsD
eor $1100,y (4) warning: modified by prenib
L5899 cpy A2H (3) set carry if this is the last nibl
and #$FC (2) strip low 2 bits
tax (2)
lda nibl,x (4)
wrefd4 .EQ *-ofsD
ldx #$60 (2) restore slot. warning: modified by prenib
sta q6h,x (5)
lda q6l,x (4)
wrefa6 .EQ *-ofsD
lda $1100,y (4) get prior nibl. warning: modified by prenib
iny (2)
bcc L5881 (3-) branch if not the last.
bcs L58B1 (3) waste 3 cycles, branch always.
L58B1 bcs L58C0 (3) branch always.
L58B3 lda |pch (4) absolute reference to zero page
sta q6h,x (5)
lda q6l,x (4)
pha (3) waste 14 micro-seconds total
pla (4)
pha (3)
pla (4)
L58C0 ldx A1H (3) use last nibl (anded with $FC) for checksum
lda nibl,x (4)
wrefd5 .EQ *-ofsD
ldx #$60 (2) restore slot. warning: modified by prenib
sta q6h,x (5)
lda q6l,x (4)
ldy #$00 (2) set y = index end mark table.
pha (3) waste another 11 micro-seconds
pla (4)
nop (2)
nop (2)
L58D3 lda endmrks,y (4) dm4, dm5, dm6 and turn off byte.
jsr wnibl (15,6) write it
iny (2)
cpy #$04 (2) have all end marks been written ?
bne L58D3 (3) if not.
clc (2,9)
wexit .EQ *-ofsD
lda q7l,x out of write mode
lda q6l,x to read mode.
rts return from write.
* 7-bit nibl write subroutines
wnibl9 .EQ *-ofsD
clc (2) 9 cycles, then write.
wnibl7 .EQ *-ofsD
pha (3) 7 cycles, then write.
pla (4)
wnibl .EQ *-ofsD
sta q6h,x (5) nibl write
ora q6l,x (4) clobbers acc, not carry
rts (6)
* preniblize subroutine (16 sector format)
*
* converts 256 bytes of user data in (buf) into 6 bit nibls in nbuf2.
* high 6 bits are translated directly by the write routines.
*
* on entry: buf is 2-byte pointer to 256 bytes of user data.
*
* on exit: a,x,y undefined. write routine modified to do direct conversion
* of high 6 bits of user's buffer data.
prenib16 .EQ *-ofsD
lda buf self-modify the addresses because of
ldy buf+1 the fast timing required.
clc all offsets are minus $AA.
adc #$02 the highest set is buf+$AC.
bcc L58FA branch if no carry,
iny otherwise add carry to high address.
L58FA sta prn3+1 self mod 3
sty prn3+2
sec
sbc #$56 middle set is buf+$56.
bcs L5906 branch if no borrow,
dey otherwise deduct from high.
L5906 sta prn2+1 self mod 2
sty prn2+2
sec
sbc #$56 low set is exactly buf
bcs L5912
dey
L5912 sta prn1+1 self mod 1
sty prn1+2
ldy #$AA count up to 0.
prn1 .EQ *-ofsD get byte from lowest group.
L591A lda $1000,y warning: self modified.
and #$03 strip high 6 bits.
tax index to 2 bit equivalent.
lda twobit1,x
pha save pattern
prn2 .EQ *-ofsD get byte from middle group.
lda $1056,y warning: self modified.
and #$03
tax
pla restore pattern.
ora twobit2,x combine 2nd group with 1st.
pha save new pattern.
prn3 .EQ *-ofsD get byte from highest group.
lda $10AC,y warning: self modified.
and #$03
tax
pla restore new pattern
ora twobit3,x and form final nibl.
pha
tya
eor #$FF
tax
pla
sta nbuf2,x save in nibl buffer.
iny inc to next set.
bne L591A loop until all $56 nibls formed.
ldy buf now prepare data bytes for write16 subr.
dey prepare end address.
sty A2H
lda buf
sta wrefd1+1 warning: the following storage addresses
beq L595F starting with 'wref' are refs into code
eor #$FF space, changed by this routine.
tay index to last byte of page in (buf).
lda (buf),y pre-niblize the last byte of the page
iny with the first byte of the next page.
eor (buf),y
and #$FC
tax
lda nibl,x get disk 7-bit nible equivalent.
L595F sta pch
beq L596F branch if data to be written is page
lda A2H aligned. check if last byte is even
lsr a or odd address. shift even/odd -> carry.
lda (buf),y if even, then leave intact.
bcc L596D branch if odd.
iny if even, then pre-xor with byte 1.
eor (buf),y
L596D sta A1L save result for write routine.
L596F ldy #$FF index to last byte of data to write.
lda (buf),y to be used as a checksum.
and #$FC strip extra bits
sta A1H and save it.
ldy buf+1 now modify address references to
sty wrefa1+2 user data.
sty wrefa2+2
iny
sty wrefa3+2
sty wrefa4+2
sty wrefa5+2
sty wrefa6+2
ldx A2L and lastly, index references to
stx wrefd2+1 controller.
stx wrefd3+1
stx wrefd4+1
stx wrefd5+1
rts
chkprev .EQ *-ofsD
eor iobpdn same slot as last ?
asl a
beq L59BD
lda #$01
sta montimeh
L59A6 lda iobpdn
and #$70
tax
beq L59BD branch if no previous ever (boot only).
jsr chkdrv0 check if previous drive running.
beq L59BD branch if stopped.
lda #$01 delay
jsr mswait
lda montimeh
bne L59A6
L59BD rts
rsetphse .EQ *-ofsD
lda unitnum get unit number.
and #$7F mask off high bit.
tax
* clear all the phases and force read mode
lda phaseoff+0,x make sure all motor phases are off.
lda phaseoff+2,x
lda phaseoff+4,x
lda phaseoff+6,x
rts
docheck .EQ *-ofsD
lda A4L command #.
cmp #$04 is the command allowed ?
bcs L59E6 if not.
lda bloknml
ldx bloknml+1
stx ibtrk calculate block's track and sector.
beq L59E8 branch if block # is in range,
dex else test further.
bne L59E6 taken if bad range.
cmp #$18 must be < $118
bcc L59E8 then ok.
L59E6 sec error.
rts
L59E8 clc
rts end of obj xrw_0
dc h'0000' pad bytes to $D6EC (pathbuf-$14)
* variables used by mli for smartport interface
spstatlist .EQ *-ofsD ref pathbuf-$14
dc h'00000000' smartport status list buffer
spunit .EQ *-ofsD ref pathbuf-$10
dc h'0000000000000000' smartport unit numbers
dc h'0000000000000000'
* pathname buffer starts at this page boundary (pathbuf = $D700)
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.DISKII
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

192
ProDOS.203/ProDOS.S.GP.txt Normal file
View File

@ -0,0 +1,192 @@
NEW
AUTO 3,1
* object code = mli_1
* global page
ofsG .EQ H2E00-MLI offset to global org
H2E00 jmp mlient1 $2E00-2EFF moved to $BF00
jspare .EQ *-ofsG
jmp jspare will be changed to point to dispatcher.
clockv .EQ *-ofsG P8 clock vector
rts changed to jmp ($4C) if clock present.
dc i2'tclk_in' clock routine entry address.
p8errv .EQ *-ofsG error reporting hook.
jmp syserr1
sysdeath .EQ *-ofsG
jmp sysdeath1 system failure hook.
p8error .EQ *-ofsG P8 error code
dc h'00'
drivertbl1 .EQ *-ofsG device driver table 1
dc i2'nodevice' slot 0 reserved
dc i2'nodevice' s1, d1
dc i2'nodevice' s2, d1
dc i2'nodevice' s3, d1
dc i2'nodevice' s4, d1
dc i2'nodevice' s5, d1
dc i2'nodevice' s6, d1
dc i2'nodevice' s7, d1
drivertbl2 .EQ *-ofsG device driver table 2
dc i2'nodevice' slot 0 reserved
dc i2'nodevice' s1, d2
dc i2'nodevice' s2, d2
dc i2'nodevice' s3, d2
dc i2'nodevice' s4, d2
dc i2'nodevice' s5, d2
dc i2'nodevice' s6, d2
dc i2'nodevice' s7, d2
devnum .EQ *-ofsG most recent accessed device
dc h'00'
numdevs .EQ *-ofsG count (-1) active devices
dc h'FF'
devlist .EQ *-ofsG active device list
dc h'00000000000000' up to 14 units may be active
dc h'00000000000000'
dc h'00'
msb off
dc c'(C)APPLE '
mlient1 .EQ *-ofsG
php
sei
jmp mlicont
aftirq .EQ *-ofsG irq returns here.
sta ramin read/write RAM bank 1
jmp fix45 restore $45 after interrupt in LC
oldacc .EQ *-ofsG
dc h'00'
afbank .EQ *-ofsG
dc h'00'
* memory map of lower 48k. each bit represents 1 page.
* protected pages = 1, unprotected = 0
memmap .EQ *-ofsG P8 memory bitmap
dc h'C000000000000000'
dc h'0000000000000000'
dc h'0000000000000001'
* table of buffer addresses for currently open files.
* these can only be changed thru the mli call setbuf.
buftbl .EQ *-ofsG
dc h'0000' file #1
dc h'0000' file #2
dc h'0000' file #3
dc h'0000' file #4
dc h'0000' file #5
dc h'0000' file #6
dc h'0000' file #7
dc h'0000' file #8
* table of interrupt vectors. these can only be changed
* by the mli call allocate_interrupt. values of the registers
* at the time of the most recent interrupt are stored here along
* with the address interrupted.
inttbl .EQ *-ofsG interrupt table
dc h'0000' int #1
dc h'0000' int #2
dc h'0000' int #3
dc h'0000' int #4
p8areg .EQ *-ofsG A register savearea
dc h'00'
p8xreg .EQ *-ofsG X register savearea
dc h'00'
p8yreg .EQ *-ofsG Y register savearea
dc h'00'
p8sreg .EQ *-ofsG S register savearea
dc h'00'
p8preg .EQ *-ofsG P register savearea
dc h'00'
bankid .EQ *-ofsG bank ID byte (ROM/RAM)
dc h'01'
intadr .EQ *-ofsG interrupt return address
dc h'0000'
p8date .EQ *-ofsG bits 15-9=yr, 8-5=mo, 4-0=day
dc h'0000'
p8time .EQ *-ofsG bits 12-8=hr, 5-0=min, low-hi format
dc h'0000'
flevel .EQ *-ofsG current file level
dc h'00'
bubit .EQ *-ofsG backup bit disable, setfileinfo only
dc h'00'
spare1 .EQ *-ofsG used to save acc
dc h'00'
newpfxptr .EQ *-ofsG appletalk alternate prefix ptr
dc h'00'
machid .EQ *-ofsG machine ID byte
dc h'00'
rommap .EQ *-ofsG slot ROM bit map
dc h'00'
preflag .EQ *-ofsG prefix active flag
dc h'00'
mliact .EQ *-ofsG MLI active flag
dc h'00'
mliretn .EQ *-ofsG last MLI call return address
dc h'0000'
mlix .EQ *-ofsG MLI X register savearea
dc h'00'
mliy .EQ *-ofsG MLI Y register savearea
dc h'00'
* language card bank switching routines which must reside at $BFA0 because
* workstation software patches this area
HBFA0 .EQ *-ofsG
eor $E000 test for rom enable
beq L2EAA taken if ram enabled
sta romin read ROM
bne L2EB5 always
L2EAA lda bnkbyt2 for alternate ram
eor $D000 test
beq L2EB5 branch if not alternate ram
lda altram else enable alt $D000
L2EB5 pla return code
rti re-enable interrupts and return
mlicont .EQ *-ofsG
sec
ror mliact notify interrupt routines MLI active.
lda $E000 preserve language card/rom orientation
sta bnkbyt1 for proper restoration when mli exits.
lda $D000
sta bnkbyt2
lda ramin force ram card on
lda ramin with write allowed
jmp xdosmli
irqexit .EQ *-ofsG
lda bankid determine state of ram card (ROM/RAM)
irqxit0 .EQ *-ofsG
beq L2EE2 branch if ram card enabled.
bmi L2EDF branch if alternate $D000 enabled.
lsr a determine if no ram card present.
bcc L2EE7 branch if rom only system.
lda romin1 enable rom
bcs L2EE7 always taken
L2EDF lda altram enable alternate $D000
L2EE2 lda #$01 preset bankid for rom.
sta bankid (reset if ram card interrupt)
L2EE7 lda p8areg restore acc
rti exit
irqent .EQ *-ofsG this entry only used when rom
bit ramin was enabled at time of interrupt.
bit ramin
jmp irqrecev
bnkbyt1 .EQ *-ofsG
dc h'00'
bnkbyt2 .EQ *-ofsG
dc h'00'
dc h'00000000' pad to before $BFFA
dc h'04' gsos compatibility byte ($BFFA)
dc h'00' pad
dc h'00' reserved
dc h'00' version # of running interpreter
dc h'00' preserved for System Utilities
kversion .EQ *-ofsG kernal version
dc h'23' represents release 2.0.3
* end of obj mli_1
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.GP
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,77 @@
NEW
AUTO 3,1
* object code = mli_3
*
* this routine handles interrupts and is coded to reach 'lreset' precisely at
* address $FFCB (ROM rts opcode) for rom switching to function.
lanirq .EQ *-ofsR2
H2D9B pha $2D9B-2DFF moved to $FF9B-FFFF
lda accsav
sta oldacc
pla
sta accsav
pla get status register from stack
pha and put it back.
and #$10 is it a break or interrupt?
bne H2DC2 branch if break.
lda $D000 get ram bankid (LC1 = $D8, LC2=$EE)
eor #$D8 is the system active? ($D8)
beq sysactv branch if it is
lda #$FF
sysactv sta bankid
sta afbank
lda #>aftirq setup return address
pha
lda #<aftirq
pha
lda #$04 status reg with interrupt flag set
pha
H2DC2 lda #>romirq setup ROM re-entry
pha
lda #<romirq
pha
gorom .EQ *-ofsR2
sta romin hits ROM rts at $FFCB
* 'lreset' address must = $FFCB for rom switch i/o to work
lreset .EQ *-ofsR2
lda rreset+1
pha
lda rreset
pha
jmp gorom
rreset .EQ *-ofsR2
dc I2'resetv-1' rts to resetv
fix45 .EQ *-ofsR2
sta p8areg A register savearea
lda oldacc
sta accsav
lda ramin read/write RAM bank 1
lda ramin
lda afbank
jmp irqxit0
stypfx .EQ *-ofsR2 fix appletalk PFI bug
sty newpfxptr
sty preflag prefix flag
rts
stapfx .EQ *-ofsR2
sta newpfxptr
sta preflag
rts
* these 3 vectors hard-coded into processor
dc i2'nmivect' nmi handler
dc i2'lreset' reset handler
irqv .EQ *-ofsR2
dc i2'lanirq' irq handler
* end of obj mli_3
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.IRQ
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

1669
ProDOS.203/ProDOS.S.LDR.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
NEW
AUTO 3,1
* object code = ram_2
* /RAM driver (main bank portion)
* origin = $FF00
ofsR2 .EQ lcsrc-lcdest offset from ram driver org
lcsrc cld no decimal.
ldx #$0B save 13 bytes of parms
H2D03 lda A1L,x
sta a1l1,x
dex
bpl H2D03
ldx #$01
H2D0D lda passit,x save xfer vectors
sta sp1,x
dex
bpl H2D0D
lda A4L get command.
beq stat 0 = status
cmp #$04 check for command too high.
bcs ioerr if it is, i/o error
eor #$03
sta A4L 0=format, 2=read, 1=write
beq format
ldy bloknml+1 check for large block number.
bne ioerr too big.
lda bloknml block #
bmi ioerr largest block number is $7F
* at this point, control is passed to the code in the alternate 64k.
* it it used for read, write and format. after the request is completed,
* control is passed back to 'noerr'.
format lda #<ramdest card entry point
sta passit
lda #>ramdest
gocard .EQ *-ofsR2 also used by 'mainwrt'
sta passit+1
sec direction ram -> card
clv start with original zero page
jmp xfer transfer control
ioerr lda #$27
bne H2D41
lda #$2B write protect error.
H2D41 sec flags error
bcs H2D47
noerr .EQ *-ofsR2
stat lda #$00
clc
H2D47 php save status
pha and error code.
ldx #$0B restore 13 byes of parms
H2D4B lda a1l1,x
sta A1L,x
dex
bpl H2D4B
lda sp1 restore xfer parms.
bit $6060 addr $FF58 must = rts ($60) as in ROM
sta passit
lda sp1+1
sta passit+1
pla restore error code
plp and status.
rts
mainwrt .EQ *-ofsR2 transfer data to card.
sta wrcardram write to alt 48K
ldy #$00
H2D6A lda (A1L),y pointers set in card by 'setptr'
sta (A4L),y
lda (A2L),y
sta (A3L),y
dey
bne H2D6A
sta wrmainram write to main 48K.
lda #<donewrt done writing card
sta passit
lda #>donewrt
jmp gocard
sp1 .EQ *-ofsR2
dc h'0000'
a1l1 .EQ *-ofsR2 13 bytes of storage
* end of obj ram_2
r2_end .EQ *
ds $D9B-(r2_end-H2000) fill to lanirq ($FF9B see note below)
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.RAM
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,45 @@
NEW
AUTO 3,1
* object code = ram_1
*
* /RAM installer - transfer part of the driver to the aux bank
* and front part of the driver to the main bank (language card).
H2C80 ldy #$99 move $9A bytesfrom lcsrc to lcdest.
H2C82 lda lcsrc,y transfer main bank portion of driver
sta lcdest,y
dey
cpy #$FF
bne H2C82
ldx #<ramsrc set up to move aux portion of driver
stx A1L
dex
stx A2L
ldx #>ramsrc
stx A1L+1
inx
stx A2L+1
lda #<ramdest
sta A4L
lda #>ramdest ramsrc to ramdest
sta A4L+1
sec direction = to aux bank.
jsr auxmove move aux bank portion of driver.
lda #<lcdest put driver address into
sta drivertbl2+6 slot 3, drive 2.
lda #>lcdest
sta drivertbl2+7
inc numdevs count (-1) active devices
ldx numdevs
lda #$BF unit num of /RAM
sta devlist,x
rts end of obj ram_1
r1_end .EQ * end of /RAM installer
ds $D00-(r1_end-H2000) pad 0's to page boundary
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.RAMI
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,348 @@
NEW
AUTO 3,1
object code = ram_0
* /RAM driver (aux bank portion)
* this code is packed into $200 length with no room for expansion !!
* (see note at end of this obj)
* after the main /RAM routine has determined that the command is ok and the
* block to be read/written is within range, it transfers control to this
* aux /RAM routine which remaps the block requested as follows:
* request blocks 0,1: invalid
* 2: returns VDIR (card block 3)
* 3: returns BITMAP (synthesized)
* 4: returns card block 0
* $05-$5F: returns card blocks $05-$5F
* $60-$67: returns blocks $68-$7F in bank 1 of language card
* $68-$7F: returns blocks $68-$7F in bank 2 of language card
ofsR0 .EQ ramsrc-ramdest offset to /RAM driver org
ramsrc lda rd80col read 80 store
pha save for later
sta store80off turn off 80 store
ldx #$04 move the parameters for use:
L5109 lda A4L,x cmd, unit, bufptr and block (lo)
sta tcmd,x -> tcmd, tunit, R2L, R2H, R01
dex
bpl L5109
and formatflg format the volume first time
bne L514F thru, or when requested.
ldx bloknml save R01 during format.
lda #>vblock1 block to be cleared.
jsr clrbuf1 clears all buffers.
ldy #$03 format volume in 2 chunks.
L511F lda VDIR,y
sta vblock1+4,y
dey
bpl L511F
lda #$FE set last block as unusable
sta BITMAP+15 to protect vectors.
tya set bitmap bits to $FF.
ldy #$0E 15 bytes to set
L5130 sta BITMAP,y
dey
bne L5130
sty BITMAP first byte = 0.
ldy #$07 do other chunk
L513B lda access,y
sta vblock1+34,y
dey
bpl L513B
lda formatflg if 0, set to $FF
bne L51AA else exitcard.
sty formatflg y = $FF, won't format next time.
stx R01 restore R01
* use the requested block number to determine
* which routine performs the transfer
L514F asl R01 block requested -> page requested.
lda R01 get page requested.
cmp #$BF in language card ?
bcs L5163 yes, do it.
cmp #$06 bitmap ?
bne L5160
jmp tbmap yes, transfer bitmap
L5160 jmp treg else normal transfer.
* when a block between $60 and $7F is requested, it must be spirited into/from
* the language card area of the 64k card. this requires a 2 stage move:
* into the temp buffer and then to it's real destination.
L5163 tax save R1 for later.
jsr setptr get direction
php and save it.
bcs L51B8 if it's a write.
lcrd .EQ *-ofsR0
txa get R1 back
cmp #$CF which bank is it in ?
bcs L5173 in main bank.
ora #$10 in secondary bank.
bne L5179 branch always.
L5173 sta altram turn on main $D000
sta altram
L5179 sta R01 restore R1.
lda R2H save R2 for later
pha
ldx R2L
sta setaltzp use alternate zero page/stack
lda #>dbuf set R2 to dbuf
sta R2H
lda #<dbuf
sta R2L
jsr setptr set pointers
tay A > 0 from setptr
L5194 lda (A1L),y move A1,A2 to A4,A3
sta (A4L),y
lda (A2L),y
sta (A3L),y
dey
bne L5194
sta setstdzp use main zero page/stack
L51A2 stx R2L
pla restore R2
sta R2H
plp get direction.
L51AA bcs L51B5 write, done with move.
sta ramin switch in MLI part of LC
sta ramin
jsr blockdo0 read, transfer dbuf to main
L51B5 jmp exitcard
L51B8 jsr blockdo0 transfer main to dbuf.
jmp lcrd transfer dbuf to language card
* blockdo0 transfers a block between main memory and the 64k card. R1 contains
* the page address of the block in the card; R2 contains the page address of
* the block in main memory. the address in main memory is always in the
* language card, so the language card is always switched in. if cmd is 2, a
* write is done (R2->R1); if cmd is 1, a read is done (R1->R2).
blockdo0 .EQ *-ofsR0 set up R1 = dbuf
lda #>dbuf
blockdo1 .EQ *-ofsR0
sta R01
blockdo .EQ *-ofsR0
jsr setptr set pointers.
bcs L51DB it's a write.
sta wrmainram transfer buffer directly to main.
tay 0 left from setptr.
L51CC lda (A1L),y transfer A1,A2 to A4,A3
sta (A4L),y
lda (A2L),y
sta (A3L),y
dey
bne L51CC
sta wrcardram back the way it was.
donewrt .EQ *-ofsR0 mainwrt returns here
rts
L51DB lda #<mainwrt pointers set up,
sta passit pass control to main ram
lda #>mainwrt
jmp ex1 set passit+1 and transfer
* setptr is used by other routines to set up pointers and dtect read or write
setptr .EQ *-ofsR0
lda tcmd is it read or write ?
lsr a
bcs L5208 taken if write.
lda R2H destination page
sta A4L+1
sta A3L+1
lda R2L
sta A4L
sta A3L
lda R01 source page
sta A1L+1
sta A2L+1
lda #$00 source page aligned
sta A1L
sta A2L
beq L5223
L5208 lda R2H source page
sta A1L+1
sta A2L+1
lda R2L
sta A1L
sta A2L
lda R01 destination page
sta A4L+1
sta A3L+1
lda #$00 destination page aligned
sta A4L
sta A3L
L5223 inc A2L+1
inc A3L+1
rts
* tzip is called if blocks 0,1,4,5 are requested.
* on write it does nothing, on read it returns 0's.
tzip jsr clrbuf0 fill dbuf with 0's
jsr blockdo transfer the 0's
jmp exitcard and return
* clrbuf fills the buffer indicated by R01 to 0's.
* should only be called on a read or format.
clrbuf0 .EQ *-ofsR0
lda #>dbuf dbuf is temp buffer.
clrbuf1 .EQ *-ofsR0
sta R01 assign to block.
clrbuf2 .EQ *-ofsR0
jsr setptr set pointers
tay acc = 0
L523A sta (A1L),y
sta (A2L),y
dey
bne L523A
rts
* treg maps the requested block into the aux card
* so that 8k data files will be contiguous (the index
* blocks will not be placed within data).
treg .EQ *-ofsR0
cmp #$04 page 4 = vdir
bne L524A not vdir, continue
lda #$07 else transfer block 7
bne L5258
L524A cmp #$0F if any page < $F (block 8) requested,
bcc tzip it is invalid.
ldx #$00 x = # of iterations.
lda bloknml use true block #.
cmp #$5D beyond 8k blocks ?
bcc L525B no, do normal
sbc #$50 else subtract offset
L5258 jmp times2 and multiply by 2
* determine which 8k chunk it is in, place in x;
* block offset into chunk goes into y.
L525B sec
sbc #$08 block=block-6
L525E cmp #$11 if <=17 then done
bcc L5268
sbc #$11 else block=block-17.
inx iteration count.
bpl L525E should branch always
dc h'00' otherwise crash !!!
L5268 tay remainder in y
* if remainder is 1 then it's an index block:
* start index blocks at $1000,$2000...$19FF.
* if remainder is 0 then it is first data block
* in 8k chunk. page is 32 + (16 * x).
* otherwise, it is some other data block.
* page is 32 + (16 * x) + (2 * y)
cpy #$01 is it index block ?
bne L5273 no.
txa index = 2 * (8 + x)
clc
adc #$08
bne L5285 multiply by 2.
L5273 inx iteration + 1.
txa page = 2 * (16 + 8x)
asl a
asl a
asl a
asl a
sta R01
tya get offset into 8k chunk
beq L5281 if 0, no offset
dey else offset = 2 * y
tya
L5281 clc
adc R01
times2 .EQ *-ofsR0
L5285 asl a acc = 2 * acc
jsr blockdo1 store in R01 and transfer
jmp exitcard and return
* when block 3 is requested, the bitmap is returned. the real bitmap is only
* 16 bytes long; the rest of the block is synthesized. the temporary buffer
* at $800 is used to build/read a full size bitmap block.
tbmap .EQ *-ofsR0
lda #>dbuf use temp buffer as block
sta R01
jsr setptr set pointers, test read/write.
bcs L52A9 branch if it's write.
jsr clrbuf2
ldy #$0F put real bitmap there
L529B lda BITMAP,y
sta (A1L),y
dey
bpl L529B
jsr blockdo move temp buf to user buf
jmp exitcard
L52A9 jsr blockdo move user buf to temp buf
jsr setptr
ldy #$0F move temp buf to bitmap.
L52B1 lda (A4L),y (pointer set by setptr)
sta BITMAP,y
dey
bpl L52B1
jmp exitcard
formatflg .EQ *-ofsR0
dc h'00' not formatted yet
tcmd .EQ *-ofsR0
dc h'00' command
dc h'00' unit (not used)
R2L .EQ *-ofsR0
dc h'00' R2 = user buffer
R2H .EQ *-ofsR0
dc h'00'
R01 .EQ *-ofsR0
dc h'00' page requested
BITMAP .EQ *-ofsR0
dc h'00FFFFFF' blocks 0-7 used
dc h'FFFFFFFF'
dc h'FFFFFFFF'
dc h'FFFFFFFE'
VDIR .EQ *-ofsR0 start of vdir.
dc h'F3' storage type = F, name length = 3
msb off
dc c'RAM'
access .EQ *-ofsR0
dc h'C3' destroy, rename, read enabled
dc h'27' entry length
dc h'0D'
dc h'0000'
dc h'0300' block 3
dc h'7F' 128 blocks
exitcard .EQ *-ofsR0
lda ramin restore language card
lda ramin
pla get 80store
bpl L52EA 80store wasn't on
sta store80on enable 80store
L52EA jmp bypass jump around passit
passit .EQ *-ofsR0
dc h'0000'
bypass .EQ *-ofsR0
lda #<noerr set up return to noerr
sta passit
lda #>noerr
ex1 .EQ *-ofsR0
sta passit+1 also used by blockwrite
clc transfer card to main
clv use standard zeropage/stack
jmp xfer jmp back from language card.
* NOTE: the previous section of code MUST NOT use $3FE or $3FF
* since the interrupt vector must go there if aux interrupts
* are to be used. no room for expansion here !!
dc h'0000' $3FE-$3FF
* end of obj ram_0
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.RAMI
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,324 @@
NEW
AUTO 3,1
* object code = sel_0
*
* dispatcher 1 - this code org's and operates at 'dispadr' (=$1000) but
* is resident in memory at 'displc2' (=$D100) in the alternate 4k bank
* of the language card. the quit call vectors to a routine high in the
* mli that moves dispatcher 1 down and jumps to it. the move routine
* must remain somewhere between $E000-$F7FF. this routine must be less
* than 3 pages in length.
ofsS .EQ disp1obj-dispadr offset to dispatcher org
disp1obj lda romin read ROM
sta clr80vid disable 80 col hardware
sta clraltchar normal LC, flashing UC
sta store80off disable 80 column store
jsr setnorm set normal text mode
jsr init init text screen
jsr setvid reset output to screen
jsr setkbd reset input to keyboard
ldx #$17 clear the memory bitmap
lda #$01 but protect page $BF00.
sta memmap,x P8 memory bitmap
dex
lda #$00
L5A22 sta memmap,x
dex
bpl L5A22
lda #$CF protect zero page, stack and
sta memmap $400-$7FF (text screen display)
L5A2D jsr home clear screen
jsr crout position top/left
ldx #<dsp1msg0-dsp1msgs
jsr prntmsg 'enter prefix...'
lda #$03 line 3
sta cv
jsr crout
jsr MLI get prefix
dc i1'$C7'
dc i2'dsp1pfx'
ldx PrefixBuf get prefix length
lda #$00 put 0 at end of prefix
sta PrefixBuf+1,x
ldx PrefixBuf get length.
beq L5A5D if no prefix to display.
L5A52 lda PrefixBuf,x display prefix directly to screen
ora #$80 normal text
sta vline5-1,x line 5
dex
bne L5A52
L5A5D ldx #$00
dec cv
jsr crout
getkey .EQ *-ofsS
jsr rdkey input char with cursor
cmp #$8D cr ?
beq L5ABD yes, accept what is entered.
pha no, save the char.
jsr clreol clear rest of line.
pla get char back
cmp #$9B esc ?
beq L5A2D yes, start over
cmp #$98 ctrl-x ?
L5A76 beq L5A2D then start over
cmp #$89 tab ?
beq badkey
cmp #$FF delete ?
beq L5A84 if yes
cmp #$88 backspace ?
bne L5A91 if not
L5A84 cpx #$00 at column 0 ?
beq L5A8B if so, do nothing
dec ch else move left
dex dec char count
L5A8B jsr clreol clear rest of line
jmp getkey get another char
L5A91 bcs L5A99
badkey jsr bell output bell for bad key
jmp getkey and get another.
L5A99 cmp #$DB below 'Z' ?
bcc L5A9F if yes
and #$DF else shift to uppercase.
L5A9F cmp #$AE below '.' ?
bcc badkey
cmp #$DB above 'Z' ?
bcs badkey
cmp #$BA below ':' ?
bcc goodkey
cmp #$C1 at or above 'A' ?
bcc badkey
goodkey inx
cpx #$27 more than 39 chars ?
bcs L5A76 then too many, go restart.
sta PrefixBuf,x save it
jsr cout
jmp getkey get another.
L5ABD cpx #$00 prefix length = 0 ?
beq L5AD3 if yes, don't set length.
stx PrefixBuf set prefix length.
jsr MLI call mli to set prefix.
dc i1'$C6'
dc i2'dsp1pfx'
bcc L5AD3 if ok, go get filename.
jsr bell if not, ring bell
lda #$00 and try again for prefix.
L5AD1 beq L5A76
L5AD3 jsr home clear screen for application name.
jsr crout
ldx #<disp1msg-dsp1msgs
jsr prntmsg 'enter pathname...'
retryrich .EQ *-ofsS
lda #$03 line 3
sta cv
jsr crout
ldx #$00
loop1 .EQ *-ofsS
jsr rdkey input char with cursor.
cmp #$9B esc ?
bne L5AF4 if not esc.
lda ch esc pressed in column 0 ?
bne L5AD3 if not, get pathname again.
beq L5AD1 if so, get prefix again.
L5AF4 cmp #$98 ctrl-x ?
L5AF6 beq L5AD3 then cancel and get pathname again.
cmp #$89 tab ?
beq L5B09 not good.
cmp #$FF delete ?
beq L5B04 delete char.
cmp #$88 backspace ?
bne L5B07
L5B04 jmp delchar delete char.
L5B07 bcs L5B0F if > $88 then char may be acceptable.
L5B09 jsr bell output bell (ctl-G)
jmp loop1 not good.
L5B0F cmp #$8D cr ?
beq L5B3C then done.
cmp #$DB less than 'Z' ?
bcc L5B19 no.
and #$DF make sure it's uppercase.
L5B19 cmp #$AE '.' ?
bcc L5B09 not good if less.
cmp #$DB less than '[' ?
bcs L5B09 not good.
cmp #$BA <= '9' ?
bcc L5B29 then ok.
cmp #$C1 greater than 'A' ?
bcc L5B09 if not, then no good.
L5B29 pha it's good, save it.
jsr clreol clear to end of line
pla
jsr cout print it
inx
cpx #$27 more than 39 chars ?
bcs L5AF6 too long, get pathname again.
sta PrefixBuf,x store it.
jmp loop1 get another char
L5B3C lda #$A0
jsr cout after cr, blank out the cursor.
stx PrefixBuf put length in front of the name.
jsr MLI get file info for pathname in PrefixBuf
dc i1'$C4'
dc i2'dsp1info'
bcc L5B4F if no errors.
jmp dsp1error
L5B4F lda dsp1type
cmp #$FF is it a SYS file ?
beq L5B5B yes.
lda #$01 not SYS file error.
jmp dsp1error
L5B5B lda #$00 it's a system file
sta dsp1cln
jsr MLI close all open files
dc i1'$CC'
dc i2'dsp1cls'
bcc L5B6B
jmp dsp1error
L5B6B lda dsp1acess check for proper access.
and #$01 is read disabled ?
bne L5B77 no, access ok.
lda #$27 i/o error
jmp dsp1error
L5B77 jsr MLI open the file
dc i1'$C8'
dc i2'dsp1open'
bcc L5B82
jmp dsp1error
L5B82 lda dsp1refn copy the reference number
sta dsp1rdn
sta dsp1eofn
jsr MLI get eof
dc i1'$D1'
dc i2'dsp1eof'
bcs L5BE2
lda dsp1eofb+2 3rd of 3 bytes.
beq L5B9C if 0 then ok
lda #$27 else i/o error because
bne L5BE2 file is too large.
L5B9C lda dsp1eofb move eof to # of bytes to read.
sta dsp1cnt
lda dsp1eofb+1
sta dsp1cnt+1
jsr MLI read the file
dc i1'$CA'
dc i2'dsp1read'
php save the status.
jsr MLI close the file.
dc i1'$CC'
dc i2'dsp1cls'
bcc L5BBB
L5BB7 plp get status (it is irrelevant now)
bne L5BE2 if close generated an error
plp here if close was ok.
L5BBB bcs L5BB7 error.
jmp sysentry execute system file
delchar .EQ *-ofsS
lda ch is cursor in column 0 ?
beq L5BD3 yes, ignore it.
dex
lda #$A0 blank out the cursor
jsr cout
dec ch
dec ch point to last char entered
jsr cout and blank it too.
dec ch point to that location.
L5BD3 jmp loop1 get next char.
prntmsg .EQ *-ofsS
L5BD6 lda dsp1msgs,x
beq L5BE1
jsr cout
inx
bne L5BD6
L5BE1 rts
* dispatcher 1 error handler
dsp1error .EQ *-ofsS
L5BE2 sta errnum
lda #$0C display error message on line 13
sta cv
jsr crout
lda errnum
cmp #$01
bne L5BF5
ldx #<dsp1err1-dsp1msgs not a type 'sys' file
bne L5C0B handled separately.
L5BF5 cmp #$40 syntax error in pathname ?
beq L5C09
cmp #$44 bad subdirectory path ?
beq L5C09
cmp #$45 volume not found ?
beq L5C09
cmp #$46 file not found ?
beq L5C09
ldx #<dsp1err2-dsp1msgs if not the errors above then 'i/o error'
bne L5C0B
L5C09 ldx #<dsp1err3-dsp1msgs otherwise display 'file/path not found'
L5C0B jsr prntmsg
jmp retryrich retry for application pathname
msb on
dsp1msgs .EQ *-ofsS
dsp1msg0 .EQ *-ofsS
dc c'ENTER PREFIX (PRESS "RETURN" TO ACCEPT)'
dc h'00'
disp1msg .EQ *-ofsS
dc c'ENTER PATHNAME OF NEXT APPLICATION'
dc h'00'
dsp1err1 .EQ *-ofsS
dc h'87'
dc c'NOT A TYPE "SYS" FILE'
dc h'00'
dsp1err2 .EQ *-ofsS
dc h'87'
dc c'I/O ERROR '
dc h'00'
dsp1err3 .EQ *-ofsS
dc h'87'
dc c'FILE/PATH NOT FOUND '
dc h'00'
dsp1info .EQ *-ofsS get file info parms
dc h'0A' 10 parameters
dc i2'PrefixBuf' pathname buffer
dsp1acess .EQ *-ofsS
dc h'00' access
dsp1type .EQ *-ofsS
dc h'00' file type
ds 13 the rest are unimportant
dsp1open .EQ *-ofsS open file parms
dc h'03' 3 parameters for open
dc i2'PrefixBuf' pathname buffer
dc i2'fbuf' fcb buffer
dsp1refn .EQ *-ofsS
dc h'00' reference #
dsp1cls .EQ *-ofsS close file parms
dc h'01' 1 parameter for close
dsp1cln .EQ *-ofsS
dc h'00' reference #
dsp1read .EQ *-ofsS
dc h'04' 4 parameters for read
dsp1rdn .EQ *-ofsS
dc h'00' reference #
dc i2'sysentry' .SYS load address
dsp1cnt .EQ *-ofsS
dc h'0000' byte count
dc h'0000'
dsp1eof .EQ *-ofsS get eof parms
dc h'02' 2 parameters
dsp1eofn .EQ *-ofsS
dc h'00' reference #
dsp1eofb .EQ *-ofsS
dc h'000000' 3 byte eof
dsp1pfx .EQ *-ofsS get/set prefix parms
dc h'01' 1 parameter
dc i2'PrefixBuf' prefix buffer
disp1end .EQ *
ds $300-(disp1end-disp1obj) fill to page boundary
* end of obj sel_0
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.SEL0
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,431 @@
NEW
AUTO 3,1
* object code = sel_1
* Bird's Better Bye at org = dispadr
ofsB .EQ birdbye-dispadr offset to Bird's Bye org
birdbye cld
lda romin read ROM
stz softev
lda #>dispadr set reset vector to 'dispadr'
sta softev+1
jsr setpwrc create power-up byte
lda #$A0
jsr init80 initialize 80 column text card
ldx #$17
* set up memory bitmap in global page
L5D16 stz memmap,x P8 memory bitmap
dex
bpl L5D16
inc memmap+$17 protect global page
lda #$CF protect zero page, stack and page 1
sta memmap
lda #$02
sta smparms init set mark parms pcount.
* drive selector
ldx numdevs get device count and
stx lstpntr store in zero page.
lda devnum get last slot/drive
bne volname
ds2 .EQ *-ofsB
L5D32 ldx lstpntr get device list pointer.
lda devlist,x get unit number from list.
cpx #$01 make sure it's real.
bcs L5D3F if so, change list pointer.
ldx numdevs get device count.
inx
L5D3F dex decrement list pointer and restore.
stx lstpntr
* get and store volume name
volname sta ol_unit store unit number for online.
jsr MLI
dc i1'$C5' online call
dc i2'ol_parms'
bcs L5D32 error check.
stz dlevel haven't read root directory yet.
lda PrefixBuf+1 load description byte.
and #$0F mask for name length.
beq L5D32 if 0, then try next unit.
adc #$02 add 2 to length.
tax name length in x.
vnam1 .EQ *-ofsB
stx PrefixBuf save the name length
lda #$2F '/'
sta PrefixBuf+1 slash before and
sta PrefixBuf,x after name.
stz PrefixBuf+1,x null after complete name.
* open and read directory
jsr MLI
dc i1'$C8' open
dc i2'op_parms'
bcc L5D7F good open.
lda dlevel trying to open root directory ?
beq L5D32 yes, just move to next volume.
jsr bell1 no, generate bell tone
jsr popdir and stay at same level.
stx PrefixBuf
jmp keyloop
L5D7F inc dlevel
stz filecount zero file count.
lda op_refn get file reference number
sta rd_refn store in read
sta sm_refn and setmark parm lists.
lda #$2B set read parm list for
sta dhdr_len directory header length.
stz dhdr_len+1
jsr doread read directory
bcs L5DB3
ldx #$03
L5D9A lda sysentry+$23,x copy directory info
sta entlen,x to zero page.
dex
bpl L5D9A
sta dhdr_len put entry length in read parm list.
lda #$01 set block file counter to 1.
sta blkfl
stz fpos_mid zero out msb's of file position
stz fpos_hi in setmark parm list.
lda filecnt any files in directory ?
ora filecnt+1
bne L5DB5 if so, continue
L5DB3 bra L5E29 else go close directory file.
L5DB5 bit filecnt+1 check msb of file count.
bmi L5DB3 if set then done.
L5DB9 lda fpos_mid get mid byte of setmark file position.
and #$FE reset lsb
sta fpos_mid and save.
ldy blkfl block file counter
lda #$00
cpy entblk have we read all entries in this block ?
bcc L5DCE if not, continue.
tay if so, zero y-reg and
sty blkfl reset block counter / flag
inc fpos_mid
* set up setmark parameters for next file to be read.
* if transfer to second sector, handle it.
L5DCC inc fpos_mid
L5DCE dey decrement file block counter
clc
bmi L5DD8
adc entlen add entry length to acc.
bcc L5DCE determine if we flopped into 2nd half of
bcs L5DCC block, if so inc mid byte position.
L5DD8 adc #$04 add 4 and put in
sta fpos_lo low byte of setmark.
jsr MLI call mli
dc i1'$CE' set mark
dc i1'smparms' parameters address = $0060
dc h'00'
bcs L5DB3 error
jsr doread
bcs L5DB3 error.
inc blkfl increase count of files read.
lda sysentry file type/length.
and #$F0 mask off high nibble.
beq L5DB9 deleted file, try next one.
dec filecnt decrement low file count.
bne L5DF8
dec filecnt+1 and high if necessary.
L5DF8 ror sysentry+$1E check access bit.
bcc L5DB5 if no read, try next file.
lda sysentry+$10 get file type.
cmp #$0F directory file ?
beq L5E08 then continue.
cmp #$FF system file ?
bne L5DB5 no, read next file.
L5E08 ldx filecount get valid files read.
cpx #$80 if greater than size of filename buffer
bcs L5E29 then close directory
sta filetyps,x else store filetype in zero page
jsr namecalc and go set up storage area.
ldy #$0F
L5E15 lda sysentry,y get byte of filename
sta (fnstore),y store in directed area
dey
bpl L5E15
iny y = 0
and #$0F mask off low nibble (name length)
sta (fnstore),y restore in name buffer
inc filecount increment valid file counter
bne L5DB5 get next file (branch always)
L5E26 jmp ds2 error. try next unit.
L5E29 jsr MLI close directory file
dc i1'$CC'
dc i2'cl_parms'
bcs L5E26 error.
jsr settxt use full screen for windows
jsr home
lda #$17 cursor at bottom of screen.
jsr tabv set vertical position.
ldy #$00
lda #$14 horizontal position.
jsr sethorz print message.
jsr homecurs cursor to upper/left.
ldx #$00
L5E48 lda PrefixBuf+1,x
beq showfiles
jsr output
inx
bne L5E48
showfiles stz valcnt
stz topname init top filename index.
lda filecount # of valid files.
beq L5EB0 if no files.
cmp #$15 more than what will fit on screen ?
bcc L5E61 no.
lda #$14 limit to 20 files on the screen.
L5E61 sta gp_cnt
lda #$02 set window dimensions
sta wndtop
sta wndlft
lda #$16
sta wndwdth
sta wndbtm
L5E6F jsr nameprnt output filename to screen
inc valcnt
dec gp_cnt file counter.
bne L5E6F continue printing names.
stz valcnt
beq L5EAA if last file, it needs to be inverse.
uparrow jsr nameprnt print old name in normal.
ldx valcnt get old name number.
beq L5EAA if already at the top name
dec valcnt else fix index.
lda cv current cursor line.
cmp #$02 at top line of window ?
bne L5EAA no, move up normally.
dec topname fix offset index
lda #$16 else sroll windows down a line.
bne L5EA7 branch always.
dnarrow jsr nameprnt print old name in normal.
ldx valcnt get old name number.
inx add one.
cpx filecount
bcs L5EAA if already at last filename
stx valcnt else update index.
lda cv current cursor line.
cmp #$15 at bottom line of window ?
bne L5EAA no, move cursor normally.
inc topname update offset index
lda #$17 else scroll up a line.
L5EA7 jsr cout
L5EAA jsr setinv set inverse text mode.
jsr nameprnt output last filename.
keyloop .EQ *-ofsB
L5EB0 lda kbd get keyboard input.
bpl L5EB0 loop until key pressed.
sta kbdstrobe clear strobe.
jsr setnorm set normal text mode.
ldx filecount are any files displayed ?
beq L5ECB no, don't accept arrow keys or return.
cmp #$8D return ?
beq L5EF4 then run selected file.
cmp #$8A down ?
beq dnarrow move down a name.
cmp #$8B up ?
beq uparrow move up a name.
L5ECB cmp #$89 tab ?
beq L5EED new volume.
cmp #$9B esc ?
bne L5EB0 no, try again else pop up a directory.
* pop a directory level
jsr popdir
dec dlevel
bra L5EF1
popdir .EQ *-ofsB
ldx PrefixBuf
L5EDD dex
lda PrefixBuf,x
cmp #$2F slash
bne L5EDD
cpx #$01
bne L5EEC
ldx PrefixBuf
L5EEC rts
L5EED jmp ds2 set up new unit number.
L5EF0 inx
L5EF1 jmp vnam1 get new directory info.
* run selected file
L5EF4 jsr MLI set prefix
dc i1'$C6'
dc i2'pf_parms'
bcs L5EED error.
ldx valcnt get name number.
jsr namecalc set up name storage area (on return y=0)
ldx PrefixBuf get prefix length.
L5F04 iny start at y = 1.
lda (fnstore),y get character of name.
inx
sta PrefixBuf,x store in prefix buffer.
cpy namelen check length of name.
bcc L5F04 loop until all transferred.
stx PrefixBuf put prefix length into buffer.
ldy valcnt get file number.
lda |filetyps,y get file type.
bpl L5EF0 branch if directory.
jsr settxt reset to full window.
jsr home makes for no flash.
lda #$95 ctrl-u
jsr cout turn off 80 columns.
jsr MLI open file
dc i1'$C8'
dc i2'op_parms'
bcs L5EED if error.
lda op_refn move reference number
sta rd_refn for read.
lda #$FF read the entire file.
sta dhdr_len
sta dhdr_len+1
jsr doread read selected file.
php save possible error.
jsr MLI close file. ignore any error from close
dc i1'$CC'
dc i2'cl_parms'
plp restore status from read.
bcs L5EED if any errors.
jmp sysentry execute selected system file.
* output messages. on entry: acc = horizontal position,
* y = index to message teminated by 0.
sethorz .EQ *-ofsB
sta ch
msgout .EQ *-ofsB
L5F4C lda dsp2msg,y
beq L5F57
jsr cout
iny
bne L5F4C
L5F57 rts
* name pointer calculator for name storage area
namecalc .EQ *-ofsB
stz fnstore+1 init high byte of 16-bit shift
txa
asl a shift to high nibble
rol fnstore+1
asl a
rol fnstore+1
asl a
rol fnstore+1
asl a
rol fnstore+1
sta fnstore low pointer
lda #>iobuf
clc
adc fnstore+1
sta fnstore+1
ldy #$00
lda (fnstore),y file name length
sta namelen
rts
* output a filename line
nameprnt .EQ *-ofsB
lda #$02
sta ch80col horizontal position = 2.
ldx valcnt filename number
txa
sec
sbc topname calculate line # to display name
inc a
inc a
jsr tabv set vertical position.
lda filetyps,x get filetype (x is unchanged by tabv).
bmi L5F99 branch if system file.
stz ch80col adjust cursor position.
lda invflg save current inverse setting
pha
ldy #<fldrmsg-dsp2msg
jsr msgout display the folder.
pla restore inverse setting.
sta invflg
L5F99 jsr outsp output a space.
jsr namecalc calc name location.
L5F9F iny y = 1 (first time).
lda (fnstore),y get name character.
jsr output put on screen.
cpy namelen end of name ?
bcc L5F9F no.
outsp .EQ *-ofsB output a space.
lda #$A0
bne L5FB1 branch always.
homecurs .EQ *-ofsB screen control - home cursor
lda #$99
output .EQ *-ofsB
ora #$80 set high bit.
L5FB1 jmp cout output to screen.
doread .EQ *-ofsB
jsr MLI mli read call
dc i1'$CA'
dc i2'rd_parms'
rts
* data area
dsp2msg .EQ *-ofsB
dc c'RETURN: Select | TAB: Chg Vol | '
dc c'ESC: Back'
dc i1'$00'
fldrmsg .EQ *-ofsB
dc h'0F' inverse control code
dc h'1B' enable mousetext
dc c'XY' folder characters
dc h'18' disable mousetext
dc h'0E' normal control code
dc h'00'
op_parms .EQ *-ofsB open parameters
dc h'03' 3 parms
dc i2'PrefixBuf' pathname
dc i2'op_buf' file buffer
op_refn .EQ *-ofsB
dc h'00' reference number
cl_parms .EQ *-ofsB close parameters
dc h'01' 1 parm
dc h'00' reference number.
ol_parms .EQ *-ofsB online parameters
dc h'02' 2 parms
ol_unit .EQ *-ofsB
dc h'60' unit number, default = s6, d1
dc i2'PrefixBuf+1' data buffer
pf_parms .EQ *-ofsB set prefix parameters
dc h'01' one parm
dc i2'PrefixBuf' pathname
rd_parms .EQ *-ofsB read parameters
dc h'04' 4 parms
rd_refn .EQ *-ofsB
dc h'01' reference number
dc i2'sysentry' data buffer
* these last 2 parms (4 bytes) may extend past $300 length limit since
* the request count is set prior to using the parm block and the transfer
* count isn't used at all (except by prodos)
* dc h'0000' requested length
* dc h'0000' actual length
dhdr_len .EQ *-ofsB directory header length
dc h'00' (actually uses 2 bytes)
* end of obj sel_1
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.SEL1
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,467 @@
NEW
AUTO 3,1
* object code = sel_2
*
* Alternate program selector segment for P8 when used in conjunction with
* gs/os. This code is used in place of the standard P8 interactive program
* selector when P8 is started up by GQuit. It is called when passing control
* from one application to another and the new application is 8-bit. This
* code first loads the specified P8 application at $2000 in bank 0 of memory.
* It then checks the message center for a possible name of a file. this file
* is passed on to the 8-bit application. This segment then passes control to
* the freshly loaded app. This code does NOT start with a CLD instruction
* (as other replacement quit code is supposed to do) because GQuit checks
* this to see if this version of quit code is available.
ofsQ .EQ GQdisp-dispadr offset to GQuit dispatcher org
msb off
GQdisp lda ramin read/write LC bank 1
clc
xce 16 bit native mode.
jmp >P8QUIT go to GQuit.
dc h'0000000000' offset to paragraph boundary.
dc c'GQ' id bytes so GQuit can identify this
* load application
*
* Entry is in 16-bit native mode. Exit is in emulation mode.
*
* On entry and exit:
* Data bank register is set to $00.
* Direct register is set to $0000.
* Stack pointer is set to $01FB.
*
* Inputs: acc = value of E1_OS_Switch (0 or 1, 1 = yes to switch)
*
* This code is moved to $00/1010 and executed there.
* first, copy the prefix passed from gs/os to our own volume name buffer
* so in case of an error setting the P8 prefix, it can be displayed in the
* error message.
SHORT M 8 bit accumulator
LONGI ON
pha save the switch status.
ldx #inbuf point to passed prefix.
jsr copyvol copy the name into the buffer.
pla retrieve the switch status
* go into emulation mode to load and run Prodos 8 application
sec
xce 8 bit emulation mode
ora #$00 switching from P16 to P8 ?
beq L602D no.
* switching from P16 to P8 so pass prefix 0 from P16 to the P8 prefix. the
* prefix is passed at $00/0200 by GQuit.
L6020 jsr MLI set prefix
dc i1'$C6'
dc i2'pfxparms'
bcc L602D if prefix ok.
jsr gqerror error handler.
bra L6020 try again
* load application at $2000
L602D xce native mode (carry clear)
LONG I 16 bit regs, 8 bit acc.
lda PrefixBuf+1 is the application name
cmp #$2F a complete pathname ?
bne L603D no, use prefix as volume name
ldx #PrefixBuf else use the application name.
jsr copyvol copy the volume name to buffer.
L603D sec back to emulation mode.
xce
L603F jsr MLI open the application file
dc i1'$C8'
dc i2'opnparms'
bcc L604C if open ok.
jsr gqerror handle error.
bra L603F try again.
L604C lda oprefnum copy ref number to parameter lists
sta eofrefn
sta rdrefnum
sta closeref
* do a geteof call for how many bytes to read
L6058 jsr MLI get eof
dc i1'$D1'
dc i2'eofparms'
bcc L6065 eof ok.
jsr gqerror handle error.
bra L6058 try again.
* store the size of the file in the read parameter list
L6065 lda eofval
sta rdcount
lda eofval+1
sta rdcount+1
L6071 jsr MLI read
dc i1'$CA'
dc i2'readparm'
bcc L607E read ok
jsr gqerror
bra L6071
L607E jsr MLI close
dc i1'$CC'
dc i2'closeprm'
bcc L608B close ok
jsr gqerror
bra L607E
L608B jsr dolaunch check for possible 2nd pathname.
bne L6099 if none then run program
jsr ckfordrv else make sure the file is online.
bcc L6099 if so then run the program.
lda #$45 volume not found error.
bra L60AB
L6099 lda romin enable ROM
jmp sysentry execute the system application
gqerror .EQ *-ofsQ
clc
xce 16 bit native mode
LONG I,M
jsr mountvol mount volume.
bcs L60AB if error.
sec back to emulation mode.
xce
rts
* generate a fatal error while running under Prodos 8.
* on input, acc = error code. this routine does not return.
L60AB clc native mode
xce
LONG I,M
and #$00FF mask off high byte of error code.
pha put on stack for IntMath tool call.
pea $0000 errval>>16
pea errval push address of string buffer.
pea $0004 make string 4 digits long.
_Int2Hex convert value to hex string.
pha make space for return value.
pea $0000 quitstr1>>16
pea quitstr1 push first error message address
pea $0000 quitstr2>>16
pea quitstr2 push second error message address
pea $0000 button1>>16
pea button1 push first button text address
pea $0000 quitbtn2>>16
pea quitbtn2 push 2nd button text address (null)
_TLTextMountVolume make the dialog box
pla retrieve button press (not used)
sec emulation mode
xce
jsr MLI quit back to GQuit
dc i1'$65'
dc i2'quitparms'
* p8 mount volume
*
* on entry: volbuf = name of volume to mount.
* on exit: carry clear if mount volume displayed and 'return' was pressed.
* carry set if no window displayed or if had window and 'esc' pressed.
mountvol .EQ *-ofsQ
ldy #$0000 volbuf>>16
ldx #volbuf set up pointer to volume name.
* if error is 'volume not found' or 'no disk in drive' then display the
* Mount Volume window, otherwise return with carry set.
and #$00FF mask just in case.
cmp #$0045 volume not found ?
beq L6101 yes
cmp #$002F no disk in drive ?
beq L6101 yes
sec indicate error not handled.
rts return with error code still in acc.
L6101 pha save error code in case esc pressed.
phy pointer to volume name.
phx
tsc
phd save D reg.
tcd point D reg at stack.
lda [$01] get length byte and leading separator.
dec a don't count leading separator.
xba then swap the bytes so the volume name
sta [$01] doesn't cpntain the separator.
pha room for result.
pea $0000 mountmsg>>16
pea mountmsg
phy hi word of pointer to volume name.
inx skip separator.
phx lo word of pointer to volume name.
pea $0000 button1>>16
pea button1 'Return'
pea $0000 button2>>16
pea button2 'Escape'
_TLTextMountVolume
lda [$01] restore first 2 bytes of vilume name
xba back to their original positions
inc a and values.
sta [$01]
pla which button: 1=Return 2=Escape.
pld restore D reg.
plx pull volume name pointer off stack
plx
cmp #$0001 which button was pressed ?
bne L613C if Escape pressed.
clc indicate Return was pressed.
pla pull original error code off stack.
rts return with carry clear.
L613C sec indicate Escape was pressed.
pla restore error code.
rts return with carry set.
* copy the volume name from the given pathname to the volume name buffer.
*
* inputs: x = length byte of complete pathname containing volume name.
* output: volume name is stored in volbuf.
copyvol .EQ *-ofsQ
lda |1,x get the first slash
sta volbuf+1
ldy #$0002 initialize the length count.
LONGI OFF
LONGA OFF
L6148 lda |2,x now copy the volume name up to
cmp #$2F the separating slash.
beq L6156
sta volbuf,y
inx
iny
bra L6148
L6156 dey fix character count.
tya length.
sta volbuf store the resultant string length.
rts
* translate a filename message from the message center to the currently
* launching P8 application if it can accept a second filename. If found,
* copy the filename into the application's filename buffer.
* on exit, the z-flag is set if a filename was correctly passed to the
* application elst the z-flag is clear if it couldn't be done.
dolaunch .EQ *-ofsQ
lda sysentry does the app start with a jump ?
cmp #$4C
bne L616F no, doesn't follow the convention.
lda #$EE check for the signature bytes.
cmp sysentry+3
bne L616F 1st one doesn't match, skip it.
cmp sysentry+4
beq L6170 both match, go get a filename message.
L616F rts just return to launch the app.
L6170 lda #$FF put flag conditioning value on
pha the stack (assume error).
clc native 16-bit mode.
xce
LONG I,M
pha make room on stack for user id.
_MMStartUp start up the memory manager.
pla get the user id and
pha leave it on the stack.
pha
pha make room on stack for new handle.
pea $0000
pea $000A get a 10 byte block of memory.
pha put user id on stack.
pea $0000 totally unrestricted block.
pha LocationPtr (not used)
pha
_NewHandle go get the block of memory.
pla get the handle from the stack.
plx
bcs L620A branch if error, no memory available.
phx leave the handle on the stack.
pha
pea $0002 'get' a message.
pea $0001 get a type 1 (filename) message.
phx put the message handle on the stack
pha (still in acc and x regs)
_MessageCenter
bcs L6203 branch if no message.
pha leave 4 bytes free on stack
pha (will be used as a direct page pointer)
tsc get the stack pointer.
phd save current direct register.
inc a point to new direct page space.
tcd make a new direct page.
lda [$04] de-reference the handle.
sta $00
ldy #$0002
lda [$04],y
sta $02
ldy #$0006 get the message command.
lda [$00],y
bne bad_msg if print, then skip it.
lda $00 adjust pointer to filename string.
clc
adc #$0008
sta $00
bcc L61D1
inc $02
L61D1 lda [$00] get the length of the string.
and #$00FF mask off high (leaving just the length)
SHORT M 8 bit accumulator
cmp sysentry+5 check against length of app buffer.
beq L61DF if equal then continue with move.
bcs bad_msg if too long then bad message.
L61DF tay string length.
L61E0 lda [$00],y get a character.
sta sysentry+6,y store it in the app's filename buffer
sta inbuf,y and in prefix buffer.
dey
bpl L61E0
lda #$00 change flag conditioning value on stack
sta $0D,s to indicate a filename is passed.
bad_msg LONG M 16-bit acc.
pld restore direct register.
pla fix stack because handle and userid
pla still on stack.
pea $0003 now delete the message (done with it).
pea $0001 message type 1.
pha garbage handle (not used).
pha
_MessageCenter go delete the message.
L6203 _DisposeHandle throw away message (handle is on stack)
L620A _MMShutDown shutdown the memory manager (userid is
sec on stack).
xce back to emulation mode.
LONGA OFF
pla condition z-flag with value on stack.
bne L6231 then done.
ldx inbuf get length of pathname.
lda #$2F look for slash.
L621B cmp inbuf,x
beq L6225 when found, set prefix.
dex
bne L621B
bra L6231 if no slash, just skip it.
L6225 dex don't include trailing slash.
stx inbuf set new length.
jsr MLI set the P8 prefix.
dc i1'$C6'
dc i2'pfxparms'
lda #$00 set z-flag
L6231 rts and go launch the app.
* check for disk volume
*
* on exit:
* carry clear = disk was found
* carry set = disk not found
ckfordrv .EQ *-ofsQ
clc native mode
xce
LONG I 16-bit regs, 8-bit acc.
ldx #sysentry+6 point to pathname buffer.
jsr copyvol copy volume name to pathname buffer.
L623C sec emulation mode.
xce
jsr MLI get info on the volume.
dc i1'$C4'
dc i2'gfiparms'
bcc L6252 branch if volume found,
clc (native mode)
xce
LONG I,M
jsr mountvol else ask user to mount the volume.
bcc L623C if <return> pressed, then try again.
sec emulation mode.
xce
sec disk not found.
L6252 rts
* Prodos 8 parameter lists
pfxparms .EQ *-ofsQ set prefix parms.
dc h'01' one parm.
dc i2'inbuf' address of prefix.
opnparms .EQ *-ofsQ open parms.
dc h'03' 3 parms.
dc i2'PrefixBuf' pathname
dc i2'op_buf' i/o buffer
oprefnum .EQ *-ofsQ
dc h'00' reference #
eofparms .EQ *-ofsQ
dc h'02' 2 parms
eofrefn .EQ *-ofsQ
dc h'00' reference #
eofval .EQ *-ofsQ
dc h'000000' 3 byte eof value
readparm .EQ *-ofsQ
dc h'04' 4 parms
rdrefnum .EQ *-ofsQ
dc h'00' reference #
dc i2'sysentry' read into $2000 (bank 0).
rdcount .EQ *-ofsQ
dc h'0000' # of bytes to read.
dc h'0000' transfer count
closeprm .EQ *-ofsQ
dc h'01' 1 parm
closeref .EQ *-ofsQ
dc h'00' reference #
quitparms .EQ *-ofsQ
dc h'04' 4 parms.
dc h'00' quit back to launcher (GQuit)
dc h'0000'
dc h'00'
dc h'0000'
gfiparms .EQ *-ofsQ get file info parms.
dc h'0A' 10 parms
dc i2'volbuf' volume buffer
dc h'00' access
dc h'00' file type
dc h'0000' aux type
dc h'00' storage type
dc h'0000' blocks used
dc h'0000' modification date
dc h'0000' modification time
dc h'0000' creation date
dc h'0000' creation time
* messages for P8 fatal error. maximum length of message is 35 characters.
* the error code will be displayed immediately after the final character.
quitstr1 .EQ *-ofsQ
dc h'1B'
dc c'Can''t run next application.'
quitstr2 .EQ *-ofsQ
dc h'14'
dc c'ProDOS Error = $'
errval .EQ *-ofsQ hex error code gets stored here
dc c' '
quitbtn2 .EQ *-ofsQ null string (no 2nd button)
dc h'00'
* messages for P8 mount volume. maximum length of message is 35 characters.
* the button labels must not be more than 16 characters.
mountmsg .EQ *-ofsQ
dc h'17'
dc c'Please insert the disk:'
button1 .EQ *-ofsQ
dc h'0D'
dc c'Accept: '
dc h'1B' mousetext on
dc h'0F' inverse on
dc h'4D' mousetext return
dc h'0E' normal on
dc h'18' mousetext off
button2 .EQ *-ofsQ
dc h'0B'
dc c'Cancel: Esc'
* end of obj sel_2 (must be < GQdisp+$300)
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.SEL2
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,107 @@
NEW
AUTO 3,1
* object code = tclock_0
* Thunderclock driver
* hard coded for slot 1
* $2F00-2F7C moved to $D742
ofsT .EQ tclock_0-tclk_in offset to Thunderclock org
tclock_0 ldx clkslt clock slot = $C1.
lda clkmode,x save current mode
pha
lda #$A3 send numeric mode byte to Thunderclock
jsr wttcp
clkslt .EQ *-ofsT+2 points to $C1.
jsr rdtcp read month, day of week, day of month
clc and time into input buffer.
ldx #$04 index for 5 values.
ldy #$0C read minutes 1st, month last.
H2F14 lda inbuf,y convert values to binary.
and #$07 no value > 5 decimal.
sta pcl 'tens' place value
asl a multiply by 10
asl a
adc pcl
asl a
adc inbuf+1,y add to ascii 'ones' place
sec and subtract out the ascii
sbc #$B0
sta pcl,x save converted value.
dey index to next lowest value
dey
dey
dex are there more values?
bpl H2F14 if yes.
tay contains month
lsr a
ror a
ror a
ror a high bit of month held in carry
ora A1L
sta p8date save low value of date.
php save high bit of month.
and #$1F isolate day.
adc tdays-1,y (y = month)
bcc H2F42 branch if not Sept 13 thru 30th
adc #$03 adj for mod 7 when day > 256
H2F42 sec
H2F43 sbc #$07
bcs H2F43 loop until < 0.
adc #$07 make it in the range of 0-6.
sbc pch the delta provides years offset.
bcs H2F4F branch if positive
adc #$07 else make it positive again.
H2F4F tay
lda yradj,y look up year
plp and combine it with hi bit of month
rol a
sta p8date+1 P8 date
lda A1L+1 hour
sta p8time+1 P8 time
lda A2L minute
sta p8time
pla restore previous mode.
ldx clkslt clock slot = $C1
sta clkmode,x
H2F69 rts
* this table contains entries for the cumulative # of days in a year,
* one entry for each month. the values are modulo 256.
tdays .EQ *-ofsT
dc h'00' January
dc h'1F' February
dc h'3B' March
dc h'5A' April
dc h'78' May
dc h'97' June
dc h'B5' July
dc h'D3' August
dc h'F2' September
dc h'14' October (MOD 256)
dc h'33' November
dc h'51' December
* the following table is used to look up the current year, based on
* the current month, day and day of week. The 1st entry corresponds
* to the year in which January 1st falls on a Monday. The 2nd entry
* is the year which January 1st is Sunday, and so on backwards thru
* the days of the week.
yradj .EQ *-ofsT
dc h'60' Monday
dc h'5F' Sunday
dc h'5E' Saturday
dc h'5D' Friday
dc h'62' Thursday
dc h'61' Wednesday
dc h'60' Tuesday
tclk_end .EQ * end of obj tclock_0.
dc h'000000' pad
*--------------------------------------
MAN
LOAD USR/SRC/PRODOS/PRODOS.S.TCLK
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

4343
ProDOS.203/ProDOS.S.XDOS.txt Normal file

File diff suppressed because it is too large Load Diff

54
ProDOS.203/ProDOS.S.txt Normal file
View File

@ -0,0 +1,54 @@
NEW
AUTO 3,1
.LIST OFF
.OP 65C02
.OR $0000
.TF PRODOS203,TSYS
*--------------------------------------
.INB INC/IO.I
.INB INC/MONITOR.I
.INB INC/MLI.I
.INB INC/MLI.E.I
.INB INC/ZP.I
*--------------------------------------
ZP.SrcPtr .EQ $12
ZP.DstPtr .EQ $14
*--------------------------------------
PrefixBuf .EQ $280
DirBlkBuf .EQ $C00
*--------------------------------------
* $2000 mli_0 mli loader/relocator
* $2C80 ram_1 installer for /RAM
* $2D00 ram_2 /RAM driver in main lc
* $2D9B mli_3 interrupts
* $2E00 mli_1 global page
* $2F00 tclock_0 Thunderclock driver
* $2F80 cclock_0 Cortland clock driver
* $3000 mli_2 xdos mli & block file manager
* $5100 ram_0 /RAM driver in aux mem
* $5300 xrw_0 disk core routines
* $5A00 sel_0 dispatcher
* $5D00 sel_1 enhanced quit code (Bird's Better Bye)
* $6000 sel_2 GQuit dispatcher support
.PH $2000
.INB USR/SRC/PRODOS/PRODOS.S.LDR
.INB USR/SRC/PRODOS/PRODOS.S.RAMI
.INB USR/SRC/PRODOS/PRODOS.S.RAM
.INB USR/SRC/PRODOS/PRODOS.S.IRQ
.INB USR/SRC/PRODOS/PRODOS.S.GP
.INB USR/SRC/PRODOS/PRODOS.S.TCLK
.INB USR/SRC/PRODOS/PRODOS.S.CCLK
.INB USR/SRC/PRODOS/PRODOS.S.XDOS
.INB USR/SRC/PRODOS/PRODOS.S.RAMX
.INB USR/SRC/PRODOS/PRODOS.S.DISKII
.INB USR/SRC/PRODOS/PRODOS.S.SEL0
.INB USR/SRC/PRODOS/PRODOS.S.SEL1
.INB USR/SRC/PRODOS/PRODOS.S.SEL2
.EP
*--------------------------------------
MAN
SAVE USR/SRC/PRODOS/PRODOS.S
ASM

View File

@ -0,0 +1,225 @@
KEEP PRODOS
MCOPY PRODOS.MAC
* disassembly of prodos version 2.0.3
* can be compiled with the orca/m assembler
* which produces an output file PRODOS (type = EXE)
* address refs beginning with 'L' were generated by orca disassembler
* address refs beginning with 'H' were added manually
* last edit: 01/24/13
* map of the object modules within prodos exe are as follows:
* $2000 mli_0 mli loader/relocator
* $2C80 ram_1 installer for /RAM
* $2D00 ram_2 /RAM driver in main lc
* $2D9B mli_3 interrupts
* $2E00 mli_1 global page
* $2F00 tclock_0 Thunderclock driver
* $2F80 cclock_0 Cortland clock driver
* $3000 mli_2 xdos mli & block file manager
* $5100 ram_0 /RAM driver in aux mem
* $5300 xrw_0 disk core routines
* $5A00 sel_0 dispatcher
* $5D00 sel_1 enhanced quit code (Bird's Better Bye)
* $6000 sel_2 GQuit dispatcher support
************************ IMPORTANT ************************
* *
* 1. In the language card area, the $D000 areas overlay. To *
* determine which bank is active requires that the main bank *
* has a CLD ($D8) at $D000 and the alternate bank does not. *
* $D000 in ROM = $6F, LC bank1 = $D8, LC bank2 = $EE *
* *
* 2. Location $E000 is used to determine the state of ROM vs. *
* language card. Therefore, the value of $E000 in the MLI *
* and ROM must differ. *
* *
* 3. In the section MEMMGR, the routine CALLDISP must access *
* the other $D000 bank so it MUST reside ABOVE $E000 in the *
* language card area. *
* *
* 4. The Disk II routine xrwtot MUST reside on a page boundary *
* to distinguish it from a ram-based driver. *
* *
* 5. In the /RAM driver ram3, the byte at $FF58 MUST be an rts *
* ($60) so the routine JSR $FF58 to determine an I/O card's *
* slot still works when the language card is switched in. *
* *
*****************************************************************
PRODOS START
* Predefined labels:
lookptr equ $0A
idapple equ $0C model machine id
idxl equ $10 general use 16 bit index pointer
devid equ $12
src equ $12
dst equ $14
cnt equ $16
cde equ $18
ecde equ $1A
wndlft equ $20
wndwdth equ $21
wndtop equ $22
wndbtm equ $23
ch equ $24 cursor horizontal
cv equ $25 cursor vertical
invflg equ $32 inverse flag
pcl equ $3A
pch equ $3B
A1L equ $3C
A1H equ $3D
A2L equ $3E
A2H equ $3F
A3L equ $40
A4L equ $42
unitnum equ $43
buf equ $44 2-byte data buffer pointer which
accsav equ $45 overlaps accsav (temp acc save byte)
bloknml equ $46 used mostly as 16 bit block # pointer
zpt equ $48 highly used zero page index pointer
datptr equ $4A ptr to data area of buffer.
sos equ $4C sos buffer pointer.
usrbuf equ $4E data ptr in user buffer.
* zero page variables for Bird's Better Bye
smparms equ $60 set mark parms
sm_refn equ $61 file reference number
fpos_lo equ $62 new file position (3 bytes)
fpos_mid equ $63
fpos_hi equ $64
lstpntr equ $65 device list pointer (16 bit)
valcnt equ $67 name counter
filecount equ $68 # of displayable files in directory
namelen equ $69 length of filename
gp_cnt equ $6A general purpose counter
dlevel equ $6B directory level
fnstore equ $6C filename storage pointer (16 bit)
entlen equ $6E directory entry length
entblk equ $6F directory entries/block
filecnt equ $70 directory file count (16 bit)
blkfl equ $72 block flag / file counter
topname equ $73 index # of top name in display
filetyps equ $74 128 byte table of filetypes
errnum equ $DE
tst128 equ $0080 temp page 0 routine for memory test
auxsp equ $0101
ramdest equ $0200 load address for aux bank /RAM driver
inbuf equ $0200 keyboard buffer
pbuf equ $0280 prefix buffer
p3vect equ $03F0 page 3 vectors (16 bytes)
softev equ $03F2 RESET vector
pwredup equ $03F4 power up byte
nmivect equ $03FB nmi handler
txtp2 equ $0400 test location for aux card
vline10 equ $04A8 line 10 of display
vmode equ $04FB video firmware operating mode
vline11 equ $0528 line 11 of display
clkmode equ $0538 clock mode
ch80col equ $057B 80 column ch position
vline12 equ $05A8 line 12 of display
vline5 equ $0600 line 5 of display
vline13 equ $0628 line 13 of display
vline14 equ $06A8 line 14 of display
vline23 equ $0750 line 23 of display
vline16 equ $07A8 line 16 of display
vline24 equ $07D0 line 24 of display
mslot equ $07F8 slot being accessed
lodintrp equ $0800
dbuf equ $0C00 8 page directory buffer
vblock1 equ $0E00 ramdisk directory block
volbuf equ $0F00 volume buffer
dispadr equ $1000 system death dispatcher run address
iobuf equ $1400 i/o buffer
fbuf equ $1800 FCB buffer
op_buf equ $1C00 open file buffer (selector)
sysentry equ $2000 .SYS file load address
prodos8 equ $BF00 prodos MLI and global page
kbd equ $C000 keyboard latch (read)
store80off equ $C000 disable 80-col store (write)
store80on equ $C001 enable 80-col store
rdmainram equ $C002 read from main 48K
rdcardram equ $C003 read from alt 48K
wrmainram equ $C004 write to main 48K
wrcardram equ $C005 write to alt 48K
setstdzp equ $C008 use main zero page/stack
setaltzp equ $C009 use alt zero page/stack
int3rom equ $C00A enable internal slot 3 ROM
slot3rom equ $C00B enable external slot 3 ROM
clr80vid equ $C00C disable 80 col hardware
clraltchar equ $C00E normal LC, flashing UC
kbdstrobe equ $C010 turn off keypressed flag
rd80col equ $C018 if 80-column store
newvideo equ $C029 video mode select
spkr equ $C030 click speaker
txtset equ $C051 switch in text
txtpage1 equ $C054 switch in text page 1
txtpage2 equ $C055 switch in text page 2
statereg equ $C068 memory state register
phaseoff equ $C080 disk port
romin1 equ $C081 read ROM/write RAM bank 2
romin equ $C082 read ROM
altram equ $C083 read/write RAM bank 2
motoroff equ $C088 disk port
motoron equ $C089 disk port
drv0en equ $C08A disk port
ramin equ $C08B read/write RAM bank 1
q6l equ $C08C disk port
q6h equ $C08D disk port
q7l equ $C08E disk port
q7h equ $C08F disk port
rdtcp equ $C108 Thunderclock read entry
wttcp equ $C10B Thunderclock write entry
init80 equ $C300 init 80 col card
slot3id1 equ $C305 slot 3 card id 1
slot3id2 equ $C307 slot 3 card id 2
slot3id3 equ $C30B slot 3 card id 3
ext80col equ $C30C slot 3 80 col id
auxmove equ $C311 move (3C)-(3E) to (42)
xfer equ $C314
slot3irq equ $C3FA slot 3 irq handler
clrrom equ $CFFF switch out $C8 ROMs
rwts equ $D000 disk ii driver in bank 1
displc2 equ $D100 system death routine stored in bank 2
pathbuf equ $D700 pathname buffer
tclk_in equ $D742 clock driver in bank 2
fcbbuf equ $D800 fcb buffer
vcbbuf equ $D900 vcb buffer
bmbuf equ $DA00 512 byte bitmap buffer
gbuf equ $DC00 general purpose 512 byte block buffer
xdosorg equ $DE00 xdos MLI in aux memory
romirq equ $FA41 monitor irq entry
breakv equ $FA59 monitor break vector
resetv equ $FA62 monitor reset entry
HFB1E equ $FB1E version check byte
init equ $FB2F init text screen
settxt equ $FB39 set text mode
tabv equ $FB5B set vertical position
setpwrc equ $FB6F create power-up byte
version equ $FBB3 monitor ROM id byte
zidbyte equ $FBC0 monitor ROM id byte
bell1 equ $FBDD generate bell tone
home equ $FC58 home cursor and clear screen
clreol equ $FC9C clear to end of line
rdkey equ $FD0C input char with cursor
crout equ $FD8E issue carriage return
cout equ $FDED output character
idroutine equ $FE1F returns system info
setinv equ $FE80 set inverse text mode
setnorm equ $FE84 set normal text mode
setkbd equ $FE89 reset input to keyboard
setvid equ $FE93 reset output to screen
lcdest equ $FF00 load address
bell equ $FF3A output bell (ctl-G)
oldrst equ $FF59 monitor reset entry
* romrts equ $FFCB an rts location that must be in ROM
P8QUIT equ $E0D000
GSOS equ $E100A8
GSOS2 equ $E100B0
OS_BOOT equ $E100BD indicates O/S initially booted

9218
ProDOS.203/prodos203src.txt Normal file

File diff suppressed because it is too large Load Diff