Hello Sorry, we were getting a late start, but we are Doing a session on extending the abstract class of privilege outcomes and lessons learned. I'm Ferris of all I am a Drupal developer with Booz Allen Hamilton Hi, and I'm Ashraf I run debug Academy Yeah Oh, we're gonna have to transition on two monitors separately All right, so we wanted to talk about What privileges first? there is some Disagreement about the definition amongst you know five-year-olds and adults we don't all agree But basically you can see here. It's When some people can eat candy every day, they don't even have to ask they just get it And other people can ask nicely and they don't They don't have access to it the less fun definition Is unearned accesses to resource resources? Feel free to read through that But that definition tends to make people feel uncomfortable I Think it's the word unearned when you're talking to someone and telling them they have something that they didn't earn Tends to strike a nerve and If you know if that's how you feel fair enough But I think we can Define it from the other perspective And we'll find that more people tend to be In agreement over the existence of this problem So what is being underprivileged? You're lacking the access to the resources Expecting that much less people have a problem than they're trying to convey We're realizing that rectifying the above would be a future goal that is actually very attainable but we are Reducing the benefits that they have just by preconceived notions, which is something that we need to work on Which is the purpose of this? So to illustrate I'm gonna Tell you about something that happened to me in high school So when I was in high school, I got pulled over for speeding Initially the cop was pretty friendly joking around with me like oh man, you know, what are you driving an airplane? You know that kind of stuff very friendly. I still expected to get a ticket But overall, you know, I wasn't very worried. I Handed him my license and that's when it changed. He read my name basically Felt then then he looked at me differently immediately after reading my name he got very hostile basically switched from joking to mad and He basically was accusing me of speeding in pursuit of terrorism He literally switched his line of questioning from, you know, were you driving an airplane to do you have a bomb in your car? Do you have machine guns in your car and he wasn't joking? my reaction was Surely you can't be serious and He didn't take too kindly to that So he arrested me he towed my car handcuffed me took me to the police station When that during that ride I tend to not really get phased when people say insulting things because I'm just like oh It's unfortunate that you're that unintelligent But I don't take it really personally. So I was basically Sitting in the cop car hands handcuffed behind my back and I started a conversation so I said, do you pull people over often and he Yeah, he engaged, you know, first he would you continue to be hostile, but eventually he basically was you know felt bad for Arresting me And he apologized He said I shouldn't have done that, but I already called it in So I can't call it in and say I changed my mind so he took me in anyway and They put me in a holding cell for about eight hours That was not his decision. So from that point forward he pretty much became an ally He was like defending me saying oh, we should let him go, you know, he didn't do anything too bad but the person there kind of had his same initial reaction and She was like no we're keeping him locked up So she kept me locked up for ten hours, even though I had the bail ready to pay and I was ready to leave The the talk isn't fully about this but a lot of people have trouble accepting that You know privilege is a real thing But I think this example really illustrates it clearly because he was very nice then very mean then very nice and This actually impacted my career because when I was not in a big way But when I was interviewing for a job that required a security clearance, they said have you ever been arrested? I had to say yes And they didn't like that So we're talking about issues that stem, you know You'd never think that sort of thing would happen, but a lot of people that take my class Have faced all sorts of situations that you wouldn't expect them to have gone through beforehand All right, so yeah, we all have biases you can see this tweet Basically yesterday a professor asked a room full of medical students who had been Asked them who had been mistaken for the nurse in the clinical situations and every female and one black male raised their hand Not a single white male raised their hand Basically bias in professional fields is real We all have biases even people who are underprivileged have biases It's natural But you have to be aware of them and you can't blindly trust your instincts when you meet someone and you have a reaction Before they speak especially you can't assume that your reaction is right You know you have all this life experience etc You have to kind of stop before you talk and say what kind of reaction did I have? what part of it is based in fact about this person specifically and If you had some reaction and you were able to catch yourself don't Then proceed to Say oh I originally thought this and I realized this you know keep it to yourself. It doesn't help anybody We don't want anyone to feel Unwelcome even in those comments and passing if people are worried that you feel a certain way you don't want to kind of Confirm I did have that thought but I don't have that thought you know Yeah I actually requested to do this one since I've had my share of gender bias There have been so many things since I've started web development as a new career since that wasn't actually where I started I dealt with having after taking debug Academy I became a Drupal developer and Even when I was going to interviews or Just talking in general people would assume that I knew less than I did and because of that I assumed it to and it actually hindered my ability to Really believe in myself until Until later until I had changed to a different company, which I'll get into that in a second Yeah, so women tend to be assigned tasks, I'm gonna just start with my story really quick Yes, I'm short. Thank you So my first tech job I worked for a startup that was seven men and me Since it was such a small office it kind of had that family feel to it Which I didn't think it was but anyway right when I had started the President and vice president they started giving me things like kitchen tasks or refilling Paper things like that things that were administrative that they could probably do themselves, but because I was there and willing to help which is how they'd so lovingly put it They started doing it more and more until finally, I just I couldn't take it and That's when I I didn't lash out But they finally knew that they weren't supposed to be asking me that since I was hired as a web developer Which brings me to a different story and I was hired as a junior dev and The only other one the only other developer was a senior one so we were assigned to work closely together and After a while it was it was pretty good. I was there a few minutes a few months and He started to act weird and I wasn't sure why and it Escalated to a point where I had to call him out and be like is there something going on that you're not telling me did I do something am I not doing what I'm supposed to be doing and he proceeded to pull me in an into a conference room and Starts yelling at me Saying that he thought I had wanted to be a developer that I was being too social with the other people in the office, which Was confusing since we all kind of talked most of the day since we were such a small team and He then said that his Feelings for me were affecting his objectivity Which again confused me since he was maybe 10 years older and I had given him no indication that that was something I wanted Even after he had asked if I wanted to get drinks and things like that and yeah, I clearly wasn't interested but He after he had finished yelling at me. He didn't apologize or anything We just left and he pulled the p.m. Into a meeting and he just explained everything that had happened and An hour later the p.m. Came to me and Apologized profusely is like I have no idea where that came from. I'm so sorry You're able to work from home if you want for a few days a week, but we can't force you to be here and It was kind of strange to me since I was so new to the tech world and I didn't want to cause too many ripples and I just said it's fine. We'll work it out. It'll be alright so that day as luck would have it I caught the flu of my life and I was home for a little over a week When I came back to the office. He was gone and I had no idea what happened. They told me he had moved projects and It was fine. I just said okay, whatever. That's I kind of expected that a few months go by and it turned out they had finally told me that he had fallen apart that week and Came into the office like unkempt. He was sobbing And I have no idea why but And he had told them that he had a gun Which was an extreme reaction So they had asked him to leave and if he had left right away, they wouldn't call anyone He would just need to seek help so I Didn't know that It months went by before they told me that and the only indication I had was that The week after I came back. I needed to be a walk to my car or actually the month I came back so two people would alternate walking me to my car every day and I had no idea why I just thought maybe he would profess his love to me in a different way but Obviously, that's an extreme thing Most stories like that don't involve firearms But the more I told that story the more I realized that people women would Come back to me with a similar story and that's something that I'm sorry, it would not happen to most men Because you're in a professional setting and you work closely with people and you don't expect to Be pulled into a conference room after having just joined the tech world and be yelled at for nothing only to have him say that and then Deal with the firearm issue, but he still haunts my dreams if that But because of that I was Nervous way more nervous that I needed to be because I wasn't sure of my ability anymore I thought maybe I was hired because he had liked me because he was the one who interviewed me So when I was dealing with that it was like, oh, no, maybe I'm not as good To even work anywhere and I stayed there until our contract ended and I wish I hadn't because I joined Booz Allen Hamilton and Joined an incredible team that I have never seen I feel like this should be at the end but I've never seen so many women in tech and just able to support and improve my skills Thank you Yeah, we open up with you know the personal stories, but it gets a little lighter Let's see so you might have read the slide, but There are a couple of things that you might be doing in your office or it might be happening in your office that you don't notice There have been studies on this it's Most of the things, you know, it's not cited because it's the PowerPoint But most of the things are based on research and they're as well as personal experiences, of course But there is a tendency to assign woman tasks that are less impressive and what I mean by that is tasks where You know, maybe it's like, okay, you go fix up the styling and you know We have something more complicated like it may be a migration and we'll give that to the guy There's a tendency to do that and think nothing of it, but that kind of accumulates and impacts promotions impacts future job interviews like what did you work on? Well, I mostly did you know styling. It's it's different than saying you did a migration and And you know in programming even if you feel like the woman hasn't done it before I think I've seen more tendency to give a guy who hasn't done something before Something he hasn't done before whereas with women you might just think well, she does front-end and Not really test the waters and find out if she likes to do back in development. Was there something all right? Yeah, and we you know, we just had other examples my my my mom actually she majored in Electrical engineering and when she was interviewing one of the things she saw from a few people was basically Oh god, you're gonna leave and have kids So that was something that you know when she was interviewing was something people could say out loud But basically, you know, there's all sorts of barriers that You know people of various genders face that maybe, you know men don't experience so, you know, I teach the debug Academy classes and I worked at aquia for a while I was doing it part-time, but I found that there was a lot I know I haven't pulled off the bullets yet, but I I found there's a lot of opportunity to kind of Help people who wouldn't get into tech. Otherwise, if only I had more time But some things I've learned from running the classes are Women are just as interested in tech as men. It's it's not even a question of What they were doing before if you talk to them and You pick your words carefully. You don't say do you do tech you might say is that something you're curious about it? You know or you you presented as well. I think you can do it. Would you want to do it? You know the wording can Can really influence it but basically You know just as many women are interested as men that I speak to and Female students tend to be the top performers in the class you'll often have sometimes you'll have a guy come in with more tech experience and just kind of Think that they get it all and you'll have women come in and think you know Maybe this field isn't for me, but they tend to work harder And I found that you know we do an assessment an exam at the end of the semester And the female students tend to do better than the male students in general So how have we actually helped or extended privilege for them? The first one is you know, they get message, you know people get messages Basically that make them feel like they're not welcome into tech. So you have to counter that. It's not just about being neutral You kind of have to let them know You know, this is something you can do It's not as complicated as people like to make it sound Let's give you the information take a stab at it if you don't like it, you know, it's not the end of the world One of the things that I've done in the class is Typically when you sign up for a class, let's say you attend the first week and you drop out. There's typically a big penalty We just we give work before the semester starts for the semester for the month before the semester starts just HTML CSS that sort of thing If you really don't like that, then maybe you shouldn't take the class, you know It's a chance to find that out But also during the semester if you're two or three weeks in I've had a couple of people basically Approach me and just say, okay, this isn't for me, you know, I don't like it and You know depending on the semester honestly because it is a business We will have some where we'll just refund them the whole payment if we can But otherwise we don't give a penalty for having joined the course We essentially pro rate it you pay for the classes you took you get all the money back for the ones you haven't taken And that's been helpful for people to also make the decision because I think if I take one class It's not the end of the world if I drop out Also, we strongly endorse them and this is something everyone can do If you know a woman looking to get into tech and you're already in tech you can speak up for them You know refer them that sort of thing But basically Unfortunately sometimes when women go to interviews, they're not taking us seriously for whatever reason and Someone who is you know a little more well known in tech Can put in a good word for them and it can make a difference and I say strongly intentionally you can don't just say like I referred her you know Speak to her level because unfortunately people tend to something, you know certain people Will take what you say as truth and won't take it as truth when they say it So you kind of just help them on the way in and then they've got it from there There's a big you know grow Drupal movement basically When we submit a patch to Drupal at work, we're really careful because we know, you know, it'll go through a Tight, you know strong review process Put that much effort into helping other people get into tech put that much effort into the referral email that you send This is a email that I sent I guess the dates on it February 21st I Don't have a template for my emails when I'm referring people in the class I get to know the people and I write, you know something that accurately reflects their knowledge I find when I'm referring a guy I maybe have to say a little bit about his personality like oh, he's introvert extrovert, you know He knows PHP when I'm referring a woman I tend to have to really explicitly lay it out to kind of cancel out the assumptions that the employer often has so like with this one Basically my emails for the guys who take the class tend to be much shorter But for this one, I'm referring someone named Lisa, you know, I it feels like overkill when I read it It feels like overkill But it just kind of tends to be necessary Lisa She does have a Degree. Oh, she actually just walked in hey Lisa Yeah, she has a degree in engineering, but she took some time off of work and You know, it can be hard for people to get back into tech so, you know with email I sent to To an employer I basically had to make sure to lay out what experience she had before that and what level I felt like she was at because employers tend to Kind of make assumptions in the wrong direction for female applicants and Lisa recently accepted a job offer Congratulations, Lisa So I feel like older people also have this bias Just to use a quick example my my dad works as an accountant with the federal government they're implementing a new system and It was assumed that he would need a few months extra to learn and Even though he had gotten it and it wasn't as Difficult as he had thought he was working at the standard level. They were still trying to Not get him out but wanting him to retire a little sooner so that they can bring in some young blood which is how they exactly put it and Do it crank it out a little bit faster so Assuming that they can't learn the tech that they would need extra time for it or that they don't even want to learn it You can't teach an old dog new tricks things like that are things that just are dangerous assumptions because they not only have the incredible experience that can only help but Most problems that they've dealt with before have been solved so Using that knowledge to pass it along is only going to Further every young developer every mid developer even older people who don't Have the resources to learn as quickly All right. Yeah, we actually had a student Take the class the semester before last Her name is Luanne. Hi Luanne if you're watching this She was near retirement and she's not the only person who takes the class when they're about to retire actually have had a handful and basically She's never programmed before she's she's has some some experience some technical experience, but she hasn't used Drupal before and She took the class. She was one of the top performers and now that she Graduated and she retired. She is actually going to be working With a cool nonprofit. She's basically volunteering on Non-profit Drupal sites. There's one in particular. I'm gonna give it a shout out because I forgot to put it in the presentation Hope one source. It's a Drupal based nonprofit in the DC area where they Basically make resources easier to locate for homeless people so she's you know, she's a Joining the join the class joining the Drupal community After retiring and she's going to be doing some good with it So So Racial bias that is something that I have heard and I've seen and it Is incredibly inaccurate but a black person early in their career usually has to prove that their personality isn't the preconceived personality that would be of any black person and that is such a shame because people of any kind of ethnicity of any kind of level can provide valuable information and experience and knowledge to To be what corporate wants you to be would be someone well-spoken and charming all the time Which is fine. I mean if you're going to be like the face of a company it Would make sense, but to have someone in the tech world or any field Want to be able to extend their knowledge and learn new things and teach new things that is obviously inaccurate And I've seen this a lot again the classes With some of the black students who take the class I sometimes will go with them to the interview and do an in-person introduction because I've seen on occasion Basically some of them will have you know solid technical knowledge and You know bias creeps in from the interviewer and they just don't give them a fair chance Basically, I've seen people who You know people of every ethnicity and programming who are introverted just quiet, etc But I've seen that be taken In a negative light for black students basically they'll they'll go in and be Quiet, you know not speak up, you know not sell themselves that well And it's almost like the interviewer assumes like something's up, you know Whereas if you have you know someone else Who's quiet the interviewer tends to assume well, they're just a nerd You know they they just like they have that nerdy personality where they're quiet And you know not great socially, but I it's not taken the same way so yeah, I I again Try to extend the privilege sort of thing by trying to you know Let them you kind of try to paint a picture and it really sucks that you know That's necessary at all like I shouldn't have to and you know it feels it feels wrong to say it because it's like that's not something I should have to do but Nonetheless until we get you know more diverse people in higher positions it's kind of necessary to You know to speak up for them And I hear this a lot I hear I've heard this from CEOs this doesn't apply to me. I don't see a color Yeah Great, I'm glad you don't see a color. That's it. That's a start but the thing is Objectivity has sailed at this point. There are people who genuinely will just You know see people of different races and be like well, I'm judging you all exactly the same, you know It's a technical test. There's there's no bias into it But I've but basically if you're the only person who doesn't see color It's still not totally a fair situation for the person Coming to the interview, you know, they're dealing with a bunch of other people who do have biases You know, I'm giving the benefit of the doubt to the people who say I don't see color. I'm not saying you You have biases that affect this but Yeah, if you want to Play that game other people do have biases that affect that So in some cases it's you know neutral isn't equal so you'll have to To have a to really find out does this person have the aptitude to be a programmer Like could they make it in this field rather than just giving them a PHP test? And I'm not saying this is easier to do For it to be fair. It's more like You know, you find out how much exposure have they had to it Maybe you put them on a trial where you give them, you know education training something like that Basically and then you kind of test them after that after they've had a chance to sit with the material So could in being in an environment that they may have not had the opportunity to be in before Because I have had people it's something I've really been torn about in my class like do I accept everybody or do I only accept people who pass some sort of minimum knowledge test and I've gone with accept everybody because there are always situations where where someone will Not know anything related to programming at the beginning of the class and that person shines at the end and joins the career, you know the downside to that is You know, sometimes you'll have people take the class and if they really aren't cut out for programming And that's kind of where we have the what I talked about earlier. If you drop out, it's prorated. There's no penalty that's kind of the balance we strike and like I said, you know Depending on how things are going with the business.  They all just happened to be there. I was posting an ad on Facebook for our class and I used that picture and You know, like I said, everybody has biases that you can be aware of other people's biases as well But you have to stop and think is this based in logic or is it just, you know, some bias that I need to overcome? So, you know, the truth is when I was posting this picture I was like, you know, there might be people who basically are racist who see this picture and might think I don't want to take that class And I was like, that's more reason I should use this picture So because, you know, on that one hand, that's thinking about the people who may be racist and look at it badly But what about the other people, you know, what about the, you know Diverse people in the picture That just means other companies are thinking this too and those people are not seeing themselves in these ads So I posted it.   I wouldn't go there. Be careful who you give your money to It's a Islamist organization. All this crazy stuff. I don't even know if Islamist is really a word But that's what it said So my concerns were realized I first deleted comments, but they kept coming. So I Basically replied and that actually ended up stopping them Looks like it's all blacks and Muslims. I wouldn't go there and I replied, well, you're not welcome So, you know You just stopped talking But, you know, just by posting that ad, you know, if you don't see color People who do see color create a really crappy environment and others have to deal with it before they get to you So that's why we have to put efforts into Reaching out and making it more welcoming because it's not neutral like neutral is not equal So a few more Examples of bias would be family life assuming that anyone with a family with children Even just close friends that need your help They would want to work from home more even though it wasn't needed or Leave early and they push their tasks to someone else Delegating like everything that was complicated, which I've seen a few times in previous jobs and having having that kind of situation at home and working full-time is very It's hard to find that right balance. So Realizing that it's not just an excuse and to find to help people find that balance or To work around with them would be ideal Another one disability someone with having a Visible physical any kind of disability in this field or any field It's also something that would need Need to be overlooked since When I first I'm just gonna tell this really quick when I first started A tech position there was someone in our office that was completely confined to a wheelchair and Couldn't move Couldn't move anything below I guess his hands and he was still able to to type and he People looked at him weird and I felt really bad and I would try to to connect with him And he was a full-stack developer He knew so much and I learned so much from him just by being there and just by Interacting with him more than everyone else did so I was really grateful for that Single employees I dealt with this also. I'm hitting all of these points just by that one job Assuming that people who are Available to work who don't have families don't have something going on at home are able to be online At all hours of the day and night I've had employers tell me that because I Don't have a family because I didn't have kids at home or anything like that I could attend every event that week and show myself off because I was a pretty girl who Would only benefit from having them see me That was yeah Somebody needs a punch now So whose job is it to fix this you can see the quote. I'm starting with the man in the mirror I also love that movie So the thing is nothing is too small Actually So small things can make an impact I actually just learned this yesterday that Went after I had taken the debug Academy class I went back to assist in a get training that was open to the public and During that time I mentioned how how it had changed my life how I became a Drupal developer and the class worked because of that a student that had attended just the get training decided to take the class and was Recently hired as a Drupal developer. I Didn't know at that time and I wish I did actually because I would have pushed him more But it was it made me feel really good because just by Raising awareness he was able to join an amazing community and Have a bomb job So nothing's too small Reaching that was also reaching beyond my circle since I hadn't planned on helping with that I just kind of came last minute and wanted to meet other developers meet someone who just needed my help and because of that I've continued to do it and I've Volunteered I've gone to events Booz Allen Hamilton, especially I've gone to a few events there and Just extending my circle and making sure that anyone who feels under represented or Needs any kind of support is Something that I can help with oh which goes into the next one participating in the free training events I had actually tried to get that first company to Get involved with the hour of code that teaches kids how to code During a week in December. I think and they refused so that kind of tells you what kind of company they were All right, let's see Yeah, one of the bullets basically like she was saying yeah, she encouraged her employers to participate in a free training that one didn't pan out but It's you know, that's what we need to do. Just like Make others who aren't thinking about it aware some of them will say yes And that might you know impact one or two people at the end of the day You might get a new core contributor, you know, they can go Go through the whole process and eventually There's a lot of talent out there basically that doesn't know they're talented So speaking about reaching out beyond our circles Okay, so I you know, I follow a lot of people outside of my circle on Twitter I really just like I'm like this isn't someone I would talk to follow, you know because I I want to bring more people in and So this is someone I had never met before she tweeted basically that she was going to become a great developer and that she was going to be an inspiration for black girls I Thought that was really cool so, you know, I followed her and she She tweeted on other occasions things that basically Gave away that She wasn't You know that well off financially But she still had an awesome attitude and I reach out to her We had the Drupal con the react JS class here on Monday. It was sold out for $450 a person When I tell that to like employers here, they're like, okay, that's reasonable, but if you talk to people who you know, I Don't know, you know are not developers or are not at this type of company. That's a lot of money But I invited her to it and she enthusiastically accepted But she didn't show up so we had that training she didn't show up You know, I was like, all right, whatever, you know, I tried I invited her Four days later or so I Was like, you know, I'm giving a talk on privilege and on you know, not being lazy about it Let me message her and see why she didn't show up for you know, truthfully I didn't ask why she didn't show up because it's not my business, but See if she had a reason, you know, I don't need to know what the reason is So I I reached out to her, you know, I said, oh, you know, it's cool that you didn't show up Did you not want to you know, did something come up? And she was really surprised I reached out, but she basically said, you know, something came up She couldn't make it and she was really embarrassed So she didn't reach out because of that So I told her, you know, it comes to the next one. So she came to the next one and You know, I met her she met Drupal After the class, she you know put out this tweet It was a class on react.js. She hadn't heard of Drupal. So I just told her come to the react class But the last sentence of that she was excited about Drupal and you know, feel free to follow her but basically She's in a community that you know, I'm not going to run out run into in in my circle of friends. She's on a slack channel that is basically a Channel for black people interested in tech in DC You know, so she has now heard of Drupal and she goes back there. She's telling them all about Drupal If she ends up Getting into Drupal. I think she would be awesome to have because every day she's tweeting about something new She's building and it's all in her spare time, etc You know, so it's it's very possible that eventually she'll be a core contributor. She seems like that port personality type But just by reaching out a little it didn't cost me anything to have another person in the room, you know So just by reaching out a little It could potentially have a big impact on Drupal and more importantly on her I'm gonna need to speed this up a little bit So what does better look like as far as Drupal goes having been a beginner pretty recently in the past three years or so the documentation for that was a little hard to follow for me and thankfully the Initiative seems to be happening soon and things are getting clear getting explained they're Becoming easier for people to actually use it and not have to go through a long list of 650 comments trying to go through that issue queue Yeah Okay package Contrib composer dependencies and as a file like core does Yeah, yeah, so I'll just mention this one because it isn't an idea I had but basically Composer really is a barrier to entry for For many it's mentioned on the next slide as well, but I'll just speak to that now basically a lot of my students used to You know work a lot of hours and they would work on the classwork on Metro a Lot of them wouldn't have internet access On and on Metro and they would have weak internet access at home or especially with Metro You know literally you pop out of a tunnel you you know you have internet for a few minutes and then you pop back in Composer being required. I don't want to say required because they say it's not required, but I'm using composer Pretty much kills working in Metro and that has been you know that has had a real impact on people Also with weak internet connections and that sort of thing so one thing I was considering is Core you know when you download core in a certain way it comes without the vendor directory without all the files You run composer install you get them But if you download core from the zip file it comes packaged with the vendor directory and that's how that's why they say you Don't need a composer. I think they should do that for contrib modules to Package the contrib modules vendor directory So that people who download the zip file don't need to then use composer at all Maybe you would throw in another set of instructions, you know drag the vendor directory to this folder or something like that and You know if a rebuttal were on the technical side Those technical the technical issues that apply to the suggestion I just made also apply to downloading modules using drush in Drupal 7, but that was good enough for a lot of people So I recommend throwing, you know, at least another link that says can't use composer Here's a full download link for the module and auto-populating documentation We we actually ran something called a barrier-free sprint. I'm gonna try to not talk too long about this but I Okay, so What we do for our classes is we write documentation for our projects And then this is a task on an actual web on an actual project on Drupal dot org We ran what's called a barrier-free sprint and basically it's a sprint where you can come in Maybe you haven't used Drupal before But you can actually set up a Drupal site and contribute something back Without any training on it. So we do that using this website. We made The issues up here, but scroll down how to install the Drupal site One-time setup it has composer instructions. If those don't work. It has git instructions Alternative if you're advanced you can do it that way How to start a new task, you know, you do more than one task You only go to these instructions and how to submit a completed task We are not writing these instructions on every issue We're writing them on the project and they're auto populating at the bottom of every issue I think Drupal dot org should have that I think it should have issues and then at a bare minimum auto-populated quick links for this how you install Drupal core This is how you install the module Using a module like the token where you can swap out text automatically You can write instructions for installing a module once put a token for the module name and have it auto populate throughout the site So basically we don't need to write the documentation for every module, but we could populate it so put in a little technical work and We can really make this Much easier make contributing and using Drupal much easier And it's like it stopped presenting when I left You So this is one of our students hopefully the audio works in this room Basically, you can just talk a little bit about, you know, why you made the changes the type of changes you made What your experience was like that sort of thing There's nothing out there identified to help, you know Identified to the community in regards to how you could use the path auto function in your URL so with the documentation that I created with me having a little background and I'm Test writing I actually created this document where I went step by step and added screenshots to the actual documentation I like to submit Laying out the path from start to finish in regards to how to use the path auto function It actually has on different ways if you've already have content created There's a path in there that identifies what you would need to do if you already have content identified that you want to go back after the fact and identify The correct path on their use of the path auto function that's available for you now Okay Alright, so that was Kevin. He's awesome. He also just accepted a job recently he He's still a current student and he wrote much better documentation for the path auto module than what we have out there So instead of I feel like instead of dividing devoting so many resources to maybe rewriting documentation you could devote resources to Getting people trained and maybe have them write documentation on their way in I'm gonna go through these really quickly so that we can get That is Kevin Very all right, sorry about that. We're just about out of time so I want to Get through those last ones pretty quickly All right. Okay. Yeah, so this is Kevin Um Very nice guy Yeah, he hadn't really used Drupal before attended a free get training and now he's a Drupal developer That's who had learned that I had become one and went to become one himself and this Drupal con three sessions are presented by people who took our classes. I didn't even know two of them were applying But basically They're all female, you know, so this is all from one small program and it's three speakers at Drupal con You know, so it's it doesn't take some insurmountable budget to You know increase the diversity in the community You just have to do it So the next three are the three speakers If you hit right on the arrow, I'll go to the next slide Okay, Kirsten you probably know her because she's amazing she had actually Already had development experience Yeah, oh we're going that fast No, no, it's fine Amani she had Become a she majored in conflict analysis and resolution and became a Drupal Developer with beaconfire red She's also a speaker That was this morning I Had never written the line of code and took the class. I became a Drupal developer and now work with booze Allen Hamilton Just gonna we've got just two more that we're showing You know, this is what a Drupal developer looks like he's like one of the nicest people I know very smart and I Think it's pioneering evolution that hired him shout out to them great company Who's you know willing to give people without development and experience a chance? But he's going to do very well in his career We've got Ali he's Ali we had taken the D book class together and he actually Works on my team now. He had been an engineering major. I think environmental science yeah, and Now works in on my team in my office every single day Yeah, that's about it Yeah, so we hope you enjoyed the session There's my Twitter, there's Farah's Twitter in our emails If you want to follow debug Academy You know spread the word we work really hard to increase the diversity in The Drupal community. I've been told it's a great community within the community But yeah, we're really you know Proud of the three new speakers. I think they're two of them are first-time attendees at Drupal con But yeah Any questions If there are let us know I didn't expect questions in this one. We didn't want to answer them anymore. Yeah All right, thank you all for coming Like how long do I have to smile


