mirror of
https://github.com/A2osX/A2osX.git
synced 2025-01-12 17:30:23 +00:00
ProDOS 203 Source code
This commit is contained in:
parent
9ec843b36e
commit
888438fb0b
71
ProDOS.203/ProDOS.S.CCLK.txt
Normal file
71
ProDOS.203/ProDOS.S.CCLK.txt
Normal 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
|
||||
|
960
ProDOS.203/ProDOS.S.DiskII.txt
Normal file
960
ProDOS.203/ProDOS.S.DiskII.txt
Normal 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
192
ProDOS.203/ProDOS.S.GP.txt
Normal 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
|
77
ProDOS.203/ProDOS.S.IRQ.txt
Normal file
77
ProDOS.203/ProDOS.S.IRQ.txt
Normal 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
1669
ProDOS.203/ProDOS.S.LDR.txt
Normal file
File diff suppressed because it is too large
Load Diff
93
ProDOS.203/ProDOS.S.RAM.txt
Normal file
93
ProDOS.203/ProDOS.S.RAM.txt
Normal 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
|
45
ProDOS.203/ProDOS.S.RAMI.txt
Normal file
45
ProDOS.203/ProDOS.S.RAMI.txt
Normal 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
|
||||
|
348
ProDOS.203/ProDOS.S.RAMX.txt
Normal file
348
ProDOS.203/ProDOS.S.RAMX.txt
Normal 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
|
324
ProDOS.203/ProDOS.S.SEL0.txt
Normal file
324
ProDOS.203/ProDOS.S.SEL0.txt
Normal 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
|
431
ProDOS.203/ProDOS.S.SEL1.txt
Normal file
431
ProDOS.203/ProDOS.S.SEL1.txt
Normal 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
|
467
ProDOS.203/ProDOS.S.SEL2.txt
Normal file
467
ProDOS.203/ProDOS.S.SEL2.txt
Normal 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
|
107
ProDOS.203/ProDOS.S.TCLK.txt
Normal file
107
ProDOS.203/ProDOS.S.TCLK.txt
Normal 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
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
54
ProDOS.203/ProDOS.S.txt
Normal 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
|
225
ProDOS.203/prodos.S - Copie.txt
Normal file
225
ProDOS.203/prodos.S - Copie.txt
Normal 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
9218
ProDOS.203/prodos203src.txt
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user