⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 malloc.c

📁 A MP3 Player Source Code, Enjoy it!
💻 C
字号:
#include "malloc.h"#include "as31glue.h"#include "printf.h"/* this "simm_id" type is what will normally be passed around, *//* and declared inside of other structs (like playlists, file *//* lists, etc.  You can't actually access memory with it until *//* you pass it through a function to turn it into a proper C *//* xdata pointer (see below) *///  defined in malloc.h// typedef unsigned long  simm_id;/* Normally this complex union won't be used *//* This funny union represents a block/offset memory address *//* and allows it to be passed between functions as a 32 bit *//* long, because SDCC can't pass structs or unions. */// typedef union dram_memory_pointer_struct {typedef union {	struct {		unsigned int offset;		unsigned int block;	} part;	simm_id addr32;} simm_id_union;#define DATA_PER_BLOCK 4090struct simm_block_struct {	unsigned int next;	unsigned int free_bytes;	unsigned int ref_count;	unsigned char bytes[DATA_PER_BLOCK];};static data unsigned int first_malloced_block=0;static data unsigned int last_malloced_block;/* don't try this sort of direct hardware access at home! */volatile static xdata at 0xFF0E unsigned int block7000;static xdata at 0x7000 struct simm_block_struct p7;simm_id simm_malloc(unsigned int num_bytes){	unsigned int block;	xdata simm_id_union mem;	unsigned int block7000_save;	// printf("simm_malloc begin, f=%d\r\n", first_malloced_block);	if (num_bytes > DATA_PER_BLOCK) return 0;	block7000_save = block7000;	if (first_malloced_block == 0) {		block7000 = first_malloced_block = \		   last_malloced_block = malloc_blocks(1);		//printf("malloc 1st: %d\r\n", block7000);		p7.next = 0;		p7.free_bytes = DATA_PER_BLOCK;		p7.ref_count = 0;	} else {		block7000 = last_malloced_block;		if (p7.free_bytes < num_bytes) {			block = malloc_blocks(1);			//printf("malloc Nth: %d\r\n", block7000);			p7.next = last_malloced_block = block;			block7000 = block;			p7.next = 0;			p7.free_bytes = DATA_PER_BLOCK;			p7.ref_count = 0;		}	}	mem.part.block = block7000;	mem.part.offset = 4096 - p7.free_bytes;	p7.free_bytes -= num_bytes;	p7.ref_count++;	//printf("malloc: %d bytes, returning %lx\r\n", num_bytes, mem.addr32);	block7000 = block7000_save;	return mem.addr32;}void simm_free(simm_id addr32){	unsigned int block, next_block;	xdata simm_id_union mem;	unsigned int block7000_save;	block7000_save = block7000;	mem.addr32 = addr32;	block7000 = mem.part.block;	if (--(p7.ref_count) != 0) return;	if (mem.part.block == first_malloced_block) {		first_malloced_block = p7.next;		free_blocks(mem.part.block);		block7000 = block7000_save;		return;	}	next_block = p7.next;	free_blocks(mem.part.block);	for (block = first_malloced_block; block != 0; block = p7.next) {		block7000 = block;		if (p7.next == mem.part.block) {			p7.next = next_block;			if (next_block == 0) {				last_malloced_block = block;			}			block7000 = block7000_save;			return;		}	}	block7000 = block7000_save;	print("Error: could find freed block\r\n");}volatile xdata at 0xFF0A unsigned int addr5_val;volatile xdata at 0xFF0C unsigned int addr6_val;volatile xdata at 0xFF0E unsigned int addr7_val;/* This is the magic function that takes the "pointer" type *//* from malloc and maps the referenced block into the 8051's *//* address space and returns a SDCC xdata * to the memory *//* See http://www.pjrc.com/tech/mp3/mem_map.html for more *//* details about how the DRAM controller page allocation works */#define DRAM_PAGE_CFG 0xFF00xdata void * addr5(simm_id addr32){	addr32;	 /* suppress unused variable warning */	_asm	push	dph		;save offset on stack	push	dpl	xch	a, b		;keep msb of block in b	mov	dptr, #DRAM_PAGE_CFG + (5 * 2)	;always map in 5000-5FFF	movx	@dptr, a	inc	dptr	mov	a, b	movx	@dptr, a	;map the block to 0x5000	pop	dpl	pop	acc	anl	a, #15	add	a, #0x50	mov	dph, a		;now dptr points to the users data	_endasm;}xdata void * addr6(simm_id addr32){	addr32;	 /* suppress unused variable warning */	_asm	push	dph		;save offset on stack	push	dpl	xch	a, b		;keep msb of block in b	mov	dptr, #DRAM_PAGE_CFG + (6 * 2)	;always map in 6000-6FFF	movx	@dptr, a	inc	dptr	mov	a, b	movx	@dptr, a	;map the block to 0x6000	pop	dpl	pop	acc	anl	a, #15	add	a, #0x60	mov	dph, a		;now dptr points to the users data	_endasm;}xdata void * addr7(simm_id addr32){	addr32;	 /* suppress unused variable warning */	_asm	push	dph		;save offset on stack	push	dpl	xch	a, b		;keep msb of block in b	mov	dptr, #DRAM_PAGE_CFG + (7 * 2)	;always map in 7000-7FFF	movx	@dptr, a	inc	dptr	mov	a, b	movx	@dptr, a	;map the block to 0x7000	pop	dpl	pop	acc	anl	a, #15	add	a, #0x70	mov	dph, a		;now dptr points to the users data	_endasm;}/* this function does the opposite of the addrX functions. *//* if you have a pointer to dynamically allocated memory, *//* (which is currently mapped into the processor's address *//* space, you can pass that 16 bit pointer to this function *//* and get the full 32 bit simm_id that represents where *//* that memory is within the SIMM */simm_id simm_id_from_pointer(xdata void *ptr){	ptr;	_asm	push	dpl		;save the pointer, we need it later	push	dph	mov	a, dph	swap	a	anl	a, #15		;acc has page # where mapped	rl	a	mov	dpl, a		;(LSB of DRAM_PAGE_CFG assumed to be zero)	mov	dph, #DRAM_PAGE_CFG >> 8	movx	a, @dptr	;read LSB of mapped block number	inc	dptr	mov	b, a	movx	a, @dptr	;read MSB of mapped block number	pop	dph	anl	dph, #15	;offset is lower 12 bits of the pointer	pop	dpl	_endasm;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -