📄 drivers.asm
字号:
lcall partition_type jc found_partition mov dptr, #msg_no_fat32 lcall pstr clr a ljmp detect_fs_donebad_mbr: lcall print_sector_buffer lcall newline mov dptr, #mesg_bad_mbr lcall pstr clr a ljmp detect_fs_donefound_partition: inc dptr inc dptr inc dptr inc dptr lcall get_byte mov f32_sector+0, a lcall get_byte mov f32_sector+1, a lcall get_byte mov f32_sector+2, a lcall get_byte mov f32_sector+3, a mov dptr, #partition_first_sector mov a, f32_sector+0 movx @dptr, a inc dptr mov a, f32_sector+1 movx @dptr, a inc dptr mov a, f32_sector+2 movx @dptr, a inc dptr mov a, f32_sector+3 movx @dptr, a mov dptr, #mesg_partition_at lcall pstr mov r0, #f32_sector push flags setb debug lcall phex32_at_r0 pop flags mov dptr, #mesg_partition_at2 lcall pstr ljmp read_vol_idpartition_type: mov r3, a mov r4, dpl mov r5, dph mov dptr, #msg_slot lcall pstr mov a, r2 lcall pint8u mov a, #':' lcall cout mov a, #' ' lcall cout mov a, r3ptbl_0: jnz ptbl_1 mov dptr, #msg_partition_empty sjmp is_not_fat32ptbl_1: cjne a, #1, ptbl_5 mov dptr, #msg_partition_fat12 sjmp is_not_fat32ptbl_5: cjne a, #5, ptbl_6 mov dptr, #msg_partition_extended sjmp is_not_fat32ptbl_6: cjne a, #6, ptbl_7 mov dptr, #msg_partition_fat16 sjmp is_not_fat32ptbl_7: cjne a, #7, ptbl_B mov dptr, #msg_partition_ntfs sjmp is_not_fat32ptbl_B: cjne a, #0xB, ptbl_C mov dptr, #msg_partition_fat32 sjmp is_fat32ptbl_C: cjne a, #0xC, ptbl_E mov dptr, #msg_partition_fat32 sjmp is_fat32ptbl_E: cjne a, #0xE, ptbl_F mov dptr, #msg_partition_fat16 sjmp is_not_fat32ptbl_F: cjne a, #0xF, ptbl_82 mov dptr, #msg_partition_extended sjmp is_not_fat32ptbl_82:cjne a, #0x82, ptbl_83 mov dptr, #msg_partition_linux_swap sjmp is_not_fat32ptbl_83:cjne a, #0x83, ptbl_unknown mov dptr, #msg_partition_linux_ext2 sjmp is_not_fat32ptbl_unknown: lcall phex mov dptr, #msg_partition_unknownis_not_fat32: lcall pstr mov dptr, #msg_lcd_eol lcall pstr mov dpl, r4 mov dph, r5 clr c retis_fat32: lcall pstr mov dptr, #msg_lcd_eol lcall pstr mov dpl, r4 mov dph, r5 setb c retbad_vol_id: lcall print_sector_buffer mov dptr, #mesg_bad_vol_id lcall pstr lcall print_sector_buffer clr a ljmp detect_fs_doneread_vol_id: push flags setb debug mov dptr, #mesg_read_vol_id lcall pstr mov dptr, #partition_first_sector movx a, @dptr mov f32_sector+0, a inc dptr movx a, @dptr mov f32_sector+1, a inc dptr movx a, @dptr mov f32_sector+2, a inc dptr movx a, @dptr mov f32_sector+3, a mov dptr, #sector_buffer lcall ide_read_sector ;acall print_sector_buffer mov dptr, #sector_buffer + 0x1FE movx a, @dptr cjne a, #0x55, bad_vol_id inc dptr movx a, @dptr cjne a, #0xAA, bad_vol_id mov dptr, #sector_buffer + 11 movx a, @dptr jnz bad_vol_id ;require 512 byte sector inc dptr movx a, @dptr cjne a, #2, bad_vol_id ;require 512 byte sector mov dptr, #sector_buffer + 16 movx a, @dptr cjne a, #2, bad_vol_id ;require BPB_NumFATs == 2 mov dptr, #mesg_vol_id_ok lcall pstr clr c mov dptr, #sector_buffer + 36 ;offset of BPB_FATSz32 movx a, @dptr rlc a mov r2, a ;r2 to r5 has BPB_FATSz32 * 2 inc dptr movx a, @dptr rlc a mov r3, a inc dptr movx a, @dptr rlc a mov r4, a inc dptr movx a, @dptr rlc a mov r5, a mov dptr, #mesg_sectors_for_fats lcall pstr mov r0, #2 lcall phex32_at_r0 lcall newline mov dptr, #sector_buffer + 14 ;read BPB_RsvdSecCnt to r6/r7 movx a, @dptr mov r6, a inc dptr movx a, @dptr mov r7, a mov dptr, #partition_first_sector ;add "partition_first_sector" movx a, @dptr ;with "BPB_RsvdSecCnt" add a, r6 mov f32_sector+0, a inc dptr movx a, @dptr addc a, r7 mov f32_sector+1, a inc dptr movx a, @dptr addc a, #0 mov f32_sector+2, a inc dptr movx a, @dptr addc a, #0 mov f32_sector+3, a mov dptr, #first_fat_sector ;store as "first_fat_sector" mov a, f32_sector+0 movx @dptr, a inc dptr mov a, f32_sector+1 movx @dptr, a inc dptr mov a, f32_sector+2 movx @dptr, a inc dptr mov a, f32_sector+3 movx @dptr, a mov a, f32_sector+0 ;add (BPB_FATSz32 * 2) add a, r2 ;to "fat_first_sector" mov f32_sector+0, a mov a, f32_sector+1 addc a, r3 mov f32_sector+1, a mov a, f32_sector+2 addc a, r4 mov f32_sector+2, a mov a, f32_sector+3 addc a, r5 mov f32_sector+3, a mov dptr, #first_data_sector ;store as "first_data_sector" mov a, f32_sector+0 movx @dptr, a inc dptr mov a, f32_sector+1 movx @dptr, a inc dptr mov a, f32_sector+2 movx @dptr, a inc dptr mov a, f32_sector+3 movx @dptr, a mov dptr, #mesg_first_data_sec lcall pstr mov r0, #f32_sector lcall phex32_at_r0 lcall newline mov dptr, #sector_buffer + 13 ;read BPB_SecPerClus movx a, @dptr mov sectors_per_cluster, a anl a, #11111000b swap a rl a mov blocks_per_cluster, a mov a, sectors_per_cluster anl a, #00000111b jz rd_vol_id2 inc blocks_per_cluster mov dptr, #mesg_per_cluster4 lcall pstrrd_vol_id2: mov dptr, #mesg_per_cluster1 lcall pstr mov a, sectors_per_cluster lcall pint8u mov dptr, #mesg_per_cluster2 lcall pstr mov a, blocks_per_cluster lcall pint8u mov dptr, #mesg_per_cluster3 lcall pstr mov dptr, #sector_buffer + 44 ;read BPB_RootClus movx a, @dptr mov cluster+0, a inc dptr movx a, @dptr mov cluster+1, a inc dptr movx a, @dptr mov cluster+2, a inc dptr movx a, @dptr mov cluster+3, a mov dptr, #root_dir_cluster mov a, cluster+0 movx @dptr, a inc dptr mov a, cluster+1 movx @dptr, a inc dptr mov a, cluster+2 movx @dptr, a inc dptr mov a, cluster+3 movx @dptr, a mov dptr, #mesg_root_dir_at_cluster lcall pstr mov r0, #cluster lcall phex32_at_r0 lcall newline pop flags mov a, #1detect_fs_done: push acc mov dptr, #dram_page_cfg + (7 * 2) movx a, @dptr mov r2, a inc dptr movx a, @dptr mov r3, a lcall free_blocks pop dpl ljmp return_addrget_byte: movx a, @dptr inc dptr retget_root_1st_cluster: mov dptr, #root_dir_cluster movx a, @dptr push acc inc dptr movx a, @dptr push acc inc dptr movx a, @dptr mov b, a inc dptr movx a, @dptr pop dph pop dpl ljmp return_addr;*************************************************************;** **;** FAT32 Filesystem **;** **;*************************************************************;TODO: I received a report that laptop drives formatted by win2k;as FAT32 won't work. Need to find a win2k machine and format;a drive for testing. .equ file_info_size, 24 ;convert a file descriptor in Acc into a the address ;of that file's info, and return it in dptr. This is ;the only place that gets the file_info's address, so ;it'll (hopefull) be less painful to add more elements ;to a file_info if needed.fd_to_ptr: anl a, #63 ;only 64 files allowed mov b, #file_info_size ;sizeof(struct file_info) mul ab add a, #file_info & 255 mov dpl, a mov a, #file_info >> 8 addc a, b mov dph, a retadd_a_to_dptr: add a, dpl mov dpl, a jnc add_a2dptr2 inc dphadd_a2dptr2: ret ;open a file. r2/r3/r4/r5 has the 32 bit first cluster. ;return the file descriptor (0 to 63), or -1 if failurefile_open_by_1st_cluster: mov dptr, #msg_fopen lcall pstr_d ;first, look for an unused entry in the file_info table mov r1, #0 ;r1 will be the file descriptorfopen_loop1: mov a, r1 lcall fd_to_ptr movx a, @dptr ;get the flags for this file_info anl a, #1 jz fopen_ok ;use it if it's available inc r1 cjne r1, #64, fopen_loop1 ;if we get here, all the file_info slots are in use ;and we can't possibly open another file. mov dptr, #mesg_error lcall pstr_d mov dpl, #255 retfopen_ok: ;now we know which file_info to use, r1 is the file ;descriptor (index into the file_info array), and dptr ;points to the file_info for this file mov a, #1 movx @dptr, a ;mark the file as open clr a mov r6, #file_info_size - 1fopen_clr_info: inc dptr movx @dptr, a ;fill the file_info with zeros djnz r6, fopen_clr_info mov a, r1 lcall fd_to_ptr mov a, #12 lcall add_a_to_dptr mov a, r2 movx @dptr, a ;store first_cluster_number inc dptr mov a, r3 movx @dptr, a inc dptr mov a, r4 movx @dptr, a inc dptr mov a, r5 movx @dptr, a mov a, r1 lcall pint8u_d mov dptr, #msg_rdc_info2 lcall pstr_d mov r0, #reg2 lcall phex32_at_r0 lcall newline_d mov dpl, r1 ljmp return_addr ;prepare to load some or all of a file into memory. ;calling this function just sets up the file_info ;entries, no data transfer happens and the drive ;doesn't start if it's in sleep mode. To actually ;cause data transfer, call "file_cache_work" ;repetitively until it has read all the data that ;was requested (by calling here). ;r0/r1/r2/r3 = 32 bit file position ;r4/r5/r6/r7 = pointer to 32 bit length ;b = file descriptorfile_cache: ;very ugly hack... recycle "cluster" and "f32_sector" ;to put the data from the eight registers into internal ;memory.... so that it looks the way this code was ;originally written to take the input. The computation ;code below should eventually be re-written to use the ;registers directly without this ugly step. mov cluster+0, r0 mov cluster+1, r1 mov cluster+2, r2 mov cluster+3, r3 mov f32_sector+0, r4 mov f32_sector+1, r5 mov f32_sector+2, r6 mov f32_sector+3, r7 mov r0, #cluster mov r1, #f32_sector mov file_desc, b mov dptr, #msg_cache1 lcall pstr_d mov a, file_desc lcall pint8u_d mov dptr, #msg_cache2 lcall pstr_d lcall phex32_at_r0 mov dptr, #msg_to lcall pstr_d ;first of all, we need to convert the program's ;byte-based input into units of clusters. The ;first step is adding the beginning byte with the ;length to get the last byte mov a, @r0 add a, @r1 mov r2, a inc r0 inc r1 mov a, @r0 mov cluster_offset+0, a addc a, @r1 mov r5, a inc r0 inc r1 mov a, @r0 mov cluster_offset+1, a addc a, @r1 mov r6, a inc r0 inc r1 mov a, @r0 mov cluster_offset+2, a addc a, @r1 mov r7, a ;decrement by one to get the actual last byte, not ;the byte immediately after it (which wasn't requested) mov a, r2 add a, #255 mov r2, a mov a, r5 addc a, #255 mov r5, a mov a, r6 addc a, #255 mov r6, a mov a, r7 addc a, #255 mov r7, a mov r0, #5 lcall phex24_at_r0 mov a, r2 lcall phex_d lcall newline_d ;now divide both numbers by the number of bytes in a cluster. ;they've already been divided by 256 by discarding the lowest ;byte mov r2, sectors_per_clusterfcache_offset_shift: clr c mov a, cluster_offset+2 rrc a mov cluster_offset+2, a mov a, cluster_offset+1 rrc a mov cluster_offset+1, a mov a, cluster_offset+0 rrc a mov cluster_offset+0, a clr c mov a, r7 rrc a mov r7, a mov a, r6 rrc a mov r6, a mov a, r5 rrc a mov r5, a mov a, r2 clr c rrc a mov r2, a jnz fcache_offset_shift
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -