commit 0c4092d7795483ff847ad97c6a58c06a91b35f94 Author: Kelvin Sherlock Date: Fri Oct 14 23:03:00 2016 -0400 initial check-in. device driver works [?] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..73679f3 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ + +LD=mpw linkIIgs +ASM=mpw asmIIgs +#ASMFLAGS=-d DEBUG_S16 -d DebugSymbols +ASMFLAGS=-case on +LDFLAGS= + + +all : host.driver host.fst + +host.fst : host.fst.o + $(LD) -t \$$BD -at \$$0000 $< -o $@ + +# aux type (-at) +# $8000 = inactive +# $0100 = gs/os driver +# $00xx = number of devices supported (should match dib) +host.driver : host.driver.o + $(LD) -t \$$BB -at \$$0101 $< -o $@ + +host.driver.o : host.driver.aii gsos.equ + +host.fst.o : host.fst.aii gsos.equ fst.equ + + + +%.o : %.aii + $(ASM) $(ASMFLAGS) $< -o $@ \ No newline at end of file diff --git a/fst.equ b/fst.equ new file mode 100644 index 0000000..2b82832 --- /dev/null +++ b/fst.equ @@ -0,0 +1,54 @@ + + ; my direct page. +dp record $0080 + +ptr ds.l 1 ; misc ptr + +my_vcr ds.l 1 +my_fcr ds.l 1 +cookie ds.w 1 + + +__end equ * + IF *>=$d4 THEN + AERROR 'dp -- too large.' + ENDIF + endr + + +fcr record 0 +id ds.w 1 ; ref num +path_name ds.l 1 +fst_id ds.w 1 +vcr_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 + +cookie ds.w 1 + +__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 + +__sizeof equ * + endr + + + + ; 5 = mfs, we're stealing it for now. +fst_id equ 5 \ No newline at end of file diff --git a/fst.macros b/fst.macros new file mode 100644 index 0000000..07e253a --- /dev/null +++ b/fst.macros @@ -0,0 +1,274 @@ + + + ; 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 _DebugGetTrace +&l ldx #$10ff + jsl $e10000 + mend + + macro +&l ~DebugGetTrace +&l ldx #$10ff + jsl $e10000 + mend + + + macro +&l _DebugSetTrace +&l ldx #$11ff + jsl $e10000 + mend + + + macro +&l ~DebugSetTrace &p1 +&l ph2 &p1 + ldx #$11ff + 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 + + + ; _rts.cc -> return iff carry clear + macro +&l _rts.&cond + + if &cond='cc' THEN + bcs @ok + ENDIF + + if &cond='cs' THEN + bcc @ok + ENDIF + + if &cond='eq' THEN + bne @ok + ENDIF + + if &cond='ne' THEN + beq @ok + ENDIF + + if &cond='mi' THEN + bpl @ok + ENDIF + + if &cond='pl' THEN + bmi @ok + ENDIF + + if &cond='vs' THEN + bvc @ok + ENDIF + + if &cond='vc' THEN + bvs @ok + ENDIF + + rts +@ok + mend + + ; reverse subtract. + macro +&l rsb &target + eor #$ffff + sec + adc &target + mend + + + diff --git a/fst_open.aii b/fst_open.aii new file mode 100644 index 0000000..d2cfe73 --- /dev/null +++ b/fst_open.aii @@ -0,0 +1,113 @@ + include 'gsos.equ' + include 'fst.equ' + include 'fst.macros' + include 'records.equ' + +open proc + + with fst_parms + + jsr check_path + bcs exit + + jsr build_vcr + bcs exit + + lda #invalid_fst_op + ldx call_number + sec + wdm #$ff + bcs exit + stx cookie + sty scratch ; actual read/write access + + ; build the fcr. + lda #fcr.__sizeof + ldx #host + ldy #^host + jsl alloc_fcr + bcs close + + jsl deref + stx my_fcr + sty my_fcr+2 + + ; need to re-deref the vcr? + + ldy #vcr.open_count + lda [my_vcr],y + inc a + sta [my_vcr],y + + lda scratch + ldy #fcr.access + sta [my_fcr],y + + lda #fst_id + ldy #fcr.fst_id + sta [my_fcr],y + + + ldy #vcr.id + lda [my_vcr],y + ldy #fcr.vcr_id + sta [my_fcr],y + +exit_ok + lda #0 + clc +exit + rtl + +close + ;; oops! close it! + lda #0 + ldx #$2014 + ldy cookie + wdm #$ff + sec + lda #out_of_mem + rtl + +host str.w ":Host" + + endp + + +path_op proc +create entry +destroy entry +get_file_info entry +set_file_info entry +clear_backup entry + + with fst_parms + + jsr check_path + bcs exit + + ; hmmm - don't really need a vcr for this... + ;jsr build_vcr + ;bcs exit + + lda #invalid_fst_op + ldx call_number + sec + wdm #$ff +exit + rtl + endp + +change_path proc + ; special since there are two pathnames. + lda #invalid_fst_op + sec + rtl + endp +judge_name proc + lda #0 + clc + rtl + endp + + end \ No newline at end of file diff --git a/gsos.equ b/gsos.equ new file mode 100644 index 0000000..f08e4c7 --- /dev/null +++ b/gsos.equ @@ -0,0 +1,263 @@ + + + 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 + +; used by ProDOS +in_cache equ $8002 + + ; 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 + + + diff --git a/host.driver.aii b/host.driver.aii new file mode 100644 index 0000000..e6a9937 --- /dev/null +++ b/host.driver.aii @@ -0,0 +1,279 @@ + + include 'gsos.equ' + include 'fst.macros' + + entry entry, startup, open, close, read, write, flush, status, control, shutdown + + ;entry open_flag, ss_count, status_word + + + + string asis +header proc + dc.w dib-header + dc.w 1 ; 1 device + dc.w 0 ; no config list + + +dib dc.l 0 ;Link pointer to next DIB + dc.l entry ;Entry pointer + dc.w %0000111100000000 ;Characteristics + dc.l 0 ;Block count + str.b 'HOST' ;Device name with length + dcb.b 32-5,$20 + dc.w $8007 ;Slot number + dc.w 1 ;Unit number + dc.w $1000 ;Version number + dc.w $0010 ;ID # file server + dc.w 0 ;No header link + dc.w 0 ;No forward link + dc.l 0 ;extended dib ptr + dc.w 0 ;Device number + + endp + + + +entry proc + + longa on + longi on + + phb ;Save the GS/OS bank register + + phk + plb + + cmp #8+1 ;Max command number + bcc @dispatch + lda #drvr_bad_req + bra exit + +@dispatch + asl a + tax + jsr (table,x) + + +exit + plb + cmp #1 + rtl + +table + dc.w startup + dc.w open + dc.w read + dc.w write + dc.w close + dc.w status + dc.w control + dc.w flush + dc.w shutdown + + endp + + +data record + export ss_count, open_flag, status_word + +ss_count dc.w 0 +open_flag dc.w 0 + + ; copied via get_device_status +status_word dc.w $0010 +blocks dc.l 0 + endr + +flush proc + lda #no_error + rts + endp + +read proc + lda #no_error + rts + endp + +write proc + lda #no_error + rts + endp + + +startup proc + stz open_flag + inc ss_count + lda #no_error + rts + endp + +shutdown proc + stz ss_count + lda #no_error + rts + endp + +open proc + lda open_flag + bne oops + + inc open_flag + lda #1 + tsb status_word + + lda #no_error + rts +oops + lda #drvr_prior_open + rts + + endp + +close proc + lda open_flag + beq oops + + stz open_flag + lda #1 + trb status_word + + lda #no_error + rts +oops + lda #drvr_not_open + rts + + endp + + +status proc + with dev_parms + + lda >8 + phb + lda #$009a00 ; hardcoded... + beq fd_op + + ; zero-out the table. + ldx #256-2 + lda #0 +@zloop + sta >$009a00+2,x + dex + dex + bpl @zloop + + ; newline list is a virtual pointer. + ldy #fcr.newline + lda [my_fcr],y + tax + iny + iny + lda [my_fcr],y + tay + jsl deref + stx ptr + sty ptr+2 + + ldy #fcr.newline_length + lda [my_fcr],y + tay + dey + + ldx #0 + lda #0 + short m +nloop + lda [ptr],y + tax + lda #$ff + sta >$009a00+2,x + dey + bpl nloop + long m + + bra fd_op + + endp + +fd_op proc + + ; read, write, truncate, etc. + ; everything (except close) that uses an fcr. + lda #invalid_fst_op + ldx call_number + ldy cookie + sec + wdm #$ff + rtl + endp + + +volume proc + ; check if a volume is ours, create vcr if necessary. + + lda fst_parms.dev1_num + beq no + + cmp dev_id + bne no + ; yes! + + lda #unknown_vol + ldx call_number + sec + wdm #$ff + bcc @ok + rtl +@ok + ; name is hardcoded to Host. + jsr build_vcr + rtl + + +no + lda #unknown_vol + sec + rtl + + endp + +build_vcr procname + + ; for now, volume hard coded as 'Host'. + + + 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 + lda dev_id + 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_id + ldy #vcr.device + sta [my_vcr],y + + lda #0 + clc +exit + rts + +default_name_colon + str.w ':Host' + +default_name + str.w 'Host' + + endp + +get_dev_num proc +path equ path1_ptr + + lda dev1_num + bne store + + jsr check_path + bcs exit + + jsr build_vcr + bcs exit + + lda dev_id +store + ldx call_class + ldy table,x + sta [param_blk_ptr],y + lda #0 + clc +exit + rtl + + +table + dc.w DevNumRec.devNum, DevNumRecGS.devNum + + endp + + ; + ; verify this path is for us + ; (via dev number or :Host:) + ; +check_path proc + lda dev1_num + beq path + cmp dev_id + beq ok + +vnf + lda #vol_not_found + sec + rts +ok + lda #0 + clc + rts +path + ldy #2 + ldx #0 + lda #0 + short m + +loop + lda [path1_ptr],y + cmp lower,y + beq @next + cmp upper,y + beq @next + long m + bra vnf +@next + iny + cpy #5+2 + bne loop + + ; check for trailing null / : + lda [path1_ptr],y + beq @ok + cmp #':' + beq @ok + + long m + bra vnf +@ok + long m + bra ok + + +lower str.w ':host' +upper str.w ':HOST' + end diff --git a/records.equ b/records.equ new file mode 100644 index 0000000..e2cd74d --- /dev/null +++ b/records.equ @@ -0,0 +1,239 @@ + + ; + ; n.b. -- __sizeof only works for the record. It does not + ; work when actually instantiated. MPW sucks for some reason. + ; perhaps it blindly adds the current * to all relative equates.... + ; + macro +&n begin_struct +&n record 0 +__begin equ * + mend + + macro +&n end_struct +&n +__end equ * +__sizeof equ __end - __begin + endr + mend + + +GSString255 begin_struct +length DS.W 1 ; Word - Number of Chars in text field +text DS.B 255 ; char[255] - + end_struct + +GSString32 begin_struct +length DS.W 1 ; Word - Number of characters in text field +text DS.B 32 ; char[32] - + end_struct + +ResultBuf255 begin_struct +bufSize DS.W 1 +bufString DS GSString255 + end_struct + +ResultBuf32 begin_struct +bufSize DS.W 1 +bufString DS GSString32 + end_struct + +TimeRec begin_struct +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 + end_struct + +DirEntryRecGS begin_struct +pCount DS.W 1 +refNum DS.W 1 +flags DS.W 1 +base DS.W 1 +displacement DS.W 1 +name DS.L 1 +entryNum DS.W 1 +fileType DS.W 1 +eof DS.L 1 +blockCount DS.L 1 +createDateTime DS TimeRec +modDateTime DS TimeRec +access DS.W 1 +auxType DS.L 1 +fileSysID DS.W 1 +optionList DS.L 1 +resourceEOF DS.L 1 +resourceBlocks DS.L 1 + end_struct + +DirEntryRec begin_struct +refNum DS.B 2 +flags DS.B 2 +base DS.B 2 +displacement DS.B 2 +nameBuffer DS.B 4 +entryNum DS.B 2 +fileType DS.B 2 +endOfFile DS.B 4 +blockCount DS.B 4 +createTime DS TimeRec +modTime DS TimeRec +access DS.B 2 +auxType DS.B 4 +fileSysID DS.B 2 + end_struct + + + +FileInfoRecGS begin_struct +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 + end_struct + + +FileRec begin_struct +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 + end_struct + +OpenRecGS begin_struct +pCount DS.W 1 +refNum DS.W 1 +pathname DS.L 1 +requestAccess DS.W 1 +resourceNumber DS.W 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 + end_struct + +OpenRec begin_struct +openRefNum DS.B 2 +openPathname DS.B 4 +ioBuffer DS.B 4 + end_struct + + +VolumeRecGS begin_struct +pCount DS.W 1 +devName DS.L 1 +volName DS.L 1 +totalBlocks DS.L 1 +freeBlocks DS.L 1 +fileSysID DS.W 1 +blockSize DS.W 1 +characteristics ds.w 1 +deviceID ds.w 1 + end_struct + + +VolumeRec begin_struct +deviceName DS.B 4 +volName DS.B 4 +totalBlocks DS.B 4 +freeBlocks DS.B 4 +fileSysID DS.B 2 + end_struct + + +JudgeNameRecGS begin_struct +pCount ds.w 1 +fileSysID ds.w 1 +nameType ds.w 1 +syntax ds.l 1 +maxLen ds.w 1 +name ds.l 1 +nameFlags ds.w 1 + end_struct + +PositionRecGS begin_struct +pCount DS.W 1 +refNum DS.W 1 +position DS.L 1 + end_struct + +MarkRec begin_struct +markRefNum DS.B 2 +position DS.B 4 + end_struct + +EOFRecGS begin_struct +pCount DS.W 1 +refNum DS.W 1 +eof DS.L 1 + end_struct + + +EOFRec begin_struct +eofRefNum DS.B 2 +eofPosition DS.B 4 + end_struct + +IORecGS begin_struct +pCount DS.W 1 +refNum DS.W 1 +dataBuffer DS.L 1 +requestCount DS.L 1 +transferCount DS.L 1 +cachePriority DS.W 1 + end_struct + +FileIORec begin_struct +fileRefNum DS.B 2 +dataBuffer DS.B 4 +requestCount DS.B 4 +transferCount DS.B 4 + end_struct + + +SetPositionRecGS begin_struct +pCount DS.W 1 +refNum DS.W 1 +base DS.W 1 +displacement DS.L 1 + end_struct + + +DevNumRecGS begin_struct +pCount DS.W 1 +devName DS.L 1 +devNum DS.W 1 + end_struct + + +DevNumRec begin_struct +devName DS.B 4 +devNum DS.B 2 + end_struct diff --git a/records.rb b/records.rb new file mode 100644 index 0000000..59a356c --- /dev/null +++ b/records.rb @@ -0,0 +1,55 @@ +#!/usr/bin/env ruby -w + + offset = 0 + record = nil + records = {} + + puts "/* generated on #{Time.now.ctime} */" + puts "" + + ARGF.each_line {|x| + + x.chomp! + x.gsub!(/(;.*)$/,'') + x = x.rstrip + next if x.empty? + + if record.nil? + record = $1 if /^(\w+\d*)\s+begin_struct$/.match x + next + end + + case x + when /^\s+end_struct$/ + puts "" + records[record] = offset + record = nil + offset = 0 + + when /^(\w+\d*)?\s+ds\s+(\w+\d*)$/i + # bleh ds timerec + puts "#define #{record}_#{$1} #{offset}" if $1 + raise "unknown record #{$2}" unless records.include? $2 + offset += records[$2] + + when /^(\w+\d*)?\s+ds\.b\s+(\d+)$/i + puts "#define #{record}_#{$1} #{offset}" if $1 + offset += $2.to_i + + when /^(\w+\d*)?\s+ds\.w\s+(\d+)$/i + puts "#define #{record}_#{$1} #{offset}" if $1 + offset += $2.to_i * 2 + + when /^(\w+\d*)?\s+ds\.l\s+(\d+)$/i + puts "#define #{record}_#{$1} #{offset}" if $1 + offset += $2.to_i * 4 + + else + + raise "bad line #{x}" + + end + + } + + exit 0