 ttl UniFLEX Disk Formatter
 sttl 5" Mini Floppy Bootstrap
 pag
 info Bootstrap for GIMIX/5" Version 2.01; 10/17/83

* UniFLEX Bootstrap Loader for 6809 DMAF

 global uboot,ubflgs

old_org equ $B000 Old boot origin
new_org equ $B800 New boot origin

* Buffers

 base new_org+512
buffer rmb 512
map rmb 512
*
ffmap equ 17 file map offset in fdn
bhxfr equ 10 transfer address offset in header
BHDSIZ equ 24 binary file header size

* System equates for single sector read

 base $F000 Floppy Controller
drvreg rmb 1 drive register
ccreg rmb 1 dma register
addreg rmb 2 dma address register
comreg rmb 1 commmand register
trkreg rmb 1 track register
secreg rmb 1 sector register
datreg rmb 1 data register
*
BUSY equ 1 busy mask
RDCMND equ $8C read command
SKCMND equ $19 seek command

* Temporary storage

 base $00EB
latch rmb 1
btdate rmb 4
direct rmb 1
mapptr rmb 2
entrys rmb 2
xfradr rmb 2
sdslct rmb 1

* System Configuration Info
 base $000C
cputyp rmb 2

 data
********************************************
* Start of program
********************************************

* Lookup "uniflex" in directory

uboot lbra uboot1 skip disk type bytes

**************************************************
ubflgs fcb 0,0
dside equ ubflgs
dnsity equ ubflgs+1
**************************************************

uboot1 ldx #old_org move bootstrap
 ldu #new_org
10 ldd ,x++
 std ,u++
 cmpx #old_org+512
 blo 10b
 lbra (uboot2-old_org)+new_org
uboot2 ldd #1 root directory fdn no.
 lbsr fdnblk read in fdn
 ldd 7,y find size of directory
 lbsr divby8
 lsra
 rorb
 std entrys save entry count
read1 lbsr rdblk read data block
 lbne noboot exit if error
lookup leax 2,u point to filespec
 leay btname,pcr point to boot file name
 ldb #14 set name length
cmpnam lda 0,x+
 cmpa 0,y+ is this boot file entry?
 bne nxtent if not, skip to next
 decb
 bne cmpnam
 ldd 0,u found it, get fdn
 bra load go load uniflex
nxtent ldx entrys
 leax -1,x decrement count
 stx entrys end of directory?
 lbeq noboot error if so
 leau 16,u point to next entry
 cmpu #buffer+512 past current block?
 bne lookup check entry if not
 bra read1 else, get another block

* Load UniFLEX

load bsr fdnblk read in uniflex fdn
 ldx mapptr point to fdn map
 leax 13*3,x skip map
 ldb #4 set count
 ldy #btdate point to date store
lode22 lda 0,x+ save the fdn date
 sta 0,y+
 decb
 bne lode22
 lbsr rdblk read 1st block of the file
 bne noboot exit if error
 ldd bhxfr,u get transfer address
 std xfradr save it
 leau BHDSIZ,u skip binary file header
getrc1 bsr getchr get record length in x
 tfr b,a
 bsr getchr
 cmpd #0 terminator?
 beq done start uniflex if so
 tfr d,x
 bsr getchr get load address in y
 tfr b,a
 bsr getchr
 tfr d,y
getrc2 bsr getchr get a data byte
 stb 0,y+ put in memory
 leax -1,x decrement the count
 bne getrc2 loop if not end of record
 bra getrc1 else, get next record

* Uniflex is loaded, begin execution

done ldx $5002 transfer date to uniflex
 ldd btdate
 std ,x++
 ldd btdate+2
 std ,x
 jmp [xfradr] jump to transfer address

* Divide contents of D by 8

divby8 lsra
 rorb
divby4 lsra
 rorb
 lsra
 rorb
 rts

* Get single character from binary file

getchr cmpu #buffer+512 more data in buffer?
 bne getch2 skip if so
 pshs a,x,y
 bsr rdblk else, read another block
 puls a,x,y
 bne nbootx exit if error
getch2 ldb 0,u+ get character, advance ptr
 rts

* Uniflex file was not found

nbootx puls d fix stack
noboot rts return to monitor ROM

* Read fdn specified in D

