not quite initial version...

This commit is contained in:
Kelvin Sherlock 2015-08-11 18:56:19 -04:00
commit 66ebcaf3bf
15 changed files with 2501 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.o

24
Makefile Normal file
View File

@ -0,0 +1,24 @@
SOURCES = main.aii volume.aii get_file_info.aii \
id_disk.aii stubs.aii tables.aii device.aii
OBJECTS=$(SOURCES:.aii=.o)
LD=mpw linkIIgs
ASM=mpw asmIIgs
#ASMFLAGS=-d DEBUG_S16 -d DebugSymbols
ASMFLAGS=-d DebugSymbols
LDFLAGS=
minix.fst : Makefile $(OBJECTS)
$(LD) $(LDFLAGS) -t \$$BD -at \$$0000 $(OBJECTS) -o $@
clean:
rm -f $(OBJECTS)
#.aii.o:
%.o : %.aii
$(ASM) $(ASMFLAGS) $< -o $@

38
device.aii Normal file
View File

@ -0,0 +1,38 @@
include 'gsos.equ'
device_rw proc
; inputs: a = call num
; outputs: carry, a
with dev_parms
sta dev_callnum
loop
jsl dev_dispatcher
bcc exit
cmp #drvr_disk_sw
beq loop
cmp #drvr_busy
beq loop
sec
exit
rts
endp
device_read proc export
lda #drvr_read
bra device_rw
endp
device_write proc export
lda #drvr_write
bra device_rw
endp
end

78
fst.equ Normal file
View File

@ -0,0 +1,78 @@
; my direct page.
dp record $0080
io_buffer ds.l 1
ptr ds.l 1 ; misc ptr
my_vcr ds.l 1
my_fcr ds.l 1
call_class ds.w 1
device ds.w 1 ; device for id_disk.
tool_error ds.w 1
inode ds.w 1
parent_inode ds.w 1
disk_inode ds v1_inode
IF *>=$d4 THEN
AERROR 'dp -- too large.'
ENDIF
endr
fcr record 0
ref_num ds.w 1
path_name ds.l 1
fst_id ds.w 1
vol_id ds.w 1
level ds.w 1
newline ds.l 1
newline_length ds.w 1
mask ds.w 1
access ds.w 1
; fst-specific items
ino ds.w 1
inode ds v1_inode
dirty ds.w 1
mark ds.l 1 ; current position
sizeof equ *
endr
vcr record 0
id ds.w 1
name ds.l 1
status ds.w 1
open_count ds.w 1
fst_id ds.w 1
device ds.w 1
fst_ptr ds.l 1
; fst-specific items
; super block elements.
super ds v1_super
first_inode_block ds.w 1
first_imap_block ds.w 1
first_zmap_block ds.w 1
sizeof equ *
endr
fst_id equ 'mx'

209
fst.macros Normal file
View File

@ -0,0 +1,209 @@
; dispatch table for variable-pcount structures.
MACRO
&lab dispatch &table
&lab
@loop
ldy &table,x
jsr (&table+2,x)
dex
dex
dex
dex
bpl @loop
MEND
MACRO
str.&size ; &arg, ...
lclc &str
lcla &i, &l
&str setc &setting('string')
STRING asis
if &size<>'' THEN
dc.&size @end-@start
ENDIF
@start
&i seta 1
&l seta &nbr(&syslist)
WHILE &i<=&l DO
dc.b &syslist[&i]
&i seta &i+1
ENDWHILE
@end
STRING &str
MEND
MACRO
long &p1,&p2
lcla &bits
&bits seta %00000000
;&p1 setc &lc(&p1)
;&p2 setc &lc(&p2)
if &p1='m' OR &p2='m' THEN
&bits seta &bits+%00100000
longa on
ENDIF
if &p1='x' OR &p2='x' THEN
&bits seta &bits+%00010000
longi on
ENDIF
IF &bits<>0 THEN
rep #&bits
ENDIF
MEND
MACRO
short &p1,&p2
lcla &bits
&bits seta %00000000
;&p1 setc &lc(&p1)
;&p2 setc &lc(&p2)
if &p1='m' OR &p2='m' THEN
&bits seta &bits+%00100000
longa off
ENDIF
if &p1='x' OR &p2='x' THEN
&bits seta &bits+%00010000
longi off
ENDIF
IF &bits<>0 THEN
sep #&bits
ENDIF
MEND
macro
&l ~ConvSeconds &p1,&p2,&p3
&l ph2 &p1
ph4 &p2
ph4 &p3
ldx #$3703
jsl $E10000
mend
macro
&l ~Long2Hex &p1,&p2,&p3
&l ph4 &p1
ph4 &p2
ph2 &p3
ldx #$230B
jsl $E10000
mend
macro
&l ~Int2Hex &p1,&p2,&p3
&l ph2 &p1
ph4 &p2
ph2 &p3
ldx #$220B
jsl $E10000
mend
macro
&l _DebugHexDump
&l ldx #$0fff
jsl $e10000
mend
macro
&l ~DebugHexDump &p1,&p2
&l ph4 &p1
ph2 &p2
ldx #$0fff
jsl $e10000
mend
macro
&l _DebugSetTrace
&l ldx #$10ff
jsl $e10000
mend
macro
&l ~DebugSetTrace &p1
&l ph2 &p1
ldx #$10ff
jsl $e10000
mend
; borrowed from orca/m
; mpw's pushword/pushlong have bugs and generally sucks
MACRO
ph2 &n1
IF &n1='*' THEN
MEXIT
ENDIF
IF &n1[1:1]='#' THEN
pea &n1[2:255]
MEXIT
ENDIF
IF &n1[1:1]='<' THEN
pei &n1
MEXIT
ENDIF
lda &n1
pha
MEND
MACRO
ph4 &n1
IF &n1='*' THEN
MEXIT
ENDIF
IF &n1[1:1]='#' THEN
pea |(&n1[2:255])>>16
pea |&n1[2:255]
MEXIT
ENDIF
IF &n1[1:1]='<' THEN
pei &n1+2
pei &n1
MEXIT
ENDIF
lda &n1+2
pha
lda &n1
pha
MEND

520
get_file_info.aii Normal file
View File

@ -0,0 +1,520 @@
include 'gsos.equ'
include 'minix.equ'
include 'fst.equ'
include 'fst.macros'
include 'M16.Debug'
TimeRec RECORD 0
second DS.B 1
minute DS.B 1
hour DS.B 1
year DS.B 1
day DS.B 1
month DS.B 1
extra DS.B 1
weekDay DS.B 1
ENDR
FileInfoRecGS RECORD 0
pCount DS.W 1
pathname DS.L 1
access DS.W 1
fileType DS.W 1
auxType DS.L 1
storageType DS.W 1
createDateTime DS TimeRec
modDateTime DS TimeRec
optionList DS.L 1
eof DS.L 1
blocksUsed DS.L 1
resourceEOF DS.L 1
resourceBlocks DS.L 1
ENDR
FileRec RECORD 0
pathname DS.B 4
fAccess DS.B 2
fileType DS.B 2
auxType DS.B 4
storageType DS.B 2
createDate DS.B 2
createTime DS.B 2
modDate DS.B 2
modTime DS.B 2
blocksUsed DS.B 4
ENDR
entry path_to_inode
import id_disk
import device_read
get_file_info procname export
with fst_parms
with dev_parms
with dp
jsr path_to_inode
bcc @inode
rtl
@inode
; we have an inode. and my_vcr is valid.
; we need to actually _load_ the inode.
; todo -- check if inode # is valid?
; todo -- check if bit set in imap?
;pha ; space
;~DebugSetTrace #1
;pla ; prev value
ldy #vcr.first_inode_block
lda [my_vcr],y
asl a ; x 2
sta dev_blk_num
; 32 inodes per block.
; however, I'd rather read half-block chunks, with means
; 16 inodes per half-block.
lda inode
dec a ; inode 1 is offset 0.
lsr a ; / 2
lsr a ; / 4
lsr a ; / 8
lsr a ; / 16
;lsr a ; / 32
clc
adc dev_blk_num
sta dev_blk_num
lda #512
sta dev_req_cnt
lda device
sta dev_num
jsr device_read
bcc ok
rtl
ok
; find the inode...
lda inode
dec a ; inode 1 is offset 0.
and #$0f
; multiply by 32
asl a ; x 2
asl a ; x 4
asl a ; x 8
asl a ; x 16
asl a ; x 32
clc
adc io_buffer
sta ptr
lda #0
adc io_buffer+2
sta ptr+2
; copy to dp
ldy #0
ldx #0
@loop
lda [ptr],y
sta disk_inode,x
inx
inx
iny
iny
cpy #v1_inode.sizeof
blt @loop
;pha ; space
;~DebugSetTrace #0
;pla ; prev value
lda <call_class
beq class0
class1
lda [param_blk_ptr] ; pcount
dec a
asl a ; x 2
asl a ; x 4
tax
dispatch file_info_dcb_1
lda tool_error
cmp #0
rtl
class0
ldx #(8-1)*4
dispatch file_info_dcb_0
lda tool_error
cmp #0
rtl
import do_ignore
import do_access
import do_create_date_time, do_mod_date_time
import do_create_date_time_0, do_mod_date_time_0
import do_option_list
import do_file_type, do_aux_type, do_storage_type
import do_eof, do_blocks, do_r_eof, do_r_blocks
file_info_dcb_0
dc.w $00, do_ignore ; pathname
dc.w $04, do_access
dc.w $06, do_file_type
dc.w $08, do_aux_type
dc.w $0c, do_storage_type
dc.w $0e, do_create_date_time_0
dc.w $12, do_mod_date_time_0
dc.w $16, do_blocks
file_info_dcb_1
;dc.w $00, do_ignore ; pCount
dc.w $02, do_ignore ; pathname
dc.w $06, do_access
dc.w $08, do_file_type
dc.w $0a, do_aux_type
dc.w $0e, do_storage_type
dc.w $10, do_create_date_time
dc.w $18, do_mod_date_time
dc.w $20, do_option_list
dc.w $24, do_eof
dc.w $28, do_blocks
dc.w $2c, do_r_eof
dc.w $30, do_r_blocks
endp
do_access proc
with dp,fst_parms
lda disk_inode.mode
lda #$c3 ; ehh
sta [param_blk_ptr],y
rts
endp
do_storage_type proc
with dp,fst_parms
lda disk_inode.mode
; check for directory. GS/OS doesn't have concepts for other types (yet).
and #S_IFMT
cmp #S_IFDIR
beq dir
lda #1
bra store
dir
lda #$0d
store
sta [param_blk_ptr],y
rts
endp
do_file_type proc
with dp,fst_parms
lda disk_inode.mode
and #S_IFMT
cmp #S_IFDIR
beq dir
cmp #S_IFREG
beq reg
unknown
lda #$00
bra store
dir
lda #$0f
bra store
reg
lda #$06 ; binary
bra store
store
sta [param_blk_ptr],y
rts
endp
do_aux_type proc
with dp,fst_parms
lda #0
sta [param_blk_ptr],y
rts
endp
do_eof proc
with dp,fst_parms
lda disk_inode.size
sta [param_blk_ptr],y
iny
iny
lda disk_inode.size+2
sta [param_blk_ptr],y
rts
endp
do_blocks proc
with dp,fst_parms
with v1
phx ; save
phy ; save
; 7 direct blocks, 1 indirect block, 1 double indirect block.
ldx #0
ldy #0 ; count
@loop
lda disk_inode.zone,x
beq @next
iny
@next
inx
inx
cpx #NR_DZONES*2
bcc @loop
; y is number of direct blocks.
; check for indirect block...
lda disk_inode.zone + NR_DZONES * 2
beq dib
;
; count up indirect blocks...
;
iny
dib
; check for double indirect block
lda disk_inode.zone + (NR_DZONES + 1) * 2
beq store
;
; count up double indirect blocks....
;
iny
store
tya
ply
sta [param_blk_ptr],y
iny
iny
lda #0
sta [param_blk_ptr],y
plx ; restore
rts
endp
do_r_eof proc
with dp,fst_parms
entry do_r_blocks
do_r_blocks
lda #0
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
rts
endp
do_option_list proc
with dp,fst_parms
; if the option list is present, store my fst id.
lda [param_blk_ptr],y
sta ptr
iny
iny
lda [param_blk_ptr],y
sta ptr+2
ora ptr
beq exit
; check if the option list ptr is large enough.
lda [ptr]
cmp #4
bcc pre
; store the size of the option list.
ldy #2
lda #2
sta [ptr],y
lda [ptr]
cmp #6
bcc bts
bra ok
; less than 4 is a parm range error.
; less than the necessary option list size is a buf_too_small error. (but store the space required)
pre
lda #parm_range_err
sta tool_error
bra exit
bts
lda #buff_too_small
sta tool_error
bra exit
ok
ldy #4
lda #fst_id
sta [ptr],y
exit
rts
endp
do_create_date_time_0 proc
with fst_parms
; todo ...
entry do_mod_date_time_0
do_mod_date_time_0
lda #0
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
rts
endp
do_create_date_time proc
with fst_parms
; todo ...
entry do_mod_date_time
do_mod_date_time
lda #0
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
iny
iny
sta [param_blk_ptr],y
rts
endp
path_to_inode proc
with dp,fst_parms
path equ path1_ptr
dev_num equ dev1_num
stz inode
lda #1
sta parent_inode
lda path_flag
and #$4000
bne check_path
no_path
; device only (eg, .dev1 )
;
lda #1
sta inode
lda dev_num
beq bps
sta device
jmp id_disk
; returns
bps
lda #bad_path_syntax
sec
rts
check_path
; but is it relative?
lda [path]
and #$00ff
cmp #':'
beq absolute
lda #1
sta inode
lda dev_num
bne bps
jsr id_disk
rts
absolute
;
; worst case ...
; 1. extract the volume name.
; 2. call find_vcr to find it by name
; 3. if that fails, scan all devices.
lda #1
sta inode
clc
rts
endp
end

