Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - z80man

Pages: 1 [2]
16
Casio Calculators / Prizm Getkey
« on: March 25, 2011, 02:50:05 am »
Many of us out here are Axe programmers. Many of us also don't want to code in SH3 asm (not me of course, SH3 asm is the best ;D). Many of us do not want to go through all of the difficult steps to set up a C compiler. So there is a solution for this. Make Axe for the Prizm.

Now this project hasn't even been started yet. I'm not even the one in charge of the language. But what I have here is an early development of the Getkey routine. So when the Axe port does come around someday, you will be able to interface with the keyboard. How this instruction works is that it returns the word length code through the stack. What is great about this routine is that the codes are easy to remember, it is extremely fast, and it supports multiple key presses.

So how to use it? Well the answer is you can't right now. unless of course you integrate it with a program you wrote in C or asm. but anyways it will function just like your standard BASIC or AXE getkey routine where you can say GetKey ->A. Before I can teach you how to use multiple key presses, I have to teach you how the instruction works internally. what is great about the SH3 is that the keyboard is memory mapped. How that works is that there are 10 bytes representing the state of the keyboard starting at 0xA44B0000. Basically each row of keys has its own byte and each key has its own bit within that byte. (On key has its own byte; 0101) So for a single key press, the routine returns the byte index of the key pressed in the MSB and the value of that byte in the LSB. An example the EXE key. Because exe it located in the first byte 00xx is the first part evaluated then because pressing the the exe key toggles bit 2 in relative address 00, 4 is loaded into the lower byte. That then yields a result of 0004. So for multiple key presses everything works just about the same way. for this example say you are pushing the shift key 0940 and the up arrow 0902. Normally you would add the 2 MSB's together, but not when they are the same. So in this case they are both 9 so do not add them. But you always add the LSB's of all the keys being pushed. So 02 + 40 = 42. Then your result would be 0942.

Sorry that this might be a bit vague. If you have a question on either the source or the routine usage, please ask.




Code: [Select]
Getkey:
MOVA  @($07,PC),R0    ;$A44B0000
MOV  $0A,R1
Loop:
DT R1
BT/S  $08             ;Exit
MOV.B  @(R0,R1),R2
CMP/PL  R2
BF/S  $FA             ;Loop
MOV  R1,R4
SHLL8  R4
ADD  R2,R3
BRA  $F6              ;Loop
ADD  R4,R3
Exit:
RTS
MOV.L  R3,@-R15
data.l  $A44B0000

17
Casio Calculators / MOVED: FPU routines
« on: March 24, 2011, 01:05:00 am »
This topic has been moved to Other Casio Calculator Discussion http://ourl.ca/9865/188881;topicseen#new

http://ourl.ca/9865

18
Casio Calculators / FPU routines
« on: March 24, 2011, 12:10:49 am »
I've now started work on creating an SH3E library for the the SH3. In case you don't know the SH3E is a version of the SH3 that incorporates an fpu. Later on I'll create libraries for the SH4 which incorporates double length double length data along with video acceleration hardware (except when emulated it will be more like video deceleration :P). For the libraries I'm making three versions of each function. In each version there are three different sub-sets for a inline function, callable function, and an interrupt triggered function. On the inline version, the register numbers are labeled Ra, Rb, Rc and so on. When used in code the programmer should define these registers as they see fit. FR0-FR15 are memory locations along with the FPSCR and the FPUL.
Fast version:
The fastest possible version of each instruction. May destroy some registers during execution so care must be taken when using them. Is more of a floating point library than an fpu emulator as it ignores the system and control registers found in the emulated hardware.

Safe version:
Protects registers from being corrupted, and is only a little bit slower than the fast routines. Closely emulates the actual hardware, but still doesn't incorporate the fpu system and control registers. 

True version:
Is an exact copy of the emulated hardware instruction. May be slow in some routines due to the system and control registers that must be managed. Also ensures that none of the general purpose registers are corrupted.

FABS  FRn
Floating point absolute value of FRn
Code: (fast) [Select]
;FABS  FRn

;*******************************
;inline
;Ra is the register to be processed
;destroyed registers
;Ra, T bit

ROTR  Ra    ;shifts Ra 1 bit right. LSB is placed into the T bit
ROTCL Ra    ;shifts Ra 1 bit left. T bit placed into the LSB of Ra


;*******************************

;callable function
;@(R15) is the data to be processed
;data returned to @(R15)
;registers destroyed
;R1 and T bit

MOV.L @R15,R1    ;pops single argument off the stack. only one argument so no point in decrementing R15
ROTR  R1         ;shifts R1 1 bit right. LSB is placed into the T bit
ROTCL R1         ;shifts R1 1 bit left. T bit placed into the LSB of R1
RTS              ;return to code. Delayed branch
MOV.L R1,@R15    ;pushes single argument back on

;*******************************

;interrupt
;jumped to from the interrupt handler
;@(R15) is the data to be processed
;registers destroyed
;R1 (bank 1)


MOV.L @R15,R1    ;pops single argument off the stack. only one argument so no point in decrementing R15
ROTR  R1         ;shifts R1 1 bit right. LSB is placed into the T bit
ROTCL R1         ;shifts R1 1 bit left. T bit placed into the LSB of R1
RTE              ;SSR/SPC -> SR/PC. returns to code. Delayed branch
MOV.L R1,@R15    ;pushes single argument back on the stack
Code: (safe) [Select]
;FABS FRn

;*******************************
;inline
;Ra is the register to be processed
;cannot use R1 as Ra
;destroyed registers
;Ra

MOV.L R1,@-R15   ;pushes R1 onto the stack
MOVT  R1         ;moves the T bit into R1
MOV.L R1,@-R15   ;moves R1 onto the stack
ROTR  Ra         ;shifts Ra 1 bit right. LSB is placed into the T bit
ROTCL Ra         ;shifts Ra 1 bit left. T bit placed into the LSB of Ra
MOV.L @R15+,R1   ;pops R1 off the stack. T bit
MOV.L R2,@-R15   ;pushes R2 onto the stack
MOV $00,R2       ;moves 0 into R2
CMP/HI R1,R2     ;if the T bit was 1 then the T bit equals 1. Sounds retarded I know :P
MOV.L @R15+,R2   ;pops R2
MOV.L @R15+,R1   ;pops R1

;*****************************
;callable
;NOT FINISHED

;*****************************
;interrupt
;jumped to from the interrupt handler
;@(R15+8) is the FR to be processed
;registers destroyed
;FRn


