khans
Posts: 4
Joined: Fri Jul 14, 2017 11:29 am

Code not working

Fri Jul 14, 2017 11:56 am

I am learning to write an OS as a hobby, using the Raspberry Pi 2, Model B.

I am using this course
http://www.cl.cam.ac.uk/projects/raspbe ... orials/os/
that I found here
https://www.raspberrypi.org/blog/buildi ... rry-pi-os/

I got through lessons OK01, OK02, and half of OK03 with everything working splendidly.
(I had to reference the mrvn post from Feb 28, 2015 here
viewtopic.php?f=72&t=72260
and use GPIO base 0x3F20 0000 and pin 47 to get it to work).

Then I went off on a tangent writing my own larger custom functions and it eventually stopped working, even though if I pasted the function logic in the main routine instead of branching, the logic would work fine. Only when I bl-ed to it did it not work, even though my bl to the simpler functions from his course worked fine.

I gave up and went back to the first lesson. I have copied it line for line (subbing in the new GPIO address and pin location) and now not even the first lesson logic works. I plugged back in my old SD with the original Raspbian and it works, so I don't think I bricked. Here is my code:


.section .init
.globl _start
_start:
ldr r0, =0x3F200000
mov r1, #1
lsl r1, #21
str r1, [r0, #0x10]
mov r1, #1
lsl r1, #15
str r1, [r0, #0x2C]
_Loop$:
b _Loop$


1. Any help on why it's not working?
This is my most immediate question. The following question does not matter to me as much.

2. What education/documentation am I missing to find that the rpi2 uses 0x3F200000 for the GPIO. I looked in most of the docs on the website and couldn't deduce it. (I have no hardware experience but am a quick learner if you point me in the right direction).

timanu90
Posts: 65
Joined: Sat Dec 24, 2016 11:54 am

Re: Code not working

Fri Jul 14, 2017 4:31 pm

Hi khans, your code seems not to work because in RPI2 th OK Led turn on when you set the GPIO to HIGH value.

In this tutorial is stated that.
http://www.valvers.com/open-software/ra ... g-in-cpt1/
/* Set the LED GPIO pin high ( Turn OK LED off for original Pi, and on for plus models )*/
for your second question, raspberry PI documentation have an explanation on the addresses.

https://www.raspberrypi.org/documentati ... dresses.md

Hope it helps
Tiago

LdB
Posts: 1210
Joined: Wed Dec 07, 2016 2:29 pm

Re: Code not working

Fri Jul 14, 2017 4:33 pm

Very easy problems

PROBLEM 1:
mov r1, #1
lsl r1, #21
That creates a bit mask for GPIO 7, GPIO 17, GPIO 27, GPIO37, GPIO47
You write it to 0x3F200000 + 0x10 so it's FSEL4 you are hitting ... So that is GPIO47

The main problem here is the Activity LED isn't on GPIO47 on any model
Activity LED is GPIO Port 16 for Pi1, GPIO Port 18 for Pi2 ... Pi3 it's not on GPIO needs a mailbox command.

PROBLEM 2:
You need to read the value at the GPFSEL clear the 3 bits for the mode and OR the bit value in before you write it. You are clearing every other port because the bits will be 0.

The last bit of your code is correct if you wanted to turn GPIO47 off which is what it does.

I don't think your code ever worked I suspect that it may have pseudo worked because you are hitting so many ports.

Anyhow lets fix it an make it hit GPIO18

Code: Select all

.globl _start
_start:
ldr r0, =0x3F200000
mov r1, #1                 ;@ this is the mode mask 1 = Output
lsl r1, #(8 * 3)            ;@ make it easier to read GPIO 8,18,28,38,48  needs the 8*3 shift  
mov r2, #7                ;@ This will be the clear mask .. 3 bits
lsl r2, #(8 * 3)            ;@ Shift it to position 
ldr r3, [r0, #0x04]      ;@ Read the value from GPFESL1 ... GPIO18 will be there
bic r3, r2                   ;@ This clears the bits that belong to GPIO18
orr r1, r3                   ;@ Join held bits and the new mode for GPIO18 
str r1, [r0, #0x04]      ;@ Write the value to GPFSEL1

;@// Lets turn GPIO18 on
mov r1, #1               
lsl r1, #18                   ;@ Mask for access to GPIO18
str r1, [r0, #0x1C]      ;@ Turn GPIO18 on

_Loop$:
;@// Now lets waste some time
mov r1, #0x8000
WaitLoop1:
sub r1, #1
cmp r1, #0
bne  WaitLoop1

;@// Lets turn GPIO18 off
mov r1, #1               
lsl r1, #18                   ;@ Mask for access to GPIO18
str r1, [r0, #0x28]      ;@ Turn GPIO18 off

;@// Now lets waste some time again
mov r1, #0x8000
WaitLoop2:
sub r1, #1
cmp r1, #0
bne  WaitLoop2

b _Loop$               ;@ Loop around flashing LED on/off repeatedly
Should give you one blinky Activity LED. I commented it walk thru and make sure you get what it is doing.

Unless you really want to play around in assembler its a lot easier to just stub the processor start and use the C compiler.

User avatar
rpdom
Posts: 15030
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Code not working

Fri Jul 14, 2017 7:09 pm

LdB wrote:The main problem here is the Activity LED isn't on GPIO47 on any model
Activity LED is GPIO Port 16 for Pi1, GPIO Port 18 for Pi2 ... Pi3 it's not on GPIO needs a mailbox command.
No. The ACT LED is GPIO 47 on a PI2B. GPIO 18 is on the P1 header and is often used for hardware PWM control.

LdB
Posts: 1210
Joined: Wed Dec 07, 2016 2:29 pm

Re: Code not working

Fri Jul 14, 2017 7:42 pm

rpdom wrote:
LdB wrote:The main problem here is the Activity LED isn't on GPIO47 on any model
Activity LED is GPIO Port 16 for Pi1, GPIO Port 18 for Pi2 ... Pi3 it's not on GPIO needs a mailbox command.
No. The ACT LED is GPIO 47 on a PI2B. GPIO 18 is on the P1 header and is often used for hardware PWM control.
Weird my main library says differently which was working ... my Pi2B is out in service atm as I started playing with Pi3's. It's currently flying around on a drone ;-)

Maybe I had external LED on it and got confused .. all together very strange I had not noticed. Shows how long since I made a blinky sample.

So I am going to take your word for it ... Modified code for GPIO47 it is then and better go change my library :-)

Code: Select all

.globl _start
_start:
ldr r0, =0x3F200000
mov r1, #1                 ;@ this is the mode mask 1 = Output
lsl r1, #(7 * 3)           ;@ make it easier to read GPIO 7,17,27,37,47  needs the 7*3 shift 
mov r2, #7                ;@ This will be the clear mask .. 3 bits
lsl r2, #(7 * 3)          ;@ Shift it to position
ldr r3, [r0, #0x10]      ;@ Read the value from GPFESL4 ... GPIO47 will be there
bic r3, r2                ;@ This clears the bits that belong to GPIO47
orr r1, r3                ;@ Join held bits and the new mode for GPIO47
str r1, [r0, #0x10]      ;@ Write the value to GPFSEL4

;@// Lets turn GPIO47 on
mov r1, #1               
lsl r1, #(47 - 32)        ;@ Mask for access to GPIO47
str r1, [r0, #0x20]      ;@ Turn GPIO18 on

_Loop$:
;@// Now lets waste some time
mov r1, #0x8000
WaitLoop1:
sub r1, #1
cmp r1, #0
bne  WaitLoop1

;@// Lets turn GPIO47 off
mov r1, #1               
lsl r1, #(47 - 32)         ;@ Mask for access to GPIO47
str r1, [r0, #0x2C]      ;@ Turn GPIO47 off

;@// Now lets waste some time again
mov r1, #0x8000
WaitLoop2:
sub r1, #1
cmp r1, #0
bne  WaitLoop2

b _Loop$               ;@ Loop around flashing LED on/off repeatedly
Last edited by LdB on Fri Jul 14, 2017 8:06 pm, edited 1 time in total.

khans
Posts: 4
Joined: Fri Jul 14, 2017 11:29 am

Re: Code not working

Fri Jul 14, 2017 8:05 pm

timanu90 wrote:Hi khans, your code seems not to work because in RPI2 th OK Led turn on when you set the GPIO to HIGH value.

In this tutorial is stated that...
Thanks that fixed my issue.
LdB wrote:You need to read the value at the GPFSEL clear the 3 bits for the mode and OR the bit value in before you write it. You are clearing every other port because the bits will be 0.
...
Unless you really want to play around in assembler its a lot easier to just stub the processor start and use the C compiler.
I know I'll need to read GPFSELn, I'll get to learning (relearning) that in a later lesson, but for now I'm concerned only with the one pin. As for ASM vs C, I know, I just want to learn it as a hobby, then I'll get into something more to the tune of the tutorial timanu90 linked, where I can use C.
rpdom wrote:The ACT LED is GPIO 47 on a PI2B.
Where can I find this documentation? All I've found is people replying on forums with which GPIO pins are LED/power, but I can't find the documentation... What am I missing?

LdB
Posts: 1210
Joined: Wed Dec 07, 2016 2:29 pm

Re: Code not working

Fri Jul 14, 2017 8:15 pm

You would need the Pi2 schematic which I have no idea ... I just get details from the linux driver and sort of use that as gospel.

It's funny as far back as an article I wrote in jan 2017 I have the GPIO on the Pi2 wrong then
https://www.codeproject.com/Articles/11 ... ated-Suppo

It was funny reading that now with the problems they had on the firmware on the Pi3 that drove me nuts until they finally fixed it. I had forgotten all about that.

I am just slowly trying to bring my samples out on Git but its wrong there on my USB code as well
https://github.com/LdB-ECM/Raspberry-Pi

arggg .. time to fix all this :-)
Is there such thing as Pi overload the GPU vcos/mmal system has cooked my brain :-)

Anyhow fixed on USB repo but think I will update articles with new graphics code with acceleration.

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: Code not working

Sat Jul 15, 2017 4:50 am

I think after the first pi's that had schematics, it has been just tribal knowledge for the led pin locations or other ways to toggle the led since. the amount of information from broadcom is still impressive for broadcom standards (generally very tight lipped), but by other standards we are getting next to no information from them. and dont expect to. so as ldb pointed out the first place folks look is the linux sources, another would be just hacking around toggle every gpio pin and hope you dont fry something. doesnt help on the pi3 as for some reason the led is driven by another chip/device...why would they do that?

for various reasons it is a very good first board to do baremetal with, but at the same time it is the most frustrating documentation wise (which is 99% of baremetal work anyway, but this begins to negate some of the benefits for starting here)

Hate to say this since you spent your money the pi-zero would have been a bit easier first pi board for bare metal (of the ones on the market, I think the pi1 A+ model was best as it had pins installed so you didnt have to solder for folks that were not prepared for doing that...).

the pi2 is either out or on its way out but good thing the 32 bit mode of the pi3 is I think an armv7 clone so the led is not there but you can translate a lot of your knowledge over.

the 0x3Fxxxxxx vs 0x20xxxxxx vs 0x7Exxxxxx is in part from the first doc we got from broadcom the arm whatever manual (the 0x7Exxxxxx is in the gpus or a system address space and we have a hole at 0x20xxxxxx to see that space). the step up to 0x3F is obvious based on what their map loops like with the arm space divided into four and those four views of pretty much the same stuff had the upper bits controlling caching, so our space is for the most part 0x40000000. 0x20000000 was short sighted and to get more ram in the arm the either fragment it or move the peripherals up, so 0x3Fxxxxx is what they should have done all along. maximizing the linear address space. And I certainly learned it through tribal knowledge but no doubt the linux sources would cover the 0x20xxxxxx vs 0x3Fxxxxxx numbers. dont remember maybe they actually covered that in a supplemental document for the pi2's chip.

there is an okay arm peripheral doc that came around the time of the first pi boards. From there for the most part they ripped the arm11 out and inserted an armv7 based core, then ripped that out and inserted an armv8 based core, the peripherals are basically the same, the processor cores are what changed, with a little bit of additional off core support that wasnt needed before (mailboxes to start cores 1,2,3) which are just memory locations, not magical, might not be memory necessarily but act that way...

User avatar
rpdom
Posts: 15030
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Code not working

Sat Jul 15, 2017 5:13 am

I think the ACT LED switch from GPIO 16 to GPIO 47 happened in the B+ (the first of the 40-pin header models) and stayed that way until the 3B came out (as GPIO 47 was needed for something else on the 3B board).

The 2B just continued with the same setup as the B+, hence why there is little documentation of it for that specific model.

User avatar
Ultibo
Posts: 158
Joined: Wed Sep 30, 2015 10:29 am
Location: Australia
Contact: Website

Re: Code not working

Sat Jul 15, 2017 11:10 am

khans wrote:Where can I find this documentation? All I've found is people replying on forums with which GPIO pins are LED/power, but I can't find the documentation... What am I missing?
You could look at the schematics (where they exist) or you could trawl through the Linux drivers, except that they often no longer contain the information directly.

But the simplest and most reliable way to determine where anything is in the Pi is to consult the plain text device tree files in the Linux source, if you look at the bcm270* and bcm283* files you will find more information than you could ever want to know, including many things that would not appear in a schematic or other documentation.

The really good thing is that these files must be both accurate and up to date because Linux requires this information in order to boot and run on the Pi.

Good luck.
Ultibo.org | Make something amazing
https://ultibo.org

Threads, multi-core, OpenGL, Camera, FAT, NTFS, TCP/IP, USB and more in 3MB with 2 second boot!

khans
Posts: 4
Joined: Fri Jul 14, 2017 11:29 am

Re: Code not working

Sun Jul 16, 2017 6:02 pm

New question (should I post here or in a new thread?)

When I write a function that uses the stack:

Code: Select all

_function:
push {lr}
@ second function
pop {pc}
It wouldn't work. (still testing with LED flashing)

In the tutorial I originally linked, he didn't mention setting up the stack, i.e.

Code: Select all

ldr sp, =0x8000
but eventually I found he does do that in his solution downloads. When I do this, everything works fine.

My questions:
1. How much space do I have in this descending stack, 8000h bytes?

2. Why do I need to set it up? I would have assumed the bootloader sets it up. (still new here, and assume I don't really know anything about bootloaders or kernel format, but can learn)

LdB
Posts: 1210
Joined: Wed Dec 07, 2016 2:29 pm

Re: Code not working

Sun Jul 16, 2017 6:26 pm

There isn't 1 stack there are multiple, FIQ and IRQ have there own :-)
You aren't using the tags so you can go all the way down to top of vector table at 0x40 so you have 0x7FA0 bytes or there abouts.
You have fixed the problem of your normal mode but IRQ and FIQ you have same issue if you try to use the stack.
The bootloader can't set the stack pointers because the stack size varies from linux distro to distro and where they want it.

If you want to set them you hit the complication of dropping the CPU out of HYP mode to set the IRQ and FIQ stacks.

Code: Select all

#define I_Bit  (1 << 7)							// Irq flag bit in cpsr (CPUMODE register)
#define F_Bit  (1 << 6)							// Fiq flag bit in cpsr (CPUMODE register)
;@"================================================================"
;@ If the cpu is in HYP_MODE(EL2) we will bring it SVC_MODE (EL1).
;@"================================================================"
    mrs r0,cpsr								;@ Fetch the cpsr register which includes CPU mode bits 
 	and r1, r0, #0x1F						;@ Mask off the CPU mode bits to register r1                            
 	cmp r1, #CPU_HYPMODE					;@ Check we are in HYP_MODE											
	bne .NotInHypMode						;@ Branch if not equal meaning was not in HYP_MODE  
	bic r0,r0,#0x1F							;@ Clear the CPU mode bits in register r0							
	orr r0, r0, #CPU_SVCMODE | I_Bit | F_Bit;@ Logical OR SVC_MODE bits onto register with Irq/Fiq disabled	
    msr spsr_cxsf,r0						;@ Hold value in spsr_cxsf
    add lr,pc,#4							;@ Calculate address of .NotInHypMode label    
    msr ELR_hyp, lr               ;@ Set the address to ELR_hyp
    eret                              ;@ Elevated return which will exit at NotInHypMode in SVC_MODE
.NotInHypMode:
;@"================================================================"
;@ Now setup stack pointers for the different CPU operation modes.
;@"================================================================"
    ldr sp, =__svc_stack					;@ Set the stack pointer for SRV_MODE
    mrs r0,cpsr								;@ Fetch the cpsr register which includes CPU mode bits 
	bic r0,r0,#0x1F							;@ Clear the CPU mode bits in register r0							
	orr r0, r0, #CPU_FIQMODE | I_Bit | F_Bit;@ Logical OR FIQ_MODE bits onto register with Irq/Fiq disabled
    msr CPSR_c, r0							;@ Switch to FIQ_MODE
	ldr sp, =__fiq_stack					;@ Set the stack pointer for that mode
	bic r0,r0,#0x1F							;@ Clear the CPU mode bits in register r0	
	orr r0, r0, #CPU_IRQMODE | I_Bit | F_Bit;@ Logical OR IRQ_MODE bits onto register with Irq/Fiq disabled	
    msr CPSR_c, r0							;@ Switch to IRQ_MODE
    ldr sp, =__irq_stack					;@ Set the stack pointer for that mode
	bic r0,r0,#0x1F							;@ Clear the CPU mode bits in register r0							
	orr r0, r0, #CPU_SVCMODE | I_Bit | F_Bit;@ Logical OR SVC_MODE bits onto register with Irq/Fiq disabled	
    msr CPSR_c, r0							;@ Switch to SVC_MODE again all stacks ready to go
So that code drops the CPU out of HYP_MOD to SVC_MODE and then walks thru the modes (with FIQ/IRQ disabled) so you can set the stack pointers for each mode.

So you have 3 stack values to set __svc_stack, __fiq_stack and __irq_stack. You can hard code them or drag them out of linker file. If you aren't comfortable with linker files hard code them but it's a lot more flexible using the linker file. My linker file stack section which looks like this and it can go anywhere in the linker file as long as it's after the start ("text" or "init") section. You can vary the stack sizes to suit at will and the linker will place them for you.

Code: Select all

.stack :
    {
        . = ALIGN(8);  /* Stack must always be aligned to 8 byte boundary AAPCS call standard */
        __stack_start__ = .;
        . = . + 512;    /* fiq stack size */
        __fiq_stack = .;
        . = . + 16384;   /* usr stack size (stratup) */
        __usrsys_stack = .;
        . = . + 16384;  /* svc stack size (common) */
        __svc_stack = .;
        . = . + 4096;   /* irq stack size */
        __irq_stack = .;
        . = ALIGN(8);
        __stack_end__ = .;        
    }
Honestly that is worst of startup all you have left after that is bring the FPU and Cache online. The loader can't set the FPU because there are a number of options of accuracy. It also can't set the cache because it doesn't know what is where in the user space.

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: Code not working

Sun Jul 16, 2017 7:26 pm

So the raspberry pi is interesting in that the ARM is not the dominant processor. There is GPU, a different instruction set tuned for lots of math. The GPU boots first, we assume off of an on chip rom, it goes out and finds the sd card and finds bootcode.bin which sets up the dram and does other things, then it goes to find start.elf which contains the firmware for the GPU, the code that deals with the video framebuffer and manages video in general for us. In addition it looks for a kernel*.img file, kernel7.img file for example. as well as a config.txt file and perhaps others these days. If you dont have a config.txt (like when you use the pi foundation built linux kernels) then lets say your arm program is loaded at 0x8000, if in that arm program you examine memory from 0x000 to 0x100 you will see there is a small program placed by the gpu that does a few things in the case of the pi2 there are four cores. It "sorts" the cores, isolates cpu0 and lets it continue, but cpu1-3 it isolates into a loop waiting for cpu0 (or other) to tell that cpu to run some code. Otherwise all four run the same code and end up stomping on each other. I dont know if the words typical or atypical are appropriate here, but single or multi-core arm processors there are individual reset lines at a minimum. These reset lines are the responsibility of the chip vendor (arm is not a chip vendor, broadcom in this case) so control of those resets is chip vendor specific and not some arm thing you can just google or better read in an arm doc. So some chips only cpu0 reset is released then once that cpu is up and ready to start other cores, then the other resets are released. Not how these chips or at least this (GPU) firmware works. So we have to sort the cores. A little after the pi2 came out but is the norm now the cores are put in HYP mode, which is not a mode that was available in the armv4 to armv6 (the pi-zero and p1 boards, are based on an armv6 arm11).

And here is why this is relevant. If you stay in HYP mode on your pi2 or on a pi3 in aarch32 mode (I think if you just use a kernel7.img file you get this mode) then there is one stack. With no config.txt file on the sd card they load us at 0x8000 traditionally (0x80000 on the pi3 in 64 bit mode). We are running baremetal so we OWN all of the ARM memory, there is no operating system to ask for memory from (malloc()), its all ours. And that includes from 0x0000 to 0x8000, so certainly my examples and the ones you found it makes sense to set the stack pointer to 0x8000 which really means it decrements first so 0x7FFC is the first address actually written. Yes if you burn a lot of stack in your program you can take it all the way down to 0x0000 and then to crashing...By using 0x8000 on raspberry pis you dont have to go sort out how much ram you have, often in a bare metal situation you might want to set the stack pointer to the top of ram if you have 256Mbytes then you set it there, but for simple examples that might want to port across different situations with this boot scheme 0x8000 is as good a choice as any. If you need more than that then you should set it somewhere else for your baremetal application, you are the program you own and allocate the memory space so you have to deal with how much and where.

if you do not have a config.txt then you do not need another stack interrupts are very similar but a little different (use an eret to return instead of a subs pc,lr,#4). Now if you want to be in that pre-armv7 type of mode then you need to not be in HYP mode, which is tricky to get out of, but has been demonstrated by Ldb above and by many others on this forum. Now you are in a traditional arm mode, when you look at the arm architectural reference manual which is required reading for this kind of work, you will see that with the modes there are banked or mode specific registers including r13, basically there is more than one r13, more than one stack pointer register. And if you are ever in one of those modes you need to initialize that, for each mode, and "allocate" (ask yourself for it as you are in charge of the memory space, no operating system or other to ask) memory for each and setup those registers. True there is some boot code that the GPU places, but the GPU cannot change arm registers before releasing reset nor after in a practical manner, relative to arm programs just doing this, and arm programmers have been doing this since forever...LdB above and others have shown how to do this and since this goes back at least to the armv4 (first core after becoming arm after acorn which was armv1 to armv3) so well over a decade now of software examples...

So you as the programmer can choose, one of the problems and I have not looked at those examples in a while, is that as the arm cores changed in this family of broadcom chips these kinds of details have changed we went from an armv6 arm11 to an armv7 quad core to an armv8 quad core that can do 32 or 64 bit arm instructions. The rest of the chip is almost exactly the same so far as we can tell, but as you have seen the boards have had some subtle changes over time including the connections to an led. It is difficult at best to try to show the equivalent of a "hello world" example in bare metal (which is blink an led) when the cores boot differently and the led moves around. so long as you stay in 32 bit mode there is a cpuid register you can use to date sort out the cores but doesnt mean you know which board you are on (where is the led on a pi1 type board). I had to start over and make a directory for each board type and then with the pi2 and pi3 the various different ways to boot it...and with the filename scheme they have now that is all out the window again...have somewhat thrown my hands up in the air about the whole thing, fortunately most of the boards are unavailable so even though I have a collection of most of the ones they made, doesnt mean I need to support more than a couple....

so long winded as usual. YOU decide if you want to be in HYP mode or a more traditional mode. If HYP mode then you pick where you want the stack, if a more traditional mode then for each mode you will be in (say svc and irq) configure both stacks to be different places (say 0x8000 and 0x6000), then you can mess with interrupts...

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: Code not working

Sun Jul 16, 2017 7:35 pm

Since the GPU has taken care of things like initializing dram in particular, we dont need a bootloader like redboot or u-boot and actually if you do a little research you will find that you certainly dont need u-boot or redboot they are massively overcomplicated bootloaders, to load linux you need to setup a few registers and some atags copy your linux kernel into ram and jump to it it takes care of the rest. You dont need one of those bootloaders to init dram, it is a task itself independent of u-boot that you have to add for your platform. On the pi platforms the gpu does the system init (dram) and other things as needed then eventually does the copy linux and setup a few registers a little memory and branch, you can see the last step by dumping and disassembling the code at address 0x000 to about 0x100. A very small amount of code, and sure they could have set the stack pointer(s) for us but didnt...

khans
Posts: 4
Joined: Fri Jul 14, 2017 11:29 am

Re: Code not working

Sun Jul 16, 2017 10:03 pm

Thanks, very informative answers. I have a lot to learn and that's a good thing.

Return to “Bare metal, Assembly language”