262
gsos.equ Normal file
View File

@ -0,0 +1,262 @@
string asis
case on
MACRO
DEFAULT &var,&value
IF &FINDSYM(&SYSGLOBAL,&var)=0 THEN
&var EQU &value
ENDIF
MEND
; ` prevents expansion during macro processing.
DEFAULT `DEBUG_S16,0
DEFAULT `DebugSymbols,0
****************************************************************
*
* The following are equates for GS/OS error codes.
*
****************************************************************
no_error equ $00 ; no error has occured
bad_system_call equ $01 ; bad system call number
fst_load_fail equ $02 ; couldn't load FST
invalid_pcount equ $04 ; invalid parameter count
gsos_active equ $07 ; gsos already active
dev_not_found equ $10 ; device not found
invalid_dev_num equ $11 ; invalid device number
drvr_bad_req equ $20 ; bad request or command
drvr_bad_code equ $21 ; bad control or status code
drvr_bad_parm equ $22 ; bad call parameter
drvr_not_open equ $23 ; character device not open
drvr_prior_open equ $24 ; character device already open
irq_table_full equ $25 ; interrupt table full
drvr_no_resrc equ $26 ; resources not available
drvr_io_error equ $27 ; I/O error
drvr_no_dev equ $28 ; device not connected
drvr_busy equ $29 ; driver is busy & not available
drvr_wr_prot equ $2B ; device is write protected
drvr_bad_count equ $2C ; invalid byte count
drvr_bad_block equ $2D ; invalid block number
drvr_disk_sw equ $2E ; disk has been switched
drvr_off_line equ $2F ; device off line / no media present
bad_path_syntax equ $40 ; invalid pathname syntax
invalid_ref_num equ $43 ; invalid reference number
path_not_found equ $44 ; subdirectory does not exist
vol_not_found equ $45 ; volume not found
file_not_found equ $46 ;
dup_pathname equ $47 ; create or rename with existing name
volume_full equ $48 ;
vol_dir_full equ $49 ; volume directory full
version_error equ $4A ;
bad_store_type equ $4B ; bad storage type
end_of_file equ $4C ;
out_of_range equ $4D ; position out of range
invalid_access equ $4E ; access not allowed
buff_too_small equ $4F ; buffer too small
softerrorlow equ $50 ; errors from $50 to $6f are soft errors
file_busy equ $50 ; file is already open
dir_error equ $51 ; directory error
unknown_vol equ $52 ; unknown volume type
parm_range_err equ $53 ; parameter out of range
out_of_mem equ $54 ; out of memory
dup_volume equ $57 ; duplicate volume name
not_block_dev equ $58 ; not a block device
invalid_level equ $59 ; specified level outside legal range
damaged_bitmap equ $5A ; block number too large
bad_path_names equ $5B ; invalid pathnames for change_path
not_system_file equ $5C ; not an executable file
os_unsupported equ $5D ; operating system not supported
stack_overflow equ $5F ; too many applications on stack
data_unavail equ $60 ; data unavailable
end_of_dir equ $61 ; end of directory has been reached
invalid_class equ $62 ; invalid FST call class
res_not_found equ $63 ; file does not contain req. resource
invalid_fst_id equ $64 ; specified FST is not present in system
invalid_fst_op equ $65 ; FST does not handle this type of call
fst_caution equ $66 ; FST handled call, but result is weird
dup_device equ $67 ; used internally only!!!
dev_list_full equ $68 ; device list is full
sup_list_full equ $69 ; supervisor list is full
fst_error equ $6A ;generic FST error
softerrorhigh equ $6f ; maximum soft error number allowed
resource_exist equ $70 ;Cannot expand file, resource already exist
res_add_err equ $71 ;cannot add resource fork to this type file.
network_error equ $88 ;Generic network error.
****************************************************************
*
* System Service Table Equates:
*
****************************************************************
dev_dispatcher equ $01FC00 ;dev_dispatch (initialized by new dev dispatcher)
cache_find_blk equ $01FC04 ;cash_find
cache_add_blk equ $01FC08 ;cash_add
cache_init equ $01FC0C ;cache initialization
cache_shutdn equ $01FC10 ;cash_shutdown
cache_del_blk equ $01FC14 ;cash_delete
cache_del_vol equ $01FC18 ;cash_del_vol
alloc_seg equ $01FC1C ;alloc_zero
release_seg equ $01FC20 ;deallocate
alloc_vcr equ $01FC24 ;allocvcr
release_vcr equ $01FC28 ;releasevcr
alloc_fcr equ $01FC2C ;allocfcr
release_fcr equ $01FC30 ;releasefcr
swap_out equ $01FC34 ;swapout
deref equ $01FC38 ;deref2
get_sys_gbuf equ $01FC3C ;s_get_sys_gbuf
sys_exit equ $01FC40 ;s_sys_exit
sys_death equ $01FC44 ;s_sys_death
find_vcr equ $01FC48 ;findvcr
find_fcr equ $01FC4C ;findfcr
set_sys_speed equ $01FC50 ;set system speed (initialized by new dev dispatcher)
cache_flsh_def equ $01FC54 ;flush deferred blocks from cache
rename_vcr equ $01FC58 ;renamevcr
rename_fcr equ $01FC5C ;renamefcr
get_vcr equ $01FC60 ;getvcr
get_fcr equ $01FC64 ;getfcr
lock_mem equ $01FC68 ;lockmem
unlock_mem equ $01FC6C ;unlockmem
move_info equ $01FC70 ;block move routines
cvt_0to1 equ $01FC74 ;cvt0to1
cvt_1to0 equ $01FC78 ;cvt1to0
replace_80 equ $01FC7C ;replace80
to_b0_core equ $01FC80 ;to_bank0_core
gen_dispatch equ $01FC84 ;g_dispatch
signal equ $01FC88 ;signal_event
get_sys_buf equ $01FC8C ;get_b0_buf
set_disksw equ $01FC90 ;set_disk_sw (initialized by new dev dispatcher)
report_error equ $01FC94 ;s_report_error
mount_message equ $01FC98 ;s_mount_msg
full_error equ $01FC9C ;s_full_error
report_fatal equ $01FCA0 ;s_report_fatal
sup_drvr_disp equ $01FCA4 ;supervisory dispatcher
install_driver equ $01FCA8 ;install device driver
get_boot_pfx equ $01FCAC ;s_get_boot_pfx
set_boot_pfx equ $01FCB0 ;s_set_boot_pfx
alloc_cache_seg equ $01FCB4 ;low_allocate
get_stked_id equ $01FCB8 ;get id of prog at top of GQUIT stack
dyn_slot_arbiter equ $01FCBC ;slot arbitration routine (initialized by new dev dispatcher)
parse_pathname equ $01FCC0 ;parse a pathname
post_os_event equ $01FCC4 ;notify external code about os event.
dynamic_install equ $01FCC8 ;install drivers (new init by SCM to JML INSERT_DRIVER)
dev_mgr_svc equ $01FCCC ;device manager entry (initialized by new dev dispatcher)
old_dev_disp equ $01FCD0 ;old device dispatcher (new init by SCM to JML DEV_DISPATCH)
init_parse_path equ $01FCD4 ;initialize for parse_path.
;
; Event codes for os_event
;
volmod_event equ $0040 ; event code for volume modified
disk_in_event equ $0008 ; disk inserted event
;
; Driver command codes
;
drvr_startup equ 0
drvr_open equ 1
drvr_read equ 2
drvr_write equ 3
drvr_close equ 4
drvr_status equ 5
drvr_control equ 6
drvr_flush equ 7
drvr_shutdown equ 8
drvr_get_dib equ 1
;
; Driver control and status call codes
;
stat_status equ 0
stat_config equ 1
*
* System Death error codes
*
vcr_unusable equ $000A ; VCR is unusable/inconsistent
fcr_unusable equ $000B ; FCR is unusable/inconsistent
vcr_swapped equ $4000 ;FLAG:Volume is swapped out (1 = true)
vcr_swapped_in equ $BFFF ;FLAG:Volume is swapped in
vcr_wr_enable equ $2000 ;FLAG:Volume has been seen write enabled
vcr_wr_unknown equ $DFFF ;FLAG:Volume has not been seen wrenbld
*
* access bits.
*
read_enabled equ $0001 ;1=Read Enabled
write_enabled equ $0002 ;1=Write Enabled
backup_enabled equ $0020 ;1=Needs to be backed up
rename_enabled equ $0040 ;1=Rename allowed
destroy_enabled equ $0080 ;1=Destroy is enabled
read_access equ $01
write_access equ $02
invis_bit equ $04
read_write_acc equ $03
; records
dev_parms record 0
;--------------------------------------------------
; Here are the device driver fields
;--------------------------------------------------
dev_num ds.w 1 ; device number being called
dev_callnum ds.w 1 ; call number
dev_dev_id ; device ID (get_dib_ptr)
dev_buff ; I/O buffer address
ds.l 1
dev_req_cnt ds.l 1 ; request count
dev_xfer_cnt ds.l 1 ; transfer count
dev_blk_num ds.l 1 ; block number
dev_blk_size ds.w 1 ; block size
dev_fst_num ; FST number
dev_stat_code ; status code
dev_ctrl_code ; control code
ds.w 1
dev_vol_id ds.w 1 ; volume ID (???)
dev_cache_pr ds.w 1 ; cache priority
dev_cache_ptr ds.l 1 ; cache pointer
dev_dib_ptr ds.l 1 ; pointer to DIB
endr
; gs/os direct page.
fst_parms record $0030
call_number ds.w 1 ; FST call number
param_blk_ptr ds.l 1 ; pointer to user's parameter block
;dev_num ; device number from parameter block
dev1_num ds.w 1 ; alias name for dev_num
dev2_num ds.w 1 ; second device number
path1_ptr ; ptr to 1st partial/entire pathname
fcr_ptr ds.l 1 ; pointer to file control record
path2_ptr ; ptr to 2nd partial/entire pathname
vcr_ptr ds.l 1 ; pointer to volume control record
path_flag ds.w 1 ; flag for path information
span1 ds.w 1 ; largest distance between path1 term.
span2 ds.w 1 ; max dist. between separators for path2
endr

96
hexdump.text Normal file
View File

@ -0,0 +1,96 @@
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
0000-0400 - boot block
00000400 20 01 20 03 01 00 01 00 0d 00 00 00 00 1c 08 10 | . .............|
00000410 7f 13 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
400-800 -- super block
super record 0
inodes $0120
nzones $0320
imap_blocks $0001
zmap_blocks $0001
firstdatazone $000d
log_zone_size $0000
max_size 10081c00
magic 137f
ds.w 1 ; padding ???
zones 1 ? 0?
endr
00000800 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000820 00 00 00 00 fe ff ff ff ff ff ff ff ff ff ff ff |................|
00000830 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
800-c00 - inode map block ($0120 inodes / 1024 = 1 block)
00000c00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000c60 00 00 f0 ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
00000c70 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
c00--1000 zone map ($0320 zones / 1024 = 1 block)
mode = 41ed
uid = 03e8
size = 2
time = 52ec17be
gid = e8
nlinks = 02
zones = [0d]
32 bytes total. -- 32 nodes per block.
00001000 ed 41 e8 03 20 00 00 00 be 17 ec 52 e8 02 0d 00 |.A.. ......R....|
00001010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
1000 -- 1000+2400 -- inode table ($120 inodes * 16 bytes / 1024 = 4068 / 1024 = 5 blocks)
3400 = block 13 = $0x0d
[{01, '.'}, {01, '..'}]
[{0, 'badblocks'}] ???
00003400 01 00 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00003410 01 00 2e 2e 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00003420 00 00 2e 62 61 64 62 6c 6f 63 6b 73 00 00 00 00 |...badblocks....|
00003430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000c8000
3400--end = data zones
range record 0
location ds.w 1
length ds.w 1
endr
vcr
{
magic ds.w 1 ;
inode_map ds range
zone_map ds range
inode_table ds range
zone_table ds range
data_table ds range
}

101
hexdump2.text Normal file
View File

@ -0,0 +1,101 @@
qnap:/tmp# mkfs.minix -1 -v minix.disk
272 inodes
800 blocks
Firstdatazone=21 (21)
Zonesize=1024
Maxsize=2147483647
qnap:/tmp# cat badblocks
100
101
102
103
104
105
106
107
108
109
100
qnap:/tmp# mkfs.minix -1 -l badblocks minix.disk
288 inodes
800 blocks
Firstdatazone=13 (13)
Zonesize=1024
Maxsize=268966912
11 bad blocks
inodes = blocks / 3
inode size = 32
direct size = 32 (max length = 30)
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| << boot block
*
00000400 20 01 20 03 01 00 01 00 0d 00 00 00 00 1c 08 10 | . .............| << super block
00000410 8f 13 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
0120 nodes
0320 zones
0001 inode map blocks
0001 zone map blocks
000d first data zone
0000 log 2 (zone size / block size)
10081c00 -- max file size
138f -- magic
0001 -- state
/* minix_super_block.s_state */
#define MINIX_VALID_FS 0x0001 /* Clean fs. */
#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
#define MINIX_SUPER_MAGIC 0x137F /* minix V1 fs, 14 char names */
#define MINIX_SUPER_MAGIC2 0x138F /* minix V1 fs, 30 char names */
#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs, 14 char names */
#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */
#define MINIX3_SUPER_MAGIC 0x4d5a /* minix V3 fs (60 char names) */
00000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000800 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| << inode map 7 = 0x0000 0111 -- node 0, node 1, node 2
00000810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000820 00 00 00 00 fe ff ff ff ff ff ff ff ff ff ff ff |................|
00000830 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000c00 07 00 00 00 00 00 00 00 00 00 00 ff 03 00 00 00 |................| << zone map { blocks 0, blocks 1, block 2 },
00000c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000c60 00 00 f0 ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
00000c70 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00001000 ed 41 00 00 60 00 00 00 cf d4 c4 55 00 02 0d 00 |.A..`......U....| << inode 1
00001010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001020 00 80 00 00 00 2c 00 00 cf d4 c4 55 00 01 64 00 |.....,.....U..d.| << inode 2
00001030 65 00 66 00 67 00 68 00 69 00 6a 00 0e 00 00 00 |e.f.g.h.i.j.....|
00001040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
block d
00003400 01 00 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| << { 1, . }
00003410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00003420 01 00 2e 2e 00 00 00 00 00 00 00 00 00 00 00 00 |................| << { 1, .. }
00003430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00003440 02 00 2e 62 61 64 62 6c 6f 63 6b 73 00 00 00 00 |...badblocks....| << { 2, .badblocks }
00003450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
block e
00003800 6b 00 6c 00 6d 00 00 00 00 00 00 00 00 00 00 00 |k.l.m...........| << indirect block
00003810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000c8000

252
id_disk.aii Normal file
View File

@ -0,0 +1,252 @@
include 'gsos.equ'
include 'minix.equ'
include 'fst.equ'
include 'fst.macros'
include 'M16.Debug'
; id_disk
; identify disk in device.
;
; inputs:
; a = device id
;
; outputs:
; (registers)
; c = 1 for error
; a = error code or 0
; (dp)
; my_vcr
;
entry check_super
entry build_vcr
import device_read
id_disk procname export
;
; read the superblock
;
;
; note - minix has 1024-k blocks. I'm only reading 512
; since there's nothing of interest in the second half of the
; superblock.
with dev_parms
with v1
sta dev_num
lda #512
sta dev_blk_size
lda #SUPER_BLOCK*2
sta dev_blk_num
lda #512
sta dev_req_cnt
jsr device_read
bcs exit
jsr check_super
bcs exit
jsr build_vcr
bcs exit
; error priority $8000?
lda #0
clc
exit
rts
endp
;
; checks if the super block is valid for minix.
; returns a = error / 0
;
check_super procname
with dev_parms
with v1_super
with dp
check_magic
ldy #magic
lda [dev_buff],y
cmp #v1.MAGIC
beq @ok
cmp #v1L.MAGIC
bne no
@ok
check_log_zone
; should be 0
ldy #log_zone_size
lda [dev_buff],y
bne no
yes
clc
rts
no
lda #unknown_vol
sec
rts
endp
build_vcr procname
; for now, volume hard coded as 'minix'.
with v1
with dp
ldx #default_name
ldy #^default_name
lda #0
jsl find_vcr
bcs create_vcr
jsl deref
stx my_vcr
sty my_vcr+2
ldy #vcr.fst_id
lda [my_vcr],y
cmp #fst_id
bne dump_vcr
ldy #vcr.status
lda [my_vcr],y
and #vcr_swapped
beq @exit
and #vcr_swapped_in
sta [my_vcr],y
lda device
ldy #vcr.device
sta [my_vcr],y
@exit
lda #0
clc
rts
dump_vcr
; vcr exists for the filename but it's not mine.
; if inactive, kick it out. otherwise, return dup error.
;
; todo -- prodos fst has kludge for change path which
; allows duplicates if using a device name or something...
;
ldy #vcr.open_count
lda [my_vcr],y
beq @dump
lda #dup_volume
sec
rts
@dump
ldy #vcr.id
lda [my_vcr],y
jsl release_vcr
; drop through.
create_vcr
lda #vcr.sizeof
ldx #default_name
ldy #^default_name
jsl alloc_vcr
lda #out_of_mem
bcs exit
jsl deref
stx my_vcr
sty my_vcr+2
lda #0
ldy #vcr.status
sta [my_vcr],y
ldy #vcr.open_count
sta [my_vcr],y
lda #fst_id
ldy #vcr.fst_id
sta [my_vcr],y
lda dev_parms.dev_num
ldy #vcr.device
sta [my_vcr],y
; copy over the super block...
clc
lda #vcr.super
adc my_vcr
sta ptr
lda #0
adc my_vcr+2
sta ptr+2
ldy #v1_super.sizeof-2
@loop
lda [dev_parms.dev_buff],y
sta [ptr],y
dey
dey
bpl @loop
;
; boot
; super
; imap blocks
; zmap blocks
; inodes
; zones
; calculate offsets
lda #2 ; hard-coded.
ldy #vcr.first_imap_block
sta [my_vcr],y
clc
ldy #vcr.super.imap_blocks
adc [my_vcr],y
ldy #vcr.first_zmap_block
sta [my_vcr],y
clc
ldy #vcr.super.zmap_blocks
adc [my_vcr],y
ldy #vcr.first_inode_block
sta [my_vcr],y
~DebugHexDump <my_vcr,#vcr.sizeof
lda #0
clc
exit
rts
default_name
str.w 'minix'
endp
end

288
main.aii Normal file
View File

@ -0,0 +1,288 @@
include 'gsos.equ'
include 'minix.equ'
include 'fst.equ'
include 'fst.macros'
include 'M16.Debug'
entry app_entry
entry sys_entry
entry sys_startup
entry sys_shutdown
entry rtl_invalid_fst_op
entry rtl_bad_system_call
entry rtl_no_error
entry rtl_invalid_pcount
import judge_name
import create
import destroy
import change_path
import set_file_info
import get_file_info
import volume
import open
import read
import write
import flush
import close
import get_mark
import set_mark
import get_eof
import set_eof
import get_dir_entry
import get_dev_num
import format
import erase_disk
header proc
;
; FST attributes
; case-insensitive = $8000 [dispatcher should upper case]
; character device = $4000
; format = $2000
; clear high bits = $1000
; read-only = $0800
dc.b 'FST '
dc.l app_entry
dc.l sys_entry
dc.w fst_id
dc.w $2002 ; flags -- format, block device, non-apple format
dc.w $0100 ; version 1.0
dc.w 1024 ; block size
dc.l $ffffffff ; max blocks/volume
dc.l $00000006 ; min blocks/volume
dc.l $10081c00 ; max file size
dc.l 0 ; reserved
str.b 'minix' ; FST Name
str.b 'minix FST' ; FST Comment
dc.w 0
; credits
str.b $0d,'Minix FST by Kelvin W Sherlock, 2014',$0d
endp
data record
export global_buffer
global_buffer ds.l 1
endr
sys_entry procname
phk
plb
rep #$30
cpx #max_sys_call+1
bge rtl_no_error
jmp (@sys_table,x)
@sys_table
dc.w rtl_no_error
dc.w sys_startup
dc.w sys_shutdown
dc.w rtl_no_error ; remove vcr
dc.w rtl_no_error ; deferred flush
max_sys_call equ *-@sys_table-2
endp
rtl_no_error proc
lda #0
clc
rtl
endp
rtl_invalid_fst_op proc
lda #invalid_fst_op
sec
rtl
endp
rtl_bad_system_call proc
lda #bad_system_call
sec
rtl
endp
rtl_invalid_pcount proc
lda #invalid_pcount
sec
rtl
endp
sys_startup procname
jsl get_sys_gbuf
stx global_buffer
sty global_buffer+2
lda #0
clc
rtl
endp
sys_shutdown procname
lda #0
clc
rtl
endp
; x = call number * 2
; y = class number * 2
app_entry procname
with dp
with fst_parms
import min_pcount
import max_pcount
phk
plb
rep #$30
IF DEBUG_S16 THEN
jsr debug
ENDIF
;brk $42
sty <call_class
; check the class 0 or 1 only.
cpy #2+1
bge @bad_system_call
cpx #max_app_call+1 ; 66+1
bge @bad_system_call
; class 1 -- check the pcount maximum.
cpy #2
bne @ok
lda [param_blk_ptr]
; gs/os already checks the minimum and verifies non-null names, etc.
;cmp min_pcount,x
;blt @invalid_pcount
cmp max_pcount,x
bge @invalid_pcount
@ok
; init stuff
lda global_buffer
sta io_buffer
sta dev_parms.dev_buff
lda global_buffer+2
sta io_buffer+2
sta dev_parms.dev_buff+2
stz <tool_error
stz <device
; fake an rtl address for sys_exit
; otherwise, would need to jml sys_exit from functions.
pea |(sys_exit-1)>>8
phb
lda #<sys_exit-1
sta 1,s
; call it...
jmp (@app_table,x)
@bad_system_call
lda #bad_system_call
sec
rtl
@invalid_pcount
lda #invalid_pcount
sec
rtl
@app_table
dc.w rtl_bad_system_call ;
dc.w create ; ($01) Create
dc.w destroy ; ($02) Destroy
dc.w rtl_bad_system_call ; ($03) OS Shutdown
dc.w change_path ; ($04) Change Path
dc.w set_file_info ; ($05) Set File Info
dc.w get_file_info ; ($06) Get File Info
dc.w judge_name ; ($07) Judge Name
dc.w volume ; ($08) Volume
dc.w rtl_bad_system_call ; ($09) Set Prefix
dc.w rtl_bad_system_call ; ($0A) Get Prefix
dc.w rtl_invalid_fst_op ; ($0B) Clear Backup Bit
dc.w rtl_bad_system_call ; ($0C) Set Sys Prefs
dc.w rtl_no_error ; ($0D) Null
dc.w rtl_bad_system_call ; ($0E) Expand Path
dc.w rtl_bad_system_call ; ($0F) Get Sys Prefs
dc.w open ; ($10) Open
dc.w rtl_bad_system_call ; ($11) NewLine
dc.w read ; ($12) Read
dc.w write ; ($13) Write
dc.w close ; ($14) Close
dc.w flush ; ($15) Flush
dc.w set_mark ; ($16) Set Mark
dc.w get_mark ; ($17) Get Mark
dc.w set_eof ; ($18) Set EOF
dc.w get_eof ; ($19) Get EOF
dc.w rtl_bad_system_call ; ($1A) Set Level
dc.w rtl_bad_system_call ; ($1B) Get Level
dc.w get_dir_entry ; ($1C) Get Dir Entry
dc.w rtl_bad_system_call ; ($1D) Begin Session
dc.w rtl_bad_system_call ; ($1E) End Session
dc.w rtl_bad_system_call ; ($1F) Session Status
dc.w get_dev_num ; ($20) Get Dev Num
dc.w rtl_bad_system_call ; ($21) Get Last Dev
dc.w rtl_bad_system_call ; ($22) Read Block
dc.w rtl_bad_system_call ; ($23) Write Block
dc.w format ; ($24) Format
dc.w erase_disk ; ($25) Erase Disk
dc.w rtl_bad_system_call ; ($26) Reset Cache
dc.w rtl_bad_system_call ; ($27) Get Name
dc.w rtl_bad_system_call ; ($28) Get Boot Vol
dc.w rtl_bad_system_call ; ($29) Quit
dc.w rtl_bad_system_call ; ($2A) Get Version
dc.w rtl_bad_system_call ; ($2B) Get FST Info
dc.w rtl_bad_system_call ; ($2C) D_INFO
dc.w rtl_bad_system_call ; ($2D) D_STATUS
dc.w rtl_bad_system_call ; ($2E) D_CONTROL
dc.w rtl_bad_system_call ; ($2F) D_READ
dc.w rtl_bad_system_call ; ($30) D_WRITE
dc.w rtl_bad_system_call ; ($31) Alloc Interrupt
dc.w rtl_bad_system_call ; ($32) Dealloc Interrupt
dc.w rtl_invalid_fst_op ; ($33) FST Specific
max_app_call equ *-@app_table-2
endp
end

154
minix.equ Normal file
View File

@ -0,0 +1,154 @@
; minix V1 (L)
; uses 30-char filenames