MOV.L R1,@R15+    ;pushes R1 onto the stack
MOV.L R2,@R15+    ;pushes R2 onto the stack
MOV.L @R15,R2     ;pops FR address off the stack. No decrement
MOV.L @R2,R1      ;places contents of @R2 into R1
ROTR  R1         ;shifts R1 1 bit right. LSB is placed into the T bit
ROTCL R1         ;shifts R1 1 bit left. T bit placed into the LSB of R1
MOV.L R1,@R2    ;places result in FRn
MOV.L @R15-,R2   ;pops R2
RTE              ;SSR/SPC -> SR/PC. returns to code. Delayed branch
MOV.L @R15-,R1    ;pops R1
So this was some of the hardest stack work I've ever done before. And it was only on the simplest of the floating point math operations. In fact I still haven't finished the safe version of the callable function or any of the true functions yet. May God save us all when we start working on the true version of the square root and the division functions. Just as a head up here is the C code for the fpu divide instruction. Now just imagine the SH3 asm version of that while preserving all of the registers.
Code: (divide) [Select]
FDIV(float *FRm,*FRn) /* FDIV FRm,FRn */
{
clear_cause_VZ();
if((data_type_of(FRm) = = sNaN) | |
(data_type_of(FRn) = = sNaN)) invalid(FRn);
else if((data_type_of(FRm) = = qNaN) | |
(data_type_of(FRn) = = qNaN)) qnan(FRn);
else case((data_type_of(FRm) {
NORM :
case(data_type_of(FRn)) {
PINF :
NINF : inf(FRn,sign_of(FRm)^sign_of(FRn)); break;
default : *FRn =*FRn / *FRm; break;
} break;
PZERO :
NZERO :
case(data_type_of(FRn)) {
PZERO :
NZERO : invalid(FRn); break;
PINF :
NINF : inf(Fn,Sign_of(FRm)^sign_of(FRn)); break;
default : dz(FRn,sign_of(FRm)^sign_of(FRn)); break;
} break;
PINF :
NINF :
case(data_type_of(FRn)) {
PINF :
NINF : invalid(FRn); break;
default :zero (FRn,sign_of(FRm)^sign_of(FRn)); break
break;
}
pc += 2;
}

19
Computer Programming / Arrays
« on: March 18, 2011, 02:11:27 am »
Sometimes I really miss programming in asm, but it can be difficult to do on x86 systems. So basically my problem is that I have an array of chars, but I need to read and write multiple types from it. Ranging from 32 bit longs, 16 bit words, and 8 bit bytes. Now the solution would be easy in asm, but this is C++ here which thinks that restricting a programmer from low-level access is a good thing.
Code: [Select]
char * memory = new char[0xFFFF];


int readmemory_long(int pointer)
{
unsigned int r_pointer = pointer - 0xA4000000;            //converts given pointer to the array address
if (r_pointer > 0x1FFFFF) return 0;
return ntohl(memory[r_pointer]);                    //ntohl(), converts data to little endian (I hope :P) issue here
                                                               // I want to get the 32 bit value at this address
}
void writememory_long(int pointer, int data)
{
unsigned int r_pointer = pointer - 0xA4000000;
if (r_pointer > 0x1FFFFF) return;
memory[r_pointer] = htonl(data);                //converts data to big endian: same issue
}
I was considering using for loops, but that could be kinda tricky. Any ideas/examples would be smiled upon  :)

20
Casio Calculators / SH3 op of the day
« on: March 10, 2011, 12:51:35 am »
You have probably now seen the new Casio Prizm calc. You might also happen to know that it is powered by a SuperH 3 processor. If so, you might want to start coding for it. The purpose of this lengthy tutorial will be to teach you how to write SH3 asm code day by day. I will not be teaching how to do Prizm specific coding, just SH3 coding. I have also designed these tutorials to show parallel between the SH3 and the z80. It is highly recommended that you previously know a machine compiled language such as z80, arm, C, C++, x86, or axe. Other languages such as Java, python, and BASIC can also be used as prior experience, but you may find coding in SH3 more difficult. I also reccomend to everyone, if you have not done already, is to read Qwerty's previous tutorial on SH3 asm here http://ourl.ca/8986. Once I finish this tutorial I will place all of the lessons into a pdf file. I will here document every single instruction on the SH3 and there will be a lesson every day. I may skip a day or week at a time, but I will make up for the days I missed.
__Day One__
__MOV #imm,Rn  0xEnii__
1 cycle, no privilege required, T bit unchanged


I'm going to start this tutorial off with what one of the simplest instructions available. For a z80 coder, it is the equivalent of the ld a,$xx. Because the SH3 is a RISC processor, it only supports 16 bit fixed-length instructions. Therefore only byte values can be stored as immediate data. The hex for this instruction is 0xEnii. Where n is the register (0-15) and ii is a byte of immediate data to be stored in register n. An important note with this instruction is that a sign extension is preformed on the entire 32 bit register even though the data is only a byte. Basically a sign extension is formating the register that way the register is read the same when it is referred to as a long word. The easiest example are positive numbers. Say you want to load $04 into R15. Because $04 is a positive number, 0's will be placed in front of it in the register to reflect this as $00000004. So if you read R15 as a long word later you will see the value of $4 in there. Negative operations are really just the opposite. Say you now want to load $FE aka -2 into R15. Because $FE is a negative value the register is reflected as such. The result would be $FFFFFFFE in R15. Now if you read R15 as a long word you will get the value of -2. Now lets say the cpu did not do a sign extension for the last instruction. Then R15 would read $000000FE. Now if you try to read this, you will get a value of 254 not -2 which you wanted. That now completes lesson one. I hope you are now onto your way into learning SH3 asm. Tomorrow's lesson will teach you how to load data from memory using a displacement value.









21
Miscellaneous / Sports
« on: March 06, 2011, 01:49:18 am »
I was wondering if anyone here participates in any sports at their schools. This thread is for discussing any sports that you do and some of your memories from there. It is not for starting a war on which sport is better. And as a note to Americans, remember that this is an international site so for the sake of simplicity please refer to soccer as football and football as American football.

For me I do distance running. In the fall I do cross country and in the spring I do track. In fact today I had my first track meet of the season and set 2 PR's (personal record) In the 1600 meter race (about a mile) I ran a 5:20 and in the 4x800 meter relay I ran a 2:28 for my leg of the race. In cross country our races are 3 miles (just under 5km) and are on various terrain including hills, mud, and sand. My PR for that is 18:40 which I am just about to set in the picture below. I'm hoping that next year my team wins the league championship.


22
Computer Programming / C++ bit field question
« on: March 06, 2011, 12:52:34 am »
Alright I was compiling my Prizm emulator when I came upon an error. As a global variable I had defined a bit field of 1 byte that is split into two 4 bit variables. I then used a #define to rewrite the bit field so that I would not have to label the the struct name. Here is an eample of  the error I got.
unsigned int n = half_byteone;
spectrum.cpp(291: Error: '(' expected following simple type name
Code: (error areas) [Select]
struct middle_byte                       //creates a bit feld for reading the middle byte of an instruction
{
unsigned char half_byteone:4;
unsigned char half_bytetwo:4;
};
unsigned char low_byte;   //creates low byte of instruction

 #define half_byteone middle_byte.half_byteone
 #define half_bytetwo middle_byte.half_bytetwo
blah...
void ADD() //ADD Rm,Rn
{
unsigned int n = half_byteone;   //291
unsigned int m = half_bytetwo;
R[n] += R[m];
PC += 2;
return;
}
blah...
half_byteone = (instruction & 0x0F00) / 0x100;     // inside the function that calls ADD()
half_bytetwo = (instruction & 0x00F0) / 0x10;
This error appears every time I reference the bit field not just this one example. When I googled this error I found that fixing it involved some sort of weird work with templates (which I have never used before :P) Some help on getting this to work would be greatly appreciated.


23
Math and Science / Math mind read
« on: February 24, 2011, 02:03:56 am »
PLEASE READ SPOILERS IN ORDER!!
Spoiler For 1:
Pick any integer between 1 and 10.
Spoiler For 2:
Now multiply that number by 9. You should now have a two digit number (unless you chose 1, in which your number is 1 digit). Find the sum of the two digits. eg. if you have 33, 3 + 3 = 6
Spoiler For 3:
Now subtract 5 from that number
Spoiler For 4:
Alright the next step is to match your number with the corresponding letter. eg. if you have 1, then your letter is A
Spoiler For 5:
The next step is to find a country that starts with that letter
Spoiler For 6:
Now take the last letter from your country and find an animal that starts with that letter
Spoiler For 7:
The last step is to find a color that starts with the last letter of your animal
Spoiler For 8:
You are thinking of an orange kangaroo in Denmark. Right  ;D If not either you messed up the instructions or you are too smart for this test.   <_<

24
Site Feedback and Questions / Randomness post requirement
« on: February 18, 2011, 02:20:28 am »
Due to many new members spamming and trolling can there be a requirement for posting in randomness such as 20 posts. I'm not going to list these people, but I believe they are mainly Casio Kingdom and Casiocalc users who came here for Prizm stuff. Also can there be a 5 post minimum for using emoticons because emoticon spam is becoming common too. Lastly could there be a short mandatory quiz on forum posting for when you register here. That could help people understand our rules before they post.

25
Site Feedback and Questions / Name/quote alert
« on: February 11, 2011, 12:10:19 am »
I had an idea where sorta like on facebook if someone uses your name in a post you are alerted via email. So if someone said in a post [name]z80man[/name] I would then receive an email with a link to that post. I thought this could also work if someone quoted someone in a post too. So I was kinda wondering if first my idea was possible to implement and second if anyone else likes it. Also this option could be disabled in your profile settings page.

26
Other Calc-Related Projects and Ideas / TI-30xs II programming
« on: February 09, 2011, 01:24:03 am »
Next year when I take physics i'll have to use a Ti-30 :P. and I do not want to use an unprogrammable calc. I happen to already own a TI-30xs II calc. In a way it is similar to the TI 83+. The screen dimensions are 32x96 (half size) and the text chars are the same. But is has no linkport and a very limited OS. My idea was what if I did some hardware modifications to get the calc to accept machine code. And does anyone know how the TI-80 got hacked because that could provide some valuable insight.


27
Computer Programming / File output
« on: February 03, 2011, 01:49:51 am »
So I've been working on an app signer program for the Prizm when I came along a problem. What I'm trying to do is copy one file and output to another. I've already tried using the << operator, the put function, and the write function, but my compiler (Visual C++ 2010) does not support these.  :P  None of the shown examples work. Also VC++ 2010 does not support the seekp method. Any ideas.  ???
Code: [Select]
ifstream app(filename, ios::binary);
char Convbuf;                                        // buffer to hold one byte at a time from the Conversion app
for( int counter = 0  ; counter < 0x7000; counter++)
{
Conv.read(&Convbuf,1);
app << Convbuf;
}
Code: [Select]
ifstream app(filename, ios::binary);
char Convbuf;
Conv.seekg(0, ios::beg);
app.seekp(0, ios::beg);
Conv.read(&Convbuf,1);
for( int counter = 1  ; counter < 0x7000; counter++)
{
app.write(&Convbuf, 1);
Conv.seekg(counter);
app.seekp(counter);
}

28
Casio PRIZM / Casio Prizm: Snake Game
« on: January 19, 2011, 08:03:05 pm »
---Updated With Newer Version---
As many know the Casio Prizm recently came out. Unfortunatley the BASIC drawing commands can be quite slow. Last week I experimented with a simple snake game, but it was really slow and took forever to play. Working on some optimization I found a new way to draw with lines instead of pixels to allow the game to run much faster. Attached you will find the program. Please comment on what you like, what you don't like and any glitches.





29
Casio Calculators / Prizm goals
« on: January 04, 2011, 02:23:03 am »
The Casio Prizm is going to bring a new era to calc development. Its biggest feature being the 216x384 16 bit color screen. This as many know will expand the possibilities of what was previously thought possible on a calc. No longer will we be restricted to low resolution monochrome screens. As a result a list of what the community wants to accomplish throughout the next few years will help serve as a guide to developers.  :)

TI 83+/nspire emulator: There are many great games currently on ticalc. Porting them to the the Prizm will take a long time and will be impossible for some games in which the original source code has been lost.  An emulator will be a difficult project to achieve though. All the ports and hardware would have to be emulated properly to allow games that use grayscale and acsess the archive and usb port to run properly.

Overclocking: Hopefully the Prizm can be clocked far past 29mhz in software. If overclocking requires physical alteration of the calc many people will not be able to enjoy games that utilize that ability. If overclocking is done care must be taken to ensure that other people's calcs are not damaged by malicious code.

Axe: After running several tests Prizm basic seems quite slow. This is most visible in any form of drawing operation. Therefore Axe will need to be ported to the Prizm allowing great games to be written much faster (both actual time to write code and speed)

Archive: The current restraints of 16mb of archive put a limit on future development. External archive additions will need to be created to open up more possibilities. Doing this though will require great knowlege on the Prizm's ports and usb protocols.

Video: This could be the first time we see real looking video on a calc. The proc seems fast enough to support it and the screen has a high resolution with 16 bits of color. The only modification needed will probaly be more archive space.

Wifi: Using this could open up many paths for development. Users will be able to connect from much farther than 3 feet away on a cord. Imagine playing a 2 person version of Phoenix on your calc with someone thousands of miles away. We could even make omnimaga accsessible from your calc.


30
Introduce Yourself! / Hi I'm Z80man
« on: December 29, 2010, 08:24:07 pm »
Hi I'm Z80man. I'm currently a sophmore in high school. Last year I got my first graphing calculator, a Ti-84+ SE. Within a few weeks I was making my first basic programs. As I got better I made more advanced programs. Eventually I became frustruated with the slow speed and lack of capability of basic. Thats when I was introduced to asm programming. I'm also fluent in the C/C++ langaunge too. This year for Christmas I got the Casio Prizm. As of now I'm trying to decode the header for apps. Other news about me is that I'm am an avid runner competing on both my school's cross country and track teams.

Pages: 1 [2]