fdnblk pshs d save fdn number
 addd #15 convert to block number
 bsr divby8
 lbsr mread read a block
 puls d restore fdn number
 bne nbootx exit if error
 decb calculate buffer offset
 andb #$07
 lda #64
 mul offset=(fdn&7)*64
 addd #map
 tfr d,y fdn pointer in y
 addd #9 point to ffmap
 std mapptr save map pointer
 lda #10 get direct block count
 sta direct initialize indirect flag
 rts

* Read a block from file

rdblk tst direct a direct block?
 beq chgind change to indirect
 dec direct dec. direct count
 ldx mapptr get file map pointer
 ldd 1,x block address in d
 leax 3,x point to next
 stx mapptr
 bsr blkts convert block to trk & sct
 ldx #buffer setup buffer address
 lbra xread read the sector

chgind ldx mapptr get file map pointer
 ldd 1,x address of indirect block
 lbsr mread read block of indirects
 bne nbootx exit if error
 stu mapptr reset file map pointer
 lda #128 set new direct count
 sta direct
 bra rdblk now read data block

* Convert block number in D to track & sector

blkts
*
* dm5sk - set up for 5" seek
*
dm5sk pshs d save block #
 bsr divby4 divide D by 4
 ldx #2 repeat following code twice
dm5sk0 addd 0,s
 lsra
 rorb
 addd 0,s
 bsr divby8 divide D by 8
 leax -1,x done?
 bne dm5sk0
* D has block/5
dm5sk1 tst dnsity,pcr double density?
 bne dm5dd yes
 pshs d save track #
 aslb
 rola
 aslb
 rola
 addd 0,s get track * 5
 pshs d
 ldd 4,s get original block #
 subd ,s++ compute block mod 5
dm5sk3
 leas 1,s line up stack
 puls a get track #
 incb adjust (no sector 0)
 clr sdslct set up side info
 tst dside,pcr double sided disk?
 beq dm5sk4 no
 lsra adjust track #
 bcc dm5sk4 second side?
** addb #5 adjust sector #
 pshs b
 ldb #$02
 stb sdslct
 puls b
dm5sk4
 leas 2,s pop original block #
 rts
dm5dd
 lsra compute block / 10
 rorb
 pshs d save track #
 aslb
 rola
 aslb
 rola
 aslb
 rola
 addd 0,s get track * 10
 addd 0,s
 pshs d
 ldd 4,s get original block #
 subd ,s++ compute block mod 10
 bra dm5sk3

* Read the specified map block

mread lbsr blkts convert block to trk & sct
 ldx #map address of buffer for block

****************************************************

* Read a single sector

xread
 stb secreg set sector
 leau 0,x save buffer start
 cmpa trkreg check new track
 beq seek4
 sta datreg setup wd reg
 lbsr del delay
 clr ccreg
 lda #SKCMND setup command
 sta comreg issue command
 lbsr del delay
seek4 bsr xwait
* select proper side and density
 ldb #$14 default to side 0 & drive 2
seek6 tst dnsity,pcr see if double density
 bne seek8 skip if so
 orb #$20 set single density
seek8 stb drvreg do select
config bsr altadr
 std addreg
 lda #RDCMND setup command
 ora sdslct

* do dma transfer

dodma ldb latch get ex address
 tst sdslct check side select
 beq dodma1
 orb #$40 set 2nd side
dodma1 orb #$10 set for controller
 stb ccreg send to dma
 sta comreg send disk command
 bsr del
 ldx #$E000 set counter
dodma2 lda drvreg get status
 asla
 bmi dodma4
 dex dec the count
 bne dodma2 loop til done
dodma4 clr ccreg clr dma
 bsr xwait xwait til finished
dodma7 bitb #$FC check for errors
 rts return

* convert address for dmaf

altadr lda $010B get memory map value
 tfr a,b
 lsra get upper half
 lsra
 lsra
 lsra
 sta latch setup dmaf latch
 lda cputyp check CPU type
 bmi 10f jump for GIMIX III (positive DAT)
 comb
10 lslb get lower half
 lslb
 lslb
 lslb
 pshs b save it
 tfr x,d get address
 anda #$0F mask off upper 4 bits
 ora 0,s+ replace with map bits
 rts return with address in d

* xwait

xwait ldb comreg get status
 bitb #BUSY check if busy
 bne xwait
xwait2 rts  return

* delay

del lda #$20
del2 deca
 bne del2
 rts

****************************************************


* filename for booting

btname fcc 'uniflex'
 fcb 0,0,0,0,0,0,0

 if (*-uboot)>512
 err 'Bootstrap Overflow'
 else
 rzb 512-(*-uboot)
 endif

 end