our next speaker, they say you can't cheat time, but he can find foes and yourself with latency try, try terrorization. Our next speaker, let's give her a round of applause. Thank you. Hello, mates. Thank you for being here and joining me in this talk. My first talk has said about geolocation. You can cheat time as a quote from Dr. Rue, as you can see from the TARDIS next to it. And I'm Lorenzo, call me Lopok if you want, and you can find me on Twitter, you can find my code I'm releasing today on my GitHub. And let's talk about geolocation. Geolocation is something that has always been important for humans and was, has always been a power driver for progress and technical things like sextant, mechanical clocks or GPS too. So very important. And even in our realm, so the cyber realm and internet is important too. Now we face some limitation. Almost anyone knows large IP based geolocation services. I don't want to name all of them, but you can just type some IPs and find with a certain precision where they are. Due to the massive use of a cloud provider and CDNs, we can no longer use them because you just have one, anycast, one or more, anycast IPs and you do not know where they are. You maybe find the location of the company that is on that subnet, nothing more. So this is what has driven my work. So looking through the cloud cartain. So answer the geolocation question in the cloud provider word. Some theory before we start, it's a mathematical physics, don't be scared, it's very simple. This is a simple one. Distance is a speed per time. This is a first order estimation of distance starting from a time. So it's something very easy and have to run. So keep in mind but it's important. It's very easy. Another thing is to keep in mind. It's obvious but keep in mind. Nothing can move faster than speed of light. Even if we are hackers, we are computer scientists, we are anti-sust, we cannot break this law. This is a law of this universe, maybe in another one it's another speed but we have to remember that nothing can travel faster than the speed of light. Even information, even things on the internet. And some terminology now, latencies versus speed. We sometimes confuse them. Maybe the person that knows best what is the difference are video gamers because the latency is actually the lag. So it's a time measure and it's in milliseconds or more but it's a time measure. Whereas speed is an amount of data or an amount of whatever, over a given amount of time. So keep in mind this and remember the speed of light limit. Latency cannot be arbitrarily low because it's the time information takes from a point to go to another one. So you cannot make information travel from Sydney to San Diego in two milliseconds. It's impossible. This university doesn't want. So obey the rules. Now, trilateration. Trilateration is a well-known method for estimating at unknown position starting from known points. So it's commonly used for GPS, for tracking smartphone. Okay, it's not very good use but it's used for or rock radio stations and so on. So it's a very well-known method. And we need for this recipe some points, fixed points from where we perform our measures and we have to know their exact position. So radio towers or so on. We will discuss what we will use for our problem. Then distances. So a method for estimating distances between the unknown target and these points and then obviously the target that is what we are looking for. So this is the simple recipe for trilateration. Then we have another important powerful tool that is a mathematical tool that is a minimizer and we will use it for providing data we have collected and inferred like points, distances and it will output some of the best points the target could be. So this is something that I will not dive into minimizer but you can. Trilateration has been used for tracking people even by dating apps. It's not actually a knack because sharing data is something that is up to the user but has been exploited for tracking people. So the system is the same. Fixed points so where you have your measure points so your client and the target, the unknown target and then do some trilateration. Well, let's do some practice now. This is a ping. Almost anyone here have used ping at least one time in his life and it's the first approach to latency. Ping is a round-trip time measure from a client and a server and it gives us as output many parameters like the average time and so on and by using it's a very naive measure but by using it we can infer some important information. For instance, in this example, we have the minimum round-trip about 55 milliseconds and combining it with the upper bound of speed in this universe so the speed of light we can assure, we can literally sign with our blood that the target cannot be farther than 8.300 kilometers. So these are very important things but okay, surprise, surprise, it's useless. It's useless because two things. Services behind clouds are not IP services and so you cannot use ICMP protocol for reaching them. You will only reach the ingress point of the CDN so it's useless and will be the nearest to you. Second thing, internet is not linear like speed per time. Speed per time is a linear function so it's almost useless.  I love BGP but it's another story and so it's not linear at all. And all of this is projected over a spherical body in the universe so it's not linear at all. We need to find a better model for estimating a distance starting from a latency. So I've used machine learning so anyone use machine learning today but I used it for estimating starting from a latency the actual distance more or less. Machine learning requires many data. I collected around 40 kilo measure, couple of measures, source destination. Each one targeted with a country code, source country code code actually and trained over the distance inferred via, computed via overseen function so the sources start between source and destination so we have as features country code and we use it as a bag of words for who knows what machine learning data science things works. And then latency times and as output the real distance. I used the NSVR support vector regression model is very simple to use and I will run on this because we are running out of time. Now recall the recipe. We need points. The best way to have many points around the world is using a cloud provider. Choose your favorite one and deploy some lines of codes on each of them. We are talking about cloud front services like command and control so we cannot use ICMP anymore but we have to measure latency on application layers so I use HTTP or so I use a cool for HTTP and HTTPS protocol. We have to deploy these lines of code on each point we choose. We have to compute latency. It's a simple instruction and the read manual is perfectly explained and then we have to compute the distance using our machine learning model and at this point we have to erase. A point of erase that are data centers and they coordinate and you have found your biosynth or googling them or whatever and distance inferred via machine learning model and the unknown point we are looking for. Now we have to do the magic with some math and we have to minimize all these things. I will go fast on these two but is a minimizing process over the residual between the hypothetical position and the distance we have collected. We have inferred before with the machine learning model. And I don't know if it's clear, yes. And you will have many outputs. I will use a small set just for make it better to be understood and this is a cloud of possible points with a centroid on the west of UK and the server was actually in London. So it works. The yellow circle is the upper bound of the speed of light radius. So we know that the point cannot be outside that circle. So it's very good for the speed of light radius. So we know that the point cannot be outside that circle. So it's very good for just latency-based method of inferring a position. But let's do something cyber. The main problem, the main things I was working on is common and control behind cloud front. At the moment anyone works on threat intel in case they have a fronted common and control or malicious site for the living malwares, raises their hands and say, oh, we cannot do nothing. We cannot say nothing on which part of the world the service is or isn't. Unless you call the cloud provider but good luck if you have tried, I don't know, let me know. But surprise now and until now it was impossible. I arrived to a good result in this method and this is not precise at all. I could have put an example that was more precise but I wanted to say that it's not very precise. It's not a kilometer precision method. Here we have a real service behind the cloud front located in Rome and using only latency's measures and no more than a dozen of point of measures. We have this fancy hit map and an error of 600 kilometers. That in Europe is a lot but imagine the rest of the world I think is a good result. Please appreciate it. Something more that we can use this method for is sandbox detection. Sandbox many times has a fake net behind. So a system that mimics the real behavior of a network of the internet but it's very difficult to cheat time or mimic the behavior of a latency versus some points. So we have just just we can embed our model inside the malware and a number of fixed points inside it embedded in it with target country and what I said before. And in presence of fake net, latency will be only few milliseconds so the result will be something that graphically is a non overlapping circles. So it's an impossible mathematically solution. It's impossible. It's impossible. There's no point that minimizes the function that we've seen before. We can even add some random latency fake net but I don't know if someone worked for it. We could try but I don't think it will work better than a real network. And the other thing similar to the sandbox detection is a malware self geolocation. And you can ship a malware with inside this model some fixed points and some automatic process for determining which area of the world is running and then turning on or turning off some features or the malware self. So I think it's nice things to do. Is it at the moment perfect? No. Is it bullet proof? Absolutely not but promising. I'm very clear. I don't want a wow effect. It's an early stage research so I'm very, very frank on it. Then I have a demo and here it is. Is it full screen? No. Okay. Sorry. Okay. This is the notebook. A Jupyter notebook that you will find on my Github. It's a poc for this and I ship it with my pertrained model but I will have to retrain it again. It starts with the measure that is a long process and then it starts estimating an offset that is important because of the inner latency of the computation due to the computational time of the server we are reaching. So we first determine an offset for all the latency measure. We subtract them to the measured latencies and then we have to estimate distance with our machine learning model. And these are the distances. This is the main process. Trilateration is done with a method that we can discuss of the records for avoiding some outlier and so on. And then we already have the 8 map now but it's not plotted. We find a cluster, the largest cluster of these points and we compute even an estimation of the error. And then the plotting time and here it is. No popping calc like my exploit friends but it's nice. Wait. Okay. So this is the one of the example in the slide. So it's an actual one and thank you for this. Then I'm done with two minutes earlier. So if some of you want to make some questions. Okay, BGP is a big mystery for me and for almost anyone but I came across the fact that BGP is more stable than what we used to. And the machine learning due to the fact that it's a large amount, not an enormous amount of data but it's a large amount of data collected. It responds very well even during a few months or a few weeks. So maybe combining it with a looking glass, BGP status and so on would be even better but I assure you that it's more stable than I expected. Sorry, I cannot. Okay, artificial latency. Yes, it's you can introduce in your services or artificial latencies but would be useful but if you collect a large amount of measures, not just one, you will find the main value. So you will have a distribution like a Gaussian one with a random latency artificially introduced in any service or so and then you can use all the smallest one or the main value and you can use the system in the same way just with a slightly modified check preconditioning of the data. I've tried my, but I'm not good at machine learning. I'm a physics actually but I've tried for SVR. It's stable, I know it well and it's very, you can control it well. So why not trying for some other models? Okay. Thank you guys. Girls, mates.


Day 9 let's make a file. This will be the first time we'll write to our file system So that will be very exciting So I've made this little make.s Program all it does is it tries to create a file using a new XSCB make that turns into The BDOS create file system call and this will create and open a new file So if you make Who it currently bails out with unimplemented? create file will create a directory entry for the file that you specify and Set set it in the open state so that you can then use it to write data We're not writing any data. So it will just get a empty directory entry So let's find In our BDOS we want Create file. We are going to have to implement nearly all of these But most of them are trivial So These are going to be unimplemented These are unimplemented this one is not unimplemented this is that should actually be direct console IO That allows you to do things like poll for pending keys I'm sorry. No, it doesn't console status here does that direct IO Actually, yeah direct IO Is direct console IO it provides a direct interface to the BIOS so it bypasses anything that the BDOS might be doing in fact our implementation here doesn't do that. So Get version just returns this constant value Close file. We're going to be working on Not quite next next but one Delete yeah, right sequential we're going to have to do eventually Rename. Yeah, get login bitmap just returns 16 bit value ditto Haven't done anything in this yet Turn the 16 bit value this one will be interesting this This looks up a value in the BIOS storage and returns it. That's not complicated These are just simple wrappers around read sequential and write sequential What they do is they seek to a certain position specified with an absolute number of records Read sequential and write sequential have all the same information in them They just stored weirdly in the FCB. So that's not tricky not complicated compute file size scans the directory it looks for the largest extent number and Uses that to compute the total number of records in the file This is used to convert a sequential position into a random access position That's pretty straightforward. That one doesn't do anything and This one is kind of special This one will write a random record to a new allocation block and Fill all the other records in that allocation block with zeros So, yeah, it is actually in CPM 2.2 despite the fact there's a gap in the numbering system So what we're gonna do is this is actually going to be part of open file I'm gonna put this here Creates a file entry File set carry for error Thinking about the Z80 Okay, so make who cannot open file. It's returned an error good So what this does? Let's find the BDOS Make here we go So what this does is it's going to look for an empty directory entry Find one copy the user's FCB into the dear end flush it to disk and That's it really We don't need to worry about a lot of these things so that you know, for example The user extent is not relevant because we know it's going to be zero. This is a new file The record count is going to be zero because this is a new file, etc, etc So the main thing we need to do is to Create a directory entry ensure that we update The number of directory entries and Make sure there isn't a matching file now weirdly If the file exists already the default action is to return to the command prompt at IE do a soft reboot Which makes no sense whatsoever I have written CPM codes that tries to create files and like you have to try and open it first to make sure that the file doesn't exist So that you can return a reasonable error message, but Anyway We're going to Initialize the FCB we want to check to see if the drive is right protected so this is calling this function called check write and This is doing a hard error which will abort the program Don't think we've done any of those This is calling an error handler routine so we're actually going to Here this looks like it's a table which you can patch I do not actually recall any of this from the error message So yes, this the standard error handling it'll print a message Wait for the user to press a key and then do a soft boot Which isn't that awful? I suppose Okay, so check This right ball. This is what the directory handling. So this would go and drive management so Drive Check disk disk writeable, and we'll just put an RTS there for now. I think create file Yeah, so we now want to search for a Deleted directory entry and to do that We are going to Call find first But we want to set the drive byte in the FCB to e5 to tell find first we're looking for empty directory entries This will overwrite the existing drive, but that's okay because we know that the It's been processed here We know that what's in there is the user code and we have the user code handy so we don't need to save it This is pushing it on to the stack in the 8080 code So we call find first If Carrie is clear We've got one so we now want to copy the contents of the user's FCB into the directory buffer We want to make sure the allocation part is The allocation part of the FCB is all zeroed That's kind of important as we have no disk blocks allocated so We're going to So this is going to be a simple loop where we just copy a byte Current dear end come away. Yep to compare that with The allocation buffer so that's just going to be Current record actually no we're going to do AL plus 16 So we are going to update the current user to the right value we are going to ensure that The These four fields are all zero. We know the s2 has been zeroed because that happens in New user FCB, but the others are not zeroed so Actually, we're going to do this further up here So we can save a tiny tiny amount of code Okay, now I can't remember what I actually called that Routine it's in find. No, it's not it's in login Check no not check dear pause. Here we go update CDR max Have I done this Right actually, I think actually I think not So we don't want to clear the metadata Because we're relying on the user Doing that the user has to clear those spikes for the routine to work properly and that's in the Specification But we do have to We do have to do this bit Because we want to leave the file. We want to leave the FCB opened We do want to clear the allocation area in the FCB So we're going to do that here So we start at here So that means that we don't have to do this here because We can just copy the whole thing out of the FCB and it should be valid So I think that's everything we need apart from one Terribly important thing. What's this set? Set foof. Okay. That's the that's the s2 byte There is one terribly important thing we want to do which is we need to write that sector back to the disk now we could Just not do that Set this bit to zero. This means that when the file gets closed by the user program then this should end up being written back, but that would be dead confusing because Firstly the close code would have to handle the case where there wasn't a matching dear end for the FCB and Also, if the user tries to create another file Because this is always going to find the first file We'll end up trying to put two files in the same directory entry and that ain't gonna work So how do we Read From the disk well Read dear entry is the code that's actually doing the work and this is pre incremented that means that this as correctly set the Sector number and DMA and so on so Hopefully all we need to do is just call write sector and it should work Okay, but we haven't actually implemented this This is luckily very easy code and this becomes by us right we're going to Bring that out Set current sector like this. Okay So let's see if it works then so make Nord cannot open file Did I remember to clear the carry make Lord cannot open file Okay, I am gonna guess that find first here is booked so let's Stick a jump star there Fire up the debugger and see what happens break One C 2 9 break point in break one C 2 9 reset continue Okay, so set the drive bite of the Dear end of the day the FCB which is at 2188. So there is our directory entry With a E5 at the beginning What we're looking at here actually is makes P blog So there is the command line afterwards, which is nice so Should be in find first now Should there be an LDA zero? Ah We need to tell it how many bytes of directory entry we want to compare so for deleted files That's a one. I've forgotten that that act that calculation normally happens in the public entry point so let's Oops, what's that? I'm scanning a big document. So if you may be able to hear machine noises occasionally and It's not a very good scanner We were going to Did I save that I Did not save that okay So we are going to restart and try that again. So we are here So we set the count Home to drive reset the directory position Read a directory entry Check to see if we're at the end of the directory. We are not Did the user want to see deleted files? Yes, so we skip the CDR max test do We are now going to do the comparison So we check the first byte. It's not a question mark This we are not looking at byte 13. We're not looking at the extent byte So we're here Compare the two characters. This should be a zero. It's a zero That's not a zero Right, that's because the first directory entry is a file. Okay, so I Think we've got four files in our directory. Okay, actually, I think I'm just going to continue and The program thought it worked. Let's do a dir and that does not look like it's worked That looks like it's corrupted our disk So let's take a look at what it did Well, it has written a directory entry It's got a user code of zero Everything here looks fine So why did dir not work? This is the first directory entry which is on a It's in the second record so Possibly something with the logic there has gone wrong. They know what's happened It's printing one file Because in the during the login process when we scan the bit scan the directory we compute CDR max We're incorrectly calculating it based on the position in the directory buffer. So we look at the first record Well, let me look at the second record and We see that There's a maximum value of one here. This is one directory entry We go down go through the rest and then when we do the directory scan Because CDR max is one we only return one file Right thing do yeah, so this is This is That's not that's it. This should be correct current dear end is the Is a counter So Wait, what's this doing? Move on to the next dear end Directory pause should be the the count of directory entries Current dear end is a pointer So the maximum directory entry in the file. This should be Directory pause and and Yeah, directory pause is a two byte value. So this Facts throughout all this code. This should be current dear end Directory pause Okay, right, let's try that couldn't open CCP. Well That'll be because this isn't working and Calculate the offset in the get the sector number Load the sector And take the directory buffer and we add What on earth is this doing? This is calculating Directory buffer plus Things if we've gone through here, I think it's expecting directory pause to be the shifted Now these things is faking a to be the shifted directory pause But if we've gone through here and loaded a new sector then that will be corrupted So I think that needs to be LD zero to indicate that the shifted the directory pause is going to be zero Which we know it will be because we're at the beginning of a new sector so it Yeah, open CCP So I'm willing to bet this is because this code is doing something wrong. Have I misunderstood how my own code works? So we read a directory entry We increment directory pause the directory pause is pointing at the directory entry. We just read Are we resetting? the CDR max value in the dph I am not actually sure we Much code if carry set return three bytes. So that is the same as A jump to exit I don't think that will help no Okay, let's put a breakpoint in here because I bet this is what is causing things to go wrong bugger One EC zero Okay, so we are reading directory pause which is zero at this point because We've just read one directory entry the first one and there's incremented the directory pointer from invalid minus one to zero And our dph is at five C4 and it's all zeros Okay So we do the two byte Comparison wait What this code is bollocks We want to you see this compare instruction is going to discard the result of the previous compare instruction That should be a sbc. So this is going to do a two byte comparison By basically subtracting directory pause and dph if dph is greater than or equal to Directory pause and I'm great. I think this wants to be a carry clear due to the way we've done this so we're subtracting This is done. This is dph minus directory pause so a is Directory pause if directory pause is greater than or equal to dph carry set. Okay, then update CDR max So compare Tracked Carry is set because we haven't updated CDR max yet So we now set CDR max and we go around again this time directory pause should be One which it is so Okay, and again and again and again and Again, so this looks like it correctly set CDR max oh oh Is the find next code here correct the directory still looks valid 1d9e Okay, so we should have done the login which means that CDR max should be set up correctly so CDR max still at 5c4 and I believe it's These two bytes indicating four You see this is actually doing a compare an SBC, but I bet that this comparison is wrong Yes, it is wrong. That's inverted. How did this ever work in the first place? so compare Current drent that should be directory pause Okay, 2obf is The directory pause which is currently Zero Yes, we've read one directory entry. So it's gone from minus one to zero So zero is less than CDR max. So we do not brunch Right, and now it loads the CCP and if we go to dir One two three four five and Good, I think that works So if I can type Fnaud and it's empty I can dump Fnaud and it's empty It's not really a lot else I can do with it So I think we're creating files Let's make some more. So if I do make Baz Okay, let's try and Make another Fnaud that shouldn't have worked and it's created two Fnauds Why did that? Oh, I know why it's because this search we did for empty dirrents has in fact Ignored the filename. So I think we're going to have to do another call to find first in fact, we don't want to load that with 15 and Want to use a symbolic number for this? so If carry is clear I if we did manage to read the file Then set carry and exit and I think we want to put that Here Because we're about to start tinkering with the FCB make Fnaud cannot open file That's correct. I want this one right. I change this file so it rebuilt the disk image Make Fnaud Fnaud cannot create file good Okay, I think that's working so what is next? Well First I have to feed the scanner Okay scanner is fed and scanning The document it's it's scanning a huge document with lots of pages and unfortunately the page feeder Oh, it feeds pages in all right. It just tends to Jumble them on the way out So once this is done, I'm going to have to put like 150 pages back into order Ah Anyway, that's a different problem. I think we now want to try and write to the file first I'm going to make me a new Helper Because we're about to have to start allocating disk blocks so let's make a Program that Dumps the allocation bitmap of the disk To the console now There is a call for this which is get allocation bitmap So we're going to put a Pointer here And we're going to have an index the allocation the allocation bitmap can contain More than 256 entries, but we know this disk is smaller than that and this is a hacky debug tool. So How does it work a return address of allocation map return address? Of the current allocation bitmap In h l okay So Get allocation bitmap sda bitmap plus zero sda in bitmap plus one So we are now going to Say repeat We are going to Load the byte index Get one of the allocation bytes Stick it in value You know what I was going to try and print it as weird as like x's and dashes but I can't be bothered. So Let's just print it as hex Which honestly is almost as easy to read. So we're going to copy this uh Print an 8-bit hex number And stick that in here So this is going to be print hex number print a space increment index Load index is it 32 which is I know is the number of bytes In my bitmap. No, I don't know that And 30 do will do fine Until it's equal Print a new line and exit Space is undefined. So there is our new program bitmap Unimplemented right that's because we didn't if we haven't implemented get allocation bitmap Which goes Here and this is going to This goes under drive management Does it no it goes under Login directory management I need to rename that banner location bitmap Say Incidentally I've had occasional comments about how clicky my keyboard is You'll be pleased to know that I have acquired a new clicky keyboard that is even clickier And it feels so nice to use. I'm probably going to end up using it as a daily driver Just not at work because I'm not allowed Where did we put the bitmap update bitmap status is doing it get bitmap location Is getting the location to the bitmap Bitmap address is in variable called bitmap Allocation bitmap from the dph. Okay. Well, that's easy Okay, so boot it bitmap Right There is that bitmap Okay, ignore the trailing garbage because we are dumping too many bytes, but we see that The first eight blocks are Allocated that's Not right Is it I think that is right, you know Because we now have lots of files. I was thinking we would just see the directory But our file system is Contains actual data So a block is Uh, how big is a block? 1k so that's 400. So we've got two blocks for the directory Uh, we've got a file We got Another file this looks like No, this is the ccp this one. It's c00 more files See there's actually quite a lot of ways to space because the allocation block is a kilobyte And most of our files are smaller than that There's a text file here we go. Uh, so p By 400 is eight. All right, that's correct. We have correctly computed the bitmap So let's go down to Make try and create the file. This is going to be it's fcb Right sequential Okay, we haven't done that one yet But we haven't imported it So now we want to Create our right sequential Right Add another library function So why are we importing get instead? Or we don't All clear So we now we are now calling right sequential in our program So We call make snored And we get unimplemented because we haven't done right sequential yet So We go to here entry right Sequential I'm sure it's spelt more or less correctly. So read sequential is this junk of code Early versions of cpm only had read sequential and write sequential if you wanted to do uh Random access Then the user would tinker with the fcb directly I'm actually not Tirely sure why they ended up putting the random access stuff in the bedoss Okay, now a lot of this code is going to be exactly the same so We're going to move some of this stuff out So this is going to be Get sequential Sector number Which is going to be all of this down to here Sector number Okay, this is going to fail because We don't have eoff yet. So if The disk block value is zero then Exit with the error code in a So here If carry is set we exit with error actually actually This can only ever return This can only ever fail like that. So Okay, so this should still work. We are reading sequentially So we are now going to copy All of this so if the Current record is equal to the record count the extent is full until we need to go and find another one So we get the allocation block We get the sector If Carry is set we're going to have to allocate a block A new one so Actually, we're not going to do it there Hmm, we did this comparison here because it's much easier to test to see if x and a are equal By writing them to memory. I think it's the only way but really We want to Do it Here So to do that we're going to do Change this way around to say there's two code paths one for big disks and one for small disks But This side of things is Harder So we actually want to All the two values together now, we can't do that there because you've put something onto the stack Uh, I think we're going to have to do this the hard way so So we all the two together if the value is zero we exit Uh, we have not set x at this point However, this code will do it We could safely reload the byte from y because we know they're both zero So now we want to Load them both again so ta to x decrement y And in fact that's better code so we can get rid of this code So read sequential. This is going to be We put that comparison there Let's make sure that still works It looks like it works Yep, good So in write sequential It essentially becomes this code So we are going to need to allocate a block number. Where is our block management code? Bitmap that'll be Here somewhere Given a block number and 10 plus zero and a block state isn't a sets it Okay, so allocate a new block from the bitmap allocate block That's going to be a procedure. I'm sure so We want to Work through the bitmap until we find a byte with a empty block in it and then we know that Okay, it's one bit per block therefore even if it's a big disk And we know that the block the bitmap must be less than 250 Do we know it's less than 256? No big disks can have more than 256 blocks So this is actually going to want to be a actual pointer arithmetic great so We're essentially going to want to load a byte Compare it with ff If it's not ff then this means that that byte must have empty blocks in it Otherwise, we're going to want to increment the pointer If roll over in 10 plus one We're also going to want to compare against the end of the bitmap So we can either compute the end of the The bitmap and then compare our pointer or we can use a counter So let's just use a counter That's the wrong field So the dp a here we go We want to know the We want to know the size of the Allocation bitmap That's not actually there that's in That's in the dpb Well, if we haven't actually I haven't created the macrofe a definition for this If I haven't created a definition for this then dp Ah, I'm copying it. That's what I'm doing. Yeah, here we go So, uh, so Wait Does the dpb contain the address of the Other that contain the length of the allocation bitmap. I am not sure it does So the dph contains directory Allocation vector Address of the allocation that's the dpb it does Not contain The address of the allocation vector. So in fact, we are going to need to Sorry does not contain the length of the allocation vector So we are going to need to CDR max is Wrong We are going to want to Load the We're going to need to compute how long it is from the uh Blocks on disk value Okay, no, we're not going to do that. We're going to do something else Because The reason it's going to be slower, but honestly, that's not important. So we copy the We take a copy of the number of blocks on disk and this is going to be our count Nope, I'm changing my mind again Our count is going to work up from zero Okay If if the block number is zero This is really really annoying Uh Rather than do this the cheap and easy way. I'm going to do this the slow and small way So This is block number We then Given the block number and temp zero return Rotated block status in a so We are going to Get bitmap status now. Unfortunately, this is going to overwrite Temp zero. Why did we do it like that? Because get bitmap location Read from temp zero and update the pointer Get bitmap Because this code Is using temp two and temp three for something else Okay So Okay, so we get the bitmap status into a And now we want to increment the block number If it rolls over Increment the high byte So then we can have a until zero That means the block is free Which means We can load the block number Into a x and return it um We don't have it's more important to be small than fast for all this stuff because even though it's a nasty O1 on Algorithm for finding the new block even on a really slow 8-bit machine The amount of time taken to find a block is insignificant compared to the amount of time taken to Actually write it to disk so This is going to be find unused Find unused block Into x a we now want to allocate it This is going to kind of change my mind about this again so Given a block number and temp zero and a single bit status in a So we are going to Block is now allocated update and Read the block number and return it Okay, so our Write code which is here We've allocated the block. We now want to Set it in the fcb Set the current block number in the fcb 2 x a set fcb block um So again, this is going to be using Temporaries block index Y Are we a big disk? So that's dx So we are going to load the low byte store the high byte door otherwise There is only the low byte simplify like this Okay, so I think this may actually do something so make Baz Hang on before we do that bitmap ff oo make baz Bitmap It did not allocate A bit. I was expecting that to be eight zero So let's get out the debugger and find out why Wait, what? We are calling write sequential That's very strange. Why is that not? going into write sequential There are no places where we can actually produce an error so I'm going to have to put our breakpoint here Foo Okay, now at least it breaks two two one seven Foo, okay So that did something weird. Let's try that one again. Shall we? Make foo kind of Make bar, okay That's better So we should have gone from We're now in xfcb Wait a minute. Wait a minute No, that's right. That's right. Um, I'm actually going to change this. I'm going to put uh Put our breakpoint here just to keep me sane So I don't have to step through the xfcb stuff Okay Break Debugger two two nine seven So we now go through the bidos here Right, we should now be in write sequential here, so We convert the user fcb We load the current record Which is zero We load the record. Oh, that's not right Ah, I know what's happening We are Uh We're treating this as end of file where we shouldn't be okay. That makes much more sense So we don't want to test against record count, but we do want to check for a Uh extent full error Because then we want to allocate a new extent and we haven't done that yet Okay, so this is going to get to the block Um Move the fcb onto the next record for next time Uh if cr is greater than record count update rc a record count is Current record is in a so compare with Param y so A is the current records if current record is greater than or equal to record count carry set Uh, we also want to We are going to want to mark the fcb as being modified and we do that by clearing that top bit of the s two Flag Which is this stuff here So we want to do that here fcb is modified And we want to do it Here Now notice that if we're writing to an existing block We don't necessarily modify the fcb. So we don't have to Clear the flag Okay, so make Floor okay bitmap four zero four zero Really still four zero. That's the wrong bit So this looks like it's uh This looks like it has actually calculated. It's it's found the right bit And then has set the wrong one. I know this because the next time through Yeah, because we've incremented it here So we actually want to do this here Break if zero Then do the increment. So then this has to become a loop end loop We were incrementing the bit block number after we did the test Yeah, and you notice that the bitmap has been reset. This is because we haven't written our fcb back eight zero good make C zero right it is allocating blocks correctly good so We are now correctly I think we are now correctly writing to Uh the file So that will This needs to go back to code Okay So make for lord bitmap Okay, so these should have written One records worth of stuff We haven't updated the directory But we should have actually written the data. So if I close this And we look at the image file We go down to the end we see In the right place a records worth of queues. That's this data here So there is one more thing we want to do One quite big thing we want to do Which is we go back to our application And we close the file now in cpm's close call is Uh badly named Because it doesn't actually close the file You use you can still write to the file after it's been closed That's not a problem because it doesn't change anything in the fcb other than to mark it as uh That it hasn't it doesn't need flushing again Uh what it does do is it syncs the fcb to disk So this is the point where any of your um New allocated blocks get written to the directory so that the next time the bitmap is read It'll see them This is actually pretty cunning It means that the file system ends up Being consistent in the extent of crashes If your program terminates without closing the file or rather without flushing the file syncing it to disk Then any blocks that have been allocated into that extent Will be uh Lost uh the data will have been written to disk but The directory entry won't have been updated to point at them This does the whole ordered write thing in a tiny amount of logic Uh, it means that the data gets flushed to disk before the metadata gets flushed to disk So that your metadata should always be correct uh The one place where this breaks down is if you change extents like if you seek between 16k boundaries We need to flush the current directory to disk So that we can load the the directory entry for the new extent Uh, so basically if you're writing to a big file you get periodic flushers As you seek around in the disk And the final changes only get flushed when you call close It's a fairly elegant system. Uh, yeah, we're gonna need to want to Add an xfcb function Now that's going to so this will go here Okay Close So we want prepare we want bidos file Okay So now when we run our program Make foo Unimplemented we haven't done close yet. So we find the n vector table Close file File open file create file close a file Flush the fcb to disk Okay So how does this work? Well As usual we want to convert the user fcb And as usual we want to go look at the original Uh implementation Now we have no idea where the Um Where the directory entry on disk actually is so we're going to have to search it So the first thing we're going to want to do is as usual Check that the disk is writable and it will fail with an error a hard error if it's not Check that this fcb has actually Changed it's an s2 If The value we just read is negative than the top bit is set And we can just return We now want to Find the Directory entry so to do this We are going to Stent we want to do a directory scan And we're looking for All The bytes Because we need something that matches Uh ex and s2 but not record count So s2 plus 1 find first if There's an error Then We do actually want to Fail Here What does it do? So if uh if it can't find it then this means that Yeah, it's just an error If the directory entry can't be found this means the user changed disks where they shouldn't There is a mechanism for testing if disks get changed By check summing the directory which we haven't implemented Okay, but at this point uh Directory entry has been updated to point at the drent We want to update the disk map Now I would have thought that you would just copy the fcb But why is this doing Such complicated code weird update the entry from the From the fcb so we want to update the Uh the record count for a start So load sd a Uh Because that's the only thing that needs copying we now want to Run through the merge algorithm Excuse me. I suppose the reason for doing this is that it's possible to have The same file open more than once That seems like a bad idea to be honest Okay, that's Yeah, I don't quite understand that but this is a big Chunk of complicated code. So I assume it's necessary Also, I am not sure that find first Uh Okay. Yeah, it does set carry if no files were found Does it Let me just double check that because that might explain why opening invalid files produces weird results No more files Does indeed set carry So I'm going to actually merge fcb into drent If there's an error exit That this is going to be fairly fairly small amount of code. So So that can just be branch if carry set to exit set exit and exit now We We do want to mark the Mark the fcb as modified fcb is not modified Okay So we need to do merge fcb into drent And we're going to put that down in the rest of our stupid internal logic They bitmap for drent Bitmap status blah blah blah Where's our Where's the code that actually Looks at The allocation block I can't remember but we were using it in right sequential We have set fcb block up here in read sequential. Well, that doesn't make any sense, but uh We want this code to be recently We want this code to be Located near each other. Okay All right now once the current block number e this is So are we a big disc? Yes That means that Our blocks are two mites. So we are going to load the fcb block number Compare it with the drent block number If they are Hmm Actually, I'm going to do the algorithm for the small disc first because that's going to be easier So and that will let me decide how it's actually supposed to work so uh If the fcb block number is zero then We don't have anything to do No, actually we do we want to we want to update the fcb from the drent in this case if the If the drent block Is zero Update it from the fcb otherwise Compare them If they are not equal Then this means that we have two files open. We've both tried to allocate different blocks for sorry. We have the file open twice and uh There is a conflict at which point we just give up so Merge error We just Fail Go on to the next one and keep going until we hit The end of the allocation map. Okay So that's our algorithm So now we have to do this For 16 bit values rm comma y And we are going to have to increment y again so that Let's actually put some new lines in to split things up a bit So that uh, we're consistent in the position of y Between the two branches of that if okay, so now Current drent comma y Hang on a second if fcb is yep. Okay. I have I flipped both sides of the But the arrow and the order so fcb goes to drent y is low so So now y is pointing at the low byte We want to compare the two do param first increment y comma y And then it's the same error code So in fact we can Like so and then increment y so it points at the next item Check for the end and terminate with success Okay not very I mean the algorithm is is simple enough, but I'm not particularly convinced by my implementation of it so Make Baz So we hang 1 d2 c d e f We're here.  No, we're doing this version Get the fcb block number. So this will be the one that we've just allocated Nope, that's not a correct block number. So our fcb is at 2 4 2 f And there is indeed a block number there, but we have set the wrong value There is a break at 1 d2 c Okay, get the block number 9 So somehow we managed to write back that Uh that block 8 is in use interesting. I wonder how that happened Anyway Um Is it zero? No Get the drent block. Is it zero? Yes therefore Copy into the drent are they different No, they're not which is a good thing because we've just copied one to the other Go around to the next one get the fcb block number. Is it zero? Yes, it is So we copy from the drent, but that's going to be zero as well, but this is harmless because they're the same Copy in the other direction. This is also going to go through And go around again. So let's just Finish that Edit So we can see that blue here does indeed have A block allocated to it. So there's bars. I don't know why So we see that there are in fact two blocks on disk Both of which are identical, but that's okay. I can dump that And we get 128 bytes of cues these shorter far names Okay, I think this is working The file system image will be extended by the moss operating system as needed I just need to make sure it's size the file is sized correctly I just need to make sure that the Disk definition is correct to make it actually fit on a floppy disk Cool, I think this is working. So we don't have any of the extent management stuff yet So when we reach the end of an extent we want to move to the next one We can't have files bigger than 16k, but I believe it is working. Let's Using make dfs to create a disk Image, okay, boot that from a real disk You see the pause as we get to here. That's because it's reading the next directory sector So I can make a file Oh interesting Right. I know what happened there. So what's happened is it's is uh It's tried to make the cpmfs file bigger So we've we've been dumped back to moss, but it can't Does xx work? Yeah So Uh This is a moss command that shows the names of the files Load address execution address length and start sector Dfs, which is what this is all based on doesn't support fragmented files So it can't make cpmfs any bigger Because the bdos file is In the way so if I kill this off and Change the order in which I add the files Like so Then I run it We see that uh bdos is below cpmfs cpmfs and the sector number. So I run that We should be able to extend the file. Indeed we can And there is our queue excellent Right, we can read and write files Just more files So that is really nice progress Uh, where's my vector table? We need to implement Uh the one The calls here that that we actually wanted to implement So that's going to be one Two three Four five six Seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen Yeah, there's still quite a lot of calls, but Most of the actual logic the hard stuff is done Uh the next bit Is going to be extent management uh, so Here and in fact All this is going to want to do Is to close the current extent to make sure it's been flushed Increment the extent pointer And Uh Open the file again So this is not going to be a lot of code and it's going to be the same code for both read and write Then of course we have to fix all the bugs Okay, so I am going to stop here for now because it's just Because I want to go and have lunch and my scan has finished So that is That's very pleasing. Okay next time extents