 ttl UniFLEX Disk Formatter
 sttl OMTI 5" Winchester Bootstrap
 pag
 info Bootstrap for GIMIX/OMTI Version 1.00; 03/07/85

* UniFLEX Bootstrap Loader for OMTI 5" Winchester

 global O_boot

* Equates
ffmap equ 17 file map offset in fdn
bhxfr equ 10 transfer address offset in header
BHDSIZ equ 24 binary file header size
*
* equates and addresses
*
SASI_CSR equ $F100 disk command register
SASI_ADR equ SASI_CSR+1 DMA address registers
SASI_DATA equ SASI_CSR+4 Xebec Command Register
SASI_REQ equ %00000001 Controller Request Data
SASI_RDS equ $08 Read Sector
SASI_RSS equ $03 Request Sense Status
SASI_IDC equ $C2 Initialize Drive Characteristics

* Temporary storage

 base $00E0 Page 0 data

sasiesw rmb 2 SASI  Error Status Word
sasisbf rmb 4 SASI  Sense Status Buffer
btdate rmb 4
direct rmb 1
mapptr rmb 2
fdnbkn rmb 3
entrys rmb 2
xfradr rmb 2

* System Configuration Info
 base $000C
cputyp rmb 2

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

 base new_org+512
buffer rmb 512
map rmb 512

*  ROM addresses
pdata equ $F800
outhex equ $F802
outspc equ $F804
*

 data

* Lookup "uniflex" in directory

O_boot ldx #old_org move bootstrap
 ldu #new_org
10 ldd ,x++
 std ,u++
 cmpx #old_org+512
 blo 10b
 lbra (uboot1-old_org)+new_org
*
uboot1 bsr sasiidf initialize SASI  controller
 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

*
* Initialize Xebec Controller
*
sasiidf lda #1 send IDC command
 leax IDCcmd,pcr
 lbsr sasicn send command
sasiid0 lbsr sasiwt wait for READY
 bitb #$14 wait for REQ=1, I/O=0, C/D=0
 bne sasiid0
 leax DP_TABLE,pcr Device Characteristics table
 lda #10
sasiid1 lbsr sasiwt wait for READY
 ldb ,x+ send next byte
 stb SASI_DATA
 deca done?
 bne sasiid1
 lbra sasist get status and return

* Load UniFLEX

load bsr fdnblk read in uniflex fdn
 ldx mapptr point to fdn map
 leax 13*3,x skip map
 ldd ,x++ save fdn date
 std btdate
 ldd ,x++
 std btdate+2
 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
 pshs d terminator?
 ldx ,s++ transfer count in X
 beq done start uniflex if so
 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 ldy $5002 get boot date vector
 ldd btdate
 std ,y++
 ldd btdate+2
 std ,y++
 jmp [xfradr] jump to transfer address

* Divide contents of D by 8

divby8 lsra
 rorb
 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
 std fdnbkn+1 save fdn block #
 clr fdnbkn
 ldy #fdnbkn
 bsr 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
 ldy mapptr get file map pointer
 ldx #buffer setup buffer address
 bsr xread read the sector
 pshs cc
 sty mapptr
 puls cc,pc

chgind ldy mapptr get file map pointer
 bsr 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

* Read the specified map block

mread ldx #map address of buffer for block

* Read a single sector
*  X - Buffer Address
*  Y - Block # Pointer

xread
 leau 0,x save X pointer
 bsr setadr set up DMA address
 lda ,y+ set up block #
 sta RDSblk,pcr
 ldd ,y++
 std RDSblk+1,pcr
 lda #$21 set up for DMA/no IRQ
 leax RDScmd,pcr Read Sector Command
 bsr sasicn send command
 bra sasist read status

* convert address for dmaf

setadr lda $010B get memory map value
 tfr a,b
 lsra get upper half
 lsra
 lsra
 lsra
 sta SASI_ADR set up DMA address
 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
 std SASI_ADR+1
 rts
*
* sasicn - set up SASI  command and send to Xebec
*    A - DMA/IRQ select mask
*    X - Xebec Device Control Block (Command)
*
sasicn sta SASI_CSR set up DMA/IRQ selection
 lda #6 send 6 bytes
sasicn3 bsr sasiwt wait for READY
 ldb ,x+ get next byte
 stb SASI_DATA send to controller
 deca done?
 bne sasicn3
 rts
*
* sasist - wait for operation complete & get status
*   A - Operation Status (error code)
*   X - Destroyed
*
sasist lda SASI_CSR wait for command completion
 bpl sasist
sasist0 bsr sasiwt get command status
 lda SASI_DATA
 pshs a
 bsr sasiwt
 ldb SASI_DATA
 puls a
 bita #2 error bit set?
 beq sasist9 no - exit
 leax <MAmsg,pcr
 jsr [pdata]
 lda #1 no DMA/IRQ
 leax RSScmd,pcr Request Sense Status
 bsr sasicn send command
 lda #4
sasist1 bsr sasiwt wait for READY
 pshs a save counter on stack
 lda SASI_DATA get data
 jsr [outhex]
 jsr [outspc]
 puls a restore count
 deca done?
 bne sasist1
 bsr sasiwt get command status
 lda SASI_DATA
 bsr sasiwt
 ldb SASI_DATA
 puls d,x clean up stack - major error code in A
 anda #$7F
 cmpa #$18 allow ECC correctable errors through
sasist9 rts return
MAmsg fcc $d,'Error: ',0
*
*  Wait for Xebec to request data
*
sasiwt ldb SASI_CSR test READY
 bitb #1
 beq sasiwt wait until READY
 rts
*
*  Data Space for Bootstrap Loader
*
RDScmd fcb SASI_RDS Read Sector Command
RDSblk rzb 3 Block #
 fcb 1 1 Sector
 fcb 0
RSScmd fcb SASI_RSS Request Sense Status Command
 fcb 0,0,0,0
 fcb 0
IDCcmd fcb SASI_IDC Initialize Drive Characteristics
 fcb 0,0,0,0
 fcb 0

*
* Device parameters control block - OMTI 20C Controller
*
 define
DP_TABLE  equ *
DP_width  fcb 0 Step Pulse Width
DP_period fcb 0 Time between pulses
DP_mode   fcb 0 Stepping mode (0->buffered)
DP_heads  fcb 0 Number of heads (-1)
DP_cyls   fdb 0 Number of cylinders (-1)
DP_wsi    fcb 0 Write Precomp cylinder
DP_type   fcb 0 Drive type
DP_sectrk fcb 0 Sectors/Track
          fcb 0 ** Filler **
 enddef


* filename for booting

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

* filler bytes

 if (*-O_boot)>512
 err 'Bootstrap overflow'
 else
 rzb 512-(*-O_boot)
 endif
